### OPEN SOURCE LICENSE - GNU AFFERO PUBLIC LICENSE Version 3.0 #######
#
#    Net::FullAuto - Powerful Network Process Automation Software
#    Copyright © 2000-2016  Brian M. Kelly
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or 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 Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public
#    License along with this program.  If not, see:
#    <http://www.gnu.org/licenses/agpl.html>.
#
#######################################################################

################################################################
#
#  Makefile.PL for Net::FullAuto
#
################################################################


our $VERSION='1.0000007';


if ($ENV{'AUTOMATED_TESTING'}) {
#if (1) {

   my $message=<<'END';

      DEAR CPAN TESTERS:

      First of all, THANK YOU for your selfless service to the Perl
      Community. Your generosity is appreciated more than is communicated,
      let me assure you.

      It has come to my attention, that this module is causing "problems"
      for CPAN Testers. It is not my desire to cause ANYONE "problems".

      Since no one has detailed just what those problems are, or expressed
      any interest in working with me to resolve them, I am disabling
      CPAN testing for the foreseeable future.

      Of course you are welcome and invited to test or use Net::FullAuto at
      any time, - simply comment out the AUTOMATED_TESTING environment
      variable conditional at the top of Makefile.PL and replace it with:
    
         if (1) {

      To avoid "problems" - I suggest testing on a virgin virtual machine.
      Net::FullAuto installs on an Amazon Free Tier micro server without
      issue. Just launch one up, and install cpan with this command:

      sudo yum -y install cpan  (on FreeBSD: 'su' then 'pkg_add -r perl')
                                (See instructions at line 1529 for openSuSe)

      run cpan and at the cpan command prompt type "install Net::FullAuto".

      Be sure $ENV{'AUTOMATED_TESTING'}==0.

      Net::FullAuto will install successfully on any Linux flavor or FreeBSD
      server in Amazon EC2. It will also install with Cygwin on Windows.

      I am willing and eager to work with anyone who is curious or
      interested in the Net::FullAuto project.

      Documentation is admittedly poor - that will be rectified soon.

      Thank you again,
      Brian Kelly

      Brian.Kelly@FullAuto.com

END

   print $message; 
   exit 0;

}

BEGIN {

   if (exists $ENV{PAR_TEMP} && $^O ne 'cygwin') {
      chdir "$ENV{PAR_TEMP}\\\\inc\\\\lib";
      my $partmp=`set`;
      my $partemp=$partmp;
      my $windir=$partmp;
      if ($partmp=~s/^.*PAR_TEMP=(.*?)\n.*$/$1/s) {
         $windir=~s/^.*windir=(.*?)\n.*$/$1/s;
         $windir=~s/\\/\\\\/g;
         $partmp=~s/\\/\\\\/g;
         my $cpancfg="$partmp\\\\inc\\\\lib\\\\CPAN\\\\Config.pm";
         my $ch=$partmp."\\\\inc\\\\cpan";
         my $cfg=`cmd /c type $cpancfg`;
         $cfg=~s/^(.*cpan_home[']?\s*[=][>]\s*q[[])[^]]+([]].*)$/$1$ch$2/s;
         my $ksw='keep_source_where';
         my $chi=$ch."\\\\sources";
         $cfg=~s/^(.*$ksw[']?\s*[=][>]\s*q[[])[^]]+([]].*)$/$1$chi$2/s;
         $chi=$ch."\\\\prefs";
         $cfg=~s/^(.*prefs_dir[']?\s*[=][>]\s*q[[])[^]]+([]].*)$/$1$chi$2/s;
         $chi=$ch."\\\\build";
         $cfg=~s/^(.*build_dir[']?\s*[=][>]\s*q[[])[^]]+([]].*)$/$1$chi$2/s;
         $chi=$ch."\\\\histfile";
         $cfg=~s/^(.*histfile[']?\s*[=][>]\s*q[[])[^]]+([]].*)$/$1$chi$2/s;
         $cfg=~s/^(.*use_sqlite[']?\s*[=][>]\s*q[[])[^]]+([]].*)$/${1}0$2/s;
         $chi=$partmp."\\\\inc\\\\tools\\\\tar.exe";
         $cfg=~s/^(.*tar[']?\s*[=][>]\s*q[[])[^]]+([]].*)$/$1$chi$2/s;
         $chi=$partmp."\\\\inc\\\\tools\\\\wget.exe";
         $cfg=~s/^(.*wget[']?\s*[=][>]\s*q[[])[^]]+([]].*)$/$1$chi$2/s;
         $chi=$partmp."\\\\inc\\\\tools\\\\dmake.exe";
         $cfg=~s/^(.*make[']?\s*[=][>]\s*q[[])[^]]+([]].*)$/$1$chi$2/s;
         $chi=$partmp."\\\\inc\\\\tools\\\\less.exe";
         $cfg=~s/^(.*pager[']?\s*[=][>]\s*q[[])[^]]+([]].*)$/$1$chi$2/s;
         $chi=$partmp."\\\\inc\\\\tools\\\\unzip.exe";
         $cfg=~s/^(.*unzip[']?\s*[=][>]\s*q[[])[^]]+([]].*)$/$1$chi$2/s;
         $chi=$partmp."\\\\inc\\\\tools\\\\bzip2.exe";
         $cfg=~s/^(.*bzip2[']?\s*[=][>]\s*q[[])[^]]+([]].*)$/$1$chi$2/s;
         $chi=$partmp."\\\\inc\\\\tools\\\\patch.exe";
         $cfg=~s/^(.*patch[']?\s*[=][>]\s*q[[])[^]]+([]].*)$/$1$chi$2/s;
         $chi=$partmp."\\\\inc\\\\tools\\\\gzip.exe";
         $cfg=~s/^(.*gzip[']?\s*[=][>]\s*q[[])[^]]+([]].*)$/$1$chi$2/s;
         $cfg=~s/^(.*gpg[']?\s*[=][>]\s*q[[])[^]]+([]].*)$/$1$2/s;
         open(CF,">$cpancfg");
         print CF $cfg;
         close CF;
      } chdir $curdir;
   }
   if (exists $ENV{PAR_TEMP} && $^O eq 'cygwin') {
      my $cygpar=`/usr/bin/cygpath -u $ENV{PAR_TEMP} 2>&1`;
      foreach my $lib (@INC) {
         next if $lib eq $cygpar;
         push @TMPINC,$lib;
      }
      @INC=@TMPINC;
   }
};

use Config;
use CPAN;
use subs qw/version name sign author license perl_version/;
use inc::Module::Install;

use if (($^O eq 'cygwin' && eval { require 'Win32::RunAsAdmin' })
   || $^O eq 'MSWin32' || $^O eq 'MSWin64'),
   'Win32::RunAsAdmin';

if ((($^O eq 'cygwin' && eval { require 'Win32::RunAsAdmin' })
      || $^O eq 'MSWin32' || $^O eq 'MSWin64') &&
      not Win32::RunAsAdmin::check()) {
   my $name=substr($0,(rindex $0,'\\')+1);
   $name=$ENV{SESSIONNAME} unless exists $ENV{PAR_TEMP};
   my $message=<<END;


   FATAL ERROR! - Windows Administrator privileges are needed in
                  order to install FullAuto or OpenSSH.
  
   If you have Administrator Rights, be sure to Right Click on the

      $name

   icon and select  -->  "Run as administrator"

   or, contact your Windows System Administrator to resolve.


END
   print $message;
   if (exists $ENV{PAR_TEMP}) {
      print "   PRESS ANY KEY to Exit Setup\n\n";
      <STDIN>;
   } exit 1;

}

# ASCII BANNER Courtesy of:  http://www.network-science.de/ascii/
# When FullAuto is installed, run:  fa --figlet  to view multiple fonts.

my $c=($^O ne 'MSWin32' && $^O ne 'MSWin64')?'©':'(C)';
my $fa_banner=<<END;



    __       __)
   (, )  |  /      /)
      | /| /   _  // _  ______    _    _/_ ___
      |/ |/  _(/_(/_(__(_) // (__(/_   (__(_)
      /  |



           _   _      _         _____      _ _    _         _
          | \\ | | ___| |_      |  ___|   _| | |  / \\  _   _| |_  |  
          |  \\| |/ _ \\ __| o o | |_ | | | | | | / _ \\| | | | __/ | \\
          | |\\  |  __/ |_  o o |  _|| |_| | | |/ ___ \\ |_| | ||     |
          |_| \\_|\\___|\\__|     |_|   \\__,_|_|_/_/   \\_\\__,_|\\__\\___/ $c 



   Copyright $c 2000-2016  Brian M. Kelly  Brian.Kelly\@FullAuto.com


END

%main::amazon=();
if ($ARGV[0]=~/\.pem/) {
   push @{$main::amazon{argv}},$ARGV[0];
}
%main::system_type='';
if ($^O eq 'linux' || $^O eq 'freebsd') {
   if ((-e "/etc/system-release-cpe") &&
         (-1<index `cat /etc/system-release-cpe`,'amazon:linux')) {

      # Manual Setup Amazon AMI host before CPAN:
      #
      # sudo yum -y install cpan

      $main::amazon{'ami'}='';
      $main::system_type='ami';
   } elsif ((-e "/etc/os-release") &&
         (-1<index `cat /etc/os-release`,'ubuntu')) {
      if (-e "/usr/bin/ec2metadata") {
         $main::amazon{'ubuntu'}='';
      }
      $main::system_type='ubuntu';
   } elsif ($^O eq 'freebsd') {

      # Manual Setup FreeBSD host before CPAN:
      #
      # su
      # pkg_add -r perl

      if ((-e "/usr/local/bin/aws") &&
            (-1<index `cat /usr/local/bin/aws`,'aws.amazon')) {
         $main::amazon{'freebsd'}='';
      }
      $main::system_type='freebsd';
   } elsif (-e "/etc/SuSE-release") {
      if (-e "/etc/profile.d/amazonEC2.sh") {
         $main::amazon{'suse'}='';
      }
      $main::system_type='suse';
   } elsif ((-e "/etc/system-release-cpe") &&
         (-1<index `cat /etc/system-release-cpe`,
         'fedoraproject')) {
      if (-e "/etc/yum/pluginconf.d/amazon-id.conf") {
         $main::amazon{'fedora'}='';
      }
      $main::system_type='fedora';
   } elsif ((-e "/etc/system-release-cpe") &&
         (-1<index `cat /etc/system-release-cpe`,
         'redhat:enterprise_linux')) {

      # Manual Setup Redhat host before CPAN:
      #
      # sudo yum -y install cpan

      if (-e "/etc/yum/pluginconf.d/amazon-id.conf") {
         $main::amazon{'rhel'}='';
      }
      $main::system_type='rhel';
   } elsif ((-e "/etc/system-release-cpe") &&
         (-1<index `cat /etc/system-release-cpe`,
         'centos:linux')) {

      # Manual Setup CentOS host before CPAN:
      #
      # sudo yum -y groupinstall "Development tools"
      # sudo yum -y install cpan 

      if ((-e "/sys/hypervisor/compilation/compiled_by") &&
            (-1<index `cat /sys/hypervisor/compilation/compiled_by`,
            'amazon')) {
         $main::amazon{'centos'}='';
      }
      $main::system_type='centos';
   } elsif (-e "/etc/gentoo-release") {

      # Manual Setup CentOS host before CPAN:
      #

      if ((-e "/sys/hypervisor/compilation/compiled_by") &&
            (-1<index `cat /sys/hypervisor/compilation/compiled_by`,
            'amazon')) {
         $main::amazon{'gentoo'}='';
      }
      $main::system_type='gentoo';
   }
} else { $main::system_type=$^O }

sub msw64bit {
   return 0 if $^O ne 'cygwin' && $^O ne 'MSWin32' && $^O ne 'MSWin64';
   my $bitout=`wmic os get osarchitecture`;
   return 1 if -1<index $bitout,'64';
   return 0;
} 

sub check_cygserver {

   my $check_for_orphaned_cygserver_service=`sc qc cygserver 2>&1`;
   unless (-1<index $check_for_orphaned_cygserver_service,'does not') {
      my $cygpath=~s/^.*H_NAME\s+:\s+(.*exe).*$/$1/s;
      $cygpath=~s/\\/\//g;
      unless (-e $cygpath) {
         # cygrunsrv does not exist - let's see if its running?
         my $chkrun=`sc query cygserver 2>&1`;
         if (-1<index $chkrun,'RUNNING') {
            # Its running - let's stop it
            my $stopout=`net stop cygserver 2>&1`;
            unless (-1<index $stopout,'stopped suc') {
               print "FATAL ERROR - cannot stop cygserver: $stopout\n";
               exit 1;
            }
         }
         # Now let's delete cygserver
         my $sc_out=`sc delete cygserver 2>&1`;
         unless (-1<$sc_out,'SUCCESS') {
            print "FATAL ERROR - cannot delete cygserver: $sc_out\n";
            exit 1;
         }
      }
   } return 0;

}

sub get_cygwin_location {
   my $cygwin_query=
         `REG QUERY HKEY_LOCAL_MACHINE\\SOFTWARE\\Cygwin\\setup 2>&1`;
   my $showcq=$cygwin_query;
   my $sep='\\';
   if ((-1<index $showcq,'unable to find') && msw64bit()) {
      $cygwin_query="$ENV{windir}\\sysnative\\cmd.exe /c ".
         "REG QUERY HKEY_LOCAL_MACHINE\\SOFTWARE\\Cygwin\\setup 2>&1";
      $showcq=$cygwin_query=`$cygwin_query`;
   } elsif ((-1<index $showcq,'Invalid key name') ||
         (-1<index $showcq,'cannot find the path') ||
         (-1<index $showcq,'unable to find')) {
      $cygwin_query=
         `REG QUERY HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Cygwin 2>&1`;
      $showcq=$cygwin_query;
      $sep='\\\\';
   }
   $showcq=~s/^/   /mg;chomp $showcq;
   my $cygwin_query_success=0;
   if (-1<index $cygwin_query,'REG_SZ') {
      $cygwin_query_success=1;
   } else {
      my $rcmd="REG QUERY HKEY_LOCAL_MACHINE${sep}SOFTWARE$sep".
               "Wow6432Node${sep}Cygwin${sep}setup 2>&1";
      $cygwin_query=`$rcmd`;
      $showcq=$cygwin_query;
      $showcq=~s/^/   /mg;chomp $showcq;
      if (-1<index $cygwin_query,'REG_SZ') {
         $cygwin_query_success=1;
      }
   }
   if ($cygwin_query_success) {
      #print "\n   REG QUERY RESULT:\n\n   $showcq";
      $cygwin_query=~s/^.*REG_SZ\s+(.*)\s*$/$1/s;
      $cygwin_query=~s/^\s*//s;
      $cygwin_query=~s/\s*$//s;
      unless (-W $cygwin_query) {
         unless (-d $cygwin_query) {
            # The cygwin directory indicated in the Registry does not
            # exist - let's delete the Registry entry
            if (-1<$cygwin_query,'Wow6432') {
               my $rcmd="REG DELETE HKEY_LOCAL_MACHINE${sep}SOFTWARE${sep}".
                        "Wow6432Node${sep}Cygwin /f 2>&1";
               my $regout=`$rcmd`;
               return 0;
            } else {
               my $rcmd='REG DELETE HKEY_LOCAL_MACHINE'.
                        "${sep}SOFTWARE${sep}Cygwin /f 2>&1";
               my $regout=`$rcmd`;
               return 0;
            }
         }
         if (-1<index $0,'Setup-FullAuto') {
            my $name=substr($0,(rindex $0,'\\'));
            print "\n\n".
               "   Fatal Error! - Write Access to $cygwin_query\n".
               "   is needed in order to install FullAuto or OpenSSH.\n\n".
               "   If you have Administrator Rights, be sure to Right\n".
               "   Click on the $name\n   icon and select ".
               "\"Run as administrator\"\n\n".
               "   Or, contact your Windows System Administrator\n".
               "   to resolve.\n\n   PRESS ANY KEY to Exit Setup\n\n";
         } else {
            print "\n\n".
               "   Fatal Error! - Write Access to $cygwin_query\n".
               "   is needed in order to install FullAuto or OpenSSH.\n\n".
               "   Please contact your Windows System Administrator\n".
               "   to resolve.\n\n   PRESS ANY KEY to Exit Setup\n\n";
         }
         <STDIN>;
         exit 1;
      }
      my $getver='';
      if ($^O eq 'cygwin') {
         $getver='cygcheck -c cygwin 2>&1';
      } else {
         $getver='SET CYGWIN=nodosfilewarning & '.
             "cmd /c $cygwin_query${sep}bin${sep}bash -lc ".
             '"cygcheck -c cygwin" 2>&1';
      }
      my $cygver=`$getver`;
      if ($cygver=~/(1.7.11-1)/) {
         print "\n\n   Fatal Error! - The current Cygwin version: $1\n".
               "   (Base Cygwin cygwin1.dll) is incompatible with\n".
               "   FullAuto. Please update to either a newer or older\n".
               "   version of Base Cygwin before again attempting to\n".
               "   to install FullAuto.\n\n".
               "   You may need to contact your Windows System\n".
               "   Administrator to resolve.\n\n".
               "   PRESS ANY KEY to Exit Setup\n\n";
         <STDIN>;
         exit 1;
      }
      if (-e "$cygwin_query/bin/bash.exe") {
         my $getid='';
         if ($^O eq 'cygwin') {
            $getid='id 2>&1';
         } else {
            $getid='SET CYGWIN=nodosfilewarning & '.
                "cmd /c $cygwin_query${sep}bin${sep}bash -lc ".
                '"id"';
         }
         my $groups=`$getid`;
         my $adm_gr=`net localgroup Administrators`;
         $adm_gr=~s/^.*---\s*(.*)\s*The command.*$/$1/s;
         my @adm_gr=split /\n/, $adm_gr;
         my $admin_flag=0;
         foreach my $id (@adm_gr) {
            chomp($id);
            $id=~s/^.*\\(.*)$/$1/;
            if (-1<index $groups,"($id)" ||
                  ($ENV{'USERNAME'} eq 'Administrator')) {
               $admin_flag=1;
               last;
            }
         }
         unless ($admin_flag) {
            print "\n\n",
                  "   Fatal Error! - The User $ENV{'USERNAME'} needs to\n",
                  "   be a member of the Administrator's group in order\n",
                  "   to install FullAuto or OpenSSH.\n\n",
                  "   Please contact your Windows System Administrator\n",
                  "   to resolve.\n\n   PRESS ANY KEY to Exit Setup\n\n";
            <STDIN> if exists $ENV{PAR_TEMP};
            exit 1;
         }
      }
      if ($_[0]) {
         my $getpath='';
         $cygwin_query=~s/\\/\\\\/g;
         if ($^O eq 'cygwin') {
            $getpath="/usr/bin/cygpath -u $cygwin_query 2>&1";
         } else {
            $getpath='SET CYGWIN=nodosfilewarning & '.
                "cmd /c $cygwin_query${sep}bin${sep}bash -lc ".
                "\"/usr/bin/cygpath -u $cygwin_query\" 2>&1";
         }
         $cygwin_query=`$getpath`;
         chomp $cygwin_query;
         return '' if $cygwin_query eq '/';
      }
      return $cygwin_query;
   } return 0
} 

$SIG{ INT } = sub{ eval { require Term::ReadKey };
                   unless ($@) { Term::ReadKey::ReadMode(0) };
                   print "\n";
                   <STDIN> if exists $ENV{PAR_TEMP};
                   exit 1};
$SIG{ INT } = sub{ eval { require Term::ReadKey };
                   unless ($@) { Term::ReadKey::ReadMode(0) };
                   print "\n";
                   <STDIN> if exists $ENV{PAR_TEMP};
                   exit 1};

use Cwd qw/cwd/;
use File::stat;
eval {
   CPAN::HandleConfig->load;
};
if ($@) {
   if ((-x "/usr/local/bin/perl") && ($^X ne "/usr/local/bin/perl")) {
      my $timeout=300;my $a='';
      my $toperror=$@;
      eval {
         local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required
         alarm $timeout;
         my $message=<<END;

   ERROR!:  $toperror

            It appears that the perl installation used to run
            Makefile.PL is an old system installation, and not
            the intended one.

            Another perl installation using /usr/local/bin/perl
            as the primary executable has been discovered.

            Would you like Makefile.PL to be run against that
            installation?

END

         my $fae="No   (FullAuto Setup will exit)";
         my $menu1 = [
                     $message,
                     [ "Yes", sub{ return 'Yes' } ],
                     [ $fae, sub{ return 'No' } ],
                     ];
         my $selection=&menu($menu1);
         exit 0 if $selection eq ']quit[';
         exit 0 if -1<index $selection, 'No   (';
         my $argvs=join " ", @ARGV;
         exec "/usr/local/bin/perl Makefile.PL $argvs";
         alarm 0;
      };
      die "$@: $!\n" if $@;
   } else {
      die "$@: $!\n" if $@;
   }
}
use POSIX qw/strftime/;
my $mycpantest=0; 
$main::curdir=&cwd;
$main::PARdir=$main::curdir;
$main::domain_gr_flag=0;
my $exec_cnt=0;
foreach my $dir (@INC) {
   my $incdir=$dir;
   $mycpantest=1 if -e $incdir."/CPAN/MyConfig.pm";
}
if (exists $ENV{PAR_TEMP}) {
   chdir $ENV{PAR_TEMP};
   $INC{'Module/Install.pm'}=$ENV{PAR_TEMP}.'/inc/inc/Module/Install.pm'
      if -e $ENV{PAR_TEMP}.'/inc/inc/Module/Install.pm';
   $main::PARdir=$ENV{PAR_TEMP};
}
unless (exists $ENV{FA_EDITOR} || grep { /Encrypted|SKIP/i } @ARGV) {
   print $fa_banner;
   sleep 2;
} elsif (grep { /SKIP/i } @ARGV) {
   $exec_cnt=$ARGV[$#ARGV];
   $exec_cnt++;
   my $module_fail=$ARGV[$#ARGV-1];
   my $mod_info='';
   eval {
      require CPAN;
      {
         local *STDOUT;
         open(STDOUT, ">", \$mod_info);
         CPAN::Shell->m($module_fail);
      }
   };
   my $instfile='';
   ($instfile=$mod_info)=~s/^.*INST_FILE\s+([^\s]+).*$/$1/s;
   my $instver='';
   ($instver=$mod_info)=~s/^.*INST_VERSION\s+([^\s]+).*$/$1/s;
   my $cpanver='';
   ($cpanver=$mod_info)=~s/^.*CPAN_VERSION\s+([^\s]+).*$/$1/s;
   if ($exec_cnt==1 && $cpanver ne $instver) {
         # && $instfile=~/vendor_perl/) { # &&
         #((exists $main::amazon{'ami'}) ||
         #(exists $main::amazon{'rhel'}))
         #&& $module_fail eq 'Pod::Man') {
      # Amazon's AMI has Pod::Man installed in the vendor_perl
      # directory which has precedence over the system directory
      # this module actually belongs in. The only solution is to
      # delete it from the vendor_perl area before we attempt to
      # install Pod::Man. We are doing this ONLY on Amazaon AMI
      # systems currently.
      system("sudo echo y | /bin/rm -rf \"$instfile\"");
   } elsif (2<$exec_cnt) {
      my $timeout=300;my $a='';
      eval {
         local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required
         alarm $timeout;
         $mod_info=~s/^.*?(CPAN.*)$/$1/s;
         $mod_info=~s/^\s*/      /mg;
         print "\n\n   Fatal Error!: The following Perl CPAN ",
               "module could\n                 ",
               "not be installed on your system:",
               "\n\n      $module_fail\n\n$mod_info\n",
               "   The FullAuto installation will not",
               "\n   succeed without this module installed",
               "\n   and loaded.",
               "\n\n   Please report any bugs and send any",
               "\n   questions, thoughts or feedback to:",
               "\n\n      Brian.Kelly\@FullAuto.com.",
               "\n\n   Press ANY key to exit.";<STDIN>;
               return;
      };
      alarm 0;
      exit 1;
   }
}

   my $demo_banner=<<'END';

                              ___     _ _   _       _
                             | __|  _| | | /_\ _  _| |_  | 
   (   /_ /_   _  _          | _| || | | |/ _ \ || |  _/ | \
   |/|/(-(( ()//)(-  To The  |_| \_,_|_|_/_/ \_\_,_|\__\___/c
    ___                        _            _   _
   |   \ ___ _ __  ___ _ _  __| |_ _ _ __ _| |_(_)___ _ _
   | |) / -_) '  \/ _ \ ' \(_-<  _| '_/ _` |  _| / _ \ ' \
   |___/\___|_|_|_\___/_||_/__/\__|_| \__,_|\__|_\___/_||_|
   --------------------------------------------------------

   If you are new to FullAuto, and would like a better idea of what it
   is and what it does, please explore the brief introduction before
   running the demonstration. You can access the introduction by just
   pressing [ENTER]

   Otherwise, use the DOWN ARROW [v] key to move the arrow to item 2
   and press [ENTER] - or just type 2 and press [ENTER] to start the
   demonstration.

END

   my $demo_banner_1=<<'END';

    ___     _ _   _       _
   | __|  _| | | /_\ _  _| |_  | 
   | _| || | | |/ _ \ || |  _/ | \
   |_| \_,_|_|_/_/ \_\_,_|\__\___/c
    ___     _               _         _   _
   |_ _|_ _| |_ _ _ ___  __| |_  _ __| |_(_)___ _ _
    | || ' \  _| '_/ _ \/ _` | || / _|  _| / _ \ ' \
   |___|_||_\__|_| \___/\__,_|\_,_\__|\__|_\___/_||_|
   --------------------------------------------------

   FullAuto is a breakthrough innovation in Network Process Automation.
   Any time a process involves more than one device, it is a "networked"
   process. Anyone who uses the Internet, engages in "network processing"
   - otherwise known as SURFING!

   The KEY <~[] to process **AUTOMATION**, is secure, persistent access
   to the command-line environments of connected devices. The Internet
   is in fact BILLIONS of connected devices.

   Browsers however, do NOT have direct access to the command-line
   functionality of remote devices, nor are they supposed to.
END

   my $demo_banner_2=<<'END';

   This is precisely why you are *not* reading this in a browser.
   -------------------------------------------------------------

   FullAuto is an Automation and High Productivity Framework - it is *NOT*
   a browser - nor is it "supposed" to be. But that doesn't mean it has to 
   be ...
               .-'''-.                                        ___
              '   _    \                                   .'/   \
   /|       /   /` '.   \         .--.   _..._            / /     \
   ||      .   |     \  '         |__| .'     '.   .--./) | |     |
   ||      |   '      |  '.-,.--. .--..   .-.   . /.''\\  | |     |
   ||  __  \    \     / / |  .-. ||  ||  '   '  || |  | | |/`.   .'
   ||/'__ '.`.   ` ..' /  | |  | ||  ||  |   |  | \`-' /   `.|   |
   |:/`  '. '  '-...-'`   | |  | ||  ||  |   |  | /("'`     ||___|
   ||     | |             | |  '- |  ||  |   |  | \ '---.   |/___/
   ||\    / '             | |     |__||  |   |  |  /'""'.\  .'.--.
   |/\'..' /              | |         |  |   |  | ||     ||| |    |
   '  `'-'`               |_|         |  |   |  | \'. __// \_\    /
                                      '--'   '--'  `'---'   `''--'
END

   my $demo_banner_3=<<'END';

                        (                   (        )   ____
                        )\ )   (     (      )\ )  ( /(  |   /
                       (()/(   )\    )\    (()/(  )\()) |  /
                        /(_))(((_)((((_)(   /(_))((_)\  | /
                       (_))  )\___ )\ _ )\ (_)) __ ((_) |/
           ___ _ _     / __|((/ __|(_)_\(_)| _ \\ \ / /(
          / _ \ '_|    \__ \ | (__  / _ \  |   / \ V / )\
          \___/_|      |___/  \___|/_/ \_\ |_|_\  |_| ((_)


 BECAUSE you don't have to . . .

  ____ ____ ____ ____ ____ ____ ____ ____     ___     _ _   _       _
 ||R |||E |||M |||E |||M |||B |||E |||R ||   | __|  _| | | /_\ _  _| |_  | 
 ||__|||__|||__|||__|||__|||__|||__|||__||   | _| || | | |/ _ \ || |  _/ | \
 |/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|   |_| \_,_|_|_/_/ \_\_,_|\__\___/c
  ____ ____ ____ ____ ____ ____ ____ ____
 ||C |||O |||M |||M |||A |||N |||D |||S ||    _  _  __ __  ______   _
 ||__|||__|||__|||__|||__|||__|||__|||__||   | \/ \|_ (_    |  |   |_||  |  
 |/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|   |_/\_/|____)  _|_ |   | ||__|__
END

   my $demo_banner_4=<<'END';

    ___     _ _   _       _
   | __|  _| | | /_\ _  _| |_  | 
   | _| || | | |/ _ \ || |  _/ | \
   |_| \_,_|_|_/_/ \_\_,_|\__\___/c

      _  _   _ _____ ___  __  __   _ _____ ___ ___
     /_\| | | |_   _/ _ \|  \/  | /_\_   _| __/ __|
    / _ \ |_| | | || (_) | |\/| |/ _ \| | | _|\__ \
   /_/ \_\___/  |_| \___/|_|  |_/_/ \_\_| |___|___/  THE

    #####   ###     #####   ##  ## #####     FASTER,
   #######  ###    ### ### ### ###  #####    EASIER,
   ### # #  ###    ### ### ### ###  ## ###   with more,
   ##      ###     ##   ## ##  ###  ##  ##   VISIBILITY,
   ##      ###     ##   ## ###  ## ###  ##   more PRECISION,
   ### # # ### ### ### ### ### ### ### ###   more CUSTOMIZABLE,
   ####### ####### ####### ####### ######    LESS COST, and MORE RESULTS than
    #####   #####   #####   #####  #####     any other technology AVAILABLE!!

END

   my $demo_banner_5=<<'END';


     __    _____ _____ / __    '########::'########::::'###::::'##:::::::
     ||    ||==   ||    ((      ##.... ##: ##.....::::'## ##::: ##:::::::
     ||__| ||___  ||   \_))     ##:::: ##: ##::::::::'##:. ##:: ##:::::::
                                ########:: ######:::'##:::. ##: ##:::::::
      ____  _____ _____         ##.. ##::: ##...:::: #########: ##:::::::
     (( ___ ||==   ||           ##::. ##:: ##::::::: ##.... ##: ##:::::::
      \\_|| ||___  ||           ##:::. ##: ########: ##:::: ##: ########:
                               ..:::::..::........::..:::::..::........:: 

   The *CLOUD* is nothing more than REMOTE DEVICES. FULL Automation of
   the *CLOUD* means FULL remote control of these devices. To achieve
   that, a tool requires FULL, PERSISTENT and SECURE access to a remote
   device's command-line environment. Computer Professionals typically
   use tools like SSH (Secure Shell) and SFTP (Secure FTP) to gain full
   access to remote command-line environments. These utilities are already
   installed on billions of devices globally, or can be easily installed
   for FREE on nearly EVERY network connected device in existence -
   including smart phones and tablets!
END

   my $demo_banner_6=<<'END';

        ___     _ _   _       _
       | __|  _| | | /_\ _  _| |_  | 
       | _| || | | |/ _ \ || |  _/ | \
   THE |_| \_,_|_|_/_/ \_\_,_|\__\___/c
    ______                    _           _                            _
   (____  \                  | |      _  | |                          | |
    ____)  ) ____ _____ _____| |  _ _| |_| |__   ____ ___  _   _  ____| |__
   |  __  ( / ___) ___ (____ | |_/ |_   _)  _ \ / ___) _ \| | | |/ _  |  _ \
   | |__)  ) |   | ____/ ___ |  _ (  | |_| | | | |  | |_| | |_| ( (_| | | | |
   |______/|_|   |_____)_____|_| \_)  \__)_| |_|_|   \___/|____/ \___ |_| |_|
                                                                (_____|

   Current automation technologies do not typically use generic and readily
   available utilities designed for human interaction - like the command
   shell you are now using for this demonstration. Rather they rely on an
   architecture known as client-server. The problem with client-server is
   that special (and often VERY costly) software needs to be installed on
   *EVERY* device BEFORE it can be accessed and automated. This very
   requirement is one of the biggest productivity obstables to rapid
   automation implementation. Additionally, client-server setups are much
   more complex, fragile, and challenging to code and maintain than FullAuto!
END

   my $demo_banner_7=<<'END';

        ___     _ _   _       _
       | __|  _| | | /_\ _  _| |_  |
       | _| || | | |/ _ \ || |  _/ | \
   THE |_| \_,_|_|_/_/ \_\_,_|\__\___/c
       ____  _ ________
      / __ \(_) __/ __/__  ________  ____  ________
     / / / / / /_/ /_/ _ \/ ___/ _ \/ __ \/ ___/ _ \
    / /_/ / / __/ __/  __/ /  /  __/ / / / /__/  __/
   /_____/_/_/ /_/  \___/_/   \___/_/ /_/\___/\___/

   FullAuto uses already available SSH and SFTP services to FULLY automate
   command operations on remote devices. The DIFFERENCE lies in *HOW* FullAuto
   connects to and uses these services. Unlike any other technology, FullAuto
   creates and maintains a PERSISENT connection via these protocols, and
   even older ones like TELNET and FTP. Current SSH 2.0 implementations can
   be configured to allow similar behavior, but it varies from device to
   device, and is not widely available. FullAuto has NO such dependency. If
   a SSH client (or TELNET or SFTP or FTP) of ANY kind can connect to the
   device, FUllAuto can connect to it as well - PERSISTENTLY.

END

   my $demo_banner_8=<<'END';

    ___     _ _   _       _
   | __|  _| | | /_\ _  _| |_  |
   | _| || | | |/ _ \ || |  _/ | \
   |_| \_,_|_|_/_/ \_\_,_|\__\___/c
    __    __ _              _____ _                  _   _
   / / /\ \ \ |__  _   _    \_   \ |_    /\/\   __ _| |_| |_ ___ _ __ ___
   \ \/  \/ / '_ \| | | |    / /\/ __|  /    \ / _` | __| __/ _ \ '__/ __|
    \  /\  /| | | | |_| | /\/ /_ | |_  / /\/\ \ (_| | |_| ||  __/ |  \__ \
     \/  \/ |_| |_|\__, | \____/  \__| \/    \/\__,_|\__|\__\___|_|  |___/
                   |___/
 
   For the very first time, there is now an automation tool that works just
   like computer professionals do. The very same commands and work-flows
   that professionals use every day can now be introduced almost verbatim
   into a FullAuto custom code file, and work precisely the same as if
   performed manually. FullAuto leverages the skillsets and legacy tools
   and scripts already in place in countless organizations all over the
   world - and simply connects them ALL together like never before. The
   result is faster automation implementation, eaiser maintainability, and
   significantly lower costs. Staff will spend less time on repetitive
   tasks, and more time on innovation.
END

   my $demo_banner_9=<<'END';

    ___     _ _   _       _
   | __|  _| | | /_\ _  _| |_  |
   | _| || | | |/ _ \ || |  _/ | \
   |_| \_,_|_|_/_/ \_\_,_|\__\___/c
      _             _   __    __ _                 __               ___
     /_\  _ __   __| | / / /\ \ \ |__  _   _    /\ \ \_____      __/ _ \
    //_\\| '_ \ / _` | \ \/  \/ / '_ \| | | |  /  \/ / _ \ \ /\ / /\// /
   /  _  \ | | | (_| |  \  /\  /| | | | |_| | / /\  / (_) \ V  V /   \/
   \_/ \_/_| |_|\__,_|   \/  \/ |_| |_|\__, | \_\ \/ \___/ \_/\_/    ()
                                       |___/

   False assumptions. The "experts" thought a tool like FullAuto was not
   possible. The assumption was because output from a generic connection
   could have INFINITE variation (TRUE), that there was "no way" to create
   a solution that could successfully separate transmission noise from
   valid command-line output and error output (which makes unpredictable
   appearances in the output). Running one command programmatically has
   never been an issue - but the goal of running MULTIPLE commands
   INTERACTIVELY over a PERSISENT "generic" (i.e., not client-server)
   connection - was assumed to be **impossible**. (FALSE!!)

END

   my $demo_banner_10=<<'END';

    ___     _ _   _       _
   | __|  _| | | /_\ _  _| |_  |      ___    __   __     _  __ _ ___ __ 
   | _| || | | |/ _ \ || |  _/ | \     | |_||_   |_  \/ |_)|_ |_) | (_
   |_| \_,_|_|_/_/ \_\_,_|\__\___/c    | | ||__  |__ /\ |  |__| \ | __)

   __      _____ ___ ___     _      _____  ____  _  _______  __ 
   \ \    / / __| _ \ __|   | | /| / / _ \/ __ \/ |/ / ___/ / /
    \ \/\/ /| _||   / _|    | |/ |/ / , _/ /_/ /    / (_-- /_/
     \_/\_/ |___|_|_\___|   |__/|__/_/|_|\____/_/|_/\____/(_)


   Not the first time in history this has happened. There is no technical
   reason that a tool like FullAuto could not have been created 30 years
   ago, but for the false belief that it wasn't possible. Experts will
   generally not spend their time trying to solve "impossible" problems.
   Not until Brian Kelly has anyone apparently thought any differently.
   Brian conceived of FullAuto as early as 1998, and began active
   development in 2000. However, it would take 15 LONG years to make it
   a reality. The experts were wrong - but they weren't crazy. The
   problem was not trivial, and the solution is not either!

END

   my $demo_banner_11=<<'END';

   People typically use utilities like SSH and SFTP to access the
   command-line environments of remote devices. These utilities are
   already installed on millions of devices globally, or can be easily
   installed for FREE on mearly EVERY networked device - including phones
   and tablets.

   Programs however, typically rely on client-server architecture,
   which requires that special software be installed on *EVERY*
   device BEFORE it can be accessed and automated.

   "Technically", ssh and sftp are also "client-server". The critical
   difference is that these programs are *NOT* "special".



   As long as a device can be remotely connected to via ssh, sftp,
   telnet, ftp, http or really, ANY remote computing protocol,
   FullAuto can completely automate any and all activities on that
   device, and other devices all simultaneously and persistently.

   Essentially, whatever a person can do on and with a device
   "manually" - FullAuto can do PROGRAMMATICALLY ... securely.

END

   my %fullauto_demo_10=(

      Name => 'fullauto_demo_10',
      Banner => $demo_banner_10,
      Result => sub { return '{fullauto_demo}<' },

   );

   my %fullauto_demo_9=(

      Name => 'fullauto_demo_9',
      Banner => $demo_banner_9,
      Result => \%fullauto_demo_10,

   );

   my %fullauto_demo_8=(

      Name => 'fullauto_demo_8',
      Banner => $demo_banner_8,
      Result => \%fullauto_demo_9,

   );

   my %fullauto_demo_7=(

      Name => 'fullauto_demo_7',
      Banner => $demo_banner_7,
      Result => \%fullauto_demo_8,

   );

   my %fullauto_demo_6=(

      Name => 'fullauto_demo_6',
      Banner => $demo_banner_6,
      Result => \%fullauto_demo_7,

   );

   my %fullauto_demo_5=(

      Name => 'fullauto_demo_5',
      Banner => $demo_banner_5,
      Result => \%fullauto_demo_6,

   );

   my %fullauto_demo_4=(

      Name => 'fullauto_demo_4',
      Banner => $demo_banner_4,
      Result => \%fullauto_demo_5,

   );

   my %fullauto_demo_3=(

      Name => 'fullauto_demo_3',
      Banner => $demo_banner_3,
      Result => \%fullauto_demo_4,

   );

   my %fullauto_demo_2=(

      Name => 'fullauto_demo_2',
      Banner => $demo_banner_2,
      Result => \%fullauto_demo_3,

   );

   my %fullauto_demo_1=(

      Name => 'fullauto_demo_1',
      Banner => $demo_banner_1,
      Result => \%fullauto_demo_2,

   );

   my %fullauto_demo=(

      Name => 'fullauto_demo',
      Item_1 => {
     
         Text => "FullAuto Introduction",
         Result => \%fullauto_demo_1,

      },
      Item_2 => {

         Text => "FullAuto Demonstration",

      },
      Scroll => 1,
      Banner => $demo_banner,

   );

   if (-1<index lc($0), 'demo') {

      my $demo_out=Menu(\%fullauto_demo);
      print "DONE WITH DEMO\n";<STDIN>;
      exit;
   }

if (-e "dependencies/CPAN/authors" &&
      !(grep {
      /(?:use[-_]?)?internet|online|connect_to_internet_ok/i } @ARGV)) {
   opendir(DH,"dependencies/CPAN/authors/id/F/FR/FREW") ||
      die "Cannot open dir dependencies/CPAN/authors/id/F/FR/FREW: $1\n";
   my $filenames_not_trunced=0;my $got_sub=0;
   while (my $line=readdir(DH)) {
      $line=~tr/\0-\11\13-\37\177-\377//d; 
      chomp($line);
      if ($line=~/Sub-Exporter-Progressive-.*gz$/) {
         $filenames_not_trunced=1;
         last;
      }
      if (-1<index $line,'Sub-') {
         $got_sub=1;
      }
   }
   close DH;
   unless ($filenames_not_trunced) {
      if ($got_sub) {
         if ($^O eq 'solaris' && (-e '/usr/sfw/bin/gtar')) {
            my $message=<<END;

   FullAuto Setup ERROR!:  It appears that the solaris system tar
                           command was used to expand
                           Net-FullAuto-Complete-$main::VERSION.tar.gz,
                           which is a problem. The solaris tar utility
                           has a limit on the length of directory depth
                           and filename that is exceeded by some of the
                           dependencies bundled with FullAuto Setup.

                           Use the tar utility /usr/sfw/bin/gtar to
                           expand Net-FullAuto-Complete-$main::VERSION.tar.gz.

END
            print $message;exit 1;
         } else {
            my $message=<<END;

   FullAuto Setup ERROR!:  It appears that the tar command used to expand
                           Net-FullAuto-Complete-$main::VERSION.tar.gz,
                           has a problem. Some tar utilities have a limit
                           on the length of directory depth and filename
                           that is exceeded by some of the dependencies
                           bundled with FullAuto Setup.

                           Hint: Install and use GNU tar to untar (expand)
                                 Net-FullAuto-Complete-$main::VERSION.tar.gz.

END
            print $message;exit 1;
         }
      } else {
         my $message=<<END;

   FullAuto Setup ERROR!:  It appears that there are missing dependencies
                           in the dependencies/CPAN/authors folder of this
                           Net-FullAuto-Complete distribution.

END
         print $message;exit 1;
      }
   }
   my $loc="$main::curdir/dependencies/CPAN";
   $CPAN::Config->{keep_source_where}=$loc;
   $CPAN::Config->{connect_to_internet_ok}=0;
   $CPAN::Config->{index_expire}=1000;
}

use File::Path;

$main::root_dir=$main::curdir;

   my $incflag=0;my @drive_options=();
   $main::uname_a='';
   my $perl_version=$^V;
   $perl_version=~s/^v//;
   $main::uname_a=`/bin/uname -a` if $^O eq 'linux' || $^O eq 'freebsd';
   if ($^O eq 'cygwin') {
      my $cygcheck=`/bin/cygcheck -c` || die $!;
      my $uname=`/bin/uname` || die $!;
      my $uname_all=`/bin/uname -a` || die $!;
      $uname_all.=$uname;
      my %need_packages=();
      if ($uname_all=~/x86_64/) {
         foreach my $package ('gcc-core','gcc-g++','make','openssh','openssl',
                              'openssl-devel','perl','db','libdb-devel',
                              'ncurses','cron','inetutils','procps','vim',
                              'unzip','libmpfr4','libcrypt-devel','nano',
                              'perl-libwww-perl','perl-LWP-Protocol-https',
                              'wget','git','figlet','autobuild','autoconf',
                              'automake','libtool','libxml2','libxml2-devel',
                              'pkg-config') {
            unless (-1<index $cygcheck, "$package ") {
               $need_packages{$package}='';
            }
         }
      } else {
         foreach my $package ('gcc-core','gcc-g++','make','openssh','openssl',
                              'openssl-devel','perl','perl-Win32','db4.8',
                              'libdb4.8-devel','ncurses','cron','inetutils',
                              'procps','vim','unzip','libmpfr4','nano',
                              'wget','git','figlet') {
            unless (-1<index $cygcheck, "$package ") {
               $need_packages{$package}='';
            }
         }
      }
      if (keys %need_packages) {
         my $packs='';
         foreach my $pack (sort keys %need_packages) {
            $packs.="$pack ";
         }
         if ($packs) {
            print "\n\n   Fatal Error!: The following Cygwin",
                  "\n                 packages are missing from",
                  "\n                 your installation:",
                  "\n\n   $packs",
                  "\n\n   Please report any bugs and send any",
                  "\n   questions, thoughts or feedback to:",
                  "\n\n      Brian.Kelly\@FullAuto.com.",
                  "\n\n";
                  <STDIN> if $ENV{PAR_TEMP};
                  exit 1;
         }
      }
      my $services=`ps -e` || die $!;
      my @required_cygwin_services=();
      foreach my $cygwin_service ('cygserver') {
         push @required_cygwin_services, $cygwin_service
            if -1==index $services,$cygwin_service;
      } 
      if (-1<$#required_cygwin_services) {
         my $services='';
         foreach my $service (sort @required_cygwin_services) {
            $services.="      $service\n";
         }
         if ($services) {
            print "\n\n   Fatal Error!: The following Cygwin ".
                  "services are not running on your system:".
                  "\n\n$services".
                  "\n\n   The FullAuto installation will not".
                  "\n   succeed without these services installed".
                  "\n   and running.".
                  "\n\n   Please report any bugs and send any",
                  "\n   questions, thoughts or feedback to:",
                  "\n\n      Brian.Kelly\@FullAuto.com.",
                  "\n\n";
                  <STDIN> if $ENV{PAR_TEMP};
                  exit 1;
         }
      }
      if (!check_for_compiler()) {
         if ($Config{cc} && $Config{cc}=~/gcc-4/) {
            `cd /usr/bin;ln -s gcc.exe gcc-4`;
            `cd /usr/bin;ln -s g++.exe g++-4;cd $main::cwd`;
         } else {
            my $stup='setup-x86.exe';
            $stup='setup-x86_64.exe' if $uname=~/WOW64/ || msw64bit();
            my $die=<<END;

       FATAL ERROR! : The Gnu C Compiler 'gcc': gcc-core
                      & gcc-g++ as provided by Cygwin
                      is required to install FullAuto
                      on Windows.

       ( Hint: Run Cygwin $stup and install 'gcc-core'
               and 'gcc-g++' under the Category 'Devel' ).

END
            die $die;
         }
      }
   } elsif ($^O eq 'MSWin32' || $^O eq 'MSWin64') {
      unless ($ENV{PAR_TEMP}) {
         my $die=<<'END';

       FATAL ERROR! : Cygwin Linux Emulation Layer
                      is required to use FullAuto
                      on Windows - goto www.cygwin.com.

           Be sure to install the following programs in
           addition to the base package:

           inetutils and openssh [as provided by Cygwin]
           perl [as provided by Cygwin] (*NOT* CPAN)
           perl-Win32 [as provided by Cygwin] (*NOT* CPAN)
           ncurses, cron, and procps [as provided by Cygwin]
           gcc-core and gcc-g++ [as provided by Cygwin]
           Oracle Berkeley DB [as provided by Cygwin or Oracle]

           **IMPORTANT** - the FullAuto install, either manual
           or via CPAN, must be run *inside* a Cygwin bash shell
           when installing FullAuto on Microsoft Windows.

END
         print $die;
         exit 1;
      }
      $incflag=1 if -e './inc';
      use if ($^O eq 'MSWin32' || $^O eq 'MSWin64'), "Win32::DriveInfo";
      use if ($^O eq 'MSWin32' || $^O eq 'MSWin64'), "Term::Menus";

      fa_license();

      my $cygwin_loc=get_cygwin_location();
      if ($cygwin_loc) {
         my $drv=substr($cygwin_loc,0,1);
         my $dt=Win32::DriveInfo::DriveType($drv);
         my $FileSystemName=(Win32::DriveInfo::VolumeInfo($drv))[3];
         my $file_size = (Win32::DriveInfo::DriveSpace("$drv:"))[6];
         my $banner=<<'END';

    ___                     _            _     _
   |_ _|_ __  _ __  ___ _ _| |_ __ _ _ _| |_  | |
    | || '  \| '_ \/ _ \ '_|  _/ _` | ' \  _| |_|
   |___|_|_|_| .__/\___/_|  \__\__,_|_||_\__| (_)
             |_|
END
   my $size_file=&size_fmt($file_size);
         $banner.=<<END;

   FullAuto Setup has detected a Cygwin installation at $cygwin_loc.
   Setup has also determined that there is $size_file Free Space on
   the Drive $drv Volume. It is IMPORTANT TO NOTE that FullAuto Setup
   will attempt to use this installation. If this is undesirable, then
   select choice '2' and FullAuto Setup will EXIT. It is recommended
   that you use the cpan utility to install or update FullAuto, if
   there is more than one Cygwin installation on your system.

   If you're sure you wish to proceed with your $cygwin_loc setup,
   then select choice '1' and FullAuto Setup will continue . . .

END
         my %cygchoice=(

               Label => 'cygchoice',
               Item_1 => {
                  Text => 'Continue with FullAuto Setup',
               },
               Item_2 => {
                  Text => 'CANCEL FullAuto Setup and EXIT',
               },
               Scroll => 1,
               Banner => $banner,

         );
         my $selection=Menu(\%cygchoice);
         chomp($selection);
         if (-1<index $selection,'Continue') {
            my $cwd=cwd();
            my $p='/usr/bin/perl -MCPAN -e';
            my $b="$cygwin_loc/bin/bash -lc";
            exec "$b \"$p 'install Net::FullAuto'\";'fa --new-user'";
         }
         exit if $selection eq ']quit[';
         exit if $selection eq 'CANCEL FullAuto Setup and EXIT';
         $main::root_dir=$cygwin_loc;
      } else {
         my $drv='';
         foreach my $d (Win32::DriveInfo::DrivesInUse()) {
            my $dt=Win32::DriveInfo::DriveType($d);
            next if $dt == 5 || $dt == 4 || !$dt;
            my $FileSystemName=(Win32::DriveInfo::VolumeInfo($d))[3];
            next if $FileSystemName ne 'NTFS';
            my $file_size = (Win32::DriveInfo::DriveSpace("$d:"))[6];
            my $one_gb=1024*1024*1024;
            if ($one_gb<$file_size) {
               $drv=$d;
               if ($dt == 3) {
                  push @drive_options, "Drive $d NTFS Fixed Disk ".
                                        &size_fmt($file_size)." Free Space";
               } elsif ($dt == 2) {
                  push @drive_options, "Drive $d NTFS Removeable Disk ".
                                        &size_fmt($file_size)." Free Space";
               } else {
                  push @drive_options, "Drive $d NTFS Volume ".
                                        &size_fmt($file_size)." Free Space";
               }
            }
         }
         if (-1<$#drive_options) {
            if (0==$#drive_options) {
               if ($^O eq 'MSWin64' || msw64bit()) {
                  $main::root_dir="$drv:\\cygwin64";
               } else {
                  $main::root_dir="$drv:\\cygwin";
               }
            } else{
               my $banner="\n\n   Please select the Drive/Volume where you ".
                          "would like\n   Cygwin and FullAuto Installed.\n".
                          "\n   ( If you don't see the Drive/Volume you ".
                          "desire,\n     it is probably because the Drive/".
                          "Volume lacks\n     sufficient disk space. At ".
                          "least One Gigabyte\n     of free space is needed ".
                          "for a Windows based\n     Cygwin/FullAuto ".
                          "Installation. )\n\n";
               my %menu_drives=(

                  Label => 'menu_drives',
                  Item_1 => {

                     Text => "]C[",
                     Convey => \@drive_options,

                  },
                  Banner => $banner,

               );
               my $selection=Menu(\%menu_drives);
               chomp($selection);
               exit if $selection eq ']quit[';
               $selection=~s/^\s*Drive\s+([A-Z])\s+NTFS.*$/$1/s;
               if ($^O eq 'MSWin64' || msw64bit()) {
                  $main::root_dir="$selection:\\cygwin64";
               } else {
                  $main::root_dir="$selection:\\cygwin";
               }
            }
         } else {
            print "\n\n   Fatal Error! - Insufficient Disk Space.\n".
                  "                 At least One Gigabyte (1.0 GB) of\n".
                  "                 Free Disk Space is needed to install\n".
                  "                 Cygwin and FullAuto on this Windows\n".
                  "                 host.".
                  "n\n   Please report any bugs and send any",
                  "\n   questions, thoughts or feedback to:",
                  "\n\n      Brian.Kelly\@FullAuto.com.",
                  "\n\n   Press ANY key to exit.\n\n";<STDIN>;
            exit 1;
         }
      }
   } elsif (!check_for_compiler() && ((exists $main::amazon{'ami'}) ||
         (exists $main::amazon{'rhel'}) ||
         (exists $main::amazon{'centos'}))) {

      my $grpi=`sudo yum grouplist`;
      if (-1<index $grpi,'no installed groups file') {
         my $out=`sudo yum groups mark convert`;
         $grpi=`sudo yum grouplist`;
      }
      my %groups=();my $group_type='';
      foreach my $ln (split "\n",$grpi) {
         if ($ln=~/^(.*) [Gg]roups:$/) {
            $group_type=$1;
            $groups{$group_type}={};
         } else {
            $ln=~/^\s*(.*)$/;
            $groups{$group_type}->{$1}='';
         }
      }
      my $yins=`sudo yum list installed`;
      unless (exists $groups{'Installed'}->{'Development tools'}) {
         open(AG,"sudo yum -y update|");
         while (my $line=<AG>) {
            print $line;
         }
         close AG;
         open(AG,"sudo yum -y clean all|");
         while (my $line=<AG>) {
            print $line;
         }
         close AG;
         open(AG,"sudo yum -y groupinstall 'Development tools'|");
         while (my $line=<AG>) {
            print $line;
         }
         close AG;
      }
      unless (-1<index $yins,'openssl-devel') {
         open(LD,"sudo yum -y install 'openssl-devel'|");
         while (my $line=<LD>) {
            print $line;
         }
         close LD;
      }
      if ((exists $main::amazon{'rhel'}) ||
            (exists $main::amazon{'centos'})) {
         unless (-1<index $yins,'wget') {
            open(LD,"sudo yum -y install 'wget'|");
            while (my $line=<LD>) {
               print $line;
            }
            close LD;
         }
         my $wget_url='http://pkgs.repoforge.org/rpmforge-release/'.
                      'rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm';
         #my=$wget_url='http://dl.fedoraproject.org/pub/epel/beta/7'.
         #             '/x86_64/epel-release-7-0.2.noarch.rpm';
         open(LD,"sudo wget $wget_url|");
         while (my $line=<LD>) {
            print $line;
         }
         close LD;
         #my $rpm='epel-release-7-0.2.noarch.rpm';
         my $rpm='rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm';
         open(LD,"sudo rpm -ivh $rpm|");
         while (my $line=<LD>) {
            print $line;
         }
         close LD;
         open(LD,"sudo rpm --import http://apt.sw.be/RPM-GPG-KEY.dag.txt|");
         while (my $line=<LD>) {
            print $line;
         }
         close LD;
      }
      unless (-1<index $yins,'figlet') {
         open(LD,"sudo yum -y install 'figlet'|");
         while (my $line=<LD>) {
            print $line;
         }
         close LD;
      }
      unless (-1<index $yins,'nano') {
         open(LD,"sudo yum -y install 'nano'|");
         while (my $line=<LD>) {
            print $line;
         }
         close LD;
      }
      my $argvs=join " ", @ARGV;
      exec "sudo $^X Makefile.PL $argvs";
   } elsif (exists $main::amazon{'centos'}) {

      my $yins=`yum list installed`;
      unless (-1<index $yins,'openssl-devel') {
         open(LD,"sudo yum -y install 'openssl-devel'|");
         while (my $line=<LD>) {
            if (-1<index $line,"allocate") {
print "YEP MEMORY=$line\n";<STDIN>;
            }
            print $line;
         }
         close LD;
      }
      my $new_wget=0;
      unless (-1<index $yins,'wget') {
         $new_wget=1;
         open(LD,"sudo yum -y install 'wget'|");
         while (my $line=<LD>) {
            print $line;
         }
         close LD;
      }
      if ($new_wget) {
         my $wget_url='http://pkgs.repoforge.org/rpmforge-release/'.
                      'rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm';
         #my=$wget_url='http://dl.fedoraproject.org/pub/epel/beta/7'.
         #             '/x86_64/epel-release-7-0.2.noarch.rpm';
         open(LD,"sudo wget $wget_url|");
         while (my $line=<LD>) {
            print $line;
         }
         close LD;
         #my $rpm='epel-release-7-0.2.noarch.rpm';
         my $rpm='rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm';
         open(LD,"sudo rpm -ivh $rpm|");
         while (my $line=<LD>) {
            print $line;
         }
         close LD;
         open(LD,"sudo rpm --import http://apt.sw.be/RPM-GPG-KEY.dag.txt|");
         while (my $line=<LD>) {
            print $line;
         }
         close LD;
      }
      unless (-1<index $yins,'figlet') {
         open(LD,"sudo yum -y install 'figlet'|");
         while (my $line=<LD>) {
            print $line;
         }
         close LD;
      }
      unless (-1<index $yins,'nano') {
         open(LD,"sudo yum -y install 'nano'|");
         while (my $line=<LD>) {
            print $line;
         }
         close LD;
      }
      my $argvs=join " ", @ARGV;
      exec "sudo $^X Makefile.PL $argvs";

   } elsif (!check_for_compiler() && (exists $main::amazon{'suse'})) {

      # Manual Setup openSuSE host before CPAN:
      #
      # zypper ar -f -n openSUSE:13.1 http://download.opensuse.org/distribution/13.1/repo/oss/ openSUSE:13.1
      # zypper -n --gpg-auto-import-keys install --force-resolution wget
      # zypper -n --gpg-auto-import-keys install --force-resolution figlet
      # zypper -n --gpg-auto-import-keys install --force-resolution nano
      # zypper -n install --type pattern Basis-Devel
      # zypper -n install openssl-devel
      # wget http://www.cpan.org/src/5.0/perl-5.20.0.tar.gz
      # tar zxvf perl-5.20.0.tar.gz
      # cd perl-5.20.0
      # ./Configure -d -Dnoextensions=ODBM_File
      # make install
      # cpan
      #

      my $zypper=`/bin/zypper packages -i`;
      if (0 && -1==index $zypper,'gcc') {
         open(ZP,"zypper -n install --type pattern Basis-Devel|");
         while (my $line=<AG>) {
            print $line;
         }
         close ZP;
         open(ZP,"zypper -n install openssl-devel|");
         while (my $line=<AG>) {
            print $line;
         }
         close ZP;
         my $repos='zypper ar -f -n openSUSE:13.1 '.
                   'openSUSE:13.1 http://download.'.
                   'opensuse.org/distribution/13.1'.
                   '/repo/oss/  openSUSE:13.1';
         open(ZP,"$repos|");
         while (my $line=<AG>) {
            print $line;
         }
         close ZP;
         my $figlet="zypper -n --gpg-auto-import-keys install".
                    " --force-resolution figlet";
         open(ZP,"$figlet|");
         while (my $line=<AG>) {
            print $line;
         }
         close ZP;
         my $nano="zypper -n --gpg-auto-import-keys install".
                    " --force-resolution nano";
         open(ZP,"$nano|");
         while (my $line=<AG>) {
            print $line;
         }
         close ZP;
      }
         
   } elsif (!check_for_compiler() && (exists $main::amazon{'ubuntu'})) {

      my $dpkg=`/bin/dpckg -l`;
      my $update_flag=0;
      if (-1==index $dpkg,'build-essential') {
         open(AG,"sudo apt-get -y update|");
         while (my $line=<AG>) {
            print $line;
         }
         close AG;
         $update_flag==1;
         open(AG,"sudo apt-get -y install 'build-essential'|");
         while (my $line=<AG>) {
            print $line;
         }
         close AG;
      }
      if (-1==index $dpkg,'libssl-dev') {
         unless ($update_flag) {
            open(AG,"sudo apt-get -y update|");
            while (my $line=<AG>) {
               print $line;
            }
         }
         open(LD,"sudo apt-get -y install 'libssl-dev'|");
         while (my $line=<LD>) {
            print $line;
         }
         close LD;
      }
      if (-1==index $dpkg,'figlet') {
         open(LD,"sudo apt-get -y install 'figlet'|");
         while (my $line=<LD>) {
            print $line;
         }
         close LD;
      }
      if (-1==index $dpkg,'nano') {
         open(LD,"sudo apt-get -y install 'nano'|");
         while (my $line=<LD>) {
            print $line;
         }
         close LD;
      }
      if (-1==index $dpkg,'perl-doc') {
         open(LD,"sudo apt-get -y install 'perl-doc'|");
         while (my $line=<LD>) {
            print $line;
         }
         close LD;
      }

   } elsif (!check_for_compiler()) {

      my $moreinfo='';my $s='          ';
      if ($Config{cc} and $Config{cc}!~/^\s*$/) {
         $moreinfo="\n\n$s            You are running $^X version $].\n".
              "\n$s            The Config.pm file for this perl installation".
              "\n$s            contains \"$Config{cc}\" as the compiler used".
              "\n$s            to build this perl, but this compiler does not".
              "\n$s            exist in the PATH and may not be installed on".
              "\n$s            this host.\n".
              "\n$s            Retrofitting an existing perl installation to".
              "\n$s            work properly with a new compiler for building".
              "\n$s            CPAN modules, is tricky and NOT recommended.".
              "\n$s            Often the available perl (especially on Unix".
              "\n$s            systems) is highly integrated with the host".
              "\n$s            OS and many of its features and utilities.".
              "\n$s            Upgrading the system perl, but not the overall".
              "\n$s            OS is risky and may result in more than a".
              "\n$s            few system problems and instabilities.\n".
              "\n$s            The recommended approach is build a NEW perl".
              "\n$s            from source with your choice of newly installed".
              "\n$s            compiler (such as gcc) in a different location".
              "\n$s            (such as /usr/local/lib) or your home directory".
              "\n$s            if you lack root/admin privileges."
      }
      my $die="\n       FATAL ERROR! : A C Compiler (such as cc or gcc)".
              "\n                      is required to install FullAuto".
              $moreinfo.
              "\n                      (Hint: goto www.gnu.org for gcc).".
              "\n\n";
      die $die;

   } elsif (exists $main::amazon{'freebsd'}) {
      unless (-e '/usr/local/bin/figlet') {
         open(AG,"pkg_add -r figlet|");
         while (my $line=<AG>) {
            print $line;
         }
         close AG;
      }
      unless (-e '/usr/local/bin/nano') {
         open(AG,"pkg_add -r nano|");
         while (my $line=<AG>) {
            print $line;
         }
         close AG;
      }
   } elsif (exists $main::amazon{'gentoo'}) {
      unless (-e '/usr/local/bin/figlet') {
         my $fs='ftp://ftp.figlet.org/pub/figlet/program'.
                '/unix/figlet-2.2.5.tar.gz';
         open(AG,"(wget $fs;tar zxvf fig*gz;cd figlet-2.2.5;make install)|");
         while (my $line=<AG>) {
            print $line;
         }
         close AG;
      }
   }
   if ($incflag && ($main::PARdir ne $main::curdir)) {
      open(PD,">$main::PARdir/inc_exists.txt")
         or die "Cannot open $main::PARdir/inc_exists.txt: $!\n";
      print PD cwd()."/inc\n";
      close(PD);
   }
   my $cpantest=0;
   $cpantest=1 unless $mycpantest;
   use if ($mycpantest), "CPAN::MyConfig";
   use if ($cpantest), "CPAN::Config";
   
   sub fa_err_exit {
      die "$_[0]\n\n*** Please manually install $_[1]".
          " from cpan.org first...\n"
   }

   sub fa_find_latest {
      my $temp=0;
      my $look=shift||'';
      unless ($look) {
         die "ERROR - No argument provided to &fa_find_latest().\n";
      }
      $look=~s/::/-/g;
      if ($look eq 'LWP') {
         $look='libwww-perl';
      } elsif ($look eq 'Compress-Zlib') {
         $look='IO-Compress';
      } elsif ($look eq 'MIME-Entity') {
         $look='MIME-tools';
      } elsif ($look eq 'Term-ReadKey') {
         $look='TermReadKey';
      } elsif ($look eq 'IO-Pty') {
         $look='IO-Tty';
      } elsif ($look eq 'Mail-Internet') {
         $look='MailTools' ;
      } elsif ($look eq 'Mail-Header') {
         $look='MailTools' ;
      } elsif ($look eq 'Mail-Field') {
         $look='MailTools' ;
      } elsif ($look eq 'Date-Format') {
         $look='TimeDate';
      } elsif ($look eq 'Pod-Man') {
         $look='podlators';
      } elsif ($look eq 'List-Util') {
         $look='Scalar-List-Utils';
      }
      print "***** Looking for Most Recent \"$look Dir\" \n";
      CPAN::HandleConfig->load;
      my $d = $CPAN::Config->{build_dir};
      if (!(defined $d) || !(-d $d)) {
         $d=(getpwuid $>)[7].'/.cpan/build';
         unless (-d $d) {
            unless (-d "/root/.cpan/build") {
               die "ERROR - Can't locate .cpan/build directory";
            } else {
               $d='/root/.cpan/build';
            }
         }
      }
      my $new='';my $file='';
      opendir(DH,$d) or
         die "ERROR - Can't read Directory $d: $!\n";
      while ($_ = readdir(DH)) {
         next if ($_ eq ".") || ($_ eq "..") || (/\.yml$/);
         if ($_!~/^$look[-][vV]?\d/) {
            if (-d $d.'/'.$_) {
               my $dr=$d.'/'.$_;
               $new=&look_inside_dir($dr,$look);
            } next
         }
         $file=sprintf("%s/%s",$CPAN::Config->{build_dir},$_);
         my $attrs = stat $file;
         my $diff = time()-$attrs->[9];
         if ($temp == 0 && $_=~/^$look[-][vV]?\d/) {
           $temp=$diff;
           $new=$file;
         }
         if ($diff<$temp) {
            $temp=$diff;
            $new=$_;
         }
      }
      close(DH);
      $new=$file if !$new && $file;
      print "***** Module Directory ",$new,"\n";
      return $new; 
   }

   sub look_inside_dir {

      my $d=$_[0];
      my $look=$_[1];
      my $found='';
      opendir(LI,$d) or
         die "ERROR - Can't read Directory $d: $!\n";
      my $tar='';
      while ($_ = readdir(LI)) {
         next if ($_ eq ".") || ($_ eq "..");
         if ($_=~/[.]tar$/ && $_=~/^$look[-][vV]?\d/) {
            $tar=$_;
            next;
         }
         if ($_=~/^$look[-][vV]?\d/ && -d $_) {
            $tar='';
            last;
         }
      }
      close(LI);
      if ($tar) {
         unless ($CPAN::Config->{tar}) {
            if (-e '/usr/sfw/bin/gtar') {
               $CPAN::Config->{tar}='/usr/sfw/bin/gtar';
            } elsif (-e '/usr/bin/tar') {
               $CPAN::Config->{tar}='/usr/bin/tar';
            } elsif (-e '/usr/local/bin/tar') {
               $CPAN::Config->{tar}='/usr/local/bin/tar';
            } else {
               print "\n\n   Fatal Error!: The 'tar' utility is".
                  " missing.\n".
                  "\n\n   Please report any bugs and send any",
                  "\n   questions, thoughts or feedback to:",
                  "\n\n      Brian.Kelly\@FullAuto.com.",
                  "\n\n   Press ANY key to exit.\n\n";<STDIN>;
                  exit 1;
            }
         }
         chdir $d;
         if (($main::system_type eq 'ami') ||
               ($main::system_type eq 'ubuntu') ||
               ($main::system_type eq 'rhel') ||
               ($main::system_type eq 'centos')) {
            print "***** Untar: sudo ",$CPAN::Config->{tar}," xvf $tar\n";
            open(FH, "sudo ".$CPAN::Config->{tar}." xvf $tar|");
         } else {
            print "***** Untar: ",$CPAN::Config->{tar}," xvf $tar\n";
            open(FH, $CPAN::Config->{tar}." xvf $tar|");
         }
         while (my $line=<FH>) {
            print $line;
         }
         close FH;
         chdir $CPAN::Config->{build_dir};
         $tar=~s/[.]tar$//;
         return "$d/$tar";
      }
      return '';

   }
   
   sub fa_install_mod {
   
      my $p=$_[0];
      my $task=$_[1];
      my $butil=$_[2]||'';
      my $force=$_[3]||'';
      my $version=$_[4]||'';
      my $echo=$_[5]||'';
      my $dir='';
      my $cpan_error='';
      eval {
         require CPAN::Mini;
         import CPAN::Mini;
      };
      if (!$@ && grep { /-*add[-_]?dependencies/i } @ARGV) {
         my $distribution = CPAN::Shell->expand(
               "Module",$p 
            )->distribution()->pretty_id();
         my $let=unpack('a1',$distribution);
         my $lett=unpack('a2',$distribution);
         my $minicpan=CPAN::Mini->new(

            #remote => "http://www.cpan.org",
            remote => "http://www.perl.com/CPAN",
            local  => cwd()."/dependencies/CPAN",
            log_level => 'debug',
            exact_mirror => 1,
            
         );
         $minicpan->mirror_file(
            "authors/id/$let/$lett/$distribution");
      }
      my $mod_info='';my $instfile='';
      if (!$version || (grep {
            /(?:use[-_]?)?internet|online|connect_to_internet_ok/i
            } @ARGV)) {
         CPAN::Shell->m($p);
         eval {
            require CPAN;
            {
               local *STDOUT;
               open(STDOUT, ">", \$mod_info);
               CPAN::Shell->m($p);
            }
         };
         my $instver='';my $cpanver='';
         if ($mod_info) {
            ($instfile=$mod_info)=~s/^.*INST_FILE\s+([^\s]+).*$/$1/s;
            ($instver=$mod_info)=~s/^.*INST_VERSION\s+([^\s]+).*$/$1/s;
            ($cpanver=$mod_info)=~s/^.*CPAN_VERSION\s+([^\s]+).*$/$1/s;
         }
         if (!$version && ($instver<$cpanver)) {
            unlink $instfile if $exec_cnt;
            $version=$cpanver;
         }
      }
      eval "require $p;1";
      my $ver='';
      my $testp=$p;
      $testp=~s/::/\//g;
      unless ($@) {
         if ($version) {
            my $ttmp='$ver=$'.$p.'::VERSION';
            eval $ttmp;
            $ver=eval $ver;
            $force=($ver<$version)?1:0;
         } else { $force=0 } 
      } elsif ((-1<index $@,"Can't locate") &&
            (-1==index $@,$testp)) {
         print "\n\n";
         print "   Fatal Error: $@\n\n";
         exit 1;
      }
      if ($@ || $instfile eq '(not' || $force) {
         if ($ENV{'AUTOMATED_TESTING'}) {
            print "Automated Testing Detected: FullAuto needs $p\n",
                  "   to continue, but $p was not detected on this\n",
                  "   host.\n\n";
                  "FullAuto Install will EXIT.";
            exit 1;
         }
         if ($version && $p eq 'Term::Menus') {
            $p="REEDFISH/Term-Menus-$version.tar.gz";
         } elsif ($version && $p eq 'Term::RawInput') {
            $p="REEDFISH/Term-RawInput-$version.tar.gz";
         }
         print "==> $p required."
         and print "*** Installing $p via CPAN\n"
         and
         eval {
            require CPAN;
            CPAN::Shell->notest('get',$p);
         };
         if ($@) {
            $cpan_error="$@ $!";
            die "CPAN Error: $cpan_error\n";
         }
         if ($version && (-1<index $p,'Term-Menus')) {
            $p='Term::Menus';
         } elsif ($version && (-1<index $p,'Term-RawInput')) {
            $p='Term::RawInput';
         }
         if (lc($task) eq 'install') {
            my $sudo='';
            if (($main::system_type eq 'ami') ||
                  ($main::system_type eq 'ubuntu') ||
                  ($main::system_type eq 'rhel') ||
                  ($main::system_type eq 'centos')) {
               $sudo='sudo ';
            }
            $dir||=&fa_find_latest($p);
            print "*** Running $sudo$^X $butil.PL\n";
            print "*** cd to $dir\n";
            if ($p eq 'Archive::Tar') {
               my @MakefilePL=();
               open(FH,"<$dir/Makefile.PL");
               @MakefilePL=<FH>;
               close FH;
               my $newfile='';
               foreach my $line (@MakefilePL) {
                  if ($line=~/sleep 10/) {
                     $newfile.="#$line";
                  } else {
                     $newfile.=$line;
                  }
               }
               unlink "$dir/Makefile.PL";
               open(FH,">$dir/Makefile.PL");
               print FH $newfile;
               close FH;
            } elsif ($p eq 'Win32::API') {
               open(FH,"<$dir/Callback/Callback.xs");
               my @callback=<FH>;
               close FH;
               my $new_callback=join '', @callback;
               my $newfile='';
               unless (-1<index $new_callback,'stricmp') {
                  foreach my $line (@callback) {
                     if ($line=~/WIN32_LEAN_AND_MEAN/) {
                        $newfile.="\n#ifndef WIN32"
                                ."\n#       define stricmp strcasecmp"
                                ."\n#       define strnicmp strncasecmp"
                                ."\n#endif\n";
                     }
                     $newfile.=$line;
                  }
                  open(FH,">$dir/Callback/Callback.xs");
                  print $newfile;
                  close FH;
               }
            } elsif ($p eq 'Win32::OLE') {
               open(FH,"<$dir/OLE.xs");
               my @ole=<FH>;
               close FH;
               my $newole=join '', @ole;
               $newole=~s/stricmp/strcasecmp/sg;
               open(FH,">$dir/OLE.xs");
               print $newole;
               close FH;
            }
            if ($echo) {
               system("cd \"$dir\";echo $echo | $sudo$^X $butil.PL");
            } else {
               system("cd \"$dir\";$sudo$^X $butil.PL");
            }
            if ($butil eq 'Makefile') {
               print "*** Running ${sudo}make install\n";
               system("cd \"$dir\";${sudo}make install");
            } else {
               print "*** Running ${sudo}Build install\n";
               system("cd \"$dir\";./Build build;${sudo}./Build install");
            }
         }
         chdir $main::curdir;
         my $_p=$p;
         $_p=~s/::/\//g;
         $_p.='.pm';
         unless (exists $INC{$_p}) {
            eval {
               require $_p;
            };
            if ($@ && -1==index $@,'Attempt to reload') {
               warn $@;
            } else {
               print "*** $p Loaded Successfully\n";
               $exec_cnt=0;
            }
         } elsif (lc($task) eq 'install') {
            my $sudo=0;
            if (($main::system_type eq 'ami') ||
                  ($main::system_type eq 'ubuntu') ||
                  ($main::system_type eq 'rhel') ||
                  ($main::system_type eq 'centos')) {
               $sudo=1;
            }
            my $argvs=join " ", @ARGV;
            if ($sudo) {
               exec "sudo $^X Makefile.PL $argvs SKIP $p $exec_cnt";
            } else {
               exec "$^X Makefile.PL SKIP $argvs $p $exec_cnt";
            }
         }
      } else {
         print "*** $p Loaded Successfully\n";
         $exec_cnt=0;
      }
      return '';
   }
   
   sub fa_install_module {
       my $stdout='';my $stderr='';
       eval { require IO::CaptureOutput };
       if ($@) {
          eval { &fa_install_mod(@_) };
          if ($@) {
             &fa_err_exit($@,$_[0]);
          }
       } else {
          eval {
             require IO::CaptureOutput;
             IO::CaptureOutput::capture {
                &fa_install_mod(@_)
             } \$stdout, \$stderr;
          };
          print $stdout if $stdout;
          &fa_err_exit($stderr,$_[0]) if $stderr;
       }
   }
   
   sub menu {
      my $m = shift;
      my $choice;
      while (1) {
         print "$m->[0]\n";
         print map { "\t$_. $m->[$_][0]\n" } (1..$#$m);
         print "\n\n   PLEASE ENTER A CHOICE: ";
         chomp ($choice = <>);
         last if ( ($choice > 0) && ($choice <= $#$m ));
         print "You chose '$choice'.  That is not a valid option.\n\n";
      }
      &{$m->[$choice][1]};
   }

   sub size_fmt {
      my $size = shift(@_);

      if ($size < 1024) {
         return $size . " bytes";
      }
      if ($size < (1024*1024)) {
         return sprintf("%.2f KB",$size / 1024);
      }
      if ($size < (1024*1024*1024)) {
         return sprintf("%.2f MB",$size / (1024*1024));
      }
      if ($size < (1024*1024*1024*1024)) {
         return sprintf("%.2f GB",$size / (1024*1024*1024));
      }
      return sprintf("%.2f TB",$size / (1024*1024*1024*1024));
   }

   my $stdout='';my $stderr='';
   if ($^O ne 'MSWin32' && $^O ne 'MSWin64') {
      &fa_install_mod('ExtUtils::MakeMaker','install','Makefile');
      &fa_install_mod('File::Which','install','Makefile');
      &fa_install_module('Term::ReadKey','install','Makefile');
      &fa_install_mod('Perl::OSType','install','Makefile');
      &fa_install_mod('Locale::Maketext::Simple','install','Makefile');
      eval { require Test::Tester };
      if ($@) {
         &fa_install_mod('Test::Simple','install','Makefile');
      } else {
         &fa_install_mod('Test::Simple','install','Makefile');
         &fa_install_mod('Test::Tester','install','Makefile');
      }
      &fa_install_mod('Params::Check','install','Makefile');
      &fa_install_mod('version','install','Makefile');
      &fa_install_mod('Module::CoreList','install','Makefile');
      &fa_install_mod('Module::Load','install','Makefile');
      &fa_install_mod('parent','install','Makefile');
      &fa_install_mod('Module::Metadata','install','Makefile');
      &fa_install_mod('Module::Load::Conditional','install','Makefile');
      &fa_install_mod('IPC::Cmd','install','Makefile');
      &fa_install_mod('ExtUtils::CBuilder','install','Makefile');
      &fa_install_mod('YAML','install','Makefile');
      &fa_install_mod('YAML::Tiny','install','Makefile');
      &fa_install_mod('Algorithm::Diff','install','Makefile');
      &fa_install_mod('Text::Diff','install','Makefile');
      &fa_install_mod('PAR::Dist','install','Makefile');
      &fa_install_mod('Compress::Raw::Bzip2','install','Makefile');
      &fa_install_mod('Compress::Raw::Zlib','install','Makefile');
      &fa_install_mod('Compress::Zlib','install','Makefile');
      &fa_install_mod('CPAN::Meta::YAML','install','Makefile');
      &fa_install_mod('Parse::CPAN::Meta','install','Makefile');
      &fa_install_mod('CPAN::Meta::Requirements','install','Makefile');
      &fa_install_mod('JSON::PP','install','Makefile');
      my $mod_info='';my $mod_build_version=0.3601;
      unless (-e "dependencies/CPAN/authors" &&
            !(grep {
            /(?:use[-_]?)?internet|online|connect_to_internet_ok/i } @ARGV)) {
         eval {
            require CPAN;
            {
               local *STDOUT;
               open(STDOUT, ">", \$mod_info);
               CPAN::Shell->m('Module::Build');
            }
         };
         unless ($@) {
            my $instfile='';my $instver='';my $cpanver='';
            if ($mod_info) {
               ($instfile=$mod_info)=~s/^.*INST_FILE\s+([^\s]+).*$/$1/s;
               ($instver=$mod_info)=~s/^.*INST_VERSION\s+([^\s]+).*$/$1/s;
               ($cpanver=$mod_info)=~s/^.*CPAN_VERSION\s+([^\s]+).*$/$1/s;
            }
            if ($instver<$cpanver) {
               $mod_build_version=$cpanver;
            }
         }
      }
      eval { require Module::Build };
      if ((!($@) && $Module::Build::VERSION<=$mod_build_version) || $@
            || grep { /-*add[-_]?dependencies/i } @ARGV) {
         &fa_install_mod('CPAN::Meta','install','Makefile');
         &fa_install_mod('ExtUtils::ParseXS','install','Makefile');
         &fa_install_mod('Compress::Raw::Bzip2','install','Makefile');
         &fa_install_mod('Compress::Raw::Zlib','install','Makefile');
         &fa_install_mod('IO::Zlib','install','Makefile');
         &fa_install_mod('Archive::Tar','install','Makefile');
         &fa_install_mod('inc::latest','install','Makefile');
         &fa_install_mod('Regexp::Common','install','Makefile');
         &fa_install_mod('Pod::Checker','install','Makefile');
         &fa_install_mod('Pod::Parser','install','Makefile');
         &fa_install_mod('Pod::Man','install','Makefile');
         &fa_install_mod('Module::Build','install','Makefile','force');
      }
      &fa_install_mod('IO::CaptureOutput','install','Makefile');
      if ($^O ne 'MSWin32' && $^O ne 'MSWin64' ||
            grep { /-*add[-_]?dependencies/i } @ARGV) {
         &fa_install_module('IO::Pty','install','Makefile');
         unless (grep { /-*add[-_]?dependencies/i } @ARGV) {
            my $argv0=$ARGV[0]||'';
            exit if $argv0 eq 'install_IO_Pty_from_CPAN';
         }
      }
      &fa_install_module('HTML::Tagset','install','Makefile');
      &fa_install_module('HTML::Parser','install','Makefile');
      &fa_install_module('URI','install','Makefile');
      &fa_install_module('HTTP::Date','install','Makefile');
      &fa_install_module('Digest::MD5','install','Makefile');
      &fa_install_module('LWP::MediaTypes','install','Makefile');
      &fa_install_module('Encode::Locale','install','Makefile');
      &fa_install_module('IO::HTML','install','Makefile');
      &fa_install_module('HTTP::Message','install','Makefile');
      &fa_install_module('File::Listing','install','Makefile');
      &fa_install_module('HTTP::Cookies','install','Makefile');
      if ($^O ne 'cygwin'
            || grep { /-*add[-_]?dependencies/i } @ARGV) {
         &fa_install_module('HTTP::Daemon','install','Makefile');
      }
      &fa_install_module('Encode::Locale','install','Makefile');
      &fa_install_module('WWW::RobotRules','install','Makefile');
      &fa_install_module('Date::Format','install','Makefile');
      &fa_install_module('Date::Parse','install','Makefile');
      &fa_install_module('Mail::Internet','install','Makefile');
      &fa_install_module('Mail::Header','install','Makefile');
      &fa_install_module('Mail::Field','install','Makefile');
      &fa_install_module('Test::NoWarnings','install','Makefile');
      &fa_install_module('Convert::BinHex','install','Makefile');
      &fa_install_module('Test::Deep','install','Makefile');
      &fa_install_module('MIME::Base64','install','Makefile');
      &fa_install_module('MIME::Entity','install','Makefile');
      &fa_install_module('LWP::MediaTypes','install','Makefile');
      &fa_install_module('HTTP::Negotiate','install','Makefile');
      &fa_install_module('Net::HTTP','install','Makefile');
      &fa_install_module('Data::Dump','install','Makefile');
      &fa_install_module('File::HomeDir','install','Makefile');
      &fa_install_module('LWP','install','Makefile');
      &fa_install_module('CPAN::Mini','install','Makefile');
      eval { require Net::SSLeay };
      if ($@) {
         my $ssleay_error_banner=<<END;

         *** THIS SCREEN WILL TIMEOUT AND FULLAUTO SETUP WILL EXIT
                    IN 5 MINUTES IF NO CHOICE IS MADE ***

      FullAuto Setup ERROR: Missing dependency 'openssl-devel'

   The CPAN module Net::SSLeay requires the 'openssl-devel' system package to
   be installed. Would you like FullAuto Setup to attempt installing this
   package?
END

         &fa_install_module('Net::SSLeay','get');
         my $dir=&fa_find_latest('Net-SSLeay');
         open(FH, "(cd \"$dir\";echo n | $^X Makefile.PL) 2>&1|");
         while (my $line=<FH>) {
            print $line;
         }
         close FH;
         SSL: while (1) {
            open(FH, "(cd \"$dir\";make install) 2>&1|");
            while (my $line=<FH>) {
               if (-1<index $line,
                     'error: openssl/err.h: No such file or directory') {
                  my $timeout=300;my $selection='';
                  eval {
                     local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required
                     alarm $timeout;
                     my $fae="No   (FullAuto Setup will exit)";
                     my $menu1 = [
                                 $ssleay_error_banner,
                                 [ "Yes", sub{ return 'Yes' } ],
                                 [ $fae, sub{ return 'No' } ],
                                 ];
                     $selection=&menu($menu1);
                     exit if $selection eq ']quit[';
                     alarm 0;
                  };
                  if ($@) {
                     # timed out
                     $selection = 'No';
                  }
                  if ($selection=~/No/) {
                     exit;
                  } alarm 0;
                  if (($main::system_type eq 'rhel') ||
                        ($main::system_type eq 'centos') ||
                        ($main::system_type eq 'fedora')) {
                     open(LD,"sudo yum -y install 'openssl-devel'|");
                     while (my $line=<LD>) {
                        print $line;
                     }
                     close LD;
                     next SSL;
                  } elsif ($main::system_type eq 'suse') {
                     open(ZP,"zypper -n install openssl-devel|");
                     while (my $line=<AG>) {
                        print $line;
                     }
                     close ZP;
                     next SSL;
                  } elsif ($main::system_type eq 'ubuntu') {
                     open(LD,"sudo apt-get -y install 'libssl-dev'|");
                     while (my $line=<LD>) {
                        print $line;
                     }
                     close LD;
                     next SSL;
                  }
               }
               print $line;
            } last;
         }
         close FH;
      } elsif (grep { /-*add[-_]?dependencies/i } @ARGV) {
         &fa_install_module('Net::SSLeay','get');
      }
      &fa_install_module('IO::Socket::SSL','install','Makefile','','','n');
      &fa_install_module('Mozilla::CA','install','Makefile');
      &fa_install_module('LWP::Protocol::https','install','Makefile');
      &fa_install_module('Task::Weaken','install','Makefile');
      &fa_install_module('ExtUtils::Depends','install','Makefile');
      &fa_install_module('B::Utils','install','Makefile');
      &fa_install_module('ExtUtils::Config','install','Makefile');
      &fa_install_module('ExtUtils::InstallPaths','install','Makefile');
      &fa_install_module('ExtUtils::Helpers','install','Makefile');
      &fa_install_module('Test::Harness','install','Makefile','','3.33');
      &fa_install_module('CPAN::Meta','install','Makefile');
      &fa_install_module('Module::Build::Tiny','install','Build');
      &fa_install_module('Class::Method::Modifiers','install','Makefile');
      &fa_install_module('common::sense','install','Makefile');
      &fa_install_module('Types::Serialiser','install','Makefile');
      &fa_install_module('Term::RawInput','install','Makefile');
      if ($^O eq 'cygwin' || grep { /-*add[-_]?dependencies/i } @ARGV) {
         &fa_install_module('Encode::compat','install','Makefile');
         &fa_install_module('Win32::API','install','Makefile');
         &fa_install_module('Win32::DriveInfo','install','Makefile');
         &fa_install_module('Devel::PL_origargv','install','Makefile');
         &fa_install_module('Win32::OLE','install','Makefile');
         &fa_install_module('Win32::RunAsAdmin','install','Makefile');
      }
      my $cpanvalue=$ENV{PERL5_CPAN_IS_RUNNING}||'';
      my $cpanmvalue=$ENV{PERL5_CPANM_IS_RUNNING}||'';
      undef $ENV{PERL5_CPAN_IS_RUNNING};
      undef $ENV{PERL5_CPANM_IS_RUNNING};
      &fa_install_module('JSON::XS','install','Makefile');
      &fa_install_module('JSON','install','Makefile');
      $ENV{PERL5_CPAN_IS_RUNNING}=$cpanvalue if $cpanvalue;
      $ENV{PERL5_CPANM_IS_RUNNING}=$cpanmvalue if $cpanmvalue;
      &fa_install_module('Devel::Symdump','install','Makefile');
      &fa_install_module('PadWalker','install','Makefile');
      eval { require Data::Dump::Streamer };
      if ($@ || grep { /-*add[-_]?dependencies/i } @ARGV) {
         &fa_install_module('Data::Dump::Streamer','get');
         unless (grep { /-*add[-_]?dependencies/i } @ARGV) {
            my $dir=&fa_find_latest('Data-Dump-Streamer');
            system("cd \"$dir\";$^X Build.PL NODDS;");
            system("cd \"$dir\";./Build install;");
         }
      }
      &fa_install_module('Term::Menus','install','Makefile');
      &fa_install_module('IO::String','install','Makefile');
      &fa_install_module('Crypt::CBC','install','Makefile');
      &fa_install_module('Crypt::DES','install','Makefile');
      &fa_install_module('Test::Manifest','install','Makefile');
      &fa_install_module('Crypt::Rijndael','install','Makefile');
      &fa_install_module('Clone','install','Makefile');
      &fa_install_module('File::Remove','install','Makefile');
      &fa_install_module('Exporter::Tiny','install','Makefile');
      &fa_install_module('List::MoreUtils','install','Makefile');
      &fa_install_module('Params::Util','install','Makefile');
      &fa_install_module('Test::Object','install','Makefile');
      &fa_install_module('Hook::LexWrap','install','Makefile');
      &fa_install_module('Test::SubCalls','install','Makefile');
      &fa_install_module('Class::Inspector','install','Makefile');
      &fa_install_module('PPI','install','Makefile');
      &fa_install_module('Tie::Cache','install','Makefile');
      &fa_install_module('String::Random','install','Build');
      &fa_install_module('Net::Telnet','install','Makefile');
      &fa_install_module('Sort::Versions','install','Makefile');
      &fa_install_module('Capture::Tiny','install','Makefile');
      &fa_install_module('IO::Capture','install','Makefile');
      &fa_install_module('Pod::Man','install','Makefile');
      &fa_install_module('Sub::Exporter::Progressive','install','Makefile');
      &fa_install_module('MRO::Compat','install','Makefile');
      &fa_install_module('Sub::Install','install','Makefile');
      &fa_install_module('Data::OptList','install','Makefile');
      &fa_install_module('B::Hooks::OP::Check','install','Makefile');
      &fa_install_module('Lexical::SealRequireHints','install','Makefile');
      &fa_install_module('multidimensional','install','Makefile');
      &fa_install_module('bareword::filehandles','install','Makefile');
      &fa_install_module('indirect','install','Makefile');
      &fa_install_module('strictures','install','Makefile');
      &fa_install_module('Role::Tiny','install','Makefile');
      &fa_install_module('Devel::GlobalDestruction','install','Makefile');
      &fa_install_module('Module::Runtime','install','Makefile');
      &fa_install_module('Import::Into','install','Makefile');
      &fa_install_module('Try::Tiny','install','Makefile');
      &fa_install_module('Sub::Exporter','install','Makefile');
      &fa_install_module('Sub::Exporter::Util','install','Makefile');
      &fa_install_module('Moo','install','Makefile');
      &fa_install_module('Test::Fatal','install','Makefile');
      &fa_install_module('MooX::Types::MooseLike','install','Makefile');
      &fa_install_module('MooX::Types::MooseLike::Base','install','Makefile');
      &fa_install_module('Devel::StackTrace','install','Makefile');
      &fa_install_module('Throwable','install','Makefile');
      &fa_install_module('Email::Date::Format','install','Makefile');
      &fa_install_module('Email::Simple','install','Makefile');
      &fa_install_module('Email::Address','install','Makefile');
      &fa_install_module('Module::Pluggable','install','Makefile');
      &fa_install_module('Email::Abstract','install','Makefile');
      &fa_install_module('Email::Sender','install','Makefile');
      &fa_install_module('Data::Password::Check','install','Makefile');

   }
#};

my %cygsrvs=();
my @output=();
my $hostname=`hostname`;
chomp($hostname);

sub ws_info {
   my $selection='';
   if ($_[0]) {
      print "\nRunning command: net user /domain ->".
            " This may take a couple of minutes\n\n";
   }
   # Do we have Cygwin?
   my $cygwin_loc=get_cygwin_location();
   my $clo=$cygwin_loc;
   $clo=~s/\\/\\\\/g;
   my %userlist=();my %passlins=();
   my @newpassw=();my $modflag=0;
   if (-e $cygwin_loc."/bin") {
      my $pasen='SET CYGWIN=nodosfilewarning & '.
                "cmd /c $cygwin_loc\\bin\\bash -lc ".
                '"cat /etc/passwd"';
      my $passe=`$pasen`;my $cnt=0;my %passlins=();
      foreach my $en (split "\n",$passe) {
         chomp($en);
         push @{$passlins{$en}},$cnt++;
         push @newpassw,$en;
      }
      foreach my $lin (keys %passlins) {
         my $linn=$lin;
         my @pl=@{$passlins{$linn}};
         if (0<$#pl) {
            my %asklin=(
               Label => 'asklin',
               Item_1 => {
                  Text => "]C[",
                  Convey => sub {

                     my @ret=();
                     foreach my $p (@pl) {
                        push @ret, "\n                $linn\n".
                                   "\n                Line: $p\n\n";
                     }
                     return @ret;

                  },
               },
               Item_2 => {
                  Text => "Skip this operation",
               },
               Banner => "   Duplicate Lines in /etc/passwd found!\n\n".
                         "   The following lines are all duplicates, ".
                         "the only one being utilized is\n   the first ".
                         "one found. It is recommended that the ".
                         "others be removed.\n\n".
                         "   Select the one you wish to keep, or choose ".
                         "'Skip this operation' and\n   FullAuto Setup ".
                         "will continue.\n\n",
            );
            my $select=Menu(\%asklin);
            chomp($select);
            exit if $select eq ']quit[';
            my $s=0;
            ($s=$select)=~s/^.*\n\s+Line: (\d+).*$/$1/s;
            my $adjust=0;
            foreach my $i (@pl) {
               my $ii=$i;
               my $n=0;
               ($n=$ii)=~s/^.*\n\s+Line: (\d+).*$/$1/s;
               next if $s eq $n;
               $n-=$adjust;
               splice(@newpassw,$n,1);
               $modflag=1;
               $adjust++;
            }
         }
      }
      if ($modflag) {
         my $npass=join "\n",@newpassw;
         open(NP,">$cygwin_loc/etc/passwd");
         foreach my $l (@newpassw) {
            print NP "$l\n";
         }
         close NP;
      } $modflag=0;
      my $users='SET CYGWIN=nodosfilewarning & '.
                "cmd /c $cygwin_loc\\bin\\bash -lc ".
                '"cat /etc/passwd |grep '.
                '\\"/bin/bash\\" |grep '.
                '\\"[5-9][0-9][0-9]\\""';
      my $userlist=`$users`;
      my %ulist=();my $cyguser='';
      foreach my $us (split "\n",$userlist) {
         chomp($us);
         $cyguser=substr($us,0,(index $us,':'));
         next if $cyguser ne 'cyg_server';
         push @{$ulist{$cyguser}}, $us;
      }
      my @u=@{$ulist{cyg_server}};
      my @list=();my @retrn=();
      my $domain_id_flag=0;
      my $local_id_flag=0;
      my %cygsrvs=();
      if (-1<$#u) {
         foreach my $e (@u) {
            my @it=split ':',$e;
            my $info=(split ',',$it[4])[1];
            my $d='';my $i='';
            if (-1<index $info,'\\') {
               ($d,$i)=split /\\/,$info;
               $d=~s/^.*-(.*)$/$1/;
               $d="DOMAIN: $d";
               $domain_id_flag=1;
            } else {
               $d="LOCAL: $hostname";
               $local_id_flag=1;
            }
            push @retrn,"cyg_server -> $d";
            $cygsrvs{"cyg_server -> $d"}=$e;
         }
      }
      if (0<$#retrn) {
         my %askcyg=(

            Label => 'askcyg',
            Item_1 => {

               Text => "]C[",
               Convey => \@retrn,

            },
            Banner => "   More than one instance of the user 'cyg_server'\n" .
                      "   have been located in the /etc/passwd file. However".
                      ",\n   only one can be used. Please choose one:\n",
         );
         my $select=Menu(\%askcyg);
         chomp($select);
         exit if $select eq ']quit[';
         delete $cygsrvs{$select};
         my $pasen='SET CYGWIN=nodosfilewarning & '.
                   "cmd /c $cygwin_loc\\bin\\bash -lc ".
                   '"cat /etc/passwd"';
         my $passe=`$pasen`;my $cnt=0;my %passlins=();
         foreach my $en (split "\n",$passe) {
            chomp($en);
            push @{$passlins{$en}},$cnt++;
            push @newpassw,$en;
         }
         my $ct=0;my $n=0;my $modflag=0;
         foreach my $lin (keys %passlins) {
            my $linn=$lin;
            $lin=~s/\s*$//;
            foreach my $i (values %cygsrvs) {
               my $ii=$i;
               $ii=~s/\s*$//;
               if ($lin eq $ii) {
                  splice(@newpassw,$n,1);
                  $ct++;
                  $modflag=1;
                  next;
               }
               $ct++;$n++;
            }
         }
         if ($modflag) {
            open(NP,">$cygwin_loc/etc/passwd");
            foreach my $l (@newpassw) {
               print NP "$l\n";
            }
            close NP;
         }
         test_windows_user_rights('cyg_server');
      }
   }
   my $found_dotted=0;
   my $domain='';
   $domain=' /domain' if $_[0];
   my $server='';
   foreach my $line (split "\n", `net user$domain 2>&1`) {
      unless ($found_dotted) {
         if (-1<index $line,'-------') {
            $found_dotted=1;
         } elsif (-1<index $line,' for domain ') {
            ($domain=$line)=~s/^.* for domain (.*)[.]\s*$/$1/s;
         } elsif (-1<index $line,' accounts for ') {
            ($server=$line)=~s/^.* accounts for\s+(.*)\s*$/$1/s;
         }
         next;
      }
      push @output, $line;
   }
   my $limit=9;
   $limit=$#output if $#output<9;
   my @test=@output[0..$limit];
   my %testone=();
   my %testtwo=();
   while (my $line=shift @test) {
      $line=~tr/\0-\11\13-\37\177-\377//d;
      chomp($line);
      $line=~s/\s*$//s;
      my $ln2=rindex $line, ' ';
      $testtwo{$ln2}++;
      substr($line,$ln2)='';
      $line=~s/\s*$//s;
      my $ln1=rindex $line, ' ';
      $testone{$ln1}++;
   }
   my $two=0;
   foreach my $key (keys %testtwo) {
      $two=$key if $two<$key;
   }
   my $one=0;
   foreach my $key (keys %testone) {
      $one=$key if $one<$key;
   }
   $one++;
   my $mid=$two-$one+1;
   my @users=();my $cyg_id='';
   my $success_flag=0;
   foreach my $line (@output) {
      my ($on,$tw,$th)=unpack("a$one a$mid a$two",$line);
      $on=~s/\s*$//;$tw=~s/\s*$//;$th=~s/\s*$//;
      if (-1<index $on,'The command compl') {
         $success_flag=1;
         last;
      }
      push @users, $on if $on;
      $cyg_id='cyg_server' if $on eq 'cyg_server';
      push @users, $tw if $tw;
      $cyg_id='cyg_server' if $tw eq 'cyg_server';
      push @users, $th if $th;
      $cyg_id='cyg_server' if $th eq 'cyg_server';

   }

   my $dom=(defined $_[0] && $_[0])?$_[0]:'Local';

   if ($dom ne 'Local' && !$success_flag) {

      my $banner='';my $op=join '', @output;
      if ((-1<$#output) && ($op!~/^\s*$/s)) {
         my $op=join "\n",@output;
         $banner=<<END;

   IMPORTANT! - The Windows command: net user /domain -> ERROR!

      $op
      
   If you intend to use a Windows Domain Account for the Cygwin sshd
      service it is helpful that the FullAuto Installer be able to query
      the $dom Domain Controller. You may proceed if the ID
      you intend to use exists, or if you wish to use a Local account.

   (If you wish to use a Windows Domain User ID, *make sure it exists*
      and that your computer or device is properly connected to the
      $dom Windows Domain.)

END
      } else {
         $banner=<<END;

   IMPORTANT! - The Windows command: net user /domain  had no output.

   If you intend to use a Windows Domain Account for the Cygwin sshd
      service it is helpful that the FullAuto Installer be able to query
      the $dom Domain Controller. You may proceed if the ID
      you intend to use exists, or if you wish to use a Local account.

   (If you wish to use a Windows Domain User ID, *make sure it exists*
      and that your computer or device is properly connected to the
      $dom Windows Domain.)

END
      } 
      unless ($success_flag) {
         my %_cygservnf=(
            Label => '_cygservnf',
            Item_1 =>  {
                  Text   => "]C[",
                  Convey => [

                     "Use Local ID \'cyg_server\'  ( Local ID will be ".
                     "created\n                 automatically if necessary. ".
                     "Default & Recommended choice. )\n\n",
                     "Use Domain ID \'cyg_server\' ( Domain ID needs to\n".
                     "                 pre-exist and you need to know the ".
                     "password! )",
                     "Enter a different Local User ID.",
                     "Enter a different Domain User ID.",
                     "Use the Local SYSTEM user (least secure)."

                  ],
            },
            Scroll => 1,
            Banner => $banner,
         );
         $selection=Menu(\%_cygservnf);
         chomp $selection;
         exit if $selection eq ']quit[';
         $selection='use_separate_local_login_id_for_sshd'
            if -1<index $selection,'Enter a different Local';
         $selection='use_separate_local_cyg_server_login_id_for_sshd'
            if -1<index $selection,'Use Local ID';
         if (-1<index $selection,'Enter a different Domain') {
            while (1) {
               print "\n\n\n   Please enter the $domain User ID you",
                     "   intend to use for the sshd service: ".
                     "\n\n\n",
                     "   Please TYPE the User ID: ";
               $cyg_id=<STDIN>;
               chomp $cyg_id;
               print "\n\n\n   You entered ==> $cyg_id\n\n".
                     "   is this correct? (Y|N): ";
               my $yn=<STDIN>;
               last if lc($yn) eq 'y' || 'yes';
            }
         }
      } elsif ($cyg_id eq 'cyg_server') {
         my $o=`net user cyg_server 2>&1`;
         if (-1==index $o,'user name could not be found') {
            my %_cygserv=(
   
               Label => '_cygserv',
               Item_1 =>  {
                     Text   => "]C[",
                     Convey => [ "Use Domain ID \'cyg_server\'\n".
                                 '                '.
                                 '( You need to know the password! )',
                                 'Select ID from All Domain ID\'s',
                                 'Use a Local account' ],
               },
               Scroll => 1,
               Banner=> "   The Domain User 'cyg_server' has been located,\n".
                        "   do you wish to use it, or would you rather\n".
                        "   select from all Domain Users, or use a Local\n".
                        "   account for the sshd service?\n\n".
                        "   (If you wish to use a Domain User ID, please\n".
                        "   *make sure it exists* in the current Domain: $dom".
                        "\n   before".
                        " running FullAuto Setup. If you wish to use\n".
                        "   a Local account, FullAuto can use an existing\n".
                        "   one, or create a new one.)",
            );
            $selection=Menu(\%_cygserv);
            chomp $selection;
            exit if $selection eq ']quit[';
            $selection='use_separate_local_login_id_for_sshd'
               if -1<index $selection,'Use a Local';
         } else {
            test_windows_user_rights('cyg_server') if $^O eq 'cygwin';
            $selection='cyg_server'; 
         }         
      } else {
         my %_cygserv=(

            Label => '_cygserv',
            Item_1 =>  {
                  Text   => "]C[",
                  Convey => [ 'Select ID from All Domain ID\'s',
                              'Use a Local account' ],
            },
            Banner=> "   'cyg_server' has *NOT* been located in the $dom ".
                     "Domain.\n".
                     "   If you wish to use the 'cyg_server' id as a Domain".
                     " ID\n".
                     "   for the OpenSSH sshd service on this host: ".
                     $hostname."\n".
                     "   type 'quit', exit FullAuto Setup, create the\n".
                     "   'cyg_server' User in the $dom Domain, and *then*\n".
                     "   run FullAuto Setup again.\n\n",
                     "   Or, would you rather select from all Domain Users,".
                     "   or use a Local account for the sshd service?\n\n".
                     "   (If you wish to use a Local account, FullAuto\n".
                     "    can use an existing one, or create a new one.)",
         );
         $selection=Menu(\%_cygserv);
         chomp($selection);
         exit if $selection eq ']quit[';
         $selection='use_separate_local_login_id_for_sshd'
            if -1<index $selection,'Use a Local';
      }
      if (-1<index $selection, 'All Domain' || !$cyg_id) {
         my %_users=(

            Label => '_users',
            Item_1 =>  {
                           Text   => "]C[",
                           Convey => \@users,
                       },
            Banner=> "   Select the $dom User to Run the sshd Service\n\n".
                     "   Hit <ENTER> or user ARROW keys to scroll\n\n".
                     "   List can be searched by typing  /[string]\n".
                     "   (forward slash key followed by text to search for).", 
         );
         $selection=Menu(\%_users);
         chomp($selection);
         exit if $selection eq ']quit[';
         test_windows_user_rights($selection) if $^O eq 'cygwin';
      } elsif (-1<index $selection, 'Use Domain') {
         test_windows_user_rights('cyg_server') if $^O eq 'cygwin';
         $selection='cyg_server'; 
      }
   }
   return $selection;

}

sub clean_mswin {
   my $rmdir_out=rmdir $main::curdir.'/inc/.author';
   print "ERROR $main::curdir/inc/.author: $!\n" unless $rmdir_out;
   my $un_out=unlink $main::curdir.'/inc/Module/Install/Base.pm';
   print "ERROR $main::curdir/inc/Module/Install/Base.pm: $!\n"
      unless $un_out;
   $un_out=unlink $main::curdir.'/inc/Module/Install/Metadata.pm';
   print "ERROR $main::curdir/inc/Module/Install.pm: $!\n" unless $un_out;
   $un_out=unlink $main::curdir.'/inc/Module/Install.pm';
   print "ERROR $main::curdir/inc/Module/Install.pm: $!\n" unless $un_out;
   $rmdir_out=rmdir $main::curdir.'/inc/Module/Install';
   print "ERROR /inc/Module/Install: $!\n" unless $rmdir_out;
   $rmdir_out=rmdir $main::curdir.'/inc/Module';
   print "ERROR $main::curdir/inc/Module: $!\n" unless $rmdir_out;
   unless (-e $main::PARdir.'/inc_exists.txt') {
      $rmdir_out=rmdir $main::curdir.'/inc';
      print "ERROR $main::curdir/inc: $!\n" unless $rmdir_out;
   } else {
      $un_out=unlink $main::PARdir.'/inc_exists.txt';
      print "ERROR $main::PARdir/inc_exists.txt: $!\n" unless $un_out;
   }

}

sub check_for_compiler
{

    # Borrowed from version module: version-0.9912

    # IMPORTANT NOTE:  This is NOT used to determine how to compile
    # extensions properly; EU::MM does that for us.  This is only
    # intended to see if that is likely to succeed.  We do not try
    # to do anything here except compile (not even link).  If you
    # want this to be a full featured test, feel free to submit a
    # patch or do something useful.

    print "Testing if you have a C compiler\n";

    eval { require ExtUtils::CBuilder };
    if ($@)
    {
        return _check_for_compiler_manually();
    }
    else
    {
        return _check_for_compiler_with_cbuilder();
    }
}

sub _check_for_compiler_with_cbuilder
{
    my $cb = ExtUtils::CBuilder->new( quiet => 1 );

    return $cb->have_compiler;
}

sub _check_for_compiler_manually
{
    unless ( open F, ">test.c" )
    {
        warn "Cannot write test.c, skipping test compilation.\n";
        return 0;
    }

    print F <<'EOF';
int main() { return 0; }
EOF

    close F or return 0;

    my ($cc, $ccflags, $obj_ext) = map { $Config{$_} } qw/cc ccflags obj_ext/;

    my $command;
    if ($^O =~ /(dos|win32)/i && $Config{'cc'} =~ /^cl/) {
        $command = "$cc $ccflags /c test.c";
    }
    elsif ($Config{gccversion}) {
        $command = "$cc $ccflags -o test$obj_ext test.c";
    }
    else {
        return 0;
    }

    my $retval = system( $command );
    map { unlink $_ if -f $_ } ('test.c',"test$obj_ext");

    return not($retval); # system returns -1
}

# Define metadata
if ($^O ne 'MSWin32' && $^O ne 'MSWin64') {

version         $main::VERSION;
name            'Net-FullAuto';
sign;
author          'Brian M. Kelly <Brian.Kelly@FullAuto.com>';
license         'gpl-3.0';
perl_version    '5.006';

}

require Mozilla::CA;
require Term::Menus;
require Term::ReadKey;
require Term::RawInput;
my $last_known_good_location=
      "http://download.oracle.com/berkeley-db/db-5.2.28.tar.gz";

if ($^O eq 'cygwin' || $^O eq 'MSWin32' || $^O eq 'MSWin64') {
   $ENV{'CYGWIN'}='nodosfilewarning' if $^O eq 'cygwin';
}

BEGIN {
   unshift @ExtUtils::MakeMaker::Overridable, 'pm_to_blib';
};

my $process_id='';my $PREFIX='';
$process_id=pop @ARGV if $ARGV[$#ARGV-1]=~/^\d+$/;
my $install_cygwin_without_asking=0;
$main::cygwin_berkeley_db_mode=777;
if (exists $ENV{FA_BERKELEY} &&
      (-1<index $ENV{FA_BERKELEY},'Owner Group')) {
   $main::cygwin_berkeley_db_mode=770;
}
$main::mozrepl_file='mozrepl-1.1-fx.xpi';
$main::install_firefox_without_asking=0;
$main::install_firefox=0;
$main::install_firefox=$ENV{FA_MOZREPL} if exists $ENV{FA_MOZREPL};
our $install_webapi=(exists $ENV{FA_WEBAPI})?$ENV{FA_WEBAPI}:'';

if (exists $Config{prefix} &&
      $Config{prefix}) {
   $PREFIX=$Config{prefix};
}

foreach my $arg (@ARGV) {
   if ($arg=~/INSTALL_*CYGWIN\s*=\*1/i) {
      $install_cygwin_without_asking=1;
   } elsif ($arg=~/INSTALL_*FIREFOX\s*=\*1/i) {
      $main::install_firefox_without_asking=1;
   } elsif ($arg=~/-*-PREFIX=/i) {
      $PREFIX=$arg;
      $PREFIX=~s/^-*-[Pp][Rr][Ee][Ff][Ii][Xx]=//;
      $PREFIX=~s/^["']//;
      $PREFIX=~s/["']$//;
   }
}

$PREFIX='' if $PREFIX='/usr';

my $editor='';my $selection='';my $berkeleydb='';
my $fa_sshd_banner=<<'END';

    ___     _ _   _       _                            _       _ ___
   | __|  _| | | /_\ _  _| |_  |      ___ _ _    _____| |_  __| |__ \
   | _| || | | |/ _ \ || |  _/ | \   / _ \ '_|  (_-<_-< ' \/ _` | /_/
   |_| \_,_|_|_/_/ \_\_,_|\__\___/c  \___/_|    /__/__/_||_\__,_|(_)


END
my $sshd_fa_banner=<<'END';

    ___     _ _   _       _                        _          _       _ ___
   | __|  _| | | /_\ _  _| |_  |      __ _ _ _  __| |   _____| |_  __| |__ \
   | _| || | | |/ _ \ || |  _/ | \   / _` | ' \/ _` |  (_-<_-< ' \/ _` | /_/
   |_| \_,_|_|_/_/ \_\_,_|\__\___/c  \__,_|_||_\__,_|  /__/__/_||_\__,_|(_)

   You have selected to install FullAuto. A local ssh Windows service (sshd)
   is *NOT* required for use with FullAuto on this host, but it is a useful
   option. However, an ssh service on Windows is a security "concern" that
   a number of experts advise against. No matter how secure it is, it is an
   additional access point to this host. Carefully consider the risk versus
   the increased utility a ssh service provides for a MS Windows based host.


END
if ($^O eq 'MSWin32' || $^O eq 'MSWin64') {

   my $cygwin_loc=get_cygwin_location();

   if ($cygwin_loc) {

      my %Menu_update_cyg=(

         Label  => 'Menu_update_cyg',
         Item_1 => {

            Text => "Install FullAuto  =>  Will automatically ".
                    "Update installed\n                                 ".
                    "   Cygwin Linux Emulation ".
                    "Layer.\n\n              ( Cygwin ".
                    "is REQUIRED to run FullAuto on Microsoft Windows ) ".
                    "\n\n",

         },
         Item_2 => {

            Text => "Install sshd only  =>  Update Base Cygwin and Install".
                    "\n                                     OpenSSH sshd ".
                    "(ssh service for Windows)\n".
                    "\n              ( Allows FullAuto processes on other ".
                    "hosts to connect and\n                ".
                    "interact with this host. FullAuto will NOT be ".
                    "installed ).\n\n",

         },
         Item_3 => {

            Text    => "Do NOT Update Cygwin ".
                       "( FullAuto Install will END ).\n\n",

         },
         Scroll => 1,
         Banner => $fa_sshd_banner,

      );
      if ($install_cygwin_without_asking) {
         $selection='Install';
      } else {
         $selection=Term::Menus::Menu(\%Menu_update_cyg);
         chomp($selection);
         exit if $selection eq ']quit[';
      }
   } else {
      my %Menu_win_to_cyg=(

         Label  => 'Menu_win_to_cyg',
         Item_1 => {

            Text => "Install Fulluto  =>  Will automatically Install or".
                    " Update\n                                   ".
                    "Cygwin Linux Emulation ".
                    "Layer.\n\n              ( Cygwin ".
                    "is REQUIRED to run FullAuto on Microsoft Windows ) ".
                    "\n\n",

         },
         Item_2 => {

            Text => "Install sshd only  =>  Install and configure Base Cygwin".
                    " and\n                                     OpenSSH sshd ".
                    "(ssh service for Windows)\n".
                    "\n              ( Allows FullAuto processes on other ".
                    "hosts to connect and\n                ".
                    "interact with this host. FullAuto will NOT be ".
                    "installed ).\n\n",

         },
         Item_3 => {

            Text    => "DO *NOT* Install Cygwin ".
                       "( FullAuto Install will END ).\n\n",

         },
         Scroll => 1,
         Banner => $fa_sshd_banner,

      );
      if ($install_cygwin_without_asking) {
         $selection='Install';
      } else {
         $selection=Term::Menus::Menu(\%Menu_win_to_cyg);
         chomp($selection);
         exit if $selection eq ']quit[';
      }
   }
   if ($selection!~/will END/s) {
      my $sshd_selection='';
      if ($selection!~/Install sshd only/s) {
         my %Menu_win_to_cyg=(

            Label  => 'Menu_win_to_cyg',
            Item_1 => {

               Text => 'Do *NOT* Install sshd with FullAuto.',

            },
            Item_2 => {

               Text => 'Install FullAuto and sshd (ssh service) for Windows.',

            },
            Scroll => 1,
            Banner => $sshd_fa_banner,

         );
         if ($install_cygwin_without_asking) {
            $sshd_selection='Do *NOT* Install sshd';
         } else {
            $sshd_selection=Term::Menus::Menu(\%Menu_win_to_cyg);
            chomp($sshd_selection);
            $sshd_selection='Do *NOT* Install sshd' if $sshd_selection
               eq 'Do *NOT* Install sshd with FullAuto.';
            exit if $sshd_selection eq ']quit[';
         }

      }

      my $url='http://www.cygwin.com/setup-x86.exe';
      $url='http://www.cygwin.com/setup-x86_64.exe'
         if $^O eq 'MSWin64' || msw64bit();
      if ($CPAN::META->has_usable('LWP')) {
         FA::LWP::UserAgent->config;
         print "Fetching with LWP:\n  $url\n";
         my $Ua;
         eval { $Ua = FA::LWP::UserAgent->new(
                timeout=>300,show_progress=>1) };
         if ($@) {
            $CPAN::Frontend->mywarn(
               "ERROR: FA::LWP::UserAgent->new dies with $@\n");
         } else {
            my($var);
            $Ua->proxy('http', $var)
               if $var = $CPAN::Config->{http_proxy} ||
               $ENV{http_proxy};
            $Ua->no_proxy($var)
               if $var = $CPAN::Config->{no_proxy} || $ENV{no_proxy};
         }
         my $req = HTTP::Request->new(GET => $url);
         $req->header('Accept' => 'text/html');
         my $res = $Ua->request($req);
         if ($res->is_success) {
            print " + request successful.\n"
               if $CPAN::DEBUG;
            mkpath($main::root_dir,1) unless -d $main::root_dir;
            unless (-w $main::root_dir) {
               print "\n\n   Fatal Error! - The current Cygwin directory: ".
                        "\n\n      ".$main::root_dir."\n\n".
                        "   is not writable. Please change the permissions\n".
                        "   to writable before installing FullAuto.\n";
               print "\n   PRESS ANY KEY TO EXIT SETUP\n\n";
               <STDIN>;
               exit 1;
            }
            if ($^O eq 'MSWin64' || msw64bit()) {
               open(CP,">$main::root_dir\\setup-x86_64.exe") || die $!;
            } else {
               open(CP,">$main::root_dir\\setup-x86.exe") || die $!;
            }
            binmode(CP);
            print CP $res->content;
            my $cyghome=$Ua->get('http://www.cygwin.com');
            if ($^O ne 'cygwin' && $cyghome->is_success) {
               my $content=$cyghome->content;
               my $cygver='';
               ($cygver=$content)=~
                  s/^.*of the Cygwin DLL is ([\d|.|-]). In.*$/$1/s;
               if ($cygver=~/(1.7.11-1)/) {
                  print "\n\n   Fatal Error! - The current Cygwin version: $1".
                        "\n   (Base Cygwin cygwin1.dll) at cygwin.com is\n".
                        "   incompatible with FullAuto. Please manually\n".
                        "   download the setup utility from www.cygwin.com,\n".
                        "   and install an\n   older version of Base Cygwin.\n".
                        "   Only then can\n   successfully install FullAuto.\n".
                        "   Optionally, you\n   can also manually install\n".
                        "   Perl when setting up\n   a compatible version of\n".
                        "   Cygwin, and afterwards\n   use the bundled cpan\n".
                        "   utility to install FullAuto\n   You may need to\n".
                        "   contact your Windows System\n   Administrator to\n".
                        "   resolve.\n\n".
                        "   PRESS ANY KEY to Exit Setup\n\n";
                  <STDIN>;
                  exit 1;
               }
            } 
         } elsif ($res->status_line=~/403/) {
            if ($^O eq 'MSWin64' || msw64bit()) { 
               $url='http://www.FullAuto.com/download/setup-x86_64.exe';
            } else {
               $url='http://www.FullAuto.com/download/setup-x86.exe';
            }
            $req = HTTP::Request->new(GET => $url);
            $req->header('Accept' => 'text/html');
            $res = $Ua->request($req);
            if ($res->is_success) {
               print " + request successful.\n"
                  if $CPAN::DEBUG;
               mkpath($main::root_dir,1) unless -d $main::root_dir;
               if ($^O eq 'MSWin64' || msw64bit()) {
                  open(CP,">$main::root_dir\\setup-x86_64.exe") || die $!;
               } else {
                  open(CP,">$main::root_dir\\setup-x86.exe") || die $!;
               }
               binmode(CP);
               print CP $res->content;
            } elsif ($res->status_line=~/403/) {
               $url='http://www.FullAuto.com/download/setup.tar.gz';
               $req = HTTP::Request->new(GET => $url);
               $req->header('Accept' => 'text/html');
               $res = $Ua->request($req);
               if ($res->is_success) {
                  print " + request successful.\n"
                     if $CPAN::DEBUG;
                  open(CP,">$main::PARdir\\setup.tar.gz") || die $!;
                  binmode(CP);
                  print CP $res->content;
               } else {
                  print $res->status_line;
                  sleep 10;
                  die $res->status_line;
               }
            } else {
               print $res->status_line;
               sleep 10;
               die $res->status_line;
            }
         } else {
            print $res->status_line;
            sleep 10;
            die $res->status_line;
         }
         close(CP) || die $!;
         if ($^O eq 'MSWin64' || msw64bit()) {
            chmod 0755, "$main::root_dir\\setup-x86_64.exe";
         } else {
            chmod 0755, "$main::root_dir\\setup-x86.exe";
         }
        
         my $mirror_url='http://www.cygwin.com/mirrors.html';
         $req = HTTP::Request->new(GET => $mirror_url);
         $req->header('Accept' => 'text/html');
         $res = $Ua->request($req);
         my $href='';my @urls=();
         $mirror_url='http://cygwin.mirrors.pair.com';
         if ($res->is_success) {
            print " + request successful.\n"
               if $CPAN::DEBUG;
            my $mirrors=$res->content;
            foreach my $href ($mirrors=~/href="(.*?)"/mg) {
               next if -1==index $href,'://';
               next if -1<index $href,'html';
               next if -1==index $href,'http';
               push @urls, $href;
            }
            $mirror_url=$urls[int(rand($#urls))];
         }
         my $setup_cmd='';
         my $drlet=substr($main::root_dir,0,2);
         if ($selection!~/Install sshd only/s) {

            $install_webapi=fa_web_api();

            my $selection='';
            ($selection,$editor)=fa_editor_mswin();

            if ($selection eq 'vim') {
               $selection='';
            } else {
               $selection=",$selection";
            }

            if ($^O eq 'MSWin64' || msw64bit()) {
               $setup_cmd="$drlet & cd \"$main::root_dir\" & "
                      .'setup-x86_64.exe -P gcc-core,perl-libwww-perl,'
                      .'gcc-g++,make,openssh,openssl,openssl-devel,perl,'
                      .'procps,vim,unzip,libmpfr4,figlet,wget,get,'
                      .'db,libdb-devel,ncurses,cron,inetutils,pkg-config,'
                      .'git,libcrypt-devel,perl-LWP-Protocol-https,nano,'
                      .'autobuild,autoconf,automake,libtool,libxml2-devel,'
                      .$selection.' -X -A -q '."-R $main::root_dir "
                      .'-s '.$mirror_url;
            } else {
               $setup_cmd="$drlet & cd \"$main::root_dir\" & "
                      .'setup-x86.exe -P gcc-core,nano,'
                      .'gcc-g++,make,openssh,openssl,openssl-devel,perl,'
                      .'perl-Win32,db4.8,libdb4.8-devel,ncurses,cron,'
                      .'inetutils,procps,vim,unzip,libmpfr4,figlet,git,'
                      .'wget -X -A -q '."-R $main::root_dir "
                      .'-s '.$mirror_url;
            }
         } else {
            if ($^O eq 'MSWin64' || msw64bit()) {
               $setup_cmd="$drlet & cd \"$main::root_dir\" & "
                      .'setup-x86_64.exe -P openssh,ncurses,inetutils,'
                      .'procps,git,vim,nano,libmpfr4,figlet,wget '
                      .'-X -A -q '."-R $main::root_dir ".'-s '.$mirror_url;
            } else {
               $setup_cmd="$drlet & cd \"$main::root_dir\" & "
                      .'setup-x86.exe -P openssh,ncurses,inetutils,'
                      .'procps,vim,nano,libmpfr4,figlet,git,wget '
                      .'-X -A -q '."-R $main::root_dir ".'-s '.$mirror_url;
            }
         }
         
         my $wver=&windows_ver;
         my $account_type='separate';
         my @sshd_password=();
         my $sshd_account='cyg_server';
         my $privl='';
         my $domain_user='';my $domain='';
         if ($wver!~/95|98|ME/ and
               ($sshd_selection ne 'Do *NOT* Install sshd')) {
            my $domain=`net config workstation`;
            $domain=~/^.*Workstation domain\s+(.+)\s*$/m;
            $domain=$1||'';
            $domain=~tr/\0-\37\177-\377//d;
            chomp($domain);
            if ($wver=~/XP|2000|NT/) {
               my $banner="   For $wver, you have a choice of using\n"
                         ."   either the Local SYSTEM user for the\n"
                         ."   REQUIRED sshd (Secure Shell Daemon/Service\n"
                         ."   supplied by OpenSSH) or a separate user\n"
                         ."   account. The Local SYSTEM account is less\n"
                         ."   maintenance and you won't need to manage or\n"
                         ."   remember a separate account and password -\n"
                         ."   BUT IT IS LESS SECURE. Using a separate user\n"
                         ."   account is *HIGHLY* recommended!:";
               my %Menu_select_account_type=(
         
                   Label  => 'Menu_select_account_type',
                   Item_1 => {
        
                      Text => "Use separate user account for sshd service",
         
                   },
                   Item_2 => {

                      Text => "Use the Local SYSTEM user (least secure)",
         
                   },
                   Banner => $banner,
         
               );
               $account_type=Term::Menus::Menu(\%Menu_select_account_type);
               chomp($account_type);
               exit if $account_type eq ']quit[';
               $privl=' --privileged' if -1<index $account_type,'separate';
            }
            $domain_user=&ws_info($domain) unless $wver=~/XP|2000|NT/;
            my $setup_cyg_server=0;
            if ($domain_user eq 'use_separate_local_login_id_for_sshd') {
               $account_type='separate';
               $domain_user='';
            } elsif ($domain_user eq 
                  'use_separate_local_cyg_server_login_id_for_sshd') {
               $account_type='separate';
               $domain_user='';
               $setup_cyg_server=1 if (-1==index `net user`,'cyg_server');
            } elsif ($domain_user eq
                  'Use the Local SYSTEM user (least secure)') {
               $account_type='system';
               $domain_user='';
            }
            if ($domain_user) {
               print "\n\n\n   Please enter the Password for the $domain ",
                     "account $domain_user,\n   and take steps to insure ".
                     "it's security and recoverability\n   ",
                     "(i.e. - store a copy in a SAFE ",
                     "place where you can find\n   it if necessary.)\n\n\n",
                     "   Please TYPE the Password\n   for ",
                     "$domain domain account \'$domain_user\': ";
               Term::ReadKey::ReadMode(2);
               my $pas=<STDIN>;
               $pas=~/^(.*)$/;
               $sshd_password[0]=$1;
               Term::ReadKey::ReadMode(0);
               chomp($sshd_password[0]);
               print "\n\n   Please verify the $domain_user Password: ";
               Term::ReadKey::ReadMode(2);
               $pas=<STDIN>;
               $pas=~/^(.*)$/;
               $sshd_password[1]=$1;
               Term::ReadKey::ReadMode(0);
               chomp($sshd_password[1]);
               if ($sshd_password[0] ne $sshd_password[1]) {
                  @sshd_password=();
                  my $cc=2;
                  while ($cc--) {
                     print "\n\n";
                     print "   Your Password entries do NOT match!\n\n",
                           "   Please carefully type the\n",
                           "   $domain_user Password: ";
                     Term::ReadKey::ReadMode(2);
                     $pas=<STDIN>;
                     $pas=~/^(.*)$/;
                     $sshd_password[0]=$1;
                     Term::ReadKey::ReadMode(0);
                     chomp($sshd_password[0]);
                     print "\n\n   Please verify the $domain_user Password: ";
                     Term::ReadKey::ReadMode(2);
                     $pas=<STDIN>;
                     $pas=~/^(.*)$/;
                     $sshd_password[1]=$1;
                     Term::ReadKey::ReadMode(0);
                     chomp($sshd_password[1]);
                     last if $sshd_password[0] eq $sshd_password[1];
                  }
               }
               if ($sshd_password[0] ne $sshd_password[1]) {
                  print "\n\n";
                  print "Fatal Error: Unable to verify Password entries!\n\n";
                  print "Press any key to exit FullAuto Setup.\n";
                  <STDIN>;exit 1;
               }
               print "\n";
            } elsif (-1<index $account_type,'separate') {
               if (!$setup_cyg_server) {
                  print "\n       Please type the name of the $wver\n",
                        "        user account that will be used by the sshd\n",
                        "        service: ";
                  $sshd_account=<STDIN>;
                  print "\n";
               }
               print "\n\n\n   Now is the time to CAREFULLY select a ",
                     "password for the\n   $sshd_account account, and",
                     " take steps to insure it's security\n   and ",
                     "recoverability (i.e. - store a copy in a SAFE ",
                     "place where\n   you can find it if necessary.)\n\n\n",
                     "   Please TYPE your new Password\n   for ",
                     "account \'$sshd_account\': ";
               Term::ReadKey::ReadMode(2);
               my $pas=<STDIN>;
               $pas=~/^(.*)$/;
               $sshd_password[0]=$1;
               Term::ReadKey::ReadMode(0);
               chomp($sshd_password[0]);
               print "\n\n   Please verify your new Password: ";
               Term::ReadKey::ReadMode(2);
               $pas=<STDIN>;
               $pas=~/^(.*)$/;
               $sshd_password[1]=$1;
               Term::ReadKey::ReadMode(0);
               chomp($sshd_password[1]);
               if ($sshd_password[0] ne $sshd_password[1]) {
                  @sshd_password=();
                  my $cc=2;
                  while ($cc--) {
                     print "\n\n";
                     print "   Your Password entries do NOT match!\n\n",
                           "   Please carefully type your\n",
                           "   new Password: ";
                     Term::ReadKey::ReadMode(2);
                     $pas=<STDIN>;
                     $pas=~/^(.*)$/;
                     $sshd_password[0]=$1;
                     Term::ReadKey::ReadMode(0);
                     chomp($sshd_password[0]);
                     print "\n\n   Please verify your new Password: ";
                     Term::ReadKey::ReadMode(2);
                     $pas=<STDIN>;
                     $pas=~/^(.*)$/;
                     $sshd_password[1]=$1;
                     Term::ReadKey::ReadMode(0);
                     chomp($sshd_password[1]);
                     last if $sshd_password[0] eq $sshd_password[1];
                  }
               }
               if ($sshd_password[0] ne $sshd_password[1]) {
                  print "\n\n";
                  print "Fatal Error: Unable to verify Password entries!\n\n";
                  print "Press any key to exit FullAuto Setup.\n";
                  <STDIN>;exit 1;
               }
            } elsif (-1<index $account_type,'system') {
               $sshd_password[0]='none';
            } else {
               my $netuser=`net user`;
               $netuser=~s/^.*----(.*)The command comp.*$/$1/s;
               $netuser=~s/^\s*//s;
               $netuser=~s/\s*$//s;
               $netuser=~s/\n/         /g;
               my @netuser=split /    \s*/, $netuser;
               @netuser=grep { $_ ne 'sshd' } @netuser;
               my %sshd_account=();
               if (grep { 'cyg_server' eq $_ } @netuser) {
                  my $cs_info=`net user cyg_server`;
                  my $pwls='';my $ll='';
                  ($pwls=$cs_info)
                     =~s/^.*(Password last set\s*.*?(?:PM|AM)).*/$1/s;
                  ($ll=$cs_info)
                     =~s/^.*(Last logon\s*.*?(?:PM|AM)).*/$1/s;
                  %sshd_account=(

                     Label => 'sshd_account',
                     Item_1 => {

                        Text => 'Remove and recreate local \'cyg_server\''.
                                ' account.'.
                                "\n                 ( Recommended )\n\n",
                     },
                     Item_2 => {

                        Text => 'Use the pre-existing local \'cyg_server\''.
                                " account.\n\n",

                     },
                     Item_3 => {

                        Text => 'Use or create a different local account.',

                     },
                     Banner => "\n   Cygwin's sshd service requires a".
                               "\n   dedicated Windows user account.".
                               "\n   A pre-existing local \'cyg_server\' ID ".
                               "\n   was found with the following properies:".
                               "\n\n      $pwls\n      $ll".
                               "\n\n   Please select an action:",


                  );
               }
               my $selection=Menu(\%sshd_account);
               if (-1<index $selection, 'Remove') {
                  my $ndout=`net user sshd /DELETE 2>&1`;
                  my $cgout=`net user cyg_server /DELETE 2>&1`;
               } elsif (-1==index $selection, 'pre-existing') {
                  @netuser=grep { $_ ne 'cyg_server' } @netuser;
                  %sshd_account=(

                     Label => 'sshd_account',
                     Item_1 => {

                        Text => 'Create a new dedicated Windows user account'.
                                "\n                   (You will be prompted)".
                                "\n\n",

                     },
                     Item_2 => {

                        Text => 'Use the pre-existing \']C[\' local account.',
                        Convey => \@netuser,

                     },
                     Banner => "\n   Cygwin's sshd service requires a".
                               "\n   dedicated Windows user account.".
                               "\n   You can select a pre-existing one,".
                               "\n   or elect to use a different one.".
                               "\n\n   Please select an action:",


                  );
                  $selection=Menu(\%sshd_account);
                  chomp($selection);
                  exit if $selection eq ']quit[';
                  if (-1<index $selection,'pre-exist') {
                     $selection=~s/^.*?['](.*?)['].*$/$1/;
                     $sshd_account=$selection;
                  } else {


                  }
               }
# Check if cyg_server exists but is bad
# Then either remove and ask or just ask if cyg_server or other id
            }
            # Let's see if Cygwin remnants remain that could mess
            # up the installation
            my $check_for_orphaned_sshd_service=`sc qc sshd 2>&1`;              
            unless (-1<index $check_for_orphaned_sshd_service,'does not') {
               my $cygpath=~s/^.*H_NAME\s+:\s+(.*exe).*$/$1/s;
               $cygpath=~s/\\/\//g;
               unless (-e $cygpath) {
                  # cygrunsrv does not exist - let's see if its running?
                  my $chkrun=`sc query sshd 2>&1`;
                  if (-1<index $chkrun,'RUNNING') {
                     # Its running - let's stop it
                     my $stopout=`net stop sshd 2>&1`;
                     unless (-1<index $stopout,'stopped suc') {
                        print "FATAL ERROR - cannot stop sshd: $stopout\n";
                        exit 1;
                     } 
                  }
                  # Now let's delete sshd 
                  my $sc_out=`sc delete sshd 2>&1`;
                  unless (-1<$sc_out,'SUCCESS') {
                     print "FATAL ERROR - cannot delete sshd: $sc_out\n";
                     exit 1;
                  }
               }
            } check_cygserver();
         } elsif ($sshd_selection eq 'Do *NOT* Install sshd') {
            check_cygserver();
         }

         if ($selection!~/Install sshd only/s) {

            my $p_one='Install with Full Access Permissions (Default)';
            my $p_two='Install with Owner Group Permissions';
            my $p_banner=<<'END';

    ___     _ _   _       _           ___                  _ _
   | __|  _| | | /_\ _  _| |_  |     / __| ___ __ _  _ _ _(_) |_ _  _
   | _| || | | |/ _ \ || |  _/ | \   \__ \/ -_) _| || | '_| |  _| || |
   |_| \_,_|_|_/_/ \_\_,_|\__\___/c  |___/\___\__|\_,_|_| |_|\__|\_, |
                                                                 |__/

   Owner/Group is more secure - but choose this only if security is
   important, and you know how to work with operating system permissions.

   Choose a Permission Setting :

END
            my %Menu_select_permissions=(

               Label  => 'Menu_select_permissions',
               Item_1 => {
                            Text => $p_one,
                         },
               Item_2 => { Text => $p_two },
               Scroll => 1,
               Banner => $p_banner,

            );

            $selection=Term::Menus::Menu(\%Menu_select_permissions);
            chomp($selection);
            exit if $selection eq ']quit[';
            $main::cygwin_berkeley_db_mode=$selection;

            &find_windows_app() if
               (-1==index $main::install_firefox,'Install') &&
               (-1==index $main::install_firefox,'NOT');

         }

         system($setup_cmd);

         if ($^O eq 'cygwin') {
            my $cygwin_loc=get_cygwin_location();
            my $clo=$cygwin_loc;
            $clo=~s/\\/\\\\/g;
            my $srvcmd='export CYGWIN=nodosfilewarning & '.
                       "cmd /c $clo\\\\bin\\\\bash -lc ".
                       '"/usr/bin/cygrunsrv -L"';
            my $cygsrvs=`$srvcmd 2>&1`;
            if (($sshd_selection ne 'Do *NOT* Install sshd')
                  && -1==index $cygsrvs,'sshd') {
               if ($domain_user) {
                  system('export CYGWIN=nodosfilewarning & '.
                         "cmd /c $clo\\\\bin\\\\bash -lc ".
                         '"/usr/bin/mkpasswd -u \"'.$domain_user.'\" '.
                         '-d \"'.$domain.'\" >> /etc/passwd"');
                  system('export CYGWIN=nodosfilewarning & '.
                         "cmd /c $clo\\\\bin\\\\bash -lc ".
                         '"/usr/bin/mkgroup -d \"'.$domain.'\" '.
                         '-g  \"Domain Users\" '.
                         '>> /etc/group"');
                  $main::domain_gr_flag=1;
                  $sshd_account=$domain_user;
               }
               system('export CYGWIN=nodosfilewarning & '.
                      "cmd /c $clo\\\\bin\\\\bash -lc ".
                      '"/usr/bin/ssh-host-config -y '.
                      '-u \"'.$sshd_account.'\" -w \"'.
                      $sshd_password[0].'\" '.
                      '-c \"ntsec\"'.$privl.'"');
               print "\n   FullAuto Install continues . . . \n\n";
               system('export CYGWIN=nodosfilewarning & '.
                      "cmd /c $clo\\\\bin\\\\bash -lc ".
                      '"/usr/bin/ssh-user-config -n"');
               print "\n   FullAuto Install continues . . . \n\n";
            }
            if (-1==index $cygsrvs,'cygserver') {
               system('export CYGWIN=nodosfilewarning & '.
                      "cmd /c $clo\\\\bin\\\\bash -lc ".
                      '"/usr/bin/cygserver-config -y"');
            }
            #system('export CYGWIN=nodosfilewarning & '.
            #       "cmd /c $clo\\\\bin\\\\bash -lc ".
            #       '"/usr/bin/cron-config"');
            if (($sshd_selection ne 'Do *NOT* Install sshd')
                  && -1==index $cygsrvs,'sshd') {
               my $netstart="cmd /c $clo\\\\bin\\\\bash -lc ".
                    '"net start sshd 2>&1"';
               my $netout=`$netstart`;
            }
            if (-1==index $cygsrvs,'cygserver') {
               system('export CYGWIN=nodosfilewarning & '.
                      "cmd /c $clo\\\\bin\\\\bash -lc ".
                      '"net start cygserver 2>&1"');
            }
            #system('export CYGWIN=nodosfilewarning & '.
            #       "cmd /c $clo\\\\bin\\\\bash -lc ".
            #       '"net start cron 2>&1"');
         } else {
            my $cygwin_loc=get_cygwin_location();
            my $clo=$cygwin_loc;
            $clo=~s/\\/\\\\/g;
            my $srvcmd='SET CYGWIN=nodosfilewarning & '.
                       "cmd /c $clo\\\\bin\\\\bash -lc ".
                       '"/usr/bin/cygrunsrv -L 2>&1"';
            my $cygsrvs=`$srvcmd 2>&1`;
            if (-1<index $cygsrvs,'system cannot find') {
               $url='http://www.cygwin.com/mirrors.html';
               $req = HTTP::Request->new(GET => $url);
               $req->header('Accept' => 'text/html');
               $res = $Ua->request($req);
               my $href='';my @urls=();my $mirror_url2='';
               if ($res->is_success) {
                  print " + request successful.\n"
                     if $CPAN::DEBUG;
                  my $mirrors=$res->content;
                  foreach my $href ($mirrors=~/href="(.*?)"/mg) {
                     next if -1==index $href,'://';
                     next if -1<index $href,'html';
                     next if -1==index $href,'http';
                     next if -1<index $href,$mirror_url;
                     push @urls, $href;
                  }
                  $mirror_url2=$urls[int(rand($#urls))];
                  $setup_cmd=~s/-s .*$/-s $mirror_url2/; 
                  system($setup_cmd);
                  my $srvcmd='SET CYGWIN=nodosfilewarning & '.
                             "cmd /c $clo\\\\bin\\\\bash -lc ".
                             '"/usr/bin/cygrunsrv -L 2>&1"';
                  my $cygsrvs=`$srvcmd 2>&1`;
                  if (-1<index $cygsrvs,'system cannot find') {
                     print "\n\n".
                        "   Fatal Error! (1) - Cannot install Cygwin\n".
                        "   There were two attempts from two different\n\n".
                        "   Cygwin mirror sites:\n\n".
                        "   $mirror_url\n".
                        "   $mirror_url2\n\n";
                        "   PRESS ANY KEY to Exit Setup\n\n";
                     <STDIN>;
                     exit 1;
                  }
               } else {
                  print "\n\n".
                     "   Fatal Error! (2) - Cannot install Cygwin\n".
                     "   There were two attempts from two different\n\n".
                     "   Cygwin mirror sites:\n\n".
                     "   $mirror_url\n".
                     "   $mirror_url2\n\n";
                     "   PRESS ANY KEY to Exit Setup\n\n";
                  <STDIN>;
                  exit 1;
               }
            } elsif (($sshd_selection ne 'Do *NOT* Install sshd')
                  && -1==index $cygsrvs,'sshd') {
               if ($domain_user) {
                  system('SET CYGWIN=nodosfilewarning & '.
                         "cmd /c $clo\\bin\\bash -lc ".
                         '"/usr/bin/mkpasswd -u \"'.$domain_user.'\" '.
                         '-d \"'.$domain.'\" >> /etc/passwd"');
                  unless ($main::domain_gr_flag) {
                     system('SET CYGWIN=nodosfilewarning & '.
                         "cmd /c $clo\\bin\\bash -lc ".
                         '"/usr/bin/mkgroup -d \"'.$domain.'\" '.
                         '-g  \"Domain Users\" '.
                         '>> /etc/group"');
                     $main::domain_gr_flag=1;
                  }
                  $sshd_account=$domain_user;
               }
               system('SET CYGWIN=nodosfilewarning & '.
                      "cmd /c $cygwin_loc\\bin\\bash -lc ".
                      '"/usr/bin/ssh-host-config -y '.
                      '-u \"'.$sshd_account.'\" -w \"'
                      .$sshd_password[0].'\" '.
                      '-c \"ntsec\"'.$privl.'"');
               print "\n   FullAuto Install continues . . . \n\n";
               system('SET CYGWIN=nodosfilewarning & '.
                      "cmd /c $cygwin_loc\\bin\\bash -lc ".
                      '"/usr/bin/ssh-user-config -n"');
               print "\n   FullAuto Install continues . . . \n\n";
            }
            if (-1==index $cygsrvs,'cygserver') {
               system('SET CYGWIN=nodosfilewarning & '.
                      "cmd /c $cygwin_loc\\bin\\bash -lc ".
                      '"/usr/bin/cygserver-config -y"');
            }
            #system('SET CYGWIN=nodosfilewarning & '.
            #       "cmd /c $cygwin_loc\\bin\\bash -lc ".
            #       '"/usr/bin/cron-config"');
            if (0<length $cygsrvs) {
               if ($sshd_selection ne 'Do *NOT* Install sshd') {
                  system('SET CYGWIN=nodosfilewarning & '.
                       "cmd /c $cygwin_loc\\bin\\bash -lc ".
                       '"net stop sshd 2>&1"');
               }
               system('SET CYGWIN=nodosfilewarning & '.
                    "cmd /c $cygwin_loc\\bin\\bash -lc ".
                    '"net stop cygserver 2>&1"');
               system('SET CYGWIN=nodosfilewarning & '.
                    "cmd /c $cygwin_loc\\bin\\dash -lc ".
                    '"/bin/rebaseall -v"');
               if ($sshd_selection ne 'Do *NOT* Install sshd') {
                  my $netstart='SET CYGWIN=nodosfilewarning & '.
                       "cmd /c $clo\\bin\\bash -lc ".
                       '"net start sshd 2>&1"';
                  my $netout=`$netstart`;
                  if (-1<index $netout,'System error') {
                     my $netdel='SET CYGWIN=nodosfilewarning & '.
                        "cmd /c $clo\\bin\\bash -lc ".
                        '"net user sshd /DELETE 2>&1"';
                     my $ndout=`$netdel`;
                     my $cygdel='SET CYGWIN=nodosfilewarning & '.
                        "cmd /c $clo\\bin\\bash -lc ".
                        '"net user cyg_server /DELETE 2>&1"';
                     my $cgout=`$cygdel`;
                     my $netrm='SET CYGWIN=nodosfilewarning & '.
                        "cmd /c $clo\\bin\\bash -lc ".
                        '"/usr/bin/cygrunsrv -R sshd 2>&1"';
                     my $rmout=`$netrm`;
                     if ($domain_user) {
                        system('SET CYGWIN=nodosfilewarning & '.
                           "cmd /c $clo\\bin\\bash -lc ".
                           '"/usr/bin/mkpasswd -u \"'.$domain_user.'\" '.
                           '-d \"'.$domain.'\" >> /etc/passwd"');
                        unless ($main::domain_gr_flag) {
                           system('SET CYGWIN=nodosfilewarning & '.
                              "cmd /c $clo\\bin\\bash -lc ".
                              '"/usr/bin/mkgroup -d \"'.$domain.'\" '.
                              '-g  \"Domain Users\" '.
                              '>> /etc/group"');
                           $main::domain_gr_flag=1;
                        }
                     }
                     system('SET CYGWIN=nodosfilewarning & '.
                            "cmd /c $cygwin_loc\\bin\\bash -lc ".
                            '"/usr/bin/ssh-host-config -y '.
                            '-u \"'.$sshd_account.'\" -w \"'.
                            $sshd_password[0].'\" '.
                            '-c \"ntsec\"'.$privl.'"');
                     print "\n   FullAuto Install continues . . . \n\n";
                     system('SET CYGWIN=nodosfilewarning & '.
                            "cmd /c $cygwin_loc\\bin\\bash -lc ".
                            '"/usr/bin/ssh-user-config -n"');
                     print "\n   FullAuto Install continues . . . \n\n";
                     my $net_start='SET CYGWIN=nodosfilewarning & '.
                           "cmd /c $clo\\\\bin\\\\bash -lc ".
                           '"net start sshd 2>&1"';
                     my $netot=`$net_start`;
                  }
               }
               system('SET CYGWIN=nodosfilewarning & '.
                    "cmd /c $cygwin_loc\\bin\\bash -lc ".
                    '"net start cygserver 2>&1"');
            }
            if (($sshd_selection ne 'Do *NOT* Install sshd')
                 && -1==index $cygsrvs,'sshd') {
               my $nettstart='SET CYGWIN=nodosfilewarning & '.
                    "cmd /c $clo\\\\bin\\\\bash -lc ".
                    '"net start sshd 2>&1"';
               my $netut=`$nettstart`;
               if (-1<index $netut,'System error') {
                  my $netdel='SET CYGWIN=nodosfilewarning & '.
                    "cmd /c $clo\\\\bin\\\\bash -lc ".
                    '"net user sshd /DELETE 2>&1"';
                  my $ndout=`$netdel`;
                  my $netrm='SET CYGWIN=nodosfilewarning & '.
                    "cmd /c $clo\\\\bin\\\\bash -lc ".
                    '"/usr/bin/cygrunsrv -R sshd 2>&1"';
                  my $rmout=`$netrm`;
                  system('SET CYGWIN=nodosfilewarning & '.
                         "cmd /c $cygwin_loc\\bin\\bash -lc ".
                         '"/usr/bin/ssh-host-config -y '.
                         '-u \"'.$sshd_account.'\" -w \"'.
                         $sshd_password[0].'\" '.
                         '-c \"ntsec\"'.$privl.'"');
                  print "\n   FullAuto Install continues . . . \n\n";
                  system('SET CYGWIN=nodosfilewarning & '.
                         "cmd /c $cygwin_loc\\bin\\bash -lc ".
                         '"/usr/bin/ssh-user-config -n"');
                  print "\n   FullAuto Install continues . . . \n\n";
                  my $net_start='SET CYGWIN=nodosfilewarning & '.
                       "cmd /c $clo\\\\bin\\\\bash -lc ".
                       '"net start sshd 2>&1"';
                  my $netot=`$net_start`;
               }
            }
            if (-1==index $cygsrvs,'cygserver') {
               system('SET CYGWIN=nodosfilewarning & '.
                    "cmd /c $cygwin_loc\\bin\\bash -lc ".
                    '"net start cygserver 2>&1"');
            }
            #system('SET CYGWIN=nodosfilewarning & '.
            #       "cmd /c $cygwin_loc\\bin\\bash -lc ".
            #       '"net start cron 2>&1"');
         }
         if ($selection!~/Install sshd only/) {
            my $cygwin_loc=get_cygwin_location();
            my $clo=$cygwin_loc;
            $clo=~s/\\/\\\\/g;
            my $incpath=$INC[0];
            $incpath=~s/\\/\//g;
            if ($^O eq 'cygwin') {
               system('export CYGWIN=nodosfilewarning & '.
                      "cmd /c $clo\\\\bin\\\\bash -lc ".
                      '"echo y | /usr/bin/perl -e \"eval { require IO::Pty;1 }'.
                      ' or do {require CPAN and '.
                      'CPAN::Shell-^^^>notest(\'install\',\'IO::Pty\')}\""');
               system('export CYGWIN=nodosfilewarning & '.
                      "cmd /c $clo\\\\bin\\\\bash -lc ".
                      '"/usr/bin/perl -e \"eval { require HTML::Tagset;1 }'.
                      ' or do {require CPAN and '.
                      'CPAN::Shell-^^^>notest(\'install\','.
                      '\'HTML::Tagset\')}\""');
               system('export CYGWIN=nodosfilewarning & '.
                      "cmd /c $clo\\\\bin\\\\bash -lc ".
                      '"/usr/bin/perl -e \"eval { require HTML::Parser;1 }'.
                      ' or do {require CPAN and '.
                      'CPAN::Shell-^^^>notest(\'install\','.
                      '\'HTML::Parser\')}\""');
               system('export CYGWIN=nodosfilewarning & '.
                      "cmd /c $clo\\\\bin\\\\bash -lc ".
                      '"/usr/bin/perl -e \"eval { require URI;1 }'.
                      ' or do {require CPAN and '.
                      'CPAN::Shell-^^^>notest(\'install\','.
                      '\'URI\')}\""');
               system('export CYGWIN=nodosfilewarning & '.
                      "cmd /c $clo\\\\bin\\\\bash -lc ".
                      '"/usr/bin/perl -e \"eval {require ExtUtils::Depends;1}'.
                      ' or do {require CPAN and '.
                      'CPAN::Shell-^^^>notest(\'install\','.
                      '\'ExtUtils::Depends\')}\""');
               system('export CYGWIN=nodosfilewarning & '.
                      "cmd /c $clo\\\\bin\\\\bash -lc ".
                      '"/usr/bin/perl -e \"eval { require Task::Weaken;1 }'.
                      ' or do {require CPAN and '.
                      'CPAN::Shell-^^^>notest(\'install\','.
                      '\'Task::Weaken\')}\""');
               system('export CYGWIN=nodosfilewarning & '.
                      "cmd /c $clo\\\\bin\\\\bash -lc ".
                      '"/usr/bin/perl -e \"eval { require Digest::MD5;1 }'.
                      ' or do {require CPAN and '.
                      'CPAN::Shell-^^^>notest(\'install\','.
                      '\'Digest::MD5\')}\""');
               system('export CYGWIN=nodosfilewarning & '.
                      "cmd /c $clo\\\\bin\\\\bash -lc ".
                      '"/usr/bin/perl -e \"eval { require B::Utils;1 }'.
                      ' or do {require CPAN and '.
                      'CPAN::Shell-^^^>notest(\'install\','.
                      '\'B::Utils\')}\""');
               system('export CYGWIN=nodosfilewarning & '.
                      "cmd /c $clo\\\\bin\\\\bash -lc ".
                      '"/usr/bin/perl -e \"eval { require Algorithm::Diff;1 }'.
                      ' or do {require CPAN and '.
                      'CPAN::Shell-^^^>notest(\'install\','.
                      '\'Algorithm::Diff\')}\""');
               system('export CYGWIN=nodosfilewarning & '.
                      "cmd /c $clo\\\\bin\\\\bash -lc ".
                      '"/usr/bin/perl -e \"eval { '.
                      'require Data::Dump::Streamer;1 }'.
                      ' or do {require CPAN and '.
                      'CPAN::Shell-^^^>notest(\'install\','.
                      '\'Data::Dump::Streamer\')}\""');
               system('export CYGWIN=nodosfilewarning & '.
                      "cmd /c $clo\\\\bin\\\\bash -lc ".
                      '"/usr/bin/perl -e \"eval { require Encode::compat;1 }'.
                      ' or do {require CPAN and '.
                      'CPAN::Shell-^^^>notest(\'install\','.
                      '\'Encode::compat\')}\""');
               system('export CYGWIN=nodosfilewarning & '.
                      "cmd /c $clo\\\\bin\\\\bash -lc ".
                      '"/usr/bin/perl -e \"eval { require Win32::API;1 }'.
                      ' or do {require CPAN and '.
                      'CPAN::Shell-^^^>notest(\'install\','.
                      '\'Win32::API\')}\""');
               system('export CYGWIN=nodosfilewarning & '.
                      "cmd /c $clo\\\\bin\\\\bash -lc ".
                      '"/usr/bin/perl -e \"eval { require Win32::DriveInfo;1 }'.
                      ' or do {require CPAN and '.
                      'CPAN::Shell-^^^>notest(\'install\','.
                      '\'Win32::DriveInfo\')}\""');
               system('export CYGWIN=nodosfilewarning & '.
                      "cmd /c $clo\\\\bin\\\\bash -lc ".
                      '"/usr/bin/perl -e \"eval { require JSON::XS;1 }'.
                      ' or do {require CPAN and '.
                      'CPAN::Shell-^^^>notest(\'install\','.
                      '\'JSON::XS\')}\""');
               system('export CYGWIN=nodosfilewarning & '.
                      "cmd /c $clo\\\\bin\\\\bash -lc ".
                      '"/usr/bin/perl -e \"eval { require JSON;1 }'.
                      ' or do {require CPAN and '.
                      'CPAN::Shell-^^^>notest(\'install\','.
                      '\'JSON\')}\""');
               system('export CYGWIN=nodosfilewarning & '.
                      "cmd /c $clo\\\\bin\\\\bash -lc ".
                      '"/usr/bin/perl -e \"eval { require Term::ReadKey;1 }'.
                      ' or do {require CPAN and '.
                      'CPAN::Shell-^^^>notest(\'install\','.
                      '\'Term::ReadKey\')}\""');
               system('export CYGWIN=nodosfilewarning & '.
                      "cmd /c $clo\\\\bin\\\\bash -lc ".
                      '"/usr/bin/perl -e \"eval { '.
                      'require Term::RawInput;1 }'.
                      ' or do {require CPAN and '.
                      'CPAN::Shell-^^^>notest(\'install\','.
                      '\'Term::RawInput\')}\""');
               system('export CYGWIN=nodosfilewarning & '.
                      "cmd /c $clo\\\\bin\\\\bash -lc ".
                      '"/usr/bin/perl -e \"eval { '.
                      'require Term::Menus;1 }'.
                      ' or do {require CPAN and '.
                      'CPAN::Shell-^^^>notest(\'install\','.
                      '\'Term::Menus\')}\""');
               system('export CYGWIN=nodosfilewarning & '.
                      "cmd /c $clo\\\\bin\\\\bash -lc ".
                      '"/usr/bin/perl -e \"eval { '.
                      'require Mozilla::CA;1 }'.
                      ' or do {require CPAN and '.
                      'CPAN::Shell-^^^>notest(\'install\','.
                      '\'Mozilla::CA\')}\""');
               my $par_dir='export CYGWIN=nodosfilewarning & '.
                      "cmd /c $clo\\\\bin\\\\bash -lc ".
                      '"/usr/bin/cygpath -lm \"'.$main::PARdir.'\""';
               my $pardir=`$par_dir`;
               chomp($pardir);my $post_install='';
               if (-1<index $install_webapi,'Web API') {
                  $post_install=";fa --iset-local".
                     ' \\"FullAuto© Proxy Chaining & RESTful Access\\"';
               } else { $post_install=";fa --new-user" }
               system('export CYGWIN=nodosfilewarning & '.
                      "cmd /c $clo\\\\bin\\\\bash -lc ".
                      '"export PERL_MM_USE_DEFAULT=1;'.
                      'export FA_EDITOR=\\"'.$editor.'\\";'.
                      'export FA_WEBAPI=\\"'.$install_webapi.'\\";'.
                      'export FA_BERKELEY=\\"'.
                         $main::cygwin_berkeley_db_mode.'\\";'.
                      'export FA_MOZREPL=\\"'.$main::install_firefox.'\\";'.
                      'export PARdir=\\"'.$pardir.'\\";'.
                      '/usr/bin/echo y|/usr/bin/cpan -i REEDFISH/'.
                      "Net-FullAuto-$main::VERSION.tar.gz$post_install\"");
            } else {
               my $build_dir='SET CYGWIN=nodosfilewarning & '.
                      "cmd /c $clo\\\\bin\\\\bash -lc ".
                      '"echo y | /usr/bin/perl -e '.
                      '\"require CPAN and CPAN::HandleConfig-^^^>load;'.
                      'print \$CPAN::Config-^^^>{build_dir}\" 2>&1"';
               my $bd=`$build_dir`;
               if ($bd=~/^\s*$|Can\'t locate/s) {
                  my $rmdir='SET CYGWIN=nodosfilewarning & '.
                      "cmd /c $clo\\\\bin\\\\bash -lc ".
                      '"/usr/bin/perl -e '.
                      '\"foreach my \$f (@INC) { my \$e=\$f;'.
                      'if (-e \$e.\'/CPAN/Config.pm\') {'.
                      'rm -f \$e.\'/CPAN/Config.pm\';'.
                      'rm -f \$e.\'/CPAN/Config.pm~\';'.
                      'last}print \'done\'}\" 2>&1"';
                  my $rmd=`$rmdir`;
                  system('SET CYGWIN=nodosfilewarning & '.
                      "cmd /c $cygwin_loc\\bin\\bash -lc ".
                      '"/usr/bin/echo y | /usr/bin/cpan"');
               }
               system('SET CYGWIN=nodosfilewarning & '.
                      "cmd /c $cygwin_loc\\bin\\bash -lc ".
                      '"/usr/bin/perl -e \"eval { require IO::Pty;1 }'.
                      ' or do {require CPAN and '.
                      'CPAN::Shell-^^^>notest(\'install\',\'IO::Pty\')}\""');
               system('SET CYGWIN=nodosfilewarning & '.
                      "cmd /c $cygwin_loc\\bin\\bash -lc ".
                      '"/usr/bin/perl -e \"eval { '.
                      'require Data::Dump::Streamer;1 }'.
                      ' or do {require CPAN and '.
                      'CPAN::Shell-^^^>notest(\'get\','.
                      '\'Win32::OLE\')}\""');
               my $streamdir='SET CYGWIN=nodosfilewarning & '.
                      "cmd /c $clo\\\\bin\\\\bash -lc ".
                      '"/usr/bin/perl -e '.
                      '\"require CPAN and CPAN::HandleConfig-^^^>load;'.
                      'print \$CPAN::Config-^^^>{build_dir}\""';
               my $stmout=`$streamdir`;
               $stmout=~s/\s*$//s;
               $stmout=~s/^\s*//s;
               $streamdir='SET CYGWIN=nodosfilewarning & '.
                      "cmd /c $clo\\\\bin\\\\bash -lc ".
                      '"/usr/bin/cygpath -lm \"'.$stmout.'\""';
               $stmout=`$streamdir`;
               $stmout=~s/\s*$//s;
               $stmout=~s/^\s*//s;
               $streamdir='SET CYGWIN=nodosfilewarning & '.
                      "cmd /c $clo\\\\bin\\\\bash -lc ".
                      '"/usr/bin/perl -e '.
                      '\"opendir(DIR,\''.$stmout.'\') or die \$!;'.
                      'my\$t=0;my\$n=\'\';my\$f=\'\';my \$e;'.
                      'while(\$e=readdir(DIR)){'.
                      'next if \$e eq \'.\';'.
                      'next if \$e eq \'..\';'.
                      'next if \$e!~/^Win32-OLE/;'.
                      'next if substr(\$e,-3) eq \'yml\';'.
                      '\$f=\''.$stmout.'\'.\'/\'.\$e;'.
                      'my \$a=(stat(\$f))[9];'.
                      'my \$d=time() - \$a;'.
                      'if(\$t==0 and \$e=~/^Win32-OLE/){'.
                      '\$t=\$d;\$n=\$f;}if(\$d^^^<\$t){'.
                      '\$t=\$d;\$n=\$f;}}\$n=\$f if !\$n and \$f;'.
                      'print \$f\""';
               my $sdir=`$streamdir`;
               $sdir=~s/\s*$//s;
               $sdir=~s/^\s*//s;
               system('SET CYGWIN=nodosfilewarning & '.
                      "cmd /c $cygwin_loc\\bin\\bash -lc ".
                      '"cd \"'.$sdir.'\";/usr/bin/sed -i '.
                      '\'s/stricmp/strcasecmp/\' OLE.xs;"');
               system('SET CYGWIN=nodosfilewarning & '.
                      "cmd /c $cygwin_loc\\bin\\bash -lc ".
                      '"cd \"'.$sdir.'\";/usr/bin/perl Makefile.PL;"');
               system('SET CYGWIN=nodosfilewarning & '.
                      "cmd /c $cygwin_loc\\bin\\bash -lc ".
                      '"cd \"'.$sdir.'\";/usr/bin/make install;"');
               my $par_dir='SET CYGWIN=nodosfilewarning & '.
                      "cmd /c $clo\\\\bin\\\\bash -lc ".
                      '"/usr/bin/cygpath -lm \"'.$main::PARdir.'\""';
               my $pardir=`$par_dir`;
               chomp($pardir);my $post_install='';
               if (-1<index $install_webapi,'Web API') {
                  $post_install=";fa --iset-local".
                     ' \\"FullAuto© Proxy Chaining & RESTful Access\\"';
               } else { $post_install=";fa --new-user" }
               system('SET CYGWIN=nodosfilewarning & '.
                      "cmd /c $cygwin_loc\\bin\\bash -lc ".
                      '"export PERL_MM_USE_DEFAULT=1;'.
                      'export FA_EDITOR=\\"'.$editor.'\\";'.
                      'export FA_WEBAPI=\\"'.$install_webapi.'\\";'.
                      'export FA_BERKELEY=\\"'.
                         $main::cygwin_berkeley_db_mode.'\\";'.
                      'export FA_MOZREPL=\\"'.$main::install_firefox.'\\";'.
                      'export PARdir=\\"'.$pardir.'\\";'.
                      '/usr/bin/echo y|/usr/bin/cpan -i REEDFISH/'.
                      "Net-FullAuto-$main::VERSION.tar.gz$post_install\"");
            }
         }
         if ($selection!~/Install sshd only/) {
            &install_firefox() if -1<index $main::install_firefox,
               'Install';
            print "\n\n   FullAuto Installation has completed",
                  "\n\n   Thank you!",
                  "\n\n   Please report any bugs and send any",
                  "\n   questions, thoughts or feedback to:",
                  "\n\n      Brian.Kelly\@FullAuto.com.\n\n";
         } else {
            print "\n\n   Cygwin sshd Installation has completed",
                  "\n\n   Thank you!",
                  "\n\n   Please report any bugs and send any",
                  "\n   questions, thoughts or feedback to:",
                  "\n\n      Brian.Kelly\@FullAuto.com.\n\n";
         }
         if (exists $ENV{PAR_TEMP}) {
            print "   Press ANY key to exit.\n\n";<STDIN>;
         }
         exit 0;
      }
   } elsif ($process_id) {
      exit;
   }
   my $die=<<'END';

       FATAL ERROR! : Cygwin Linux Emulation Layer
                      is required to use FullAuto
                      on Windows - goto www.cygwin.com.

           Be sure to install the following programs in
           addition to the base package:

           inetutils and openssh [as provided by Cygwin]
           perl [as provided by Cygwin] (*NOT* CPAN)
           perl-Win32 [as provided by Cygwin] (*NOT* CPAN)
           ncurses, cron, and procps [as provided by Cygwin]
           gcc-core and gcc-g++ [as provided by Cygwin]
           Oracle Berkeley DB [as provided by Cygwin or Oracle]

           **IMPORTANT** - the FullAuto install, either manual
           or via CPAN, must be run *inside* a Cygwin bash shell
           when installing FullAuto on Microsoft Windows.

END
   die $die;
}

unless (-e $Config{installsitelib}."/Net/FullAuto/Custom/fa_conf.pm") {
   my @editors=();
   my $banner="\n   ".
           "*** THIS SCREEN WILL TIMEOUT IN 2 MINUTES ***\n\n".
           "   In order is use the integrated edit features\n".
           "   you will need to choose an editor.\n\n".
           "   ( '>' points to default selection )\n\n";
   unless ($editor) {
      if ($^O eq 'cygwin') {
         if (exists $ENV{FA_EDITOR} and $ENV{FA_EDITOR}) {
            $editor=$ENV{FA_EDITOR};
         } else {
            my $tp='';
            my $mount=`/bin/mount -p`;
            $mount=~s/^.*(\/\S+).*$/$1/s;
            unless ($tp=&fa_find_editor('TextPad.exe')) {
               my $sysdr=`cmd /c echo %SystemDrive%`;
               $sysdr=~s/^\s*(.*)\s*$/$1/s;
               my $let=substr($sysdr,0,1);
               my $lt=lc($let);
               if (-e $mount."/$lt/Program Files/TextPad 5/TextPad.exe") {
                  $tp='default';
               }
            }
            if ($tp) {
               push @editors, 'TextPad (Will not work from remote ssh)';
            }
            my $sysdr=`cmd /c echo %SystemDrive%`;
            $sysdr=~s/^\s*(.*)\s*$/$1/s;
            my $let=substr($sysdr,0,1);
            my $lt=lc($let);
            if (-e $mount.
                  "/$lt/Program Files/Windows NT/Accessories/wordpad.exe") {
               unshift @editors,
                  'Microsoft WordPad (Will not work from remote ssh)';
            }
            if (-e '/bin/nano.exe') {
               unshift @editors, 'nano (Recommended for Beginners)';
            }
            if ((-e '/bin/vim.exe') ||
                  (-e '/bin/vim-nox.exe')) {
               unshift @editors, 'vim';
            }
            if ((-e '/bin/emacs.exe') ||
                  (-e '/bin/emacs-nox.exe')) {
               push @editors, 'emacs';
            }
            if (-e '/bin/joe.exe') {
               push @editors, 'joe';
            }
            my %Menu_select_editor=(

                  Label  => 'Menu_select_editor',
                  Item_1 => {

                     Text    => "]C[",
                     Convey  => \@editors,

                  },
                  Scroll => 1,
                  Banner => $banner,

            );
            eval {
               local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required
               alarm 120;
               $selection=Term::Menus::Menu(\%Menu_select_editor);
               alarm 0;
            };
            if ($@) {
               $selection=$editors[0];
            } else {
               chomp($selection);
               exit if $selection eq ']quit[';
               if ($selection=~/TextPad/) {
                  if ($tp eq 'default') {
                     my $sysdr=`cmd /c echo %SystemDrive%`;
                     $sysdr=~s/^\s*(.*)\s*$/$1/s;
                     my $let=substr($sysdr,0,1);
                     my $lt=lc($let);
                     $editor=$mount.
                        "/$lt/Program Files/TextPad 5/TextPad.exe";
                  } else {
                     $tp=~s/\\/\//g;
                     $tp=~s/^([A-Za-z]):(.*)/$1$2/;
                     $editor="$mount/$tp";
                  }
               } elsif ($selection=~s/(wordpad)/$1/i) {
                  $editor=$mount.
                     "/$lt/Program Files/Windows NT/Accessories/wordpad.exe";
               } elsif ($selection=~s/(vim)/$1/i) {
                  if (-e '/bin/vim-nox.exe') {
                     $editor='/bin/vim-nox.exe';
                  } else {
                     $editor='/bin/vim.exe';
                  }
               } elsif ($selection=~s/(emacs)/$1/) {
                  if (-e '/bin/emacs-nox.exe') {
                     $editor='/bin/emacs-nox.exe';
                  } else {
                     $editor='/bin/emacs.exe';
                  }
               } elsif ($selection=~s/(joe)/$1/) {
                  $editor='/bin/joe.exe';
               } elsif ($selection=~s/(nano)/$1/) {
                  $editor='/bin/nano.exe';
               }
               exit if $selection eq ']quit[';
            }
         }
      } else {
         if ((-e '/usr/bin/vi') || (-e '/bin/vi')) {
            push @editors, 'vi';   
         }
         if (-e '/usr/bin/emacs') {
            push @editors, 'emacs';
         }
         if (1<$#editors) {
            my %Menu_select_editor=(

               Label  => 'Menu_select_editor',
               Item_1 => {

                  Text    => "]C[",
                  Convey  => \@editors,

               },
               Scroll => 1,
               Banner => $banner,

            );
            $selection=Term::Menus::Menu(\%Menu_select_editor);
            chomp($selection);
            exit if $selection eq ']quit[';
            if ($selection=~s/(vi)/$1/) {
               if (-e '/usr/bin/vi') {
                  $editor='/usr/bin/vi';
               } else {
                  $editor='/bin/vi';
               }
            } elsif ($selection=~s/(emacs)/$1/) {
               $editor='/usr/bin/emacs';
            }
         } elsif (1==$#editors) {
            $editor=$editors[0];
         } else {
            $editor='';
         }
      }
   }
} else {
   chmod 0755, $Config{installsitelib}."/Net/FullAuto/Distro";
   chmod 0755, $Config{installsitelib}."/Net/FullAuto/Cloud";
   chmod 0755, $Config{installsitelib}."/Net/FullAuto/ISets";
}

&find_windows_app() if $^O eq 'cygwin' &&
   ((-1==index $main::install_firefox,'Install') &&
   (-1==index $main::install_firefox,'NOT'));

if ($^O eq 'cygwin' && !check_for_compiler()) {
   my $uname=`/bin/uname`;
   my $stup='setup-x86.exe';
   $stup='setup-x86_64.exe' if $uname=~/WOW64/ || msw64bit();
   my $die="\n       FATAL ERROR! : The Gnu C Compiler 'gcc': gcc-core".
           "\n                      & gcc-g++ as provided by Cygwin".
           "\n                      is required to install FullAuto".
           "\n                      on Windows.".
           "\n(Hint: Run Cygwin $stup and install 'gcc-core' ".
           "and 'gcc-g++' under the Category 'Devel' ).".
           "\n\n";
   die $die;
} 

if ($^O eq 'cygwin' && !(can_run('/bin/ssh') || can_run('/bin/telnet'))) {
   my $timeout=120;my $a='';
   eval {
      local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required
      alarm $timeout;
      my $uname=`/bin/uname`;
      my $stup='setup-x86.exe';
      $stup='setup-x86_64.exe' if $uname=~/i686/ || msw64bit();
      print "\n       *** THIS SCREEN WILL TIMEOUT IN 2 MINUTES ***\n". 
            "\n       WARNING! : The Secure Shell - 'ssh'".
            "\n                  and/or 'telnet' (via inetutils)".
            "\n                  as provided by Cygwin".
            "\n                  is required to install FullAuto".
            "\n                  on Windows.".
            "\n(Hint: Run Cygwin $stup and install OpenSSH ".
            "under the Category 'Net' ).".
            "\n\n";
      print "Press <ENTER> if you wish to continue, or 'N' to quit . . . [Y] ";
      $a=<STDIN>;
      alarm 0;
   };
   if ($@) {
      # timed out
      exit 1;
   } elsif ($a=~/^[Nn]$/s) {
      exit;
   } alarm 0;
}
if (!can_run('make') && !(($^O eq 'cygwin') && (-e "/usr/bin/make"))) {
   my $die="\n       FATAL ERROR! : Cannot locate 'make'. This program ".
           "\n                      is required to install FullAuto".
           "\n                      (Hint: goto www.gnu.org for gnumake).".
           "\n\n";
   die $die;
}
my $greppath='';
if (-e "/bin/grep") {
   $greppath="/bin/";
} elsif (-e "/usr/bin/grep") {
   $greppath="/usr/bin/";
} elsif (-e "/usr/local/bin/grep") {
   $greppath="/usr/local/bin/";
}
my $get_BerkeleyDB=0;
eval { require BerkeleyDB };
$get_BerkeleyDB=1 if $@;
my $cpan_error='';
eval {
   require CPAN::Mini;
   import CPAN::Mini;
};
if (!$@ && grep { /-*add[-_]?dependencies/i } @ARGV) {
   my $distribution = CPAN::Shell->expand(
         "Module",'BerkeleyDB'
      )->distribution()->pretty_id();
   my $let=unpack('a1',$distribution);
   my $lett=unpack('a2',$distribution);
   my $minicpan=CPAN::Mini->new(

      #remote => "http://www.cpan.org",
      remote => "http://www.perl.com/CPAN",
      local  => cwd()."/dependencies/CPAN",
      log_level => 'debug',
      exact_mirror => 1,

   );
   $minicpan->mirror_file(
      "authors/id/$let/$lett/$distribution");
}
if ($get_BerkeleyDB && $^O ne 'cygwin') {
   # Let's find if Berkeley DB is already on the system
   my $findpath='';
   if (-e "/bin/find") {
      $findpath="/bin/";
   } elsif (-e "/usr/bin/find") {
      $findpath="/usr/bin/";
   } elsif (-e "/usr/local/bin/find") {
      $findpath="/usr/local/bin/";
   }
   my $xargspath='';
   if (-e "/bin/xargs") {
      $xargspath="/bin/";
   } elsif (-e "/usr/bin/xargs") {
      $xargspath="/usr/bin/";
   } elsif (-e "/usr/local/bin/xargs") {
      $xargspath="/usr/local/bin/";
   }
   if ($findpath && $xargspath && $greppath) {
      my @output=();
      my $testgrep =`${greppath}grep -H 2>&1`;
      my $testgrep2=`${greppath}grep 2>&1`;
      my $grepopt='';
      if ((-1==index $testgrep,'illegal option')
            && (-1==index $testgrep2,'-insvxbhwyu')) {
         $grepopt='-H ';
      }
      my $testfind =`find -help 2>&1`;
      my $maxdepth=(-1<index $testfind,'[-P]')?
            " -maxdepth 4":'';
      my $find_cmd1="${findpath}find ";
      my $find_cmd2="$maxdepth -name \'*.h\' ".
                   "| ${xargspath}xargs ${greppath}grep ".
                   "${grepopt}DB_VERSION_STRING";
      print "\nSearching for latest verison of Berkeley DB.\n".
            "This may take up to five minutes ...\n\n";
      FE: foreach my $dir ('/usr/','/opt/',(getpwuid $>)[7].'/') {
         next if unpack('a1',$dir) eq '.';
         next unless -d $dir;
         opendir(DIR, $dir) or die $!;
         while (my $file = readdir(DIR) ) {
            next if ($file eq "." or $file eq ".." or $file eq "doc" or
                     $file eq "X11R6" or $file eq "docs" or
                     $file eq "man" or $file eq "ssl" or
                     $file eq "license" or $file eq "logfile" or
                     $file eq "bin" or ($^O eq 'cygwin' &&
                     ($file eq "Application Data" or
                      $file eq "Favorites" or $file eq
                      "Local Settings" or $file eq "Recent" or
                      $file eq "Start Menu" or $file eq "SendTo" or
                      $file eq "NetHood" or $file eq "PrintHood")));
            if (-d $dir.$file) {
               print "Searching $dir$file ...\n";
               my @subout=`$find_cmd1\"$dir$file\"$find_cmd2`;      
               push @output, @subout;
            }
            last FE if $dir.$file eq "/usr/local";
         }
      }
      my @vers=();my %verhash=(); 
      if (-1<$#output) {
         foreach my $version (@output) {
            next if (-1<index $version, $CPAN::Config->{cpan_home}) || 
                    (-1<index $version, 'Net-FullAuto-') ||
                    $version!~/db.h:.*DB_VERSION_STRING/;
            my @fileparts=split 'db.h:', $version;
            $fileparts[1]=~s/^.*DB (\d+[^:]+):.*\s*$/$1/s;
            $verhash{$fileparts[1]}=$fileparts[0]; 
         }
      }
      my $header_to_use='';my $ver='';
      foreach my $vr (reverse sort keys %verhash) {
         $header_to_use=$verhash{$vr};
         $vr=~/^((^\d+[.]\d+)[.]?\d*).*$/;
         $vr=$1;$ver=$2;
         chomp($vr);chomp($ver);
         my $find_cmd="${findpath}find /usr -name \"libdb-".$ver.".a\"";
         my @lib=`$find_cmd`;
         chomp($lib[0]);$berkeleydb=$lib[0];last;
      }
      my $major_minor_ver=substr($ver,0,(rindex $ver,'.'));
      $major_minor_ver=$ver if -1==index $major_minor_ver,'.';
      if ($^O eq 'cygwin' && !(grep { /build_berkeleydb/i } @ARGV)) {
         if ($berkeleydb && $major_minor_ver>=4.5) {
            $berkeleydb=~s/^(.*)\/.*$/$1/;
            $ENV{'BERKELEYDB_INCLUDE'}=$header_to_use;
            $ENV{'BERKELEYDB_LIB'}=$berkeleydb;
            $ENV{'BERKELEYDB_NAME'}="-ldb-$ver";
            $ENV{'DB_FILE_INCLUDE'}=$header_to_use;
            $ENV{'DB_FILE_LIB'}=$berkeleydb;
            $ENV{'DB_FILE_NAME'}="-ldb-$ver";
            $ENV{'LD_LIBRARY_PATH'}=$berkeleydb;
            $ENV{'LD_RUN_PATH'}=$ENV{'LD_LIBRARY_PATH'};
         } else {
            my $uname=`/bin/uname`;
            my $uname_all=`/bin/uname -a`;
            $uname_all.=$uname;
            my $dbdev="libdb${major_minor_ver}-devel";
            $dbdev='libdb-devel' if $uname=~/WOW64|x86_64/;
            print "\n\n   Fatal Error!: The \'$dbdev\' package is".
                  " missing from your Cygwin installation.\n".
                  "\n\n   Please report any bugs and send any",
                  "\n   questions, thoughts or feedback to:",
                  "\n\n      Brian.Kelly\@FullAuto.com.",
                  "\n\n   Press ANY key to exit.\n\n";<STDIN>;
                  exit 1;
         }
      } elsif ($ENV{AUTOMATED_TESTING} ||
            ($berkeleydb && $major_minor_ver>=5.1)) {
         $berkeleydb=~s/^(.*)\/.*$/$1/;
         $ENV{'BERKELEYDB_INCLUDE'}=$header_to_use;
         $ENV{'BERKELEYDB_LIB'}=$berkeleydb;
         $ENV{'BERKELEYDB_NAME'}="-ldb-$ver";
         $ENV{'DB_FILE_INCLUDE'}=$header_to_use;
         $ENV{'DB_FILE_LIB'}=$berkeleydb;
         $ENV{'DB_FILE_NAME'}="-ldb-$ver";
         $ENV{'LD_LIBRARY_PATH'}=$berkeleydb;
         $ENV{'LD_RUN_PATH'}=$ENV{'LD_LIBRARY_PATH'};
      } else {
         if (-e "dependencies/BerkeleyDB" && !(grep {
               /(?:use[-_]?)?internet|online|connect_to_internet_ok/i
               } @ARGV)) {
            cpan_gunzip_and_untar();
            my $dir=&cwd.'/dependencies/BerkeleyDB';
            opendir(DIR,$dir);
            my @files = readdir(DIR);
            closedir(DIR);
            my $file='';my $filename='';
            foreach my $f (@files) {
               next if $f eq '.';
               next if $f eq '..';
               if (-1==index $f,'.md5') {
                  $file=$f;
                  last;
               }
            }
            my $filenm=$file;
            $file=~s/.tar.gz$//;
            $filename="${file}_${$}.tar.gz";
            File::Copy::copy("$dir/$filenm",&cwd."/$filename");
            my $so=system($CPAN::Config->{gzip}." -d $filename");
            if ($so==-1) {
               die "Cannot gunzip $filename: $!\n";
            }
            $filename=~s/\.gz$//;
            print "***** Untar4: ",
               $CPAN::Config->{tar}," xvf $filename\n";
            open(FH, $CPAN::Config->{tar}." xvf $filename|");
            while (my $line=<FH>) {
               print $line;
            }
            close FH;
            $filename=~/^(.*)_(\d+).tar$/;
            $filename=$1;
            my $uniq=$2;
            File::Copy::move("$filename.NC","$filename.NC_$uniq");
            my $ver=$filenm;
            $ver=~s/_.*$//;
            $ver=~s/^.*db-(\d+[.]\d+).*$/$1/;
            my $pre="/usr/local/BerkeleyDB.$ver";
            $pre=$PREFIX."BerkeleyDB$ver" if $PREFIX;
            build_berkeleydb($filename,$uniq,$pre,$PREFIX,'');
         } else {
            download_berkeleydb();
         }
         unless (exists $ENV{'BERKELEYDB_INCLUDE'} &&
               $ENV{'BERKELEYDB_INCLUDE'}) {
            my $BerkDownload='http://www.oracle.com/technetwork/products/'.
                             'berkeleydb/downloads/index.html';
            my $PackManagers='http://en.wikipedia.org/wiki/'.
                             'List_of_software_package_management_systems';
            my $w='      ';
            my $die="\n$w ".
               "FATAL ERROR! : Cannot locate 'Berkeley DB'. This C Library".
               " \n$w                is required to install FullAuto".
               "\n$w                (Hint: goto\n".
               "\n$w $BerkDownload\n".
               "\n$w                 for Berkeley DB Source Code. Binary".
               " versions".
               "\n$w                 of the Library are widely available via".
               "\n$w                 package managers such as yum and apt-get".
               "\n$w                 See:\n".
               "\n$w $PackManagers).".
               "\n\n";
            die $die;
         }
      }
   }
} elsif ($^O eq 'cygwin') {
   my $uname=`/bin/uname` || die $!;
   my $uname_all=`/bin/uname -a` || die $!;
   $uname_all.=$uname;
   $ENV{'BERKELEYDB_INCLUDE'}='/usr/include';
   $ENV{'BERKELEYDB_LIB'}='/usr/lib';
   if ($uname_all=~/WOW64|x86_64/) {
      $ENV{'BERKELEYDB_NAME'}='-ldb';
      $ENV{'DB_FILE_NAME'}='-ldb';
   } else {
      $ENV{'BERKELEYDB_NAME'}='-ldb-4.8';
      $ENV{'DB_FILE_NAME'}='-ldb-4.8';
   }
   $ENV{'DB_FILE_INCLUDE'}='/usr/include';
   $ENV{'DB_FILE_LIB'}='/usr/lib';
}

if (grep { /-*add[-_]?dependencies/i } @ARGV) {
   my @download=download_berkeleydb();
   `mkdir -p 'dependencies/BerkeleyDB'` unless
      -e 'dependencies/BerkeleyDB';
   `rm -rf dependencies/BerkeleyDB/*`;
   File::Copy::move($download[0],
      "dependencies/BerkeleyDB/$download[2].tar.gz");
   File::Copy::move($download[1],
      "dependencies/BerkeleyDB/$download[2].tar.gz.md5");
   require File::Copy;
   open(MO,"<MANIFEST");
   open(MN,">MANIFEST_NEW");
   while (my $file=<MO>) {
      next if $file=~/dependencies\/CPAN/s;
      next if $file=~/dependencies\/BerkeleyDB/s;
      next if $file=~/demo.*exe/s;
      print MN $file;
   }
   close MO;close MN;
   File::Copy::move('MANIFEST_NEW','MANIFEST');
   open(MF,">>MANIFEST") || die "Cannot open MANIFEST: $!\n";
   my $found=`find dependencies/CPAN -type f`;
   $found.=`find dependencies/BerkeleyDB -type f`;
   my @found=split "\n",$found;
   open(MF,">>MANIFEST") || die "Cannot open MANIFEST: $!\n";
   foreach my $fnd (@found) {
      print MF "$fnd\n";
   }
   print MF "demo/pscp.exe\n";
   print MF "demo/putty.exe\n";
   print MF "demo/puttygen.exe\n";
   print MF "demo/runputty.exe\n";
   print MF "demo/puttykey.exe\n";
   print MF "demo/engine.exe\n";
   print MF "demo/puttycfg.exe\n";
   print MF "demo/puttyyes.exe\n";
   close MF;
} else {
   require File::Copy;
   open(MO,"<MANIFEST");
   open(MN,">MANIFEST_NEW");
   while (my $file=<MO>) {
      next if $file=~/dependencies\/CPAN/s;
      next if $file=~/dependencies\/BerkeleyDB/s;
      print MN $file;
   }
   close MO;close MN;
   File::Copy::move('MANIFEST_NEW','MANIFEST');
}

chdir $main::curdir;

if ($get_BerkeleyDB) {

   do {
      my $p='BerkeleyDB';
      eval "use $p;1" or
      do {
         print"==> $p required."
         and print "*** Installing $p\n"
         and
         do {
            eval{
               require CPAN;
               CPAN::Shell->force('install',$p);
            };
            eval "use $p;1" ||
               die "$@ *** Please manually install $p from cpan.org first...\n"
         }
      }
   }
}

chdir $main::curdir;

my $B_flag=1;
while (1) {
   eval {
      my %hash=();
      require BerkeleyDB;
      my $db = tie %hash, "BerkeleyDB::Btree",
          -Filename => "fullauto_test_for_db_creation.db",
          -Flags =>  BerkeleyDB::DB_CREATE()
      or die "Cannot tie fullauto_test_for_db_creation.db: $!";
      undef $db;
      untie %hash;
      unlink "fullauto_test_for_db_creation.db";
   };
   if ($@) {
      if (-1<index $@,'libgcc_s.so.1' && $B_flag) {
         if (-e '/usr/local/lib/libgcc_s.so.1') {
            `ln -s /usr/local/lib/libgcc_s.so.1 /usr/lib/libgcc_s.so.1`;
            # Flush inheritance caches
            @{BerkeleyDB::ISA} = ();
            my $symtab = 'BerkeleyDB::';
            # Delete all symbols except other namespaces
            for my $symbol (keys %$symtab) {
               next if $symbol =~ /\A[^:]+::\z/;
               delete $symtab->{$symbol};
            }
            delete $INC{'BerkeleyDB.pm'};
            $B_flag=0;
            next;
         }
      }
      my $die=<<END;
$@
   FATAL ERROR! : Cannot create 'fullauto_test_for_db_creation.db'
                  You may be missing the Berkeley DB 'c' library.
                  This 'c' library is required to install FullAuto.
END
      if ($^O eq 'cygwin') {
         my $uname=`/bin/uname`;
         my $stup='setup-x86.exe';
         $stup='setup-x86_64.exe' if $uname=~/i686/ || msw64bit();
         $die.="\n(Hint: Run Cygwin $stup and install Oracle Berkley ".
               "DB under the Category 'Database' ).";
      } else {
         $die.="\n(Hint: goto ->  http://www.oracle.com/technetwork/".
               "products/berkeleydb/downloads/index.html ).";
      }
      $die.="\n\n";
      die $die;
   }
   last
}

sub download_berkeleydb {

   my $url=
      'http://www.oracle.com/technetwork/'.
      'products/berkeleydb/downloads/index.html';
   if ($CPAN::META->has_usable('LWP')) {
      FA::LWP::UserAgent->config;
      print "Fetching with LWP:\n  $url\n";
      my $Ua;
      eval { $Ua = FA::LWP::UserAgent->new(
             timeout=>300,show_progress=>1) };
      if ($@) {
         $CPAN::Frontend->mywarn(
            "ERROR: FA::LWP::UserAgent->new dies with $@\n");
      } else {
         my($var);
         $Ua->proxy('http', $var)
            if $var = $CPAN::Config->{http_proxy} ||
            $ENV{http_proxy};
         $Ua->no_proxy($var)
            if $var = $CPAN::Config->{no_proxy} || $ENV{no_proxy};
      }
      my $req = HTTP::Request->new(GET => $url);
      $req->header('Accept' => 'text/html');
      my $res = $Ua->request($req);
      my $BDB_selection='NON-ENCRYPTED';
      if ($res->is_success) {
         print " + request successful.\n"
            if $CPAN::DEBUG;
         my $source=$res->content;
         my $site='download.oracle.com';
         $source=~
           s/^.*?(http:\/\/$site\/)(?:otn\/)*(b.*?\d.tar.gz).*$/$1$2/s;
         my $file=$2;
         my $file=substr($file,(index $file,'/')+1,-7);
         my $ver=$file;
         $ver=~s/_.*$//;
         $ver=~s/^.*db-(\d+[.]\d+).*$/$1/;
         my $timeout=120;my $a='';my $w="      ";
         my $pre="/usr/local/BerkeleyDB.$ver";
         $pre=$PREFIX."BerkeleyDB$ver" if $PREFIX;
         my $berkeley_banner=<<END;

         *** THIS SCREEN WILL TIMEOUT AND PROCEED WITH Berkeley DB
                      INSTALLATION in 5 MINUTES ***

   Berkeley DB is a file-based (lightweight) database that FullAuto uses for
   storing and retrieving credentials and persistence data. Berkeley DB is
   maintained by Oracle Corporation and hosted at Oracle.com. It has the same
   open source license as FullAuto: GNU Affero General Public License V3.0.
   The default version of Berkeley DB that FullAuto will install and use is
   the latest **NON-ENCRYPTED** version. There is an option to choose
   Encrypted on the next screen.

         There is **NO WARRANTY** for Berkeley DB. USE AT YOUR RISK!

   FullAuto setup will download source code from Oracle.com and build it. It
   will be installed into:   $pre
END

               my $berkeleybanner=<<END;

         *** THIS SCREEN WILL TIMEOUT AND PROCEED WITH Berkeley DB
                      INSTALLATION in 5 MINUTES ***







END

               my $encrypted_banner=<<END;

   From http://http://docs.oracle.com/cd/E17076_03/html/index.html:

   "Berkeley DB releases optionally include strong cryptographic support;
   this release DOES contain cryptographic support. Export/import and/or
   use of cryptography software, or even communicating technical details
   about cryptography software, is illegal in some parts of the world. You
   are strongly advised to pay close attention to any export/import and/or
   use laws which apply to you when you import a release of Berkeley DB
   including cryptography to your country or re-distribute source code
   from it in any way."

   FullAuto does *NOT* utilize the encrypted features of Berkeley DB, and
   only offers to install the encrypted version as a courtesy. You are
   advised to install the NON-ENCRYPTED version unless you have specific
   reasons for needing the encrypted one.
END

         my %encryted_berkeley=(

            Name => 'encrypted_berkeley',
            Item_1 => {

               Text => "Install NON-ENCRYPTED Berkeley DB".
                       " ( Recommended! )",

            },

            Item_2 => {

               Text => "Install Encrypted Berkeley DB",

            },
            Banner => $encrypted_banner,

         );

         my %berkeleymenu=(

             Name => 'berkeleymenu',
             Item_1 => {

                Text => "Install NON-ENCRYPTED Berkeley DB",

             },
             Item_2 => {

                Text => "Install Encrypted Berkeley DB",
                Result => \%encryted_berkeley,

             },
             Item_3 => {

                Text => "Exit FullAuto Setup",

             },
             Scroll => 1,
             Banner => $berkeleybanner,

         );
         my %berkeley_menu=(

            Name   => 'berkeley_menu',
            Result => \%berkeleymenu,
            Banner => $berkeley_banner,

         );
         my $already_downloaded=0;
         my $filename='';
         unless (grep { /Encrypted/i } @ARGV) {
            unless (keys %main::amazon) { 
               eval {
                  local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required
                  alarm $timeout;
                  $BDB_selection=Menu(\%berkeley_menu);
                  alarm 0;
               };
               if ($@) {
                  # timed out
                  $BDB_selection='NON-ENCRYPTED';
                  $source=~s/tar.gz/NC.tar.gz/;
               } elsif ($BDB_selection=~/\]quit\[|Exit/s) {
                  print "\n";
                  exit;
               } elsif (-1<index $BDB_selection,'Encrypted') {
                  $BDB_selection='Encrypted';
               } else {
                  $source=~s/tar.gz/NC.tar.gz/;
               } alarm 0;
            } else {
               $BDB_selection='NON-ENCRYPTED';
               $source=~s/tar.gz/NC.tar.gz/;
            }
         } elsif (grep  { /Encrypted/ } @ARGV) {
            $BDB_selection='Encrypted';
            $already_downloaded=1;
            $filename=$ARGV[$#ARGV];
         } else {
            $source=~s/tar.gz/NC.tar.gz/;
            $already_downloaded=1;
            $filename=$ARGV[$#ARGV];
         }
         my $fh='';
         my $suffix=($BDB_selection eq 'Encrypted')?
               '.tar.gz':'.NC.tar.gz';
         unless ($already_downloaded) {
            ($fh,$filename)=get_temp_file($file,$suffix);
            my $end_flag=0;my $md5filename='';
            my %errors = ('500'=>'Bad hostname supplied',
                          '404'=>'URL not found',
                          '403'=>'URL forbidden',
                          '401'=>'Authorization failed',
                          '400'=>'Bad request found',
                          '302'=>'Redirected URL'
            );
            while (1) {
               $req = HTTP::Request->new(GET => $source);
               $req->header('Accept-Encoding' => 'gzip, compress');
               $res = $Ua->request($req);
               my $success=1;
               if ($res->is_success) {
                  print " + request successful.\n"
                     if $CPAN::DEBUG;
                  print $fh $res->content;
                  close $fh;
               } else {
                  my $status_line=$res->status_line;
                  ($status_line) = ($status_line =~ /(\d+)/);
                  if (defined($errors{$status_line})) {
                     print(
                        "LWP failed with code $status_line, ",
                        "message $errors{$status_line}\n".
                        "Please check your connection to the Internet!\n",
                        $status_line,
                        $res->message,
                     );
                     if (!$end_flag && ($status_line eq '404')) {
                        $source=$last_known_good_location;
                        $end_flag=1;my $rt=qr/b.*?\d.tar.gz/;
                        my $h=qr/http:\/\/$site\//;
                        $source=~s/^.*?($h)(?:otn\/)*($rt).*$/$1$2/s;
                        $file=$2;
                        $file=substr($file,(index $file,'/')+1,-7);
                        $ver=$file;
                        $ver=~s/_.*$//;
                        $ver=~s/^.*db-(\d+[.]\d+).*$/$1/;
                        next;
                     }
                  } else {
                     print(
                        "LWP failed with an Unknown Error\n".
                        "Please check your connection to the Internet!\n",
                     );
                  }
                  $success = 0;
                  close $fh;
                  last;
               }
               print(qq{ + saved content to $filename \n})
                  if $CPAN::DEBUG;
               my $md5fh='';
               ($md5fh,$md5filename)=get_temp_file($file,$suffix.'.md5');
               $req = HTTP::Request->new(GET => $source.'.md5');
               $req->header('Accept-Encoding' => 'gzip, compress');
               $res = $Ua->request($req);
               if ($res->is_success) {
                  print " + request successful.\n"
                     if $CPAN::DEBUG;
                  print $md5fh $res->content;
                  close $md5fh;
               } else {
                  my $status_line=$res->status_line;
                  ($status_line) = ($status_line =~ /(\d+)/);
                  if (defined($errors{$status_line})) {
                     print(
                        "LWP failed with code $status_line, ",
                        "message $errors{$status_line}\n".
                        "Please check your connection to the Internet!\n",
                        $status_line,
                        $res->message,
                     );
                     if (!$end_flag && ($status_line eq '404')) {
                        $source=$last_known_good_location;
                        $end_flag=1;my $rt=qr/b.*?\d.tar.gz/;
                        my $h=qr/http:\/\/$site\//;
                        $source=~s/^.*?($h)(?:otn\/)*($rt).*$/$1$2/s;
                        $file=$2;
                        $file=substr($file,(index $file,'/')+1,-7);
                        $ver=$file;
                        $ver=~s/_.*$//;
                        $ver=~s/^.*db-(\d+[.]\d+).*$/$1/;
                        next;
                     }
                  } else {
                     print(
                        "LWP failed with an Unknown Error\n".
                        "Please check your connection to the Internet!\n",
                     );
                  }
                  $success = 0;
                  close $fh;
                  last;
               }
               print(qq{ + saved md5 content to $md5filename \n})
                  if $CPAN::DEBUG;
               open(MH,"<$md5filename") || die $!;
               my $mhf=<MH>;
               close(MH);
               my $checksum=$mhf;
               $checksum=~s/^\s*(\S+)\s+.*$/$1/s;
               open(FILE, $filename) or die "Can't open '$file': $!";
               binmode(FILE);
               require Digest::MD5;
               import Digest::MD5;
               my $digestmd5=Digest::MD5->new->addfile(*FILE)->hexdigest;
               if ($checksum eq $digestmd5) {
                  print(qq{ + CHECKSUM Test for $filename *PASSED* \n})
                     if $CPAN::DEBUG;
               } else {
                  print "CHECKSUM test for $filename *FAILED*\n";
                  print "CALCULATED=$digestmd5 and ",
                        "DOWNLOADED=$checksum\n";
                  print "\nPress ANY key to terminate FullAuto ",
                        "installation ...\n";
                  <STDIN>;
                  die "FATAL ERROR! : ".
                      "CHECKSUM Test for $filename *FAILED*\n";
               }
               close(FILE);
               last;
            }
            if (grep { /-*add[-_]?dependencies/i } @ARGV) {
               Term::ReadKey::ReadMode(0);
               return $filename,$md5filename,$file;
            } else {
               cpan_gunzip_and_untar();
               unless (keys %main::amazon) {
                  my $so=system($CPAN::Config->{gzip}." -d $filename");
                  if ($so==-1) {
                     die "Cannot gunzip $filename: $!\n";
                  }
               }
               $filename=~s/\.gz$//;
            }
         }
         if (keys %main::amazon) {
            unless (exists $main::amazon{'freebsd'}) {
               unless ($already_downloaded) {
                  if (grep { /-*add[-_]?dependencies/i } @ARGV) {
                     exec 'sudo',$^X,'Makefile.PL','add_dependencies',
                          $BDB_selection,$filename;
                  } else {
                     exec 'sudo',$^X,'Makefile.PL',$BDB_selection,
                          $filename;
                  }
               }
               my $so=system($CPAN::Config->{gzip}." -d $filename");
               if ($so==-1) {
                  die "Cannot gunzip $filename: $!\n";
               }
               print "***** Untar1: sudo ",
                  $CPAN::Config->{tar}," xvf $filename\n";
               open(FH, "sudo ".$CPAN::Config->{tar}." xvf $filename|");
            } else {
               unless ($already_downloaded) {
                  if (grep { /-*add[-_]?dependencies/i } @ARGV) {
                     exec 'sudo',$^X,'Makefile.PL','add_dependencies',
                          $BDB_selection,$filename;
                  } else {
                     exec 'sudo',$^X,'Makefile.PL',$BDB_selection,
                          $filename;
                  }
               }
               my $so=system($CPAN::Config->{gzip}." -d $filename");
               if ($so==-1) {
                  die "Cannot gunzip $filename: $!\n";
               }
               print "***** Untar2: ",
                  $CPAN::Config->{tar}," xvf $filename\n";
               open(FH, $CPAN::Config->{tar}." xvf $filename|");
            }
         } else {
            print "***** Untar3: ",
               $CPAN::Config->{tar}," xvf $filename\n";
            open(FH, $CPAN::Config->{tar}." xvf $filename|");
         }
         while (my $line=<FH>) {
            print $line;
         }
         close FH;
         my $uniq='';
         if ($BDB_selection eq 'Encrypted') {
            $filename=~/^.*(......).tar$/;
            $uniq=$1;
            $filename=~s/........tar$//;
            `mv -f $filename ${filename}_$uniq`;
         } else {
            $filename=~/^.*(......).NC.tar$/;
            $uniq=$1;
            $filename=~s/........NC.tar$//;
            `mv -f $filename.NC $filename.NC_$uniq`;
         }
         build_berkeleydb($filename,$uniq,$pre,$PREFIX,$BDB_selection);
      } else {
         if ($res->is_error(500)) {
            print(sprintf(
               "LWP failed with code[%s], message[%s]\n".
               "Please check your connection to the Internet!\n",
               $res->code,
               $res->message,
            ));
         } else {
            print(sprintf(
               "LWP failed with code[%s], message[%s]\n",
               $res->code,
               $res->message,
            ));
         }
      }
   } else {
      $CPAN::Frontend->mywarn("  LWP not available\n");
   }

}

sub build_berkeleydb {

   my $filename=$_[0];
   my $uniq=$_[1];
   my $pre=$_[2]||'';
   my $PREFIX=$_[3]||'';
   my $BDB_selection=$_[4]||'';
   my $args=' --enable-sql --enable-sql_compat';
   if ($PREFIX) {
      $args.=' --prefix="'.$PREFIX.'"';
   }
   my $one=1;
   WH: while ($one) {
      if ($BDB_selection eq 'Encrypted') {
         open(FH,
            "cd ${filename}_$uniq/build_unix;".
            "../dist/configure$args 2>&1|")
         || warn $!;
      } else {
         open(FH,
            "cd ${filename}.NC_$uniq/build_unix;".
            "../dist/configure$args 2>&1|")
         || warn $!;
      }
      while (my $line=<FH>) {
         if (-1<index $line,'C compiler cannot create executables') {
            $ENV{'CC'}='gcc';
            next WH;
         }
      }
      last;
   }
   close FH;
   unless ($CPAN::Config->{make}) {
      if (-e '/usr/bin/make') {
         $CPAN::Config->{make}='/usr/bin/make';
      } elsif (-e '/usr/local/bin/make') {
         $CPAN::Config->{make}='/usr/local/bin/make';
      }
   }
   if ($BDB_selection eq 'Encrypted') {
      print "*** Starting Encrypted BerkeleyDB build\n";
      system("(cd ${filename}_$uniq/build_unix;".
            $CPAN::Config->{make}." install) 2>&1")
         || warn $!;
      print "*** Completed Encrypted BerkeleyDB build\n";
   } else {
      print "*** Starting Non-Encrypted BerkeleyDB build\n";
      system("(cd ${filename}.NC_$uniq/build_unix;".
         $CPAN::Config->{make}." install) 2>&1")
         || warn $!;
      print "*** Completed Non-Encrypted BerkeleyDB build\n";
   }
   my $ver=$filename;
   $ver=~s/^.*db-(\d+[.]\d+).*$/$1/;
   $berkeleydb=$pre.'/lib';
   my $header_to_use=$pre.'/include';
   $ENV{'BERKELEYDB_INCLUDE'}=$header_to_use;
   $ENV{'BERKELEYDB_LIB'}=$berkeleydb;
   $ENV{'BERKELEYDB_NAME'}="-ldb-$ver";
   $ENV{'DB_FILE_INCLUDE'}=$header_to_use;
   $ENV{'DB_FILE_LIB'}=$berkeleydb;
   $ENV{'DB_FILE_NAME'}="-ldb-$ver";
   $ENV{'LD_LIBRARY_PATH'}=$berkeleydb;
   $ENV{'LD_RUN_PATH'}=$ENV{'LD_LIBRARY_PATH'};

}

sub get_temp_file {

   my $file=$_[0];
   my $suffix=$_[1];
   my $fh='';my $filename='';
   if ($CPAN::META->has_usable("File::Temp")) {
      $fh = File::Temp->new(
            dir      => cwd(),
            template => "${file}_XXXXXX",
            suffix => $suffix,
            unlink => 0,
           );
      $filename = $fh->filename;
   } else {
      $fh = FileHandle->new;
      $filename = "${file}_${$}$suffix";
   }
   chomp($filename);
   return $fh,$filename;

}

sub cpan_gunzip_and_untar {

   unless ($CPAN::Config->{gzip}) {
      if (-e '/usr/bin/gzip') {
         $CPAN::Config->{gzip}='/usr/bin/gzip';
      } elsif (-e '/usr/local/bin/gzip') {
         $CPAN::Config->{gzip}='/usr/local/bin/gzip';
      } else {
         print "\n\n   Fatal Error!: The 'gzip' utility is".
            " missing.\n".
            "\n\n   Please report any bugs and send any",
            "\n   questions, thoughts or feedback to:",
            "\n\n      Brian.Kelly\@FullAuto.com.",
            "\n\n   Press ANY key to exit.\n\n";<STDIN>;
            exit 1;
      }
   }
   unless ($CPAN::Config->{tar}) {
      if (-e '/usr/sfw/bin/gtar') {
         $CPAN::Config->{tar}='/usr/sfw/bin/gtar';
      } elsif (-e '/usr/bin/tar') {
         $CPAN::Config->{tar}='/usr/bin/tar';
      } elsif (-e '/usr/local/bin/tar') {
         $CPAN::Config->{tar}='/usr/local/bin/tar';
      } else {
         print "\n\n   Fatal Error!: The 'tar' utility is".
            " missing.\n".
            "\n\n   Please report any bugs and send any",
            "\n   questions, thoughts or feedback to:",
            "\n\n      Brian.Kelly\@FullAuto.com.",
            "\n\n   Press ANY key to exit.\n\n";<STDIN>;
            exit 1;
      }
   }

}

sub find_windows_app {

   # Let's look for Firefox
   my $firefox='REG QUERY "HKEY_LOCAL_MACHINE\\SOFTWARE\\'.
               'Mozilla\\Mozilla Firefox" 2>&1';
   $firefox=`$firefox`;
   $firefox=~tr/\0-\11\13-\37\177-\377//d;
   chomp($firefox);
   $firefox=~s/^.*CurrentVersion\s*REG_SZ\s*(.*?)\n.*$/$1/s;
   $firefox='REG QUERY "HKEY_LOCAL_MACHINE\\SOFTWARE\\'.
            "Mozilla\\Mozilla Firefox\\$firefox\\Main\" 2>&1";
   open (FF,"$firefox|");
   while (my $line=<FF>) {
      $firefox.=$line;
   }
   close FF;
   $firefox=~tr/\0-\11\13-\37\177-\377//d;
   chomp($firefox);
   $firefox=~s/^.*Path(?:To)*Exe\s*REG_SZ\s*(.*\.exe).*$/$1/s;
   $firefox=~s/\s*$//s;
   my $fftest=substr($firefox,0,2) if 1<length $firefox;
   $fftest||='';
   my $selection='';
   if ($fftest=~/\w:|\/\w/) {
      $fftest=substr($firefox,0,(rindex $firefox,'\\'));
   } else {
      $fftest='';
   }
   if (-1<index $firefox,'unable to find') {
      unless ($main::install_firefox_without_asking) {
         # Ask if we should install
         my $one="YES - Install Mozilla Firefox & MozRepl\n\n";
         my %_askfirefox=(

            Label => '_askfirefox',
            Item_1 =>  {
                           Text   => "]C[",
                           Convey => [ $one,
                                       'NO  - DO *NOT* INSTALL Firefox' ],
                       },
            Scroll => 2,
            Banner=> "   *** THIS SCREEN WILL TIMEOUT IN 2 MINUTES ***\n\n".
                     "   Mozilla Firefox has an available add-on called ".
                     "MozRepl.\n\n   With Firefox equipped with MozRepl, ".
                     "FullAuto can do\n   extremely powerful WEB ".
                     "Automation!\n\n   Would you like the FullAuto ".
                     "installer to install Firefox\n   and MozRepl?\n\n",
         );
         eval {
            local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required
            alarm 120;
            $selection=Term::Menus::Menu(\%_askfirefox);
            alarm 0;
         };
         if ($@) {
            $selection='DO_NOT_INSTALL';
         } else {
            chomp($selection);
            $selection='Install_Mozilla_Firefox'
               if -1<index $selection,'Install Mozilla Firefox';
            $selection='DO_NOT_INSTALL'
               if -1<index $selection,'*NOT* INSTALL';
            exit if $selection eq ']quit[';
         }
      } else { $selection='Install_Mozilla_Firefox' }
      $main::install_firefox=$selection;
   } else { # Look for MozRepl
      my $up=$ENV{'USERPROFILE'};
      if (-1<index $up,'Documents') {
         $up.="\\Application Data\\Mozilla\\Firefox\\Profiles\\";
      } else {
         $up.="\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\";
      }
      my @dirs=();
      if (-e $up) {
         opendir(DIR,$up);
         @dirs = readdir(DIR);
         closedir(DIR);
      }
      if (-1<$#dirs) {
         foreach my $profile (@dirs) {
            opendir(DIR,$up."\\$profile\\extensions");
            my @files = readdir(DIR);
            closedir(DIR);
            foreach my $file (@files) {
               if (-1<index $file,'mozrepl') {
                  return 0;
               }
            }
         }
      }
      unless ($main::install_firefox_without_asking) {
         # Ask if we should install
         my $one="YES - Install MozRepl Plugin for Firefox\n\n";
         my %_askfirefox=(

            Label => '_askfirefox',
            Item_1 =>  {
                           Text   => "]C[",
                           Convey => [ $one,'NO  - DO *NOT* INSTALL MozRepl' ],
                        },
            Scroll => 2,
            Banner=> "   Mozilla Firefox has an available add-on ".
                     "called MozRepl.\n\n   With Firefox equipped ".
                     "with MozRepl, FullAuto can do\n   extremely ".
                     "powerful WEB Automation!\n\n   Would you ".
                     "like the FullAuto installer to install ".
                     "the\n   MozRepl plugin?\n\n",
         );
         $selection=Term::Menus::Menu(\%_askfirefox);
         chomp($selection);
         $selection='Install_MozRepl'
            if -1<index $selection,'Install MozRepl Plugin';
         $selection='DO_NOT_INSTALL'
            if -1<index $selection,'*NOT* INSTALL';
         exit if $selection eq ']quit[';
      } else { $selection='Install_MozRepl' }
      $main::install_firefox=$selection;
   }
}

sub install_firefox {

   my $Ua;
   $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}=0;
   if ($CPAN::META->has_usable('LWP')) {
      FA::LWP::UserAgent->config;
      eval { $Ua = FA::LWP::UserAgent->new(
             timeout=>300,show_progress=>1) };
      if ($@) {
         $CPAN::Frontend->mywarn(
         "ERROR: FA::LWP::UserAgent->new dies with $@\n");
      } else {
         my($var);
         $Ua->proxy('http', $var)
            if $var = $CPAN::Config->{http_proxy} ||
            $ENV{http_proxy};
         $Ua->no_proxy($var)
            if $var = $CPAN::Config->{no_proxy} || $ENV{no_proxy};
      }
      $Ua->ssl_opts( SSL_verify_mode => 'SSL_VERIFY_NONE' );
   } else {
      die "Unable to install Firefox due to no LWP availability";
   }
   my $fftest='';
   unless ($main::install_firefox eq 'Install_MozRepl') {
      my $url='http://www.mozilla.org/en-US/firefox/all/';
      print "Fetching with LWP:\n  $url\n";
      my $req = HTTP::Request->new(GET => $url);
      $req->header('Accept' => 'text/html');
      my $res = $Ua->request($req);
      my $href='';
      if ($res->is_success) {
         print " + request successful.\n"
            if $CPAN::DEBUG;
         my $count=0;
         my $content = $res->decoded_content();
         if (utf8::is_utf8($content)) {
            binmode STDOUT,':utf8';
         } else {
            binmode STDOUT,':raw';
         }
         foreach my $line (split "\n", $content) {
            if ((-1<index $line, 'english (us) english (us)') ||
                  ((0<$count) && ($count<5))) {
               if ($count==3) {
                  $href=$line;
                  last;
               }
               $count++;
            }
         }
      }
      $href=~s/^.*href=["](.*?)["].*$/$1/;
      $href=~s/https/http/;
      $href=~s/&amp;/&/g;
      my $exe_name=substr($href,(rindex $href,'/'));
      $exe_name=~s/^.*?product=(.*?)[&].*$/$1/;
      $exe_name=~s/firefox-/Firefox Setup /;
      $req = HTTP::Request->new(GET => $href);
      $req->header('Accept' => 'text/html');
      $res = $Ua->request($req);
      if ($res->is_success) {
         print " + request successful.\n"
         if $CPAN::DEBUG;
         mkpath($main::root_dir,1) unless -d $main::root_dir;
         unless (-w $main::root_dir) {
            print "\n\n   Fatal Error! - The current Cygwin directory: ".
                  "\n\n      ".$main::root_dir."\n\n".
                  "   is not writable. Please change the permissions\n".
                  "   to writable before installing FullAuto.\n";
            print "\n   PRESS ANY KEY TO EXIT SETUP\n\n";
            <STDIN>;
            exit 1;
         }
         open(CP,">$main::root_dir/${exe_name}.exe") || die $!;
         binmode(CP);
         print CP $res->content;
         close CP;
         if ($^O eq 'cygwin') {
            `/usr/bin/chmod 777 \"$main::root_dir/${exe_name}.exe\"`;
         } else {
            my $cygwin_loc=get_cygwin_location();
            system('SET CYGWIN=nodosfilewarning & '.
                "cmd /c $cygwin_loc\\bin\\bash -lc ".
                "/usr/bin/chmod 777 \"$main::root_dir/${exe_name}.exe\"");
         }
         `"$main::root_dir/${exe_name}.exe" -ms`;
         # Let's look for Firefox
         my $firefox='REG QUERY "HKEY_LOCAL_MACHINE\\SOFTWARE\\'.
                     'Mozilla\\Mozilla Firefox" 2>&1';
         $firefox=`$firefox`;
         $firefox=~tr/\0-\11\13-\37\177-\377//d;
         chomp($firefox);
         $firefox=~s/^.*CurrentVersion\s*REG_SZ\s*(.*?)\n.*$/$1/s;
         $firefox='REG QUERY "HKEY_LOCAL_MACHINE\\SOFTWARE\\'.
                  "Mozilla\\Mozilla Firefox\\$firefox\\Main\" 2>&1";
         open (FF,"$firefox|");
         while (my $line=<FF>) {
            $firefox.=$line;
         }
         close FF;
         $firefox=~tr/\0-\11\13-\37\177-\377//d;
         chomp($firefox);
         $firefox=~s/^.*Path(?:To)*Exe\s*REG_SZ\s*(.*\.exe).*$/$1/s;
         $firefox=~s/\s*$//s;
         $fftest=substr($firefox,0,2) if 1<length $firefox;
         $fftest||='';
         my $selection='';
         if ($fftest=~/\w:|\/\w/) {
            $fftest=substr($firefox,0,(rindex $firefox,'\\'));
         } else {
            $fftest='';
         }
      }
   } else {
      # Let's look for Firefox
      my $firefox='REG QUERY "HKEY_LOCAL_MACHINE\\SOFTWARE\\'.
                  'Mozilla\\Mozilla Firefox" 2>&1';
      $firefox=`$firefox`;
      $firefox=~tr/\0-\11\13-\37\177-\377//d;
      chomp($firefox);
      $firefox=~s/^.*CurrentVersion\s*REG_SZ\s*(.*?)\n.*$/$1/s;
      $firefox='REG QUERY "HKEY_LOCAL_MACHINE\\SOFTWARE\\'.
               "Mozilla\\Mozilla Firefox\\$firefox\\Main\" 2>&1";
      open (FF,"$firefox|");
      while (my $line=<FF>) {
         $firefox.=$line;
      }
      close FF;
      $firefox=~tr/\0-\11\13-\37\177-\377//d; 
      chomp($firefox);
      $firefox=~s/^.*Path(?:To)*Exe\s*REG_SZ\s*(.*\.exe).*$/$1/s;
      $firefox=~s/\s*$//s;
      $fftest=substr($firefox,0,2) if 1<length $firefox;
      $fftest||='';
      my $selection='';
      if ($fftest=~/\w:|\/\w/) {
         $fftest=substr($firefox,0,(rindex $firefox,'\\'));
      } else {
         $fftest='';
      }
   }
   my $url='https://addons.mozilla.org/firefox/downloads/file/'.
        "138898/$main::mozrepl_file?src=dp-btn-primary";
   my $req = HTTP::Request->new(GET => $url);
   $req->header('Accept' => 'text/html');
   my $res = $Ua->request($req);
   my $href='';
   my $cygwin_loc=get_cygwin_location();
   my $clo=$cygwin_loc;
   my $mz="$clo\\$main::mozrepl_file";
   if ($res->is_success) {
      print " + request successful.\n"
         if $CPAN::DEBUG;
      open(CP,">$mz") || die $!;
      binmode(CP);
      print CP $res->content;
      close CP;
      my $ff=$fftest.'\\firefox';
      my $mP=$main::PARdir;
      if ($^O eq 'cygwin') {
         $mz=~s/\\/\\\\/g;
         my $chmod_out=
               `chmod -v 777 \"$mP/bin/install_mozrepl_plugin\" 2>&1`;
         print "CYGCHMOD=$chmod_out\n" if $chmod_out;
         print "MOZREPL COMMAND=\"$mP/bin/install_mozrepl_plugin\" ".
               "\"$ff\" \"$mz\" 2>&1\n";
         my $output=
               `\"$mP/bin/install_mozrepl_plugin\" \"$ff\" \"$mz\" 2>&1`;
         print "CYGOUTPUT=$output\n" if $output;
      } else {
         my $output=
               `\"$mP\\bin\\install_mozrepl_plugin\" \"$ff\" \"$mz\" 2>&1`;
         print "WINOUTPUT=$output\n" if $output;
      }
   }
}

sub remove_sshd {
   my $sshd_account=$_[0];
   my $cygwin_loc=get_cygwin_location();
   my $clo=$cygwin_loc;
   $clo=~s/\\/\\\\/g;
   if (-e $cygwin_loc) {
      if ($^O eq 'cygwin') {
         my $srvcmd='export CYGWIN=nodosfilewarning & '.
                    "cmd /c $clo\\\\bin\\\\bash -lc ".
                    '"/usr/bin/cygrunsrv --verbose --query sshd"';
         my $cygout=`$srvcmd 2>&1`;
         if ($cygout=~/^Account\s+: .\\$sshd_account$/m) {
            my $srvcmd='export CYGWIN=nodosfilewarning & '.
                       "cmd /c $clo\\\\bin\\\\bash -lc ".
                       '"/usr/bin/cygrunsrv --remove sshd"';
            my $cygout=`$srvcmd 2>&1`;
         } elsif (-1==index $cygout,'service does not exist') {
            return 0;
         }
      } else {
         my $srvcmd='SET CYGWIN=nodosfilewarning & '.
                    "cmd /c $clo\\\\bin\\\\bash -lc ".
                    '"/usr/bin/cygrunsrv --verbose --query sshd"';
         my $cygout=`$srvcmd 2>&1`;
         if ($cygout=~/^Account\s+: .\\$sshd_account$/m) {
            my $srvcmd='SET CYGWIN=nodosfilewarning & '.
                       "cmd /c $clo\\\\bin\\\\bash -lc ".
                       '"/usr/bin/cygrunsrv --remove sshd"';
            my $cygout=`$srvcmd 2>&1`;
         } elsif (-1==index $cygout,'service does not exist') {
            return 0;
         }
      }
      my $remove_out=`net user /delete sshd 2>&1`;
      if (-e "$cygwin_loc\\etc\\passwd") {
         do {
            local $^I='.bak'; # see perlvar(1)
            local @ARGV=("$cygwin_loc\\etc\\passwd");
            while(<>){
               s/^$sshd_account:.*\s*$//;
               s/^sshd:.*\s*$//;
               print;
            }
         };
      }
   }
   return 1;
}

sub test_windows_user_rights {

   my $user=$_[0];

   # Is Cygwin installed?
   my $cygwin_location=get_cygwin_location();

   # Adjust memory quotas for a process             (SeIncreaseQuotaPrivilege)
   # Create a token object                          (SeCreateTokenPrivilege)
   # Log on as a service                            (SeServiceLogonRight)
   # Replace a process level token
   #                                           (SeAssignPrimaryTokenPrivilege)

   # Act as part of the operating system            (SeTcbPrivilege)

   # >  And for security.....

   # Deny log on locally                         (SeDenyInteractiveLogonRight)
   # Deny access to this computer from the network   (SeDenyNetworkLogonRight)
   # Deny log on through Terminal Services
   #                                       (SeDenyRemoteInteractiveLogonRight)

   my $rights=`$cygwin_location\\bin\\editrights -u $user -l`;
   my $output='';
   if ((-1==index $rights,'SeServiceLogonRight') ||
         (-1==index $rights,'SeTcbPrivilege') ||
         (-1==index $rights,'SeCreateTokenPrivilege') ||
         (-1==index $rights,'SeAssignPrimaryTokenPrivilege') || 1) {
      my $die='DYING';
      my @missing_rights=();
      if (-1==index $rights,'SeTcbPrivilege') {
         unless ($output=
               `/bin/editrights -a SeTcbPrivilege -u $user`) {
            push @missing_rights, 'SeTcbPrivilege';
         }
      }
      if (-1==index $rights,'SeCreateTokenPrivilege') {
         my $prv='SeCreateTokenPrivilege';
         unless (`/bin/editrights -a $prv -u $user`) {
            push @missing_rights, 'SeCreateTokenPrivilege';
         }
      }
      if (-1==index $rights,'SeAssignPrimaryTokenPrivilege') {
         my $prv='SeAssignPrimaryTokenPrivilege';
         unless (`/bin/editrights -a $prv -u $user`) {
            push @missing_rights, 'SeAssignPrimaryTokenPrivilege';
         }
      }
      if (-1==index $rights,'SeServiceLogonRight') {
         my $prv='SeServiceLogonRight';
         unless (`/bin/editrights -a $prv -u $user`) {
            push @missing_rights, 'SeServiceLogonRight';
         }
      }
      if (-1<$#missing_rights) {
         my $mis=join "\n",map { "               $_" } @missing_rights;
         my $die="   Fatal Error! - The following priviliges are\n   ".
                 "               missing from the ID '".$user."':\n\n".
                 $mis."\n\n   An attempt was made to add these rights,\n".
                 "   but was not successul. Please contact your\n".
                 "   your Domain and Server Administrators for\n".
                 "   assistance.\n\n   PRESS ANY KEY to EXIT FullAuto".
                 " Setup.\n\n";
         print $die;<STDIN>;
         exit 1;
      }
      my $gpout=`gpupdate 2>&1`;
      if (-1<index $gpout,'completed successfully') {
         @missing_rights=();
         if (-1==index $rights,'SeTcbPrivilege') {
            push @missing_rights, 'SeTcbPrivilege';
         }
         if (-1==index $rights,'SeCreateTokenPrivilege') {
            push @missing_rights, 'SeCreateTokenPrivilege';
         }
         if (-1==index $rights,'SeAssignPrimaryTokenPrivilege') {
            push @missing_rights, 'SeAssignPrimaryTokenPrivilege';
         }
         if (-1==index $rights,'SeServiceLogonRight') {
            push @missing_rights, 'SeServiceLogonRight';
         }
         if (-1<$#missing_rights) {
            my $mis=join "\n",map { "               $_" } @missing_rights;
            my $die="   Fatal Error! - The following priviliges were\n".
                    "                  added to the ID '".$user."':\n\n".
                    $mis."\n\n   However, these priviliges were\n".
                    "   subsequently removed by a Domain Global\n".
                    "   Policy Update. Please contact your Windows\n".
                    "   Domain and Server Administrators to have the\n".
                    "   Global Domain Policy changed for this ID.\n\n".
                    "   PRESS ANY KEY to EXIT FullAuto".
                    " Setup.\n\n";
            print $die;<STDIN>;
            exit 1;
         }
      }
   }
}

sub test_windows_user {

   my $sshd_account=$_[0];
   my $test_user=`net user $sshd_account 2>&1`;
   if (-1<index $test_user,'not be found') {
      my $return=&remove_sshd($sshd_account); 
      return 1;
   }
   # Is Cygwin installed?
   my $cygwin_location=get_cygwin_location();

   # Adjust memory quotas for a process             (SeIncreaseQuotaPrivilege)
   # Create a token object                          (SeCreateTokenPrivilege)
   # Log on as a service                            (SeServiceLogonRight)
   # Replace a process level token
   #                                           (SeAssignPrimaryTokenPrivilege)

   # Act as part of the operating system            (SeTcbPrivilege)

   # > 	And for security.....

   # Deny log on locally                         (SeDenyInteractiveLogonRight)
   # Deny access to this computer from the network   (SeDenyNetworkLogonRight)
   # Deny log on through Terminal Services 
   #                                       (SeDenyRemoteInteractiveLogonRight)

   if ($cygwin_location) {
      my $rights=`$cygwin_location\\bin\\editrights -u $sshd_account -l`;
      print "RIGHTS for $sshd_account ======>\n$rights\n<=======\n";
      if ((-1==index $rights,'SeServiceLogonRight') || 
            ((-1==index $rights,'SeDenyRemoteInteractiveLogonRight') &&
            (-1==index $rights,'SeDenyInteractiveLogonRight'))) {
         my $message=<<END;

   FullAuto Install has determined that the current
  \"$sshd_account\" user ID, lacks sufficient privileges
   to act as the sshd service ID;

      The needed privileges are:

         SeServiceLogonRight  SeCreateTokenPrivilege
         SeDenyInteractiveLogonRight  SeTcbPrivilege
         SeAssignPrimaryTokenPrivilege

   Use:  /bin/editrights -u $sshd_account -l
   to manually inspect these privileges.
   Some corporate environments enforce strict group
   rights from the Domain Controller, and these
   privileges may be surreptiously removed from the
   $sshd_account account without notice. Check with your
   Microsoft Infrastructure Admins if you suspect this
   may be a possibility with your setup. You will need
   to get an exception added to their configuration.
   Press ANY key to continue . . .

END
         print $message;
         <STDIN>;
         my $remove_out=`net user /delete $sshd_account 2>&1`;
         if (-1<index $remove_out,"command completed successfully") {
            my $return=&remove_sshd($sshd_account);
            return $return;
         } else {
            my $message=<<END;

   FullAuto Install attempted to remove the ID $sshd_account
   *before* trying a re-install but was unsuccessful:

   $remove_out

   Please remedy the situtation before
   trying FullAuto Install again.

   Please report any bugs and send any
   questions, thoughts or feedback to:

      Brian.Kelly\@FullAuto.com

   Press ANY key to exit.

END
            print $message;
            <STDIN>;
            exit 1;
         }
      }
      unless (-e "$cygwin_location\\var\\empty") {
         my $remove_out=`net user /delete $sshd_account 2>&1`;
         if (-1<index $remove_out,"command completed successfully") {
            my $return=&remove_sshd($sshd_account);
            return $return;
         } else {
            print "\n\n   FullAuto Install has determined that the.",
                  "\n   current sshd service setup was not completed",
                  "\n   correctly with the user ID \"$sshd_account\":",
                  "\n\n      The directory: $cygwin_location\\var\\empty",
                  "\n\n      does NOT exist.", 
                  "\n\n      FullAuto Install attempted to remove",
                  "\n   the ID before trying a re-install but",
                  "\n   was unsuccessful:\n\n   $remove_out.\n\n",
                  "\n\n   Please remedy the situtation before trying.",
                  "\n   FullAuto Install again.",
                  "\n\n   Please report any bugs and send any",
                  "\n   questions, thoughts or feedback to:",
                  "\n\n      Brian.Kelly\@FullAuto.com.",
                  "\n\n   Press ANY key to exit.\n\n";<STDIN>;
            exit 1;
         }
      }
      return 0;
   } else {
      return 0;
   }
}

sub windows_ver {
   # Thanks - http://ss64.org/viewtopic.php?id=879
   # and    - http://en.wikipedia.org/wiki/Ver_(command)
   my $output=`cmd /c ver`;
   if (-1<index $output,'4.0.950') {
      return 'Windows 95';
   } elsif (-1<index $output,'4.0.950') {
      return 'Windows 98';
   } elsif (-1<index $output,'4.10.2222') {
      return 'Windows 98 SE';
   } elsif (-1<index $output,'4.90.3000') {
      return 'Windows ME';
   } elsif (-1<index $output,'NT') {
      return 'Windows NT';
   } elsif (-1<index $output,'5.0.2195') {
      return 'Windows 2000';
   } elsif (-1<index $output,'5.1.2600') {
      return 'Windows XP';
   } elsif (-1<index $output,'5.2.3790') {
      return 'Windows Server 2003';
   } elsif (-1<index $output,'5.2.4500') {
      return 'Windows Home Server'; # aka Windows XP 64-Bit Edition
   } elsif (-1<index $output,'6.0.6001') {
      return 'Windows Vista';
   } elsif (-1<index $output,'6.0.6002') {
      return 'Windows Server 2008';
   } elsif (-1<index $output,'6.1.7600') {
      return 'Windows Server 2008 R2'
   } elsif (-1<index $output,'6.1.7601') {
      return 'Windows 7 SP1';
   } else {
      $output=~s/\s*\[.*$//s;
      return $output;
   }
}

if ($^O eq 'cygwin' && &windows_ver=~/XP|2000|NT/) {
   my $regc='regtool -v check "/HKLM/Software/Microsoft/'.
            'Windows/CurrentVersion/Explorer/AlwaysUnloadDLL" 2>&1';
   my $outp=`$regc`;
   my $notthere=0;
   if ($outp=~/key\s+exists/s) {
      my $regc='regtool -v list "/HKLM/Software/Microsoft/'.
            'Windows/CurrentVersion/Explorer/AlwaysUnloadDLL" 2>&1';
      my $outp=`$regc`;
      if ($outp!~/\(REG_SZ\) = \"1\"/) {
         $notthere=1; 
      }
   } else { $notthere=1 }
   if ($notthere) {
      eval {
         my $timeout=120;
         local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required
         alarm $timeout;
         print "\n       *** THIS SCREEN WILL TIMEOUT IN 2 MINUTES ***\n".
               "\n       IMPORTANT! : FullAuto is VERY Memory Intensive.".
               "\n                  Setup has detected that a recommended".
               "\n                  Windows XP registry setting does NOT".
               "\n                  exist. As a result, Windows XP does".
               "\n                  not remove DLL's from memory when an".
               "\n                  an application exits, but keeps them".
               "\n                  in memory for a time in order to speed".
               "\n                  up application startup *in case* the".
               "\n                  the app is restarted. Cygwin and ssh".
               "\n                  load DLLs and with repeated invocation".
               "\n                  (which is common FullAuto usage),".
               "\n                  memory can 'max' out and cause all".
               "\n                  active FullAuto and Cygwin processes".
               "\n                  to freeze and hang.".
               "\n\n       Therefore, it is *HIGHLY* recommended that this".
               "\n       registry setting exist:\n".
               "\n       /HKLM/Software/Microsoft/Windows/CurrentVersion/".
               "Explorer/AlwaysUnload DLL\n".
               "\n       FullAuto setup can do this for you, but only with".
               "\n       your approval. Would you like FullAuto setup to".
               "\n       attempt to insert this registry setting?".
               "\n\n       (If you do not wish FullAuto setup to".
               "\n       perform this step, type 'N' and setup will".
               "\n       continue WITHOUT modifying the Windows registry.)".
               "\n\n";
         print "Type <Y> if you wish to FullAuto setup to modify ",
               "the registry,\nor 'N' to proceed without this step ",
               ". . . [N] ";
         $a=<STDIN>;
         alarm 0;
      };
      if ($@) {
         # timed out
         # exit;
      } elsif ($a=~/^[Yy]$/s) {
         $regc='cmd /c "REG ADD HKLM\\Software\\Microsoft\\Windows\\'.
               'CurrentVersion\\Explorer\\AlwaysUnloadDLL '.
               '/ve /t REG_SZ /d 1" 2>&1';
         $outp=`$regc`;
         print $outp."\n";
      } alarm 0;

   }
}

#Specific dependencies for web caching functionality
#requires        'Cache::Cache'              => 0;
#requires        'CHI'                       => 0;

auto_install();

my $c_file='';
my $date=strftime('%D',localtime);

my $banner='';my $perllibdir='';my $perlsitebin='';
if (exists $ENV{PERL_LOCAL_LIB_ROOT}) {
   $perllibdir=$ENV{PERL_LOCAL_LIB_ROOT};
   $perlsitebin=$ENV{PERL_LOCAL_LIB_ROOT}.'/bin';
} else {
   unless (-e $Config{installsitelib}) {
      `mkdir -p $Config{installsitelib}`;
   }
   unless (-w $Config{installsitelib}) {
      $banner=
           "\n   *** THIS SCREEN WILL TIMEOUT AND CHOOSE 'NO' IN 2 MINUTES ***\n".
           "\n   WARNING!: You do not have permission to install FullAuto".
           "\n   to the default location -> $Config{installsitelib}.\n".
           "\n   Hint 1: You can use the PREFIX and LIB attributes to".
           "\n   set several attributes at once. The quickest way to".
           "\n   install FullAuto in a non-default location might be".
           "\n   setting PREFIX to '~'. You can do this by selecting".
           "\n   'Yes' below, or by re-running Makefile.PL with the".
           "\n   the following argument:\n".
           "\n   perl Makefile.PL PREFIX=~\n".
           "\n   This will install all FullAuto files under your home".
           "\n   directory, with man pages and libraries going into the".
           "\n   appropriate place (most likely ~/man and ~/lib)\n".
           "\n   You may also consider using the LIB attribute:\n".
           "\n   perl Makefile.PL LIB=~/lib\n".
           "\n   See the MakeMaker.pm module documetation for more".
           "\n   information:\n".
           "\n   http://search.cpan.org/~mschwern/ExtUtils-MakeMaker-6.56".
           "/lib/ExtUtils/MakeMaker.pm#PREFIX_and_LIB_attribute\n".
           "\n   Hint 2: Run perl MakeMaker.PL with an appropriate user".
           "\n   (such as root) or with a utility such as sudo if you".
           "\n   are authorized to use it (sudo perl Makefile.PL).".
           "\n   The same is true if you are attempting to install".
           "\n   FullAuto via the CPAN resposiory (i.e. 'sudo cpan')\n".
           "\n   Would like to install FullAuto to your home (~) directory?\n\n"
   }
   $perllibdir=$Config{installsitelib};
   $perlsitebin=$Config{installsitebin};
}

if ($banner) {

   my $timeout=120;my $selection='';
   eval {
      local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required
      alarm $timeout;
      my $menu1 = [
                  $banner,
                  [ "Yes", sub{ return 'Yes' } ],
                  [ "No   (FullAuto install will exit)", sub{ return 'No' } ],
                  #[ "Quit", sub {exit;} ],
                  ];
      $selection=&menu($menu1);
      exit if $selection eq ']quit[';
      alarm 0;
   };
   if ($@) {
      # timed out
      $selection = 'No';
   }
   if ($selection=~/No/) {
      exit;
   } alarm 0;
}

print "$main::curdir\n";
chdir $main::curdir;

open(FH,">fullauto.c");

print FH '/* program: fullauto'."\n".
"   author:  Brian Kelly\n".
"   date:    $date\n".
"\n".
"   purpose: C program wrapper that calls $perlsitebin/fullauto.pl script\n".
"   WARNING: This file is auto-generated by Makefile.PL, please change Makefile.PL.\n".
"            Any modifications made to this source file will be lost!\n".
'*/'."\n".
"\n".
'#define REAL_PL '.'"'.$perlsitebin."/fullauto.pl\"\n".
"main(int argc, char *argv[])\n".
'{'."\n".
"\tsetuid(0);\n".
"\tseteuid(0);\n".
"\texecv(REAL_PL, argv);\n".
'}'."\n";

close FH;

my $timeout=120;my $selection='';
if (keys %main::amazon) {
   $selection='Install with Full Access Permissions (Recommended Default)';
} elsif (!exists $ENV{FA_BERKELEY}) {
   eval {
      local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required
      alarm $timeout;
      my @list=();
      my %perms_menu=();
      unless ($^O eq 'cygwin') {
         @list=('Install with Full Access Permissions (Recommended Default)',
                'Install with Setuid Permissions',
                'Install with Setgid Permissions',
                'Install with Owner Group Permissions');
         my $banner="\n   *** THIS SCREEN WILL TIMEOUT AND CHOOSE ".
               "\'Full Access\' IN 2 MINUTES ***\n".
               "\n   Choose a Permission Setting :\n\n";
         %perms_menu=(

            Name => 'perms_menu',
            Item_1 => {

               Text => ']C[',
               Convey => \@list,

            },
            Scroll => 1,
            Banner => $banner,

         ); 
      } else {
         @list=('Install with Full Access Permissions (Default)',
                'Install with Owner Group Permissions');
         my $banner="\n   *** THIS SCREEN WILL TIMEOUT AND CHOOSE ".
               "\'Full-Access\' IN 2 MINUTES ***\n".
               "\n   Choose a Permission Setting :\n\n";
         %perms_menu=(

            Name => 'perms_menu',
            Item_1 => {

               Text => ']C[',
               Convey => \@list,

            },
            Scroll => 1,
            Banner => $banner,

         );
      }
      $selection=Term::Menus::Menu(\%perms_menu);
      alarm 0;
   };
   exit if $selection eq ']quit[';
   if ($@) {
      # timed out
      print "\n";
      $selection = 'Full Access';
      Term::ReadKey::ReadMode(0);
   } alarm 0;
} elsif (-1<index $ENV{FA_BERKELEY},'Owner Group') {
   $selection='Install with Owner Group Permissions';
} elsif (-1<index $ENV{FA_BERKELEY},'Full Access') {
   $selection='Install with Full Access Permissions (Default)';
}

my $permission = 'Full Access';
if (-1<index $selection,'Setuid') {
   $permission = 'Setuid';
} elsif (-1<index $selection,'Setgid') {
   $permission = 'Setgid';
} elsif (-1<index $selection,'Owner Group') {
   $permission = 'Owner-Group';
   $main::cygwin_berkeley_db_mode=770 if $^O eq 'cygwin';
} elsif (-1<index $selection,'Full Access') {
   $permission = 'Full-Access';
   $main::cygwin_berkeley_db_mode=777  if $^O eq 'cygwin';
} elsif (-1<index $selection,'quit') {
   exit;
} print "\n";

if ($^O eq 'cygwin') {
   open(FH,">bin/fullauto.exe");
   print FH "\n";
   close FH;
   install_script('bin/fullauto.exe');
   install_script('bin/install_mozrepl_plugin.exe');
   unlink "bin/fullauto.exe";
   &install_firefox() if -1<index $main::install_firefox,'Install';
} else {
   open(FH,">bin/fullauto");
   print FH "\n";
   close FH;
   install_script('bin/fullauto');
   unlink "bin/fullauto";
}
install_script('bin/fullauto.pl');

my $good_choice=<<'END';

     ___               _     ___ _        _        _ 
    / __| ___  ___  __| |   / __| |_  ___(_)__ ___| |
   | (_ |/ _ \/ _ \/ _` |  | (__| ' \/ _ \ / _/ -_)_|
    \___|\___/\___/\__,_|   \___|_||_\___/_\__\___(_)


   The Nano Editor is widely considered to be the easiest Terminal Editor to
   learn. Here are a couple of important things to remember. When you look at
   at the bottom of the screen, you will see character combinations like this:

   ^E ^W ^O  -->  the caret symbol (for Ctrl key) followed by a letter.

   Ctrl key is pressed with letter next to it. For example, to exit Nano (^E)
    ________     ____                    _______     ____ 
   || Ctrl ||   ||E ||                  || Alt ||   ||C ||
   ||______|| + ||__||  M-C  is  alt c  ||_____|| + ||__||
   |/______\|   |/__\|                  |/_____\|   |/__\|

END

my $nano_banner=<<END;

   .e.f8 ee.     88**8.  e888 88**8. .d88b.   GNU
   i '8f'  Q,    88  88 88 88 88  88 88  88
      8.   8:    88  88 "t888 88  88 "t88P"   Text Editor
      8.   8:
      W.   8:    In Terminal Environments, Documentation
           8:    for Nano can be seen anytime by typing:
           8:    
           tD    man nano    at the command line.


   You can also see online documentation at:

   http://www.nano-editor.org/docs.php
END

my $learn_nano=sub {

   my %learn_nano=(

      Name => 'learn_nano',
      Item_1 => {

         Text => "Go to Nano man page (type q to return)",
         Result => sub { system('man nano');return '<' },

      },
      Item_2 => {

         Text   => "Launch and explore Nano (type ctrl + e to return)",
         Result => sub { system('nano');return '<' },

      },
      Item_3 => {

         Text => "Continue Installing FullAuto",

      },
      Scroll => 3,
      Banner => $nano_banner,

   );
   return \%learn_nano;

};

my $goodchoice=sub {

   my %goodchoice=(

      Name => 'goodchoice',
      Item_1 => {

         Text   => "Learn more about Nano",
         Result => $learn_nano, 

      },
      Item_2 => {

         Text   => "Continue Installing FullAuto",

      },
      Scroll => 2,
      Banner => $good_choice,

   );
   return \%goodchoice;

};

sub fa_editor_mswin {

   # http://pen-testing.sans.org/blog/2012/06/06/ \
   # escaping-restricted-linux-shells/comment-page-1/
   my @editors=('vim     ( ViIMproved - enhanced vi editor )',
                'nano    ( Easiest - Recommended for Beginners )',
                "emacs   ( The extensible, customizable,\n           ".
                "               self-documenting real-time\n         ".
                '                display editor )',
                "joe     ( Fast and simple editor that\n             ".
                '             emulates 5 other editors )',
               );
   my $tp='';my $selection='';
   unless ($tp=&fa_find_editor('TextPad.exe')) {
      if (-e ${ENV}{SystemDrive}.
            "\\Program Files\\TextPad 5\\TextPad.exe") {
         $tp='default';
      }
   }
   if ($tp) {
      push @editors, 'TextPad (The Text Editor for Windows)';
   }
   my $banner=<<'END';
    ___      _        _      ___    _ _ _
   / __| ___| |___ __| |_   | __|__| (_) |_ ___ _ _
   \__ \/ -_) / -_) _|  _|  | _|/ _` | |  _/ _ \ '_|
   |___/\___|_\___\__|\__|  |___\__,_|_|\__\___/_|

   In order to use the integrated edit features you will need to choose
   an editor. 'vim' (or 'vi') is set as the default - but it is
   recommended you try 'nano' if you do not know the vim or vi editor.

END
   my %Menu_select_editor=();
   if (-e ${ENV}{SystemDrive}.
         "\\Program Files\\Windows NT\\Accessories\\wordpad.exe") {
      %Menu_select_editor=(

            Label  => 'Menu_select_editor',
            Item_1 => {

               Text    => "]C[",
               Convey  => \@editors,

            },
            Item_2 => {

               Text => "Wordpad (Microsoft Wordpad -\n               ".
                       "        Available on all Windows Systems)",

            },
            Scroll => 1,
            Banner => $banner,

      );
   } else {
      %Menu_select_editor=(

            Label  => 'Menu_select_editor',
            Item_1 => {

               Text    => "]C[",
               Convey  => \@editors,

            },
            Scroll => 1,
            Banner => $banner,

      );
   }

   if ($install_cygwin_without_asking) {
      my $look_for_wordpad=${ENV}{SystemDrive}.
            "\\Program Files\\Windows NT\\Accessories\\wordpad.exe";
      if (-e $look_for_wordpad) {
         $selection='wordpad';
         my $sysdr=`cmd /c echo %SystemDrive%`;
         $sysdr=~s/^\s*(.*)\s*$/$1/s;
         my $let=substr($sysdr,0,1);
         my $lt=lc($let);
         $editor='/cygdrive/'.$lt.'/Program Files/Windows NT/'.
                 'Accessories/wordpad.exe';
      }
   } elsif (0<$#editors) {
      $selection=Term::Menus::Menu(\%Menu_select_editor);
      chomp($selection);
      exit if $selection eq ']quit[';
   } elsif (0==$#editors) {
      $selection=$editors[0];
   }
   if ($selection=~/([Ww]ordpad)/) {
      $selection=$1;
      my $sysdr=`cmd /c echo %SystemDrive%`;
      $sysdr=~s/^\s*(.*)\s*$/$1/s;
      my $let=substr($sysdr,0,1);
      my $lt=lc($let);
      $editor='/cygdrive/'.$lt.
         '/Program Files/Windows NT/Accessories/wordpad.exe';
   } elsif ($selection=~/(TextPad)/) {
      $selection=$1;
      if ($tp eq 'default') {
         my $sysdr=`cmd /c echo %SystemDrive%`;
         $sysdr=~s/^\s*(.*)\s*$/$1/s;
         my $let=substr($sysdr,0,1);
         my $lt=lc($let);
         $editor='/cygdrive/'.$lt.
            '/Program Files/TextPad 5/TextPad.exe';
      } else {
         $tp=~s/\\/\//g;
         $tp=~s/^([A-Za-z]):(.*)/$1$2/;
         $editor='/cygdrive/'.$tp;
      }
   } elsif ($selection=~/(vim)/) {
      $selection=$1;
      $editor='/bin/vim.exe';
   } elsif ($selection=~/(emacs)/) {
      $selection=$1;
      $editor='/bin/emacs.exe';
   } elsif ($selection=~/(joe)/) {
      $selection=$1;
      $editor='/bin/joe.exe';
   } elsif ($selection=~/(nano)/) {
      $selection=$1;
      $editor='/bin/nano.exe';
   }
   return $selection,$editor;

}

sub fa_web_api {

   my $api_banner=<<'END';

    ___         _        _ _   __      __   _         _   ___ ___ ___
   |_ _|_ _  __| |_ __ _| | |  \ \    / /__| |__     /_\ | _ \_ _|__ \
    | || ' \(_-<  _/ _` | | |   \ \/\/ / -_) '_ \   / _ \|  _/| |  /_/
   |___|_||_/__/\__\__,_|_|_|    \_/\_/\___|_.__/  /_/ \_\_| |___|(_)


   The FullAuto core installation is a command shell environment utility.
   In this configuration, EVERYTHING can be automated via scripts written
   in the Perl scripting language.

   With the Web API option, FullAuto worker processes with persistent
   connections to remote hosts are fully accessible in *ANY* programming
   or scripting language. The FullAuto Web API is secured via OAuth 2.0
   tokens and is a RESTful/JSON implementation.

END

   my $what_to_expect=<<'END';

   __      ___         _      _          ___                  _
   \ \    / / |_  __ _| |_   | |_ ___   | __|_ ___ __  ___ __| |_
    \ \/\/ /| ' \/ _` |  _|  |  _/ _ \  | _|\ \ / '_ \/ -_) _|  _|
     \_/\_/ |_||_\__,_|\__|   \__\___/  |___/_\_\ .__/\___\__|\__|
                                                |_|

   The FullAuto base install can take just ten minutes on a top tier cloud
   server, or an hour or more on a mini host like an Amazon EC2 Free-Tier
   t2.micro server. This is due to multiple factors such as network
   bandwidth, CPU speed and memory capacity of the target host.

   If you elected to install the Web API, you are likely to DOUBLE the
   overall installation time. A total of 20-30 minutes on a top tier host,
   to as long as 3 hours or more for a micro server during peak traffic
   periods - especially on Windows hosts (which have an additional Cygwin
   dependency).

   FullAuto and the FullAuto Web API have numerous dependencies that
   all take time to download, build and configure. A short list is
   BerkeleyDB, Catalyst MVC Application Server, and ZeroMQ Messaging.

END

   my $expectations={

      Name => 'expectations',
      Result => sub { my $return="]P[";return $return },
      Banner => $what_to_expect,

   };

   my $which_install={

      Name => 'which_install',
      Item_1 => {

         Text => 'Install Base FullAuto and the FullAuto Web API',
         Result => $expectations,

      },
      Item_2 => {

         Text => 'Install Base FullAuto Only',
         Result => $expectations,

      },
      Scroll => 1,
      Banner => $api_banner,

   };
   my $selection=Term::Menus::Menu($which_install);
print "RETURNING THIS=$selection<==\n";sleep 5;
   return $selection;

}

sub fa_license {

   my %read_license=(

      Name => 'read_license',
      Item_1 => {
         Text => "I accept the license provisions",
      },
      Item_2 => {
         Text => "I do *NOT* accept the license provisions ".
                 "(Install will Exit)",
      },
      Item_3 => {
         Text => "Review GNU Affero Public License Version 3\n".
                 "                   in its entirety".
                 " (type 'q' to return)",
         Result => sub {

            if (exists $ENV{PAR_TEMP}) {
               system("$ENV{PAR_TEMP}\\inc\\tools\\less.exe ".
                      "$ENV{PAR_TEMP}\\inc\\LICENSE");
            } else {
               system('less LICENSE');
            } return '<'
         },
      },
      Item_4 => {
         Text => "Return to previous screen",
         Result => sub { return '{license_agree}<' },
      },
      Scroll => 1,
      Banner => sub {

            my $linenumber="]P[";
            $linenumber||=1;
            $linenumber=~s/["]//g;
            my $dir='';
            $dir="$ENV{PAR_TEMP}/inc/" if exists $ENV{PAR_TEMP};
            open (FH,"<${dir}LICENSE")
               or die "Cannot open ${dir}LICENSE: $!\n";
            my @content=<FH>;
            close FH;
            my $co=$#content+1;
            my $endcount=(13<$co)?13:$co;
            if (-1==index $linenumber,'Review') {
               if ($linenumber=~/Next|Previous/) {
                  $linenumber=~s/^(?:Next|Previous) Page\s*//;
               }
               ($linenumber,$endcount)=split '-', $linenumber;
               my $tl=$#content+1;
               my $lt=$linenumber+13;
               $endcount=($lt<$tl)?$lt:$tl;
            } elsif (-1<index $linenumber,'WARRANTY') {
               $linenumber=588;
               $endcount=597;
            } else { $linenumber=1 }
            $linenumber=0 if $linenumber==1;
            --$endcount;
            my $banner=join "", @content[$linenumber..$endcount];
            $banner=~s/^/   /mg;
            return $banner;

      }

   );

   my $cryptography_banner=<<'END';
   __      __             _           _ 
   \ \    / /_ _ _ _ _ _ (_)_ _  __ _| |
    \ \/\/ / _` | '_| ' \| | ' \/ _` |_|
     \_/\_/\__,_|_| |_||_|_|_||_\__, (_)
                                |___/  

   Exporting, importing and/or using cryptography software, or even
   communicating technical details about cryptography software, is illegal
   in some parts of the world. You are strongly advised to investigate and
   adhere to any export/import and use laws which apply to you when you
   import a release of Net::FullAuto including cryptography modules like
   Crypt::CBC, Crypt::DES and Crypt::Rijndael to your country or
   re-distribute source code from them in any way.
END

   my $cryptography=sub {

      my %cryptography=(

         Name => 'cryptography',
         Result => sub { return '{license_agree}<' },
         Banner => $cryptography_banner,      

      );
      return \%cryptography

   };

   my $license_banner=<<END;

   *THANK YOU* For Trying FullAuto!   Net::FullAuto INSTALLATION PROGRAM

   Copyright (C) 2000-2016   Brian M. Kelly   Brian.Kelly\@FullAuto.com

   This program comes with ABSOLUTELY NO WARRANTY; for details select 2.
   This is free software, and you are welcome to redistribute it under certain
   conditions. Select 2 for full license. FullAuto uses  Crypt::DES  which is
   software developed by Systemics Ltd (http://www.systemics.com/). FullAuto
   uses the  Net::SSLeay  module which is software developed by the OpenSSL
   Project for use in the OpenSSL Toolkit. (http://www.openssl.org/) and
   includes cryptographic software written by Eric Young (eay\@cryptsoft.com)
   and Tim Hudson (tjh\@cryptsoft.com)

END

   my %license_agree=(

      Name => 'license_agree',
      Item_1 => {

         Text => "I agree to the license provisions\n\n",

      },
      Item_2 => {

         Text => "Review GNU Affero Public License WARRANTY DISCLAIMER\n",
         Result => \%read_license,
      },
      Item_3 => {

         Text => "*IMPORTANT* STRONG CRYPTOGRAPHY WARNING!",
         Result => $cryptography,

      },
      Item_4 => {

         Text => "I DO NOT AGREE to the license provisions\n".
                 "                   ( FullAuto Install will EXIT )",
      },
      Scroll => 1,
      Banner => $license_banner,

   );
   my $lic_sel='';
   if (!(exists $ENV{PERL5_CPAN_IS_RUNNING}
         && $ENV{PERL5_CPAN_IS_RUNNING}) ||
         exists $ENV{PAR_TEMP}) {
      $lic_sel=Menu(\%license_agree);
      chomp($lic_sel);
      exit if $lic_sel eq ']quit[';
      if (-1<index $lic_sel, 'NOT') {
         my $exitmsg=<<END;

   You have elected *NOT* to install FullAuto.
   Please report any bugs and send any
   questions, thoughts or feedback to:

      Brian.Kelly\@FullAuto.com.

END
         print $exitmsg;
         if (exists $ENV{PAR_TEMP}) {
            print "   Press ANY key to exit.\n\n";<STDIN>;
         }
         exit;
      }
   }

}

WriteAll();

if (keys %main::amazon) {
   system('sudo make install');
   if (exists $main::amazon{argv}) {
      my $p=$main::amazon{argv}->[0];
      my $username=getlogin || getpwuid($<);
      exec "/usr/local/bin/fa",'-i',$p,
           '--iset-amazon','--login',
           $username,'--log';
   }
}

sub fa_find_editor {
   my $editor=$_[0];
   $editor=~s/^.*\///;
   $editor=~s/[.]exe$//;
   return 0 unless $editor;
   foreach my $path (split ':', $ENV{PATH}) {
      $path=~s/[\/]*$/\//;
      if ($^O eq 'cygwin' && (-e $path.$editor.'.exe')) {
         return $path.$editor.'.exe';
      } elsif (-e $path.$editor) {
         return $path.$editor;
      }
   } return 0;
}

package MY; # so that "SUPER" works right
sub MY::top_targets {

   my $inherited = shift->SUPER::top_targets(@_);

   $inherited =~ s/pure_all :: /pure_all :: fullauto\$(EXE_EXT) /;
   $inherited =~ s/ linkext//;

   $inherited; #

}

package MY; # so that "SUPER" works right
sub MY::makefile {

   use Config;

   my $inherited = shift->SUPER::makefile(@_);

   $inherited .= "fullauto\$(EXE_EXT): fullauto.c\n\t\$(CC) fullauto.c -o \$@".
                 "\n\t\$(CP) \$@ bin\n\n";

   unless (-e $Config{installsitelib}."/Net/FullAuto/Custom/fa_host.pm") {
      $inherited .= "lib/Net/FullAuto/Custom/fa_host.pm:".
                    "\n\t\$(CP) lib/Net/FullAuto/Distro/fa_host.pm \$@\n\n";
   } else {
      $inherited =~ s/^(.*FullAuto.*fa_host.pm.*)$//m;
      $inherited .= "lib/Net/FullAuto/Custom/fa_host.pm:".
                    "\n\t\$(NOECHO)\n\n";
      unlink "lib/Net/FullAuto/Custom/fa_host.pm";
      unlink "blib/lib/Net/FullAuto/Custom/fa_host.pm";
   }
   unless (-e $Config{installsitelib}."/Net/FullAuto/Custom/fa_conf.pm") {
      $editor=~s/\//\\\//g;
      $inherited .= "lib/Net/FullAuto/Custom/fa_conf.pm:".
                    "\n\t\$(CP) lib/Net/FullAuto/Distro/fa_conf.pm \$@\n\n";
   } else {
      $inherited =~ s/^(.*Custom\/fa_conf.pm.*)$//m;
      $inherited .= "lib/Net/FullAuto/Custom/fa_conf.pm:".
                    "\n\t\$(NOECHO)\n\n";
      unlink "lib/Net/FullAuto/Custom/fa_conf.pm";
      unlink "blib/Net/FullAuto/Custom/fa_conf.pm";
   }
   unless (-e $Config{installsitelib}."/Net/FullAuto/Custom/fa_menu.pm") {
      $inherited .= "lib/Net/FullAuto/Custom/fa_menu.pm:".
                    "\n\t\$(CP) lib/Net/FullAuto/Distro/fa_menu.pm \$@\n\n";
   } else {
      $inherited =~ s/^(.*Custom\/fa_menu.pm.*)$//m;
      $inherited .= "lib/Net/FullAuto/Custom/fa_menu.pm:".
                    "\n\t\$(NOECHO)\n\n";
      unlink "lib/Net/FullAuto/Custom/fa_menu.pm";
      unlink "blib/lib/Net/FullAuto/Custom/fa_menu.pm";
   }
   unless (-e $Config{installsitelib}."/Net/FullAuto/Custom/fa_code.pm") {
      $inherited .= "lib/Net/FullAuto/Custom/fa_code.pm:".
                    "\n\t\$(CP) lib/Net/FullAuto/Distro/fa_code.pm \$@\n\n";
   } else {
      $inherited =~ s/^(.*Custom\/fa_code.pm.*)$//m;
      $inherited .= "lib/Net/FullAuto/Custom/fa_code.pm:".
                    "\n\t\$(NOECHO)\n\n";
      unlink "lib/Net/FullAuto/Custom/fa_code.pm";
      unlink "blib/lib/Net/FullAuto/Custom/fa_code.pm";
   }
   if (-1<index $main::install_firefox,'Install') {
      my $cygwin_loc=main::get_cygwin_location(1);
      $cygwin_loc=~s/\\/\//;
      $inherited .= "$Config{installsitelib}/Net/FullAuto/$main::mozrepl_file:".
                    "\n\t\$(CP) $cygwin_loc/$main::mozrepl_file \$@\n\n";
   }

   $inherited; #

}

package MY; # so that "SUPER" works right
sub MY::dist {

   use Config;

   my $inherited = shift->SUPER::dist(@_);

   if (grep { /-*add[-_]?dependencies/i } @ARGV) {

      $inherited =~ s/^(DISTVNAME.*Net-FullAuto)(.*)$/$1-Complete$2/m;

   }

   $inherited; #

}

package MY; # so that "SUPER" works right
sub MY::tools_other {

   use Config;

   my $inherited = shift->SUPER::tools_other(@_);

   $inherited =~
      s/^MV.*$/MV = mv -f/m;

   $inherited =~
      s/^(MV.*)$/$1\nSED = sed/m;

   $inherited; #

}

package MY; # so that "SUPER" works right
sub MY::constants {

   use Config;

   my $inherited = shift->SUPER::constants(@_);

   unless (-e $Config{installsitelib}."/Net/FullAuto/Custom/fa_host.pm") {
      my $fa_h="\tlib\/Net\/FullAuto\/Custom\/fa_host.pm ".
               "\\\n\tblib\/Net\/FullAuto\/Custom\/fa_host.pm \\";
      $inherited =~
         s/(\s+lib.*Distro\/fa_host.pm \\)/$1\n\tlib\/Net\/FullAuto\/Custom\/fa_host.pm \\/m; 
      $inherited =~
         s/(\s+blib.*Distro\/fa_host.pm \\)/$1\n$fa_h/m;
   } else {
      $inherited =~ s/^(.*Custom\/fa_host.pm.*)$//;
   }
   unless (-e $Config{installsitelib}."/Net/FullAuto/Custom/fa_conf.pm") {
      my $fa_g="\tlib\/Net\/FullAuto\/Custom\/fa_conf.pm ".
               "\\\n\tblib\/Net\/FullAuto\/Custom\/fa_conf.pm \\";
      $inherited =~
         s/(\s+lib.*Distro\/fa_conf.pm \\)/$1\n\tlib\/Net\/FullAuto\/Custom\/fa_conf.pm \\/m;
      $inherited =~
         s/(\s+blib.*Distro\/fa_conf.pm \\)/$1\n$fa_g/m;
   } else {
      $inherited =~ s/^(.*Custom\/fa_conf.pm.*)$//;
   }
   unless (-e $Config{installsitelib}."/Net/FullAuto/Custom/fa_menu.pm") {
      my $fa_m="\tlib\/Net\/FullAuto\/Custom\/fa_menu.pm ".
               "\\\n\tblib\/Net\/FullAuto\/Custom\/fa_menu.pm \\";
      $inherited =~
         s/(\s+lib.*Distro\/fa_menu.pm \\)/$1\n\tlib\/Net\/FullAuto\/Custom\/fa_menu.pm \\/m;
      $inherited =~
         s/(\s+blib.*Distro\/fa_menu.pm \\)/$1\n$fa_m/m;
   } else {
      $inherited =~ s/^(.*Custom\/fa_menu.pm.*)$//;
   }
   unless (-e $Config{installsitelib}."/Net/FullAuto/Custom/fa_code.pm") {
      my $fa_c="\tlib\/Net\/FullAuto\/Custom\/fa_code.pm ".
               "\\\n\tblib\/Net\/FullAuto\/Custom\/fa_code.pm \\";
      $inherited =~
         s/(\s+lib.*Distro\/fa_code.pm \\)/$1\n\tlib\/Net\/FullAuto\/Custom\/fa_code.pm \\/m;
      $inherited =~
         s/(\s+blib.*Distro\/fa_code.pm \\)/$1\n$fa_c/m;
   } else {
      $inherited =~ s/^(.*Custom\/fa_code.pm.*)$//;
   }

   $inherited =~ 
      s/(PERM_RWX = \d+)/$1\nPERM_S_X = 4511\nPERM_G_X = 2551/m;
   $inherited =~
      s/(PERM_G_X = \d+)/$1\nPERM_S+X = 4555\n/m;
   $inherited =~
      s/(PERM_S[+]X = \d+)/$1\nPERM_R+X = 555\nPERM_R-X = 550\nPERM_R_X = 511/m;
   $inherited =~
      s/(PERM_R_X = \d+)/$1\nPERM_D-X = 750\nPERM_D_X = 700\nPERM_WRX = 777/m;
   $inherited =~
      s/(PERM_WRX = \d+)/$1\nPERM_OG_ = 770/m;

   $inherited; #

}

package MY; # so that "SUPER works right
sub MY::installbin {

   my $inherited = shift->SUPER::installbin(@_);

   $inherited =~ s/RM_F\) \\/RM_F\) bin\/fullauto\$(EXE_EXT) fullauto.c fullauto\$(EXE_EXT)\\/;

   $inherited; #

}

package MY; # so that "SUPER" works right
sub MY::install {

   use Config;
   my $inherited = shift->SUPER::install(@_);

   if ($permission eq 'Setuid') {
      $inherited =~ s/(install ::.*)$/$1 setuid_permissions/m;
   } elsif ($permission eq 'Setgid') {
      $inherited =~ s/(install ::.*)$/$1 setgid_permissions/m;
   } elsif ($permission eq 'Owner-Group') {
      if (-1<index $main::install_firefox,'Install') {
         my $mz="$Config{installsitelib}/Net/FullAuto/$main::mozrepl_file";
         $inherited =~
            s/(install ::.*)$/$1 owner_group_permissions $mz/m;
      } else {
         $inherited =~ s/(install ::.*)$/$1 owner_group_permissions/m;
      }
   } else {
      if (-1<index $main::install_firefox,'Install') {
         my $mz="$Config{installsitelib}/Net/FullAuto/$main::mozrepl_file";
         $inherited =~
            s/(install ::.*)$/$1 full_access_permissions $mz/m;
      } else {
         $inherited =~ s/(install ::.*)$/$1 full_access_permissions/m;
      }
   }

   if (-e '/usr/share/figlet') {
      $inherited =~ s/(install ::.*)$/$1 figlet_fonts/m;
   }

   my $link='';
   my $lnpath='';
   if (-e "/bin/ln") {
      $lnpath="/bin/ln";
   } elsif (-e "/usr/bin/ln") {
      $lnpath="/usr/bin/ln";
   } elsif (-e "/usr/local/bin/ln") {
      $lnpath="/usr/local/bin/ln";
   }

   if ($lnpath) {
      $link="\t\$(NOECHO) $lnpath -f -s ".
            "\$(DESTINSTALLSITESCRIPT)\/fullauto\$(EXE_EXT) ".
            "\$(DESTINSTALLSITESCRIPT)\/fa\n"; 
   }

   $inherited .= "\nsetuid_permissions ::\n".
     "\t\$(NOECHO) \$(ECHO) \"Applying Setuid Permissions\"\n".
      "\t\$(NOECHO) \$(CHMOD) \$(PERM_S+X) \$(DESTINSTALLSITESCRIPT)\/fullauto\$(EXE_EXT)\n".
      "\t\$(NOECHO) \$(CHMOD) \$(PERM_R+X) \$(DESTINSTALLSITESCRIPT)\/fullauto.pl\n".
      "\t\$(NOECHO) \$(CHMOD) \$(PERM_R_X) \$(DESTINSTALLSITELIB)\/Net\/FullAuto.pm\n".
      "\t\$(NOECHO) \$(CHMOD) \$(PERM_D_X) \$(DESTINSTALLSITELIB)\/Net\/FullAuto\n".
      "\t\$(NOECHO) \$(CHMOD) \$(PERM_R_X) \$(DESTINSTALLSITELIB)\/Net\/FullAuto\/*\n".
      $link;
   $inherited .= "\nsetgid_permissions ::\n".
      "\t\$(NOECHO) \$(ECHO) \"Applying Setgid Permissions\"\n".
      "\t\$(NOECHO) \$(CHMOD) \$(PERM_G_X) \$(DESTINSTALLSITESCRIPT)\/fullauto\$(EXE_EXT)\n".
      "\t\$(NOECHO) \$(CHMOD) \$(PERM_R-X) \$(DESTINSTALLSITESCRIPT)\/fullauto.pl\n".
      "\t\$(NOECHO) \$(CHMOD) \$(PERM_R-X) \$(DESTINSTALLSITELIB)\/Net\/FullAuto.pm\n".
      "\t\$(NOECHO) \$(CHMOD) \$(PERM_D-X) \$(DESTINSTALLSITELIB)\/Net\/FullAuto\n".
      "\t\$(NOECHO) \$(CHMOD) \$(PERM_R-X) \$(DESTINSTALLSITELIB)\/Net\/FullAuto\/*\n".
      $link;
   $inherited .= "\nowner_group_permissions ::\n".
      "\t\$(NOECHO) \$(ECHO) \"Applying Owner-Group Permissions\"\n".
      "\t\$(NOECHO) \$(CHMOD) \$(PERM_R+X) \$(DESTINSTALLSITESCRIPT)\/fullauto\$(EXE_EXT)\n".
      "\t\$(NOECHO) \$(CHMOD) \$(PERM_R+X) \$(DESTINSTALLSITESCRIPT)\/fullauto.pl\n".
      "\t\$(NOECHO) \$(CHMOD) \$(PERM_R+X) \$(DESTINSTALLSITELIB)\/Net\/FullAuto.pm\n".
      "\t\$(NOECHO) \$(CHMOD) \$(PERM_OG_) \$(DESTINSTALLSITELIB)\/Net\/FullAuto\n".
      "\t\$(NOECHO) \$(CHMOD) \$(PERM_R+X) \$(DESTINSTALLSITELIB)\/Net\/FullAuto\/*\n".
      "\t\$(NOECHO) \$(CHMOD) \$(PERM_OG_) \$(DESTINSTALLSITELIB)\/Net\/FullAuto\/Custom\n".
      "\t\$(NOECHO) \$(CHMOD) \$(PERM_OG_) \$(DESTINSTALLSITELIB)\/Net\/FullAuto\/Custom\/*\n".
      $link.
      "\t\$(NOECHO) \$(CHMOD) \$(PERM_OG_) /var\n".
      "\t\$(NOECHO) if [ -d /var/db ];".
      "then \$(CHMOD) \$(PERM_OG_) /var/db; fi\n";
      "\t\$(NOECHO) if [ -d /var/db/Berkeley ];".
      "then \$(CHMOD) \$(PERM_OG_) /var/db/Berkeley; fi\n";
      "\t\$(NOECHO) if [ -d /var/db/Berkeley/FullAuto ];".
      "then \$(CHMOD) \$(PERM_OG_) /var/db/Berkeley/FullAuto; fi\n";
   $inherited .= "\t\$(SED) \'s/^[ ]*our[ ]*\\(.\\)".
      "cygwin_berkeley_db_mode[ ]*[=].*/".'our \\1'.
      "cygwin_berkeley_db_mode = \$(PERM_OG_);/g\' ".
      "\$(DESTINSTALLSITELIB)/Net/FullAuto/FA_Core.pm >tmp_fa_core.pm\n".
      "\t\$(MV) ./tmp_fa_core.pm \$(DESTINSTALLSITELIB)".
      "/Net/FullAuto/FA_Core.pm\n"
      if $^O eq 'cygwin';
   $inherited .= "\nfull_access_permissions ::\n".
      "\t\$(NOECHO) \$(ECHO) \"Applying Full-Access Permissions\"\n".
      "\t\$(NOECHO) \$(CHMOD) \$(PERM_R+X) \$(DESTINSTALLSITESCRIPT)\/fullauto\$(EXE_EXT)\n".
      "\t\$(NOECHO) \$(CHMOD) \$(PERM_R+X) \$(DESTINSTALLSITESCRIPT)\/fullauto.pl\n".
      "\t\$(NOECHO) \$(CHMOD) \$(PERM_R+X) \$(DESTINSTALLSITELIB)\/Net\/FullAuto.pm\n".
      "\t\$(NOECHO) \$(CHMOD) \$(PERM_WRX) \$(DESTINSTALLSITELIB)\/Net\/FullAuto\n".
      "\t\$(NOECHO) \$(CHMOD) \$(PERM_R+X) \$(DESTINSTALLSITELIB)\/Net\/FullAuto\/*\n".
      "\t\$(NOECHO) \$(CHMOD) \$(PERM_WRX) \$(DESTINSTALLSITELIB)\/Net\/FullAuto\/Custom\n".
      "\t\$(NOECHO) \$(CHMOD) \$(PERM_WRX) \$(DESTINSTALLSITELIB)\/Net\/FullAuto\/Custom\/*\n".
      $link.
      "\t\$(NOECHO) \$(CHMOD) \$(PERM_WRX) /var\n".
      "\t\$(NOECHO) if [ -d /var/db ];".
      "then \$(CHMOD) \$(PERM_WRX) /var/db; fi\n";
      "\t\$(NOECHO) if [ -d /var/db/Berkeley ];".
      "then \$(CHMOD) \$(PERM_WRX) /var/db/Berkeley; fi\n";
      "\t\$(NOECHO) if [ -d /var/db/Berkeley/FullAuto ];".
      "then \$(CHMOD) \$(PERM_WRX) /var/db/Berkeley/FullAuto; fi\n";
   $inherited .= "\t\$(SED) \'s/^[ ]*our[ ]*\\(.\\)".
      "cygwin_berkeley_db_mode[ ]*[=].*/".'our \\1'.
      "cygwin_berkeley_db_mode = \$(PERM_WRX);/g\' ".
      "\$(DESTINSTALLSITELIB)/Net/FullAuto/FA_Core.pm >tmp_fa_core.pm\n".
      "\t\$(MV) ./tmp_fa_core.pm \$(DESTINSTALLSITELIB)".
      "/Net/FullAuto/FA_Core.pm\n"
      if $^O eq 'cygwin';
   $inherited .= "\nfiglet_fonts ::\n".
      "\t\$(NOECHO) \$(CP) dependencies/FIGlet_fonts/* /usr/share/figlet";

   $inherited; #

}

package MY; # so that "SUPER" works right
sub MY::dist_core {

   my $inherited = shift->SUPER::dist_core(@_);

   $inherited =~ s/tar$/tar\n\t\$(MV) \$(DISTVNAME).tar\$(SUFFIX) dist/m;

   $inherited; #

}

package MY; # so that "SUPER" works right
sub MY::clean {

   my $inherited = shift->SUPER::clean(@_);

   $inherited =~ s/blib\s*$/blib setup\$(EXE_EXT) /m;

   $inherited; #

}

package MY; # so that "SUPER" works right
sub MY::distdir {

   my $inherited = shift->SUPER::distdir(@_);

   $inherited =~ s/^(distdir .*)$/$1 distsignature/m;

   $inherited; #

}

package MY; # so that "SUPER" works right
sub MY::pm_to_blib {

   use Config;

   my $inherited = shift->SUPER::pm_to_blib(@_);

   unless ((-e $Config{installsitelib}."/Net/FullAuto/Custom/fa_host.pm") &&
         ($inherited !~ /Custom\/fa_host.pm/)) {
      my $fa_h="\t  lib\/Net\/FullAuto\/Custom\/fa_host.pm ".
               "blib\/lib\/Net\/FullAuto\/Custom\/fa_host.pm";
      my $wrap='';
      $inherited =~ /\s+blib.*Distro\/fa_host.pm( \\)/m;
      $wrap=$1;
      $inherited =~
         s/(\s+blib.*Distro\/fa_host.pm).*/$1 \\\n$fa_h$wrap/m;
   } else {
      $inherited =~ s/.*Custom\/fa_host.pm.*\n//m;
   }
   unless ((-e $Config{installsitelib}."/Net/FullAuto/Custom/fa_conf.pm") &&
         ($inherited !~ /Custom\/fa_conf.pm/)) {
      my $fa_g="\t  lib\/Net\/FullAuto\/Custom\/fa_conf.pm ".
               "blib\/lib\/Net\/FullAuto\/Custom\/fa_conf.pm";
      my $wrap='';
      $inherited =~ /\s+blib.*Distro\/fa_conf.pm( \\)/m;
      $wrap=$1;
      $inherited =~
         s/(\s+blib.*Distro\/fa_conf.pm).*/$1 \\\n$fa_g$wrap/m;
   } else {
      $inherited =~ s/.*Custom\/fa_conf.pm.*\n//m;
   }
   unless ((-e $Config{installsitelib}."/Net/FullAuto/Custom/fa_menu.pm") &&
         ($inherited !~ /Custom\/fa_menu.pm/)) {
      my $fa_m="\t  lib\/Net\/FullAuto\/Custom\/fa_menu.pm ".
               "blib\/lib\/Net\/FullAuto\/Custom\/fa_menu.pm";
      my $wrap='';
      $inherited =~ /\s+blib.*Distro\/fa_menu.pm( \\)/m;
      $wrap=$1;
      $inherited =~
         s/(\s+blib.*Distro\/fa_menu.pm).*/$1 \\\n$fa_m$wrap/m;
   } else {
      $inherited =~ s/.*Custom\/fa_menu.pm.*\n//m;
   }
   unless ((-e $Config{installsitelib}."/Net/FullAuto/Custom/fa_code.pm") &&
         ($inherited !~ /Custom\/fa_code.pm/)) {
      my $fa_c="\t  lib\/Net\/FullAuto\/Custom\/fa_code.pm ".
               "blib\/lib\/Net\/FullAuto\/Custom\/fa_code.pm";
      my $wrap='';
      $inherited =~ /\s+blib.*Distro\/fa_code.pm( \\)/m;
      $wrap=$1;
      $inherited =~
         s/(\s+blib.*Distro\/fa_code.pm).*/$1 \\\n$fa_c$wrap/m;
   } else {
      $inherited =~ s/.*Custom\/fa_code.pm.*\n//m;
   }
   
   $inherited =~ s/\s+\\(\s*[$][(]NOE)/$1/s;
   $inherited =~ s/([\$][(]NOECHO[)] [\$])/-$1/s;
   my $newline_flag=0;
   unless (-e $Config{installsitelib}."/Net/FullAuto/Custom/fa_conf.pm") {
      $inherited .= "\t\$(SED) \'s/^#[ ]*our[ ]*\\(.\\)editor[ ]*[=].*/".
         'our \\1'."editor = \"$editor\";/g\' ".
         "blib/lib/Net/FullAuto/Custom/fa_conf.pm >tmp_conf.pm\n".
         "\t\$(MV) tmp_conf.pm blib/lib/Net/FullAuto/Custom/fa_conf.pm\n\n"
         if defined $editor and $editor;
   } else {
      $newline_flag=1;
      $inherited .= "\n";
   }

   unless (-e $Config{installsitelib}."/Net/FullAuto/FA_Core.pm") {
      $inherited .= "\t\$(SED) \'s/^[ ]*our[ ]*\\(.\\)".
         "cygwin_berkeley_db_mode[ ]*[=].*/".'our \\1'.
         "cygwin_berkeley_db_mode = $main::cygwin_berkeley_db_mode;/g\' ".
         "blib/lib/Net/FullAuto/FA_Core.pm >tmp_fa_core.pm\n".
         "\t\$(MV) ./tmp_fa_core.pm blib/lib".
         "/Net/FullAuto/FA_Core.pm\n\n"
         if $^O eq 'cygwin';
   } elsif (!$newline_flag) {
      $inherited .= "\n";
   }

   $inherited; #

}

package FA::LWP::UserAgent;
use strict;
our @ISA = qw(LWP::UserAgent); # inherits from LWP::UserAgent
use vars qw(@ISA $USER $PASSWD $SETUPDONE);
# we delay requiring LWP::UserAgent and setting up inheritance until we need it

$FA::LWP::UserAgent::VERSION = "1.94";

sub config {
    return if $SETUPDONE;
    if ($CPAN::META->has_usable('LWP::UserAgent')) {
        require LWP::UserAgent;
        @ISA = qw(Exporter LWP::UserAgent); ## no critic
        $SETUPDONE++;
    } else {
        $CPAN::Frontend->mywarn("  LWP::UserAgent not available\n");
    }
}

sub get_basic_credentials {
    my($self, $realm, $uri, $proxy) = @_;
    if ($USER && $PASSWD) {
        return ($USER, $PASSWD);
    }
    if ( $proxy ) {
        ($USER,$PASSWD) = $self->get_proxy_credentials();
    } else {
        ($USER,$PASSWD) = $self->get_non_proxy_credentials();
    }
    return($USER,$PASSWD);
}

sub get_proxy_credentials {
    my $self = shift;
    my ($user, $password);
    if ( defined $CPAN::Config->{proxy_user} ) {
        $user = $CPAN::Config->{proxy_user};
        $password = $CPAN::Config->{proxy_pass} || "";
        return ($user, $password);
    }
    my $username_prompt = "\nProxy authentication needed!
 (Note: to permanently configure username and password run
   o conf proxy_user your_username
   o conf proxy_pass your_password
     )\nUsername:";
    ($user, $password) =
        _get_username_and_password_from_user($username_prompt);
    return ($user,$password);
}

sub get_non_proxy_credentials {
    my $self = shift;
    my ($user,$password);
    if ( defined $CPAN::Config->{username} ) {
        $user = $CPAN::Config->{username};
        $password = $CPAN::Config->{password} || "";
        return ($user, $password);
    }
    my $username_prompt = "\nAuthentication needed!
     (Note: to permanently configure username and password run
       o conf username your_username
       o conf password your_password
     )\nUsername:";

    ($user, $password) =
        _get_username_and_password_from_user($username_prompt);
    return ($user,$password);
}

sub _get_username_and_password_from_user {
    my $username_message = shift;
    my ($username,$password);

    ExtUtils::MakeMaker->import(qw(prompt));
    $username = prompt($username_message);
        if ($CPAN::META->has_inst("Term::ReadKey")) {
            Term::ReadKey::ReadMode("noecho");
        }
    else {
        $CPAN::Frontend->mywarn(
            "Warning: Term::ReadKey seems not to be available, ".
            "your password will be echoed to the terminal!\n"
        );
    }
    $password = prompt("Password:");

        if ($CPAN::META->has_inst("Term::ReadKey")) {
            Term::ReadKey::ReadMode("restore");
        }
        $CPAN::Frontend->myprint("\n\n");
    return ($username,$password);
}

# mirror(): Its purpose is to deal with proxy authentication. When we
# call SUPER::mirror, we relly call the mirror method in
# LWP::UserAgent. LWP::UserAgent will then call
# $self->get_basic_credentials or some equivalent and this will be
# $self->dispatched to our own get_basic_credentials method.

# Our own get_basic_credentials sets $USER and $PASSWD, two globals.

# 407 stands for HTTP_PROXY_AUTHENTICATION_REQUIRED. Which means
# although we have gone through our get_basic_credentials, the proxy
# server refuses to connect. This could be a case where the username or
# password has changed in the meantime, so I'm trying once again without
# $USER and $PASSWD to give the get_basic_credentials routine another
# chance to set $USER and $PASSWD.

# mirror(): Its purpose is to deal with proxy authentication. When we
# call SUPER::mirror, we relly call the mirror method in
# LWP::UserAgent. LWP::UserAgent will then call
# $self->get_basic_credentials or some equivalent and this will be
# $self->dispatched to our own get_basic_credentials method.

# Our own get_basic_credentials sets $USER and $PASSWD, two globals.

# 407 stands for HTTP_PROXY_AUTHENTICATION_REQUIRED. Which means
# although we have gone through our get_basic_credentials, the proxy
# server refuses to connect. This could be a case where the username or
# password has changed in the meantime, so I'm trying once again without
# $USER and $PASSWD to give the get_basic_credentials routine another
# chance to set $USER and $PASSWD.

sub mirror {
    my($self,$url,$aslocal) = @_;
    my $result = $self->SUPER::mirror($url,$aslocal);
    if ($result->code == 407) {
        undef $USER;
        undef $PASSWD;
        $result = $self->SUPER::mirror($url,$aslocal);
    }
    $result;
}

1;