#!/usr/bin/perl
use warnings;
use strict;

# ns4 - Configuration Management Tool
# Copyright (c) 2007-2009 Chris Mason <chris@noodles.org.uk>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

my $_nn = '4.3.6';

use Getopt::Long;
Getopt::Long::Configure ('pass_through');
Getopt::Long::Configure ('bundling');

use Expect;
use YAML::Syck;

use File::Path;
use IO::Socket;
use IO::Select;
use POSIX;

use vars qw(
  $script_version
  $script_criteria
  $script_timeout
  $ns4_version
);

my %_I3 = ();
$_I3{'root'}{'cartridge'} = 0;
$_I3{'cartridge'}{'prompt'} = 1;
$_I3{'cartridge'}{'options'} = 0;
$_I3{'cartridge'}{'pre'} = 0;
$_I3{'cartridge'}{'post'} = 0;
$_I3{'pre'}{'expect'} = 0;
$_I3{'post'}{'expect'} = 0;
$_I3{'options'}{'terminator'} = 0;
$_I3{'options'}{'rawpty'} = 0;
$_I3{'options'}{'logout_cmd'} = 0;
$_I3{'options'}{'alt_username_prompt'} = 0;
$_I3{'options'}{'alt_password_prompt'} = 0;
$_I3{'options'}{'tag'} = 0;
$_I3{'options'}{'pre_login_seq'} = 0;

my %_iO = ();
$_iO{'root'}{'proxy'} = 0;
$_iO{'root'}{'transport_ftp'} = 0;
$_iO{'root'}{'transport_sftp'} = 0;
$_iO{'root'}{'alert_smtp'} = 0;
$_iO{'root'}{'alert_http'} = 0;
$_iO{'root'}{'container'} = 0;
$_iO{'root'}{'gpg_path'} = 0;
$_iO{'root'}{'socks_wrapper'} = 0;
$_iO{'root'}{'terminator'} = 0;
$_iO{'root'}{'max_sessions_null_proxy'} = 0;
$_iO{'root'}{'min_nps_null_proxy'} = 0;
$_iO{'root'}{'explicit_null_tag'} = 0;
$_iO{'root'}{'default_report_type'} = 0;
$_iO{'root'}{'syslog_facility'} = 0;
$_iO{'root'}{'max_buffer_kb'} = 0;
$_iO{'transport_ftp'}{'id'} = 0;
$_iO{'transport_ftp'}{'address'} = 1;
$_iO{'transport_ftp'}{'username'} = 1;
$_iO{'transport_ftp'}{'password'} = 1;
$_iO{'transport_ftp'}{'max_retries'} = 0;
$_iO{'transport_sftp'}{'id'} = 0;
$_iO{'transport_sftp'}{'address'} = 1;
$_iO{'transport_sftp'}{'username'} = 1;
$_iO{'transport_sftp'}{'password'} = 1;
$_iO{'transport_sftp'}{'max_retries'} = 0;
$_iO{'alert_smtp'}{'id'} = 0;
$_iO{'alert_smtp'}{'from'} = 1;
$_iO{'alert_smtp'}{'to'} = 1;
$_iO{'alert_smtp'}{'cc'} = 0;
$_iO{'alert_smtp'}{'relay'} = 1;
$_iO{'alert_smtp'}{'timeout'} = 0;
$_iO{'alert_smtp'}{'username'} = 0;
$_iO{'alert_smtp'}{'password'} = 0;
$_iO{'alert_http'}{'id'} = 0;
$_iO{'alert_http'}{'post_url'} = 1;
$_iO{'alert_http'}{'proxy_url'} = 0;
$_iO{'alert_http'}{'timeout'} = 0;
$_iO{'proxy'}{'id'} = 0;
$_iO{'proxy'}{'address'} = 0;
$_iO{'proxy'}{'username'} = 1;
$_iO{'proxy'}{'password'} = 1;
$_iO{'proxy'}{'method'} = 1;
$_iO{'proxy'}{'prompt'} = 1;
$_iO{'proxy'}{'rawpty'} = 0;
$_iO{'proxy'}{'terminal'} = 0;
$_iO{'proxy'}{'tag'} = 0;
$_iO{'proxy'}{'terminator'} = 0;
$_iO{'proxy'}{'logout_cmd'} = 0;
$_iO{'proxy'}{'max_sessions'} = 0;
$_iO{'proxy'}{'socks_wrapper'} = 0;
$_iO{'proxy'}{'local_socks_port'} = 0;
$_iO{'proxy'}{'min_nodes_per_session'} = 0;
$_iO{'proxy'}{'max_proxy_retries'} = 0;
$_iO{'proxy'}{'timeout'} = 0;
$_iO{'proxy'}{'alt_username_prompt'} = 0;
$_iO{'proxy'}{'alt_password_prompt'} = 0;
$_iO{'container'}{'options'} = 0;
$_iO{'container'}{'node'} = 0;
$_iO{'container'}{'container'} = 0;
$_iO{'options'}{'command'} = 0;
$_iO{'options'}{'tag'} = 0;
$_iO{'options'}{'cartridge'} = 1;
$_iO{'options'}{'location'} = 0;
$_iO{'options'}{'proxy'} = 0;
$_iO{'options'}{'alert'} = 0;
$_iO{'options'}{'transport'} = 0;
$_iO{'options'}{'username'} = 1;
$_iO{'options'}{'password'} = 1;
$_iO{'options'}{'custom'} = 0;
$_iO{'options'}{'method'} = 1;
$_iO{'options'}{'max_node_retries'} = 0;
$_iO{'options'}{'timeout'} = 0;
$_iO{'options'}{'gpg_keyid'} = 0;
$_iO{'options'}{'snmp_oids'} = 0;
$_iO{'options'}{'snmp_community'} = 0;
$_iO{'node'}{'id'} = 0;
$_iO{'node'}{'address'} = 0;
$_iO{'node'}{'_usedns_'} = 0;

my $_2z = '/etc/ns4/ns4.yaml';
my $_Jo = '/etc/ns4/cartridges.yaml';
my @_ZX = ('command', 'tag', 'pre', 'post', 'to', 'cc', 'gpg_keyid', 'proxy', 'alert', 'transport', 'snmp_oids');
my %_UF = ();

my @_ZQ = ('command');
my @_pY = ('pre', 'post');
my @_5o = ('pre', 'post', 'prompt');
my @_UX = ('password');
my @_Yi = ('username', 'password');

my @_kM = ('byproxy', 'bytag', 'raw', 'detail');

my @_B2 = (
  'Net::FTP',
  'Net::SSH2',
  'Net::SMTP',
  'LWP::UserAgent',
  'Sys::Syslog',
  'MIME::Base64',
  'Net::SNMP'
);

our %_80 = ();
my $_wh = 3;
my $_ea = 3;
my $_zV = 3;
my $_LV = 5;
my $_Lb = 12;
my $_hy = 1;
my $_xA = 1;
my $_xh = 1;
my $_DG = 0;
my $_w2 = 10;
my $_HD = 10;
my $_Zv = ($^O =~ m/cygwin/i) ? "\r\n" : "\n";
my $_4D = "\n";
my $_IV = qr/[ \t]*\r*\n(?:\r(?!\n))*/;
my $_ch = 'exit';
my $_gY = 0;
my $_IT = 'byproxy';
my $_md = 120;
my $_CA = 15;
my $_vl = 15;
my $_IG = 15;
my $_yp = 30;
my $_XA = 0;
my $_rH = 16384 + (int (rand (16383)) + 1);
my @_ut = ();
my $_9X = '%a, %b %d %H:%M %Z %Y';
my $_3s = (exists $ENV{'TEMP'}) ? $ENV{'TEMP'} : '/tmp';
my $_4S = $$;
our $_r3 = $_3s . '/.ns4-' . $_4S . '.sem';
my $_wK = $_3s . '/.ns4-' . $_4S . '.lock';
my $_Hk = $_3s . '/.ns4-' . $_4S . '.ipc';
my $_ZE = join (' ', @ARGV);
my $_7l = 0;

if (not $>) {
  warn ('root is dangerous' . "\n");
  exit (1);
}

$SIG{'HUP'} = 'IGNORE';

print 'ns4 v' . $_nn . "\n";
print 'Configuration Management Tool' . "\n";
print 'url http://www.noodles.org.uk/ns4.html' . "\n";
print 'by Chris Mason <chris@noodles.org.uk>' . "\n\n";

$_80{'verbose'} = 0;

GetOptions (
  \%_80,
  'all|a',
  'node|n=s',
  'nodelist|N=s',
  'tag|t=s@',
  'report|r:s',
  'default|d:s',
  'command|c=s',
  'list|l=s',
  'script|s=s',
  'test|x',
  'poller|p:s',
  'cfg|C=s',
  'cartridges|R=s',
  'alerts|A',
  'failed|f:s',
  'version|V',
  'verbose|v+'
);

if (exists $_80{'script'}) {
  if (index ($_80{'script'}, ',') != -1) {
    my @_z8 = split (m/\s*,\s*/, substr ($_80{'script'}, index ($_80{'script'}, ',') + 1));
    $_80{'script'} = substr ($_80{'script'}, 0, index ($_80{'script'}, ','));
    foreach my $_7Y (@_z8) {
      my ($_Fx, $_cE) = split (m/\s*=\s*/, $_7Y);
      $_80{'script_options'}{lc $_Fx} = $_cE;
    }
  }
}

if (exists $_80{'version'}) {
  &_QT;
  exit;
}

if (
  $ARGV[0] or
  (not exists $_80{'node'} and not exists $_80{'nodelist'} and not exists $_80{'all'} and not exists $_80{'tag'}) or
  (not exists $_80{'report'} and not exists $_80{'default'} and not exists $_80{'command'} and not exists $_80{'list'} and not exists $_80{'script'} and not exists $_80{'test'} and not exists $_80{'poller'}) or
  (exists $_80{'node'} and (exists $_80{'nodelist'} or exists $_80{'all'})) or
  (exists $_80{'all'} and (exists $_80{'node'} or exists $_80{'nodelist'})) or
  (exists $_80{'command'} and (index ($_80{'command'}, ',') == -1)) or
  (exists $_80{'list'} and (index ($_80{'list'}, ',') == -1)) or
  (exists $_80{'command'} and (exists $_80{'list'} or exists $_80{'script'} or exists $_80{'test'} or exists $_80{'report'} or exists $_80{'default'} or exists $_80{'poller'})) or
  (exists $_80{'list'} and (exists $_80{'command'} or exists $_80{'script'} or exists $_80{'test'} or exists $_80{'report'} or exists $_80{'default'} or exists $_80{'poller'})) or
  (exists $_80{'script'} and (exists $_80{'list'} or exists $_80{'command'} or exists $_80{'test'} or exists $_80{'report'} or exists $_80{'default'} or exists $_80{'poller'})) or
  (exists $_80{'report'} and (exists $_80{'list'} or exists $_80{'script'} or exists $_80{'test'} or exists $_80{'command'} or exists $_80{'default'} or exists $_80{'poller'})) or
  (exists $_80{'poller'} and (exists $_80{'list'} or exists $_80{'script'} or exists $_80{'test'} or exists $_80{'command'} or exists $_80{'default'} or exists $_80{'report'})) or
  (exists $_80{'test'} and (exists $_80{'list'} or exists $_80{'script'} or exists $_80{'poller'} or exists $_80{'command'} or exists $_80{'default'} or exists $_80{'report'})) or
  (exists $_80{'default'} and (exists $_80{'list'} or exists $_80{'script'} or exists $_80{'test'} or exists $_80{'command'} or exists $_80{'report'} or exists $_80{'poller'}))
) {
  print 'Usage: ' . &_NG ($0) . ' <criteria> <action> [options]' . "\n";
  print ' Criteria:' . "\n";
  print '  -a                   all nodes' . "\n";
  print '  or -n \'re\'           node pattern' . "\n";
  print '  or -N \'file\'         node list file' . "\n";
  print '  or/and -t \'re\'@      tag pattern' . "\n";
  print ' Actions:' . "\n";
  print '  -r \'[type]\'          node summary report' . "\n";
  print '   where \'type\' is:' . "\n";
  print '    \'byproxy\'           group by proxy (default)' . "\n";
  print '    \'bytag\'             group by tag' . "\n";
  print '    \'raw\'               raw output' . "\n";
  print '    \'detail\'            detailed output' . "\n";
  print '  or -c \'x[,x,..],y\'   command = \'x\', output file = \'y\'' . "\n";
  print '  or -l \'x,y\'          list file = \'x\', output file = \'y\'' . "\n";
  print '  or -s \'x[,a=x,..]\'   script file = \'x\', variables (\'a=x\', etc)' . "\n";
  print '  or -d \'[file]\'       execute commands from configuration' . "\n";
  print '  or -x                test mode (verify node login only)' . "\n";
  print '  or -p \'[logfile]\'    simple snmp poller' . "\n";
  print ' Options:' . "\n";
  print '  -C \'file\'            alternative configuration file' . "\n";
  print '  -R \'file\'            alternative cartridges file' . "\n";
  print '  -f \'[file]\'          create failed node list file' . "\n";
  print '  -A                   enable alerting of failures' . "\n";
  print '  -V                   output version information' . "\n";
  print '  -v@                  verbosity level (max 4)' . "\n";
  exit (5);
}

eval { $_80{'node'} = (exists $_80{'node'}) ? qr/$_80{'node'}/i : qr/.+/i };

if ($@) {
  (my $_Yf = $@) =~ s/\s+at\s+.*//sg;
  warn ('Error: Invalid node regular expression specified - ' . $_Yf . "\n");
  exit (1);
}

eval {
  if (exists $_80{'tag'}) {
    for (my $_7X = 0; $_7X < $#{$_80{'tag'}} + 1; $_7X++) {
      ${$_80{'tag'}}[$_7X] = qr/${$_80{'tag'}}[$_7X]/i;
    }
  }
  else {
    $_80{'tag'} = [qr/.*/i];
  }
};

if ($@) {
  (my $_Yf = $@) =~ s/\s+at\s+.*//sg;
  warn ('Error: Invalid tag regular expression specified - ' . $_Yf . "\n");
  exit (1);
}

if (exists $ENV{'NS4_CFG_FILE'}) {
  if ($ENV{'NS4_CFG_FILE'} =~ m/\w+/) {
    $_2z = $ENV{'NS4_CFG_FILE'};
  }
  else {
    warn ('Warning: Ignoring environment variable \'NS4_CFG_FILE\' - invalid content' . "\n");
    $_7l++;
  }
}

if (exists $ENV{'NS4_CARTRIDGES_FILE'}) {
  if ($ENV{'NS4_CARTRIDGES_FILE'} =~ m/\w+/) {
    $_Jo = $ENV{'NS4_CARTRIDGES_FILE'};
  }
  else {
    warn ('Warning: Ignoring environment variable \'NS4_CARTRIDGES_FILE\' - invalid content' . "\n");
    $_7l++;
  }
}

$_2z = (exists $_80{'cfg'}) ? $_80{'cfg'} : $_2z;
$_Jo = (exists $_80{'cartridges'}) ? $_80{'cartridges'} : $_Jo;

if (exists $_80{'nodelist'}) {
  if (open (my $_q6, '<', $_80{'nodelist'})) {
    my $_l1 = $_80{'nodelist'};
    delete ($_80{'nodelist'});
    while (<$_q6>) {
      s/^\s*(.*?)\s*$/$1/;
      if (length and not m/^#/) {
        ${$_80{'nodelist'}}{$_} = 1;
      }
    }
    close ($_q6);

    if (not exists $_80{'nodelist'}) {
      warn ('Error: Invalid node list file \'' . $_l1 . '\' - not enough entries' . "\n");
      exit (1);
    }
  }
  else {
    warn ('Error: Unable to open node list file \'' . $_80{'nodelist'} . '\'' . "\n");
    exit (1);
  }
}

my $_Ah = 0;
my $_y6 = 0;

my ($_RM) = &_qR;
my ($_Ae, $_xT, $_K2, $_fJ, $_Qm) = &_P2;

if ($_Ah) {
  warn ('Error: Warnings have been detected within the configuration' . "\n");
  exit (1);
}

&_Cl ($_Ae, $_RM, $_xT, $_K2, $_fJ, $_Qm);

# ---

our $_34 = sub {
  my ($_YV, $_EW, $_Bw, $_lF) = @_;

  my %_8H = ();
  $_8H{'pid'} = $_4S;
  $_8H{'date'} = strftime ('%Y%m%d', localtime);
  $_8H{'time'} = strftime ('%H%M%S', localtime);

  if (defined $_Bw) {
    $_8H{'p:username'} = $_Qm->{$_Bw}{'username'};
    $_8H{'p:address'} = $_Qm->{$_Bw}{'address'};

    if (defined $_EW) {
      $_8H{'node'} = $_EW;
      $_8H{'n:username'} = $_fJ->{$_EW}{'username'};
      $_8H{'n:address'} = $_fJ->{$_EW}{'address'};
      $_8H{'n:location'} = $_fJ->{$_EW}{'location'};
      $_8H{'n:tags'} = join (',', @{$_fJ->{$_EW}{'tag'}});
  
      if (not $_lF) {
        $_8H{'n:prompt'} = $_RM->{$_fJ->{$_EW}{'cartridge'}}{'prompt'};
        $_8H{'n:prompt'} = (index ($_8H{'n:prompt'}, ' :!: ') > 0) ? substr ($_8H{'n:prompt'}, 0, index ($_8H{'n:prompt'}, ' :!: ')) : $_8H{'n:prompt'};
        $_8H{'n:prompt'} = &_G7 ($_8H{'n:prompt'}, $_EW, $_Bw, 1, 1);
      }

      if ($_YV =~ m/^C:(\S+)$/i) {
        if (exists $_fJ->{$_EW}{'custom_' . lc ($1)}) {
          return ($_fJ->{$_EW}{'custom_' . lc ($1)});
        }
        else {
          return (undef);
        }
      }
    }
  }
  if ($_YV =~ m/^MATCH_(L|R)(\?|\*)\s*,\s*(\S+?)\s*,\s*(.)$/i) {
    my ($_FS, $_y3, $_xZ, $_9E) = ($1, $2, $3, $4);
    my ($_0f, $_R1) = (undef, undef);

    if (exists $_8H{lc $_xZ}) {
      $_xZ = $_8H{lc $_xZ};

      if (uc ($_FS) eq 'L') {
        $_R1 = ($_y3 eq '*') ? rindex ($_xZ, $_9E) : index ($_xZ, $_9E);
        $_0f = ($_R1 != -1) ? substr ($_xZ, 0, $_R1) : $_xZ;
        $_0f =~ s/\\$//;
      }
      elsif (uc ($_FS) eq 'R') {
        $_R1 = ($_y3 eq '*') ? index ($_xZ, $_9E) : rindex ($_xZ, $_9E);
        $_0f = ($_R1 != -1) ? substr ($_xZ, $_R1 + 1) : $_xZ;
      }
      return ($_0f);
    }
    else {
      return (undef);
    }
  }
  else {
    return ((exists $_8H{lc $_YV}) ? $_8H{lc $_YV} : undef);
  }
};

our $_pV = sub {
  my ($_MR, $_EW, $_85, $_jU) = @_;
  my $_rg = strftime ('%b %d %H:%M:%S', localtime);
  my $_eg = getpwuid ($>);
  my $_Uj = undef;
  $_eg = ($_eg) ? $_eg : 'unknown';

  if (exists $ENV{'NS4_AI'} and ($ENV{'NS4_AI'} =~ m/(.+)/)) {
    $_Uj = $1;
  }

  if (defined ($_EW) and ($_80{'verbose'} > 1)) {
    &_Z2 ($_MR, $_EW . ': \'' . $_85 . '\'');
  }

  if (exists $_Ae->{'syslog_facility'}) {
    openlog ('ns4', 'ndelay,pid', $_Ae->{'syslog_facility'});
    syslog ('info', 'USER=\'' . $_eg . '\'; ' . ((defined $_Uj) ? 'AI=\'' . $_Uj . '\'; ' : '') . ((defined $_EW) ? 'NODE=\'' . $_EW . '\'; CMD=\'' : 'CMD_LINE=\'') . $_85 . '\'');
    closelog ();
  }
};

# ---

my %_tP = ();
my %_xq = ();
my %_sw = ();
if (not exists $_80{'report'}) {
  if ((not -t STDIN) or (not -t STDOUT)) {
    if (keys %_UF) {
      warn ('Error: Cannot use \'ask\' attribute on non-interactive sessions' . "\n");
      exit (1);
    }
  }

  foreach my $_pG ('command', 'list', 'default') {
    if (exists $_80{$_pG}) {
      if ($_pG ne 'default') {
        if ($_80{$_pG} =~ m/\s*(.+)\s*,\s*(\S+)\s*/) {
          $_80{$_pG} = $1;
          $_80{'file'} = $2;
        }
        else {
          warn ('Error: Invalid command/list format detected' . "\n");
          exit (1);
        }
      }
      elsif (length $_80{'default'}) {
        $_80{'file'} = $_80{'default'};
      }

      if (exists $_80{'file'}) {
        (my $_D1 = $_80{'file'}) =~ s/\\/\//g;

        if ($_D1 !~ m/^(\/|\.+\/)/) {
          $_D1 = './' . $_D1;
        }

        foreach my $_Bw (keys %{$_Qm}) {
          if (exists $_Qm->{$_Bw}{'nodes'}) {
            foreach my $_EW (@{$_Qm->{$_Bw}{'nodes'}}) {
              my ($_0B, $_uM) = &_x0 ($_D1, $_EW, $_Bw);
              if ($_0B == 10) {
                warn ('Error: Output directory \'' . $_uM . '\' not writable - permission denied' . "\n");
                exit (1);
              }
              elsif ($_0B == 20) {
                if (not exists $_xq{$_uM}) {
                  warn ('Warning: Dynamic output file \'' . $_uM . '\' already exists and will be appended' . "\n");
                  $_xq{$_uM} = 1;
                }
                $_7l++;
              }
              elsif ($_0B == 30) {
                warn ('Error: Dynamic output file \'' . $_uM . '\' already exists and isn\'t writable - permission denied' . "\n");
                exit (1);
              }
              elsif ($_0B) {
                warn ('Error: Invalid output file specified' . "\n");
                exit (1);
              }
              $_fJ->{$_EW}{'ofile'} = $_uM;
            }
          }
        }
      }
    }
  }

  if (exists $_80{'failed'}) {
    my $_av = (length $_80{'failed'}) ? $_80{'failed'} : 'ns4.' . $$ . '.failed';
    if (-e $_av) {
      warn ('Error: Failed node list file \'' . $_av . '\' already exists' . "\n");
      exit (1);
    }
  }

  if (exists $_80{'list'}) {
    if (open (my $_qh, '<', $_80{'list'})) {
      my $_K5 = $_80{'list'};
      delete ($_80{'list'});
      while (<$_qh>) {
        s/^\s*(.*?)\s*$/$1/;
        if (length and not m/^#/) {
          push (@{$_80{'list'}}, $_);
        }
      }
      close ($_qh);

      if (not exists $_80{'list'}) {
        warn ('Error: Invalid list file \'' . $_K5 . '\' - not enough entries' . "\n");
        exit (1);
      }
    }
    else {
      warn ('Error: Unable to open list file \'' . $_80{'list'} . '\'' . "\n");
      exit (1);
    }
  }

  if (exists $_80{'script'}) {
    if (not -f $_80{'script'} or not -r $_80{'script'}) {
      warn ('Error: Unable to open script file \'' . $_80{'script'} . '\'' . "\n");
      exit (1);
    }
    eval { require $_80{'script'} };
    if ($@) {
      print '---' . "\n";
      print $@;
      print '---' . "\n";
      warn ('Error: (' . &_NG ($_80{'script'}) . '): Syntax error within script' . "\n");
      exit (1);
    }

    $script_criteria = (defined $script_criteria) ? $script_criteria : ':';

    if ($_nn =~ m/^(\d+)\.(\d+)\.(\d+)/) {
      my $_M8 = $1 . $2 . $3;

      if (defined $ns4_version) {
        if ($ns4_version =~ m/^(\d+)\.(\d+)\.(\d+)$/) {
          my $_t2 = $1 . $2 . $3;

          if ($_t2 > $_M8) {
            warn ('Error: (' . &_NG ($_80{'script'}) . '): Script requires a minimum ns4 version of ' . join ('.', split (m//, $_t2)) . "\n");
            exit (1);
          }
        }
        else {
          warn ('Error: (' . &_NG ($_80{'script'}) . '): \$ns4_version is an invalid format' . "\n");
          exit (1);
        }
      }
    }
    else {
      warn ('Error: $_nn is an invalid format - system error' . "\n");
      exit (1);
    }

    $_80{'script_timeout'} = (defined $script_timeout) ? $script_timeout : $_md;

    $script_version = (defined $script_version) ? $script_version : '';
    $script_version =~ s/^\s*(.*?)\s*$/$1/s;

    if (length $script_version) {
      ($_80{'script_version'} = $script_version) =~ s/^/* /gm;
    }

    foreach my $_Rf (split (m/\s*,\s*/, $script_criteria)) {
      if (index ($_Rf, ':') == -1) {
        warn ('Error: (' . &_NG ($_80{'script'}) . '): \':[,:]\' $script_criteria must contain a \':\' within each element' . "\n");
        exit (1);
      }
      elsif (index ($_Rf, ':') != rindex ($_Rf, ':')) {
        warn ('Error: (' . &_NG ($_80{'script'}) . '): \':[,:]\' $script_criteria cannot contain more than one \':\' within each element' . "\n");
        exit (1);
      }

      my ($_n3, $_JK) = split (m/\s*:\s*/, $_Rf);
      eval { $_n3 = (length ($_n3)) ? qr/$_n3/i : qr/.*/i };

      if ($@) {
        (my $_Yf = $@) =~ s/\s+at\s+.*//sg;
        warn ('Error: (' . &_NG ($_80{'script'}) . '): $script_criteria contains an invalid regular expression - ' . $_Yf . "\n");
        exit (1);
      }

      eval { $_JK = (length ($_JK)) ? qr/$_JK/i : qr/.+/i };

      if ($@) {
        (my $_Yf = $@) =~ s/\s+at\s+.*//sg;
        warn ('Error: (' . &_NG ($_80{'script'}) . '): $script_criteria contains an invalid regular expression - ' . $_Yf . "\n");
        exit (1);
      }

      push (@{$_80{'script_criteria'}}, $_n3 . '::' . $_JK);
    }

    if (not defined &main) {
      warn ('Error: (' . &_NG ($_80{'script'}) . '): mandatory subroutine \'main\' undefined' . "\n");
      exit (1);
    }
  }

  if (exists $_Ae->{'max_buffer_kb'}) {
    $_gY = $_Ae->{'max_buffer_kb'};
  }

  if (not exists $_Ae->{'terminator'}) {
    $_Ae->{'terminator'} = $_Zv;
  }
  else {
    $_Ae->{'terminator'} =~ s/cr/\r/gi;
    $_Ae->{'terminator'} =~ s/lf/\n/gi;
  }

  for (my $_7X = 0; $_7X < 10; $_7X++) {
    my $_Ve = $_wK . $_7X;

    if (not mkdir ($_Ve, 0000)) {
      warn ('Error: Unable to create lock file \'' . $_Ve . '\' - ' . $! . "\n");
      exit (1);
    }
    elsif (not rmdir ($_Ve)) {
      warn ('Error: Unable to remove lock file \'' . $_Ve . '\' - ' . $! . "\n");
      exit (1);
    }
  }

  foreach my $_Xz ($_r3) {
    if (-e $_Xz) {
      unlink ($_Xz);
      if (-e $_Xz) {
        warn ('Error: Unable to remove unix semaphore file - \'' . $_Xz . '\'' . "\n");
        exit (1);
      }
    }
    else {
      if (open (my $_8a, '>', $_Xz)) {
        close ($_8a);
        unlink ($_Xz);
      }
      else {
        warn ('Error: Unable to create unix semaphore file - \'' . $_Xz . '\'' . "\n");
        exit (1);
      }
    }
  }
}
else {
  my %_GA = ();
  my %_VM = ();
  my %_VW = ();
  my $_y6 = 0;
  my $_g0 = 0;
  my $_fQ = keys (%{$_fJ});

  if ($_7l) {
    print "\n";
  }

  if (not length ($_80{'report'})) {
    if (exists $_Ae->{'default_report_type'}) {
      if (&_NP (qr/$_Ae->{'default_report_type'}/i, @_kM)) {
        $_80{'report'} = $_Ae->{'default_report_type'};
      }
      else {
        warn ('Error: Unknown report type \'' . $_Ae->{'default_report_type'} . '\' set within \'' . $_2z . '\'' . "\n");
        exit (1);
      }
    }
    else {
      $_80{'report'} = $_IT;
    }
  }

  foreach my $_Bw (keys %{$_Qm}) {
    if (exists $_Qm->{$_Bw}{'nodes'}) {
      foreach my $_EW (@{$_Qm->{$_Bw}{'nodes'}}) {
        my $_fi = (exists $_fJ->{$_EW}{'_usedns_'}) ? 'DNS' : $_fJ->{$_EW}{'address'};
        $_y6 = (length ($_EW) > $_y6) ? length ($_EW) : $_y6;
        $_g0 = (length ($_fi) > $_g0) ? length ($_fi) : $_g0;
        push (@{$_GA{$_Bw}{uc (join (', ', @{$_fJ->{$_EW}{'tag'}}))}}, $_EW);
        push (@{$_VM{uc (join (', ', @{$_fJ->{$_EW}{'tag'}}))}{$_Bw}}, $_EW);
        if (exists $_VW{uc (join (', ', @{$_fJ->{$_EW}{'tag'}}))}) {
          $_VW{uc (join (', ', @{$_fJ->{$_EW}{'tag'}}))} += 1;
        }
        else {
          $_VW{uc (join (', ', @{$_fJ->{$_EW}{'tag'}}))} = 1;
        }
      }
    }
  }

  if (lc ($_80{'report'}) eq 'byproxy') {
    foreach my $_Bw (sort {
        if ($a eq 'null') { return (-1) }
        elsif ($b eq 'null') { return (1) }
        else {return (lc ($a) cmp lc ($b))}
      } keys %{$_Qm}) {
      if (exists $_Qm->{$_Bw}{'nodes'}) {
        if ($_Bw eq 'null') {
          print '[Proxy: null] (nodes = ' . ($#{$_Qm->{$_Bw}{'nodes'}} + 1) . ')' . "\n";
        }
        else {
          if ($_Bw =~ m/\|/) {
            (my $_7P = $_Bw) =~ s/\|/ -> /g;
            print '[Proxy: ' . $_7P . '] (nodes = ' . ($#{$_Qm->{$_Bw}{'nodes'}} + 1) . ')' . "\n";
          }
          else {
            print '[Proxy: ' . $_Bw . '] (nodes = ' . ($#{$_Qm->{$_Bw}{'nodes'}} + 1) . ')' . "\n";
          }
        }

        my $_uF = 0;
        foreach my $_2t (sort keys %{$_GA{$_Bw}}) {
          if (not length ($_2t)) {
            print ' [Tags: None]' . "\n";
            $_uF++;
          }
          else {
            if ($_uF) {
              print "\n";
            }
            print ' [Tags: ' . $_2t . ']' . "\n";
            $_uF++;
          }
          foreach my $_EW (sort @{$_GA{$_Bw}{$_2t}}) {
            my $_fi = (exists $_fJ->{$_EW}{'_usedns_'}) ? 'DNS' : $_fJ->{$_EW}{'address'};
            my $_dV = '.' x (($_y6 + $_g0) - (length ($_EW) + length ($_fi)));
            print '  - ' . $_EW . ' .' . $_dV . '. ' . $_fi . '  /' . $_fJ->{$_EW}{'location'} . "\n";
            $_fQ--;
          }
        }
        if ($_fQ) {
          print "\n";
        }
      }
    }
  }
  elsif (lc ($_80{'report'}) eq 'bytag') {
    foreach my $_2t (sort keys %_VM) {
      if (not length ($_2t)) {
        print '[Tags: None] (nodes = ' . $_VW{$_2t} . ')' . "\n";
      }
      else {
        print '[Tags: ' . $_2t . '] (nodes = ' . $_VW{$_2t} . ')' . "\n";
      }

      my $_uF = 0;
      foreach my $_Bw (sort {
          if ($a eq 'null') { return (-1) }
          elsif ($b eq 'null') { return (1) }
          else {return (lc ($a) cmp lc ($b))}
        } keys %{$_VM{$_2t}}) {

        if ($_Bw eq 'null') {
          print ' [Proxy: null]' . "\n";
          $_uF++;
        }
        else {
          if ($_uF) {
            print "\n";
          }
          if ($_Bw =~ m/\|/) {
            (my $_7P = $_Bw) =~ s/\|/ -> /g;
            print ' [Proxy: ' . $_7P . ']' . "\n";
          }
          else {
            print ' [Proxy: ' . $_Bw . ']' . "\n";
          }
          $_uF++;
        }

        foreach my $_EW (sort @{$_VM{$_2t}{$_Bw}}) {
          my $_fi = (exists $_fJ->{$_EW}{'_usedns_'}) ? 'DNS' : $_fJ->{$_EW}{'address'};
          my $_dV = '.' x (($_y6 + $_g0) - (length ($_EW) + length ($_fi)));
          print '  - ' . $_EW . ' .' . $_dV . '. ' . $_fi . '  /' . $_fJ->{$_EW}{'location'} . "\n";
          $_fQ--;
        }
      }
      if ($_fQ) {
        print "\n";
      }
    }
  }
  elsif (lc ($_80{'report'}) eq 'raw') {
    foreach my $_EW (sort keys %{$_fJ}) {
      my $_cO = uc (join (', ', @{$_fJ->{$_EW}{'tag'}}));
      if (not length ($_cO)) {
        $_cO = 'None';
      }
      if (exists $_fJ->{$_EW}{'_usedns_'}) {
        print $_EW . ', DNS, ' . $_fJ->{$_EW}{'cartridge'} . ', ' . $_fJ->{$_EW}{'phops'} . ', [Tags: ' . $_cO . ']' . "\n";
      }
      else {
        print $_EW . ', ' . $_fJ->{$_EW}{'address'} . ', ' . $_fJ->{$_EW}{'cartridge'} . ', ' . $_fJ->{$_EW}{'phops'} . ', [Tags: ' . $_cO . ']' . "\n";
      }
    }
  }
  elsif (lc ($_80{'report'}) eq 'detail') {
    my $_2L = 0;
    my @_SR = ('proxy', 'comp_method', 'method_args', 'raw', '_usedns_', '_socks_');

    foreach my $_EW (sort keys %{$_fJ}) {
      if ($_2L++) {
        print "\n";
      }
      print 'Node: ' . $_EW . "\n";
      foreach my $_wJ (sort keys %{$_fJ->{$_EW}}) {
        if ($_wJ !~ m/^enc:/) {
          if (not &_NP (qr/$_wJ/, @_SR)) {
            my $_4b = '<empty>';
            if (ref ($_fJ->{$_EW}{$_wJ}) eq 'ARRAY') {
              if ($#{$_fJ->{$_EW}{$_wJ}} > -1) {
                $_4b = '[' . join (', ', @{$_fJ->{$_EW}{$_wJ}}) . ']';
              }
            }
            else {
              if (length ($_fJ->{$_EW}{$_wJ})) {
                if (($_wJ eq 'address') and (exists $_fJ->{$_EW}{'_usedns_'})) {
                  $_4b = 'DNS';
                }
                elsif (exists $_fJ->{$_EW}{'enc:' . $_wJ}) {
                  $_4b = $_fJ->{$_EW}{'enc:' . $_wJ};
                }
                elsif ($_fJ->{$_EW}{$_wJ} =~ m/^x\|X\|(.+)\|X\|x$/) {
                  $_4b = '<ask>' . $1 . '</ask>';
                }
                else {
                  $_4b = $_fJ->{$_EW}{$_wJ};
                }
              }
            }

            if ($_wJ =~ m/^custom_(.+)/) {
              print '  Custom:' . uc (substr ($1, 0, 1)) . lc (substr ($1, 1)) . ' = ' . $_4b . "\n";
            }
            elsif ($_wJ eq 'snmp_oids') {
              print '  Snmp_oids:' . "\n";

              foreach my $_xb (sort keys %{$_fJ->{$_EW}{'snmp_oids'}}) {
                print '    ' . $_xb . ' = ' . $_fJ->{$_EW}{'snmp_oids'}{$_xb} . "\n";
              }
            }
            else {
              if ($_wJ eq 'phops') {
                $_wJ = 'proxy';
              }

              if (($_wJ eq 'proxy') and (exists $_fJ->{$_EW}{'_socks_'})) {
                print '  ' . uc (substr ($_wJ, 0, 1)) . lc (substr ($_wJ, 1)) . ' = ' . $_4b . ' (SP)' . "\n";
              }
              else {
                print '  ' . uc (substr ($_wJ, 0, 1)) . lc (substr ($_wJ, 1)) . ' = ' . $_4b . "\n";
              }
            }
          }
        }
      }
    }
  }
  else {
    warn ('Error: Unknown report type \'' . $_80{'report'} . '\'' . "\n");
    exit (1);
  }
  print "\n" . 'Total Nodes: ' . (keys %{$_fJ}) . "\n";
  exit;
}

if ($_7l) {
  print "\n";
}

if (exists $_80{'poller'}) {
  if ((not -t STDIN) or (not -t STDOUT)) {
    warn ('Error: Cannot use snmp poller on non-interactive sessions' . "\n");
    exit (1);
  }

  eval { require Net::SNMP };

  if ($@) {
    warn ('Warning: Unable to snmp poll nodes - can\'t locate module Net::SNMP' . "\n");
    exit (1);
  }

  (my $_D1 = $_80{'poller'}) =~ s/\\/\//g;

  if ($_D1 !~ m/^(\/|\.+\/)/) {
    $_D1 = './' . $_D1;
  }

  my $_dT = 0;
  my @_U9 = ();
  foreach my $_EW (sort keys %{$_fJ}) {
    if ($_fJ->{$_EW}{'proxy'} ne 'null') {
      warn ('Warning: [node id = \'' . $_EW . '\'] Skipping node - not using a null proxy (need direct connection)' . "\n");
      $_dT++;
    }
    elsif (not exists $_fJ->{$_EW}{'snmp_oids'}) {
      warn ('Warning: [node id = \'' . $_EW . '\'] Skipping node - attribute \'snmp_oids\' is not defined' . "\n");
      $_dT++;
    }
    else {
      if (length $_80{'poller'}) {
        my ($_0B, $_uM) = &_x0 ($_D1, $_EW, 'null');
        if ($_0B == 10) {
          warn ('Error: Logfile output directory \'' . $_uM . '\' not writable - permission denied' . "\n");
          exit (1);
        }
        elsif ($_0B == 20) {
          if (not exists $_xq{$_uM}) {
            warn ('Warning: Logfile \'' . $_uM . '\' already exists and will be appended' . "\n");
            $_xq{$_uM} = 1;
          }
          $_dT++;
        }
        elsif ($_0B == 30) {
          warn ('Error: Logfile \'' . $_uM . '\' already exists and isn\'t writable - permission denied' . "\n");
          exit (1);
        }
        elsif ($_0B) {
          warn ('Error: Invalid logfile specified' . "\n");
          exit (1);
        }
        $_fJ->{$_EW}{'ofile'} = $_uM;
      }
      push (@_U9, $_EW);
    }
  }

  if ($#_U9 eq -1) {
    warn ('Error: No valid nodes selected' . "\n");
    exit (1);
  }

  if ($_dT) {
    print "\n";
  }

  my ($_bF, $_GT) = (0, 1);

  $SIG{'INT'} = $SIG{'TERM'} = 'IGNORE';
  $SIG{'USR1'} = sub { $_bF = 1 };
  $SIG{'USR2'} = sub { $_GT = 0 };
  $SIG{'CHLD'} = \&_Rd;

  &_yH (__LINE__, undef, '[' . uc (strftime ('%d/%b/%y %H:%M', localtime)) . '] Connecting to Nodes...');

  foreach my $_EW (@_U9) {
    if (not my $_uj = fork) {
      $SIG{'CHLD'} = '';
      
      while (not $_bF) {
        sleep (1);
      }

      my $_XS = undef;
      my %_if = ();

      foreach my $_Ns (sort keys %{$_fJ->{$_EW}{'snmp_oids'}}) {
        $_if{$_fJ->{$_EW}{'snmp_oids'}{$_Ns}}{'id'} = $_Ns;
      }

      my $_pK = 'NaN';
      my $_vM = 0;

      while ($_GT) {
        my $_sy = floor (time / 60);

        if ($_sy > $_vM) {
          if (($_sy > ($_vM + 1)) and $_vM) {
            &_yH (__LINE__, $_fJ->{$_EW}{'ofile'}, '[' . uc (strftime ('%d/%b/%y %H:%M', localtime (($_vM + 1) * 60))) . '] ' . $_EW . ': ' . $_pK);
            $_vM = $_vM + 1;
          }

          if (not defined $_XS) {
            ($_XS, my $_vZ) = Net::SNMP->session (
              -hostname => $_fJ->{$_EW}{'address'},
              -version => '2c',
              -nonblocking => 1,
              -community => $_fJ->{$_EW}{'snmp_community'}
            );
          }

          if (defined $_XS) {
            my $_te = $_XS->get_request (
              -varbindlist => [keys %_if],
              -callback => sub {
                my ($_rg) = @_;

                my $_V1 = $_rg->var_bind_list;
                if (defined $_V1) {
                  my @_ig = ();
                  foreach my $_SD (sort keys %_if) {
                    if (exists $_V1->{$_SD}) {
                      push (@_ig, $_if{$_SD}{'id'} . ': ' . $_V1->{$_SD});
                    }
                  }
                  &_yH (__LINE__, $_fJ->{$_EW}{'ofile'}, '[' . uc (strftime ('%d/%b/%y %H:%M', localtime ($_sy * 60))) . '] ' . $_EW . ': ' . join (', ', @_ig));
                  $_pK = 'OK';
                  $_vM = $_sy;
                }
                else {
                  $_XS->close;
                  $_XS = undef;
                  $_pK = 'NaN';
                }
              }
            );

            if (not defined $_te) {
              if (defined $_XS) {
                $_XS->close;
                $_XS = undef;
              }
              $_pK = 'NaN';
            }
            else {
              Net::SNMP->snmp_dispatcher;
            }
          }
          else {
            $_pK = 'NaN';
          }
          if (not $_vM) {
            $_vM = $_sy - 1;
          }
        }
        if ($_GT) {
          sleep (5);
        }
      }

      if (defined $_XS) {
        $_XS->close;
      }
      exit;
    }
    else {
      $_sw{$_uj} = 1;
      kill ('USR1', $_uj);
    }
  }

  $SIG{'INT'} = $SIG{'TERM'} = sub {
    kill ('USR2', keys %_sw);
  };

  while (keys %_sw) {
    sleep (1);
  }
  exit (0);
}

if (keys %_UF) {
  local $| = 1;

  foreach my $_c7 (sort { $_UF{$a}{'key'} cmp $_UF{$b}{'key'} } (keys %_UF)) {
    if (exists $_UF{$_c7}{'valid'}) {
      if ($_UF{$_c7}{'type'} eq 'password') {
        system ('stty -echo');
      }
      print $_c7 . ': ';

      $_UF{$_c7}{'value'} = <STDIN>;
      if (defined $_UF{$_c7}{'value'}) {
        chop ($_UF{$_c7}{'value'});
      }

      if ($_UF{$_c7}{'type'} eq 'password') {
        system ('stty echo');
        print "\n";
      }
    }
    else {
      delete ($_UF{$_c7});
    }
  }

  if (keys %_UF) {
    print "\n";
    foreach my $_Bw (keys %{$_Qm}) {
      if ($_Bw !~ m/\|/) {
        foreach my $_Ep ('username', 'password') {
          if (exists ($_Qm->{$_Bw}{$_Ep}) and ($_Qm->{$_Bw}{$_Ep} =~ m/^x\|X\|(.+)\|X\|x$/)) {
            if (exists $_UF{$1}) {
              $_Qm->{$_Bw}{$_Ep} = $_UF{$1}{'value'};
            }
          }
        }
        if (exists $_Qm->{$_Bw}{'method_args'}) {
          foreach (my $_7X = 0; $_7X < @{$_Qm->{$_Bw}{'method_args'}}; $_7X++) {
            $_Qm->{$_Bw}{'method_args'}[$_7X] =~ s/x\|X\|(.+)\|X\|x/$_UF{$1}{'value'}/e;
          }
        }
      }
    }

    foreach my $_DN (keys %{$_xT}) {
      foreach my $_Ep ('username', 'password') {
        if (exists ($_xT->{$_DN}{$_Ep}) and ($_xT->{$_DN}{$_Ep} =~ m/^x\|X\|(.+)\|X\|x$/)) {
          if (exists $_UF{$1}) {
            $_xT->{$_DN}{$_Ep} = $_UF{$1}{'value'};
          }
        }
      }
    }

    foreach my $_wN (keys %{$_K2}) {
      if (exists $_K2->{$_wN}{'nodes'}) {
        foreach my $_Ep ('username', 'password') {
          if (exists ($_K2->{$_wN}{$_Ep}) and ($_K2->{$_wN}{$_Ep} =~ m/^x\|X\|(.+)\|X\|x$/)) {
            if (exists $_UF{$1}) {
              $_K2->{$_wN}{$_Ep} = $_UF{$1}{'value'};
            }
          }
        }
      }
    }

    foreach my $_EW (keys %{$_fJ}) {
      foreach my $_Ep (keys %{$_fJ->{$_EW}}) {
        if ($_Ep =~ m/^(username$|password$|custom_)/) {
          if ($_fJ->{$_EW}{$_Ep} =~ m/^x\|X\|(.+)\|X\|x$/) {
            if (exists $_UF{$1}) {
              $_fJ->{$_EW}{$_Ep} = $_UF{$1}{'value'};
            }
          }
        }
        if (exists $_fJ->{$_EW}{'method_args'}) {
          foreach (my $_7X = 0; $_7X < @{$_fJ->{$_EW}{'method_args'}}; $_7X++) {
            $_fJ->{$_EW}{'method_args'}[$_7X] =~ s/x\|X\|(.+)\|X\|x/$_UF{$1}{'value'}/e;
          }
        }
      }
    }
  }
}

unlink ($_Hk);
my $_xL = new IO::Socket::UNIX (Type => SOCK_DGRAM, Local => $_Hk, Listen => SOMAXCONN);
if (not $_xL) {
  warn ('Error: Unable to create unix domain socket \'' . $_Hk . '\' - ' . $! . "\n");
  exit (1);
}

$SIG{'INT'} = $SIG{'TERM'} = sub {
  &_VG ('1');
  $_XA = 1;
};

# ---

my $_CC = time;

&$_pV (__LINE__, undef, &_NG ($0) . ' ' . $_ZE); 

if (exists $_80{'script_version'}) {
  print $_80{'script_version'} . "\n\n";
}

if (defined &post) {
  $_y6 = (6 > $_y6) ? 6 : $_y6;
}
elsif (defined &pre) {
  $_y6 = (5 > $_y6) ? 5 : $_y6;
}

if (defined &pre) {
  my $_4N = undef;

  {
    local $SIG{'ALRM'} = sub {
      die ('ALRM' . "\n");
    };
    no warnings;
    alarm ($_80{'script_timeout'});
    eval {
      $_4N = &pre;
    };
    alarm (0);
  }

  if ($@) {
    if ($@ =~ m/^ALRM/) {
      print '>> S/PRE ' . '.' x (($_y6 - 6) + 2) . ' ' . '[Global] Script Timed Out' . "\n";
      $_80{'script_pre_failure'} = '[Global] Script Timed Out';
    }
    else {
      print '---' . "\n";
      print $@;
      print '---' . "\n";
      print '>> S/PRE ' . '.' x (($_y6 - 5) + 2) . ' ' . '[Global] Script Syntax Error' . "\n";
      $_80{'script_pre_failure'} = '[Global] Script Syntax Error';
    }
  }
  else {
    if (not defined $_4N) {
      print '>> S/PRE ' . '.' x (($_y6 - 5) + 2) . ' ' . '[Global] Unknown Script Error' . "\n";
      $_80{'script_pre_failure'} = '[Global] Unknown Script Error';
    }
    elsif ($_4N =~ m/^100(?::(.+))?$/) {
      if (defined $1) {
        print '>> S/PRE ' . '.' x (($_y6 - 5) + 2) . ' ' . '[Global] OK (' . $1 . ')' . "\n";
      }
      else {
        print '>> S/PRE ' . '.' x (($_y6 - 5) + 2) . ' ' . '[Global] OK' . "\n";
      }
    }
    else {
      print '>> S/PRE ' . '.' x (($_y6 - 5) + 2) . ' ' . '[Global] [CSR] ' . $_4N . "\n";
      $_80{'script_pre_failure'} = '[Global] [CSR] ' . $_4N;
    }
  }
}

my $_6W = 0;
my $_gE = 0;
my %_Ko = ();
my %_iu = ();

$SIG{'CHLD'} = \&_Rd;

my $_8t = undef; 
foreach my $_Bw (sort keys %{$_Qm}) {
  $_8t = (defined $_8t) ? $_8t + 1 : 0;
  if (exists $_Qm->{$_Bw}{'nodes'}) {
    if (pipe (PCHILD, PPARENT)) {
      if (not my $_uj = fork) {
        $SIG{'INT'} = $SIG{'TERM'} = $SIG{'HUP'} = 'IGNORE';
        $SIG{'CHLD'} = \&_RR;
        close ($_xL);
        close (PPARENT);
        <PCHILD>;

        my $_vj = $_Bw;
        my $_BS = undef;
        my @_TC = ();
        my $_Rx = '';
        my $_1m = 0;

        if ($_Bw =~ m/\|/) {
          @_TC = split (m/\|/, $_Bw);
          $_Bw = shift (@_TC);
        }
        elsif (exists $_Qm->{$_Bw}{'socks_supported'}) {
          $_Rx = $_Qm->{$_Bw}{'socks_wrapper'};
        }

        my $_iN = (exists $_Qm->{$_Bw}{'timeout'}) ? $_Qm->{$_Bw}{'timeout'} : $_w2;
        my $_OK = (exists $_Qm->{$_Bw}{'max_proxy_retries'}) ? $_Qm->{$_Bw}{'max_proxy_retries'} : $_wh;
        my $_tI = (exists $_Qm->{$_Bw}{'max_sessions'}) ? $_Qm->{$_Bw}{'max_sessions'} : $_LV;
        my $_iE = (exists $_Qm->{$_Bw}{'min_nodes_per_session'}) ? $_Qm->{$_Bw}{'min_nodes_per_session'} : $_hy;
        my $_zk = ($_iN * 3) + 10;
        my $_Mr = undef;

        if ($_Bw eq 'null' or length ($_Rx)) {
          $_tI = (exists $_Ae->{'max_sessions_null_proxy'}) ? $_Ae->{'max_sessions_null_proxy'} : $_Lb;
          $_iE = (exists $_Ae->{'min_nps_null_proxy'}) ? $_Ae->{'min_nps_null_proxy'} : $_xA;
        }

        my $_NU = $_tI;
        while (($_tI * $_iE) > ($#{$_Qm->{$_vj}{'nodes'}} + 1)) {
          if ($_tI == 1) {
            last;
          }
          $_tI--;
        }

        if ($_Bw =~ m/~$/) {
          if ($_tI == $_NU) {
            $_tI -= 1;
          }
        }

        my $_Hb = floor (($#{$_Qm->{$_vj}{'nodes'}} + 1) / $_tI);
        my $_lx = ($#{$_Qm->{$_vj}{'nodes'}} + 1) - ($_Hb * $_tI) + 1;

        my $_pW = 0;
        my $_qH = 199;
        our $_TL = undef;

        my $_y1 = sub {
          my $_8P = $_Qm->{$_Bw}{'comp_method'};
          my @_e2 = @{$_Qm->{$_Bw}{'method_args'}};
          my $_EK = (exists $_Qm->{$_Bw}{'local_socks_port'}) ? $_Qm->{$_Bw}{'local_socks_port'} : ($_rH + $_8t);

          for (my $_KT = 0; $_KT < $_OK; $_KT++) {
            if (not -e $_r3) {
              $_TL = new Expect;
              (my $_fm = $_Bw) =~ s/~$//;

              if ($_80{'verbose'}) {
                if ($_KT) {
                  if (exists $_Qm->{$_Bw}{'socks_supported'}) {
                    &_Z2 (__LINE__, 'Connecting to Proxy (SP=' . $_EK . ') \'' . $_fm . '\'... (Retry)');
                  }
                  else {
                    &_Z2 (__LINE__, 'Connecting to Proxy \'' . $_fm . '\'... (Retry)');
                  }
                }
                else {
                  if (exists $_Qm->{$_Bw}{'socks_supported'}) {
                    &_Z2 (__LINE__, 'Connecting to Proxy (SP=' . $_EK . ') \'' . $_fm . '\'...');
                  }
                  else {
                    &_Z2 (__LINE__, 'Connecting to Proxy \'' . $_fm . '\'...');
                  }
                }
              }

              unless (exists $_Qm->{$_Bw}{'rawpty'} and (lc ($_Qm->{$_Bw}{'rawpty'}) eq 'no')) {
                $_TL->raw_pty (1);
              }

              $_TL->log_stdout (($_80{'verbose'} > 2) ? 1 : 0);
              $_TL->exp_internal (($_80{'verbose'} > 3) ? 1 : 0);
              $_TL->restart_timeout_upon_receive (1);

              if (not $_TL->spawn ($_8P, @_e2)) {
                $_TL = undef;
                last;
              }

              $_qH = &_X2 (\$_TL, $_iN, undef, $_Bw, $_Bw, undef, $_Qm->{$_Bw}{'username'}, $_Qm->{$_Bw}{'password'}, $_Qm->{$_Bw}{'prompt'}, undef, $_8P);

              if (($_qH == 100) and (exists $_Qm->{$_Bw}{'terminal'})) {
                my $_bo = 101;
                $_TL->send ('export TERM=' . $_Qm->{$_Bw}{'terminal'} . $_Qm->{$_Bw}{'terminator'});
                $_TL->expect ($_iN, [ qr/$_Qm->{$_Bw}{'prompt'}/im, sub { $_bo = 100 } ]);
                $_qH = $_bo;
                if ($_qH != 100) {
                  if (defined $_TL->pid) {
                    kill ('KILL', $_TL->pid);
                  }
                  $_TL = undef;
                }
              }

              my $_7P = $_Bw;
              if (($_qH == 100) and ($#_TC > -1)) {
                foreach my $_Mm (@_TC) {
                  my $_4H = undef;
                  my $_wZ = undef;

                  if ($_80{'verbose'}) {
                    if ($_KT) {
                      &_Z2 (__LINE__, 'Connecting to Proxy \'' . $_Mm . '\'... (Retry)');
                    }
                    else {
                      &_Z2 (__LINE__, 'Connecting to Proxy \'' . $_Mm . '\'...');
                    }
                  }

                  $_iN = (exists $_Qm->{$_Mm}{'timeout'}) ? $_Qm->{$_Mm}{'timeout'} : $_w2;
                  $_Mr = $_Mm;

                  my $_9p = $_Qm->{$_Mm}{'comp_method'};
                  my @_Aa = @{$_Qm->{$_Mm}{'method_args'}};

                  $_TL->send ($_9p . ' ' . join (' ', @_Aa) . $_Qm->{$_7P}{'terminator'});
                  $_qH = &_X2 (\$_TL, $_iN, undef, $_Bw, $_Mm, $_7P, $_Qm->{$_Mm}{'username'}, $_Qm->{$_Mm}{'password'}, $_Qm->{$_Mm}{'prompt'}, undef, $_9p);

                  if (($_qH == 100) and (exists $_Qm->{$_Mm}{'terminal'})) {
                    my $_bo = 101;
                    $_TL->send ('export TERM=' . $_Qm->{$_Mm}{'terminal'} . $_Qm->{$_Mm}{'terminator'});
                    $_TL->expect ($_iN, [ qr/$_Qm->{$_Mm}{'prompt'}/im, sub { $_bo = 100 } ]);
                    $_qH = $_bo;
                    if ($_qH != 100) {
                      if (defined $_TL->pid) {
                        kill ('KILL', $_TL->pid);
                      }
                      $_TL = undef;
                      last;
                    }
                  }
                  if ($_qH != 100) {
                    last;
                  }
                  $_7P = $_Mm;
                }
              }
              if (($_qH == 100) or ($_qH >= 150)) {
                return ($_qH);
              }
            }
            else {
              $_qH = &_6k (100, \$_pW);
              last;
            }
          }
          return ($_qH);
        };

        if (length ($_Rx)) {
          if (pipe (RX, TX)) {
            if (pipe (CHILD, PARENT)) {
              if (not $_BS = fork) {
                my $_iD = 1;
                $SIG{'INT'} = $SIG{'HUP'} = 'IGNORE';
                $SIG{'TERM'} = sub { $_iD = 0 };
                $SIG{'CHLD'} = '';
                close (PARENT);
                close (RX);
                <CHILD>;

                $_1m = (exists $_Qm->{$_Bw}{'local_socks_port'}) ? $_Qm->{$_Bw}{'local_socks_port'} : ($_rH + $_8t);
                unshift (@{$_Qm->{$_Bw}{'method_args'}}, '-D ' . $_1m);

                if (($_qH = &$_y1) == 100) {
                  syswrite (TX, '199' . "\n");

                  while ($_iD) {
                    sleep (1);
                  }

                  if (exists $_Qm->{$_Bw}{'logout_cmd'}) {
                    $_TL->send ($_Qm->{$_Bw}{'logout_cmd'} . $_Qm->{$_Bw}{'terminator'});
                  }
                  else {
                    if ($_Bw ne 'null') {
                      $_TL->send ($_ch . $_Qm->{$_Bw}{'terminator'});
                    }
                  }
                  $_TL->soft_close;
                }
                else {
                  syswrite (TX, $_qH . "\n");
                }
                exit;
              }
              else {
                close (CHILD);
                $_iu{$_BS} = 1;
                close (PARENT);
              }
            }
            close (TX);

            $_qH = 101;
            my $_GR = new IO::Select (\*RX);
            for (my $_c7 = 0; $_c7 < $_zk; $_c7++) {
              if ($_GR->can_read (1)) {
                $_qH = <RX>;
                last;
              }
            }
            $_GR->remove (\*RX);
          }
        }

        my $_iv = new IO::Socket::UNIX (Type => SOCK_DGRAM, Peer => $_Hk, Timeout => 5);
        if (not $_iv) {
          warn ('Warning: Unable to connect to unix domain socket \'' . $_Hk . '\' - ' . $! . "\n");
        }
        else {
          if ($_qH != 199) {
            foreach my $_EW (@{$_Qm->{$_vj}{'nodes'}}) {
              while (not $_iv->send ($$ . '|' . $_EW . '|' . $_qH)) {
                sleep (1);
              }
            }
          }
          else {
            for (my ($_7X, $_7U) = (0, 0); $_7X < $_tI; $_7X++, $_7U += ($_Hb + ($_lx ? 1 : 0))) {
              if ($_lx) {
                $_lx--;
              }

              if (pipe (CHILD, PARENT)) {
                if (not my $_uj = fork) {
                  $SIG{'INT'} = $SIG{'TERM'} = $SIG{'HUP'} = 'IGNORE';
                  $SIG{'CHLD'} = '';
                  close (PARENT);
                  <CHILD>;

                  my $_wJ = 0;
                  OLOOP: for (; $_wJ < ($_Hb + ($_lx ? 1 : 0)); $_wJ++, $_7U++) {
                    my $_EW = $_Qm->{$_vj}{'nodes'}[$_7U];
                    my $_51 = (exists $_fJ->{$_EW}{'max_node_retries'}) ? $_fJ->{$_EW}{'max_node_retries'} : $_ea;
                    our $_x9 = (exists $_fJ->{$_EW}{'timeout'}) ? $_fJ->{$_EW}{'timeout'} : $_HD;
                    my $_PD = undef;
                    $_Mr = $_Bw;

                    if (exists $_80{'script_pre_failure'}) {
                      $_qH = 217;
                      last (OLOOP);
                    }

                    if (not -e $_r3) {
                      if (length ($_Rx)) {
                        $_1m = (exists $_Qm->{$_Bw}{'local_socks_port'}) ? $_Qm->{$_Bw}{'local_socks_port'} : ($_rH + $_8t);
                        $_Bw = 'null';
                        unshift (@{$_fJ->{$_EW}{'method_args'}}, '-o ProxyCommand ' . $_Rx . ' -S 127.0.0.1:' . $_1m . ' %h %p');
                      }

                      if (not $_PD) {
                        my $_kh = $_fJ->{$_EW}{'comp_method'};
                        my @_HC = @{$_fJ->{$_EW}{'method_args'}};

                        ILOOP: for (my $_ec = 0; $_ec < $_51; $_ec++) {
                          $_PD = undef;
                          if (not -e $_r3) {
                            our $_8X = $_RM->{$_fJ->{$_EW}{'cartridge'}}{'terminator'};
                            our $_kW = $_RM->{$_fJ->{$_EW}{'cartridge'}}{'prompt'};
                            $_kW = &_G7 ($_kW, $_EW, $_Mr, 1, 0);

                            my $_v1 = sub {
                              $_PD = $_[0];
                              if (defined $_TL->pid) {
                                kill ('KILL', $_TL->pid);
                              }
                              $_TL = undef;
                            };

                            my $_Ku = sub {
                              if ($_80{'verbose'}) {
                                my @_Vn = split ($_IV, $_TL->before);
                                if ($#_Vn > -1) {
                                  &_Z2 (__LINE__, 'Node \'' . $_EW . '\' - Unmatched Last Line: \'' . $_Vn[-1] . '\'');
                                }
                              }
                              &$_v1 (103);
                            };

                            if ((not $_TL) and ($_Bw ne 'null') and (not length ($_Rx))) {
                              if (($_qH = &$_y1) != 100) {
                                last (OLOOP);
                              }
                            }

                            if (exists $_80{'script'}) {
                              my $_Uv = sub {
                                my $_Yu = 154;
                                foreach my $_Rf (@{$_80{'script_criteria'}}) {
                                  my ($_n3, $_JK) = split (m/\s*::\s*/, $_Rf);

                                  if ($_EW =~ $_JK) {
                                    if (&_in ($_n3, @{$_fJ->{$_EW}{'tag'}})) {
                                      $_Yu = 0;
                                    }
                                  }
                                  if (not $_Yu) {
                                    last;
                                  }
                                }
                                return ($_Yu);
                              };
                              my $_Of = &$_Uv;
                              if ($_Of) {
                                $_PD = $_Of;
                              }
                            }

                            if (not -e $_r3) {
                              if (not defined $_PD) {
                                if ($_80{'verbose'}) {
                                  if ($_ec) {
                                    if (length $_Rx) {
                                      &_Z2 (__LINE__, 'Connecting to Node (via SP:' . $_1m . ') \'' . $_EW . '\'... (Retry)');
                                    }
                                    else {
                                      &_Z2 (__LINE__, 'Connecting to Node \'' . $_EW . '\'... (Retry)');
                                    }
                                  }
                                  else {
                                    if (length $_Rx) {
                                      &_Z2 (__LINE__, 'Connecting to Node (via SP:' . $_1m . ') \'' . $_EW . '\'...');
                                    }
                                    else {
                                      &_Z2 (__LINE__, 'Connecting to Node \'' . $_EW . '\'...');
                                    }
                                  }
                                }

                                if ($_Bw eq 'null') {
                                  $_TL = new Expect;
                                  $_PD = 198;

                                  unless (exists $_fJ->{$_EW}{'rawpty'} and (lc ($_fJ->{$_EW}{'rawpty'}) eq 'no')) {
                                    $_TL->raw_pty (1);
                                  }

                                  $_TL->log_stdout (($_80{'verbose'} > 2) ? 1 : 0);
                                  $_TL->exp_internal (($_80{'verbose'} > 3) ? 1 : 0);
                                  $_TL->restart_timeout_upon_receive (1);

                                  if (not $_TL->spawn ($_kh, @_HC)) {
                                    $_TL = undef;
                                    last;
                                  }
                                }
                                else {
                                  $_TL->send ($_kh . ' ' . join (' ', @_HC) . $_Qm->{$_Mr}{'terminator'});
                                }

                                if (exists $_RM->{$_fJ->{$_EW}{'cartridge'}}{'pre_login_seq'}) {
                                  sleep ($_xh);
                                  $_TL->send ($_RM->{$_fJ->{$_EW}{'cartridge'}}{'pre_login_seq'});
                                }

                                $_PD = &_X2 (\$_TL, $_x9, $_EW, $_Bw, $_Mr, undef, $_fJ->{$_EW}{'username'}, $_fJ->{$_EW}{'password'}, $_kW, $_8X, $_kh);
                              }

                              if ($_PD == 100) {
                                if ($_80{'verbose'}) {
                                  &_Z2 (__LINE__, 'Connected to Node \'' . $_EW . '\'');
                                }

                                $_kW = (index ($_kW, ' :!: ') > 0) ? substr ($_kW, 0, index ($_kW, ' :!: ')) : $_kW;

                                if (exists $_RM->{$_fJ->{$_EW}{'cartridge'}}{'pre'}) {
                                  foreach my $_85 (@{$_RM->{$_fJ->{$_EW}{'cartridge'}}{'pre'}}) {
                                    my %_5E = ();
                                    my ($_lP, $_85) = &_ih ($_85, $_EW, $_Bw, undef, undef, \%_5E, $_8X);

                                    if ($_85 =~ m/^(.+?)(\s\((.+)\))?$/) {
                                      ($_85, my $_6r) = (defined $3) ? ($1, $3) : ($1, undef);
                                      if (defined $_6r) {
                                        $_kW = &_G7 ($_6r, $_EW, $_Bw, 1, 0);
                                      }

                                      &$_pV (__LINE__, $_EW, $_85);
                                      $_TL->send ($_85 . $_8X);
                                      push (@{$_lP}, [qr/$_kW/im, sub { }]);
                                      $_TL->expect ($_x9, [ timeout => \&$_Ku ], @{$_lP}) or next (ILOOP);
                                    }
                                  }
                                }

                                if (not -e $_r3) {
                                  if (exists $_80{'script'}) {
                                    our %_4G = ();
                                    $_4G{'node'} = $_EW;
                                    $_4G{'proxy'} = (length ($_Rx)) ? $_Mr : $_Bw;
                                    our ($_PX, $_R6) = (0, 0);

                                    {
                                      package ScriptObject;

                                      sub new {
                                        my $_po = shift;
                                        my $_N2 = bless ({@_}, $_po);
                                        return ($_N2);
                                      }

                                      sub cmd {
                                        my ($_N2, $_Fo, %_lD) = @_;

                                        if ((caller (1))[3] ne 'main::main') {
                                          warn ('Warning: ScriptObject->cmd() can only be called from script subroutine \'main\'' . "\n");
                                          return (undef);
                                        }

                                        my $_cD = sub {
                                          if ($_80{'verbose'}) {
                                            my @_Vn = split ($_IV, $_TL->before);
                                            if ($#_Vn > -1) {
                                              &main::log (__LINE__, 'Node \'' . $_4G{'node'} . '\' - Unmatched Last Line: \'' . $_Vn[-1] . '\'');
                                            }
                                          }
                                        };

                                        $_lD{'Timeout'} = (exists $_lD{'Timeout'}) ? $_lD{'Timeout'} : $_x9;
                                        $_lD{'Prompt'} = (exists $_lD{'Prompt'}) ? $_lD{'Prompt'} : $_kW;

                                        &$_pV (__LINE__, $_4G{'node'}, $_Fo);

                                        my $_kC = '';
                                        $_TL->clear_accum;
                                        $_TL->send ($_Fo . $_8X);

                                        if (not $_TL->expect ($_lD{'Timeout'},
                                            [ qr/$_lD{'Prompt'}/im ],
                                            [ qr/^.{1024,}\r*\n/os, sub {
                                              my $_N2 = shift;

                                              my $_s1 = $_N2->match;
                                              $_s1 =~ s/$_IV/$_Ae->{'terminator'}/osg;
                                              $_kC .= $_s1;

                                              if ($_gY) {
                                                if (length ($_kC) >= ($_gY * 1024)) {
                                                  $_PD = 156;
                                                  return;
                                                }
                                              }
                                              return ($_N2->exp_continue_timeout);
                                            } 
                                            ],
                                            [ timeout => \&$_cD ]
                                          )) {
                                          $_PD = 103;
                                          goto (_END_EVAL_);
                                        }

                                        if ($_PD == 156) {
                                          goto (_END_EVAL_);
                                        }

                                        my $_s1 = $_TL->before;
                                        $_s1 =~ s/$_IV/$_Ae->{'terminator'}/sg;
                                        $_kC .= $_s1;

                                        &main::_rE ($_fJ->{$_EW}{'raw'}, $_Ae->{'terminator'}, \$_kC);

                                        return ((wantarray) ? split (m/$_Ae->{'terminator'}/, $_kC) : $_kC);
                                      }

                                      sub svar {
                                        my ($_N2, $_dp) = @_;
                                        return (exists $_80{'script_options'}{lc $_dp}) ? $_80{'script_options'}{lc $_dp} : undef;
                                      }

                                      sub dvar {
                                        my ($_N2, $_dp) = @_;

                                        if ((caller (1))[3] ne 'main::main') {
                                          if ($_dp !~ m/^(pid|date|time)$/i) {
                                            warn ('Warning: ScriptObject->dvar(\'' . $_dp . '\') can only be called from script subroutine \'main\'' . "\n");
                                            return (undef);
                                          }
                                        }

                                        return (&$_34 ($_dp, $_4G{'node'}, $_4G{'proxy'}, 0));
                                      }

                                      sub break {
                                        my ($_N2) = @_;

                                        return ((-e $_r3) and (-s $_r3 == 1)) ? 1 : 0;
                                      }

                                      sub lock {
                                        my ($_N2, $_bu) = @_;

                                        $_bu = (defined $_bu) ? $_bu : 5;
                                        for (my $_7X = 0; $_7X < $_bu; $_7X++) {
                                          return (1) if (mkdir ($_wK . 'S', 0000));
                                          sleep (1) if ($_7X != ($_bu - 1));
                                        }
                                        return (0);
                                      }

                                      sub unlock {
                                        my ($_N2) = @_;

                                        rmdir ($_wK . 'S') or warn ($!);
                                      }

                                      sub create_config_tree {
                                        my ($_N2, $_nE) = @_;
                                        my @_sy = ();

                                        my %_JU = ();
                                        my ($_H6, $_S9) = (0, 0);
                                        my ($_7i, $_Ax) = (0, undef);
                                        my %_yh = ();
                                        my $_Iy = undef;
                                        my $_ec = undef;

                                        if (not length (ref $_nE)) {
                                          if (open (my $_xy, '<', $_nE)) {
                                            @_sy = <$_xy>;
                                            close ($_xy);
                                            $_nE = \@_sy;
                                          }
                                          else {
                                            return (undef);
                                          }
                                        }

                                        foreach my $_nz (@{$_nE}) {
                                          if (defined $_Ax or $_nz !~ m/^\s*(?:!|#)/) {
                                            my $_32 = undef;
                                            if (defined $_Ax) {
                                              ($_ec = $_nz) =~ s/^(\s*)(.*?)\s*$/$1$2/;
                                              $_32 = length ($1);
                                            }
                                            else {
                                              ($_ec = $_nz) =~ s/^(\s*)(.*?)\s*$/$2/;
                                              $_32 = length ($1);
                                            }

                                            chomp ($_ec);
                                            if (length $_ec) {
                                              if ($_ec =~ m/^(banner\s+\S+)\s+(\^?\S)(.*?)(\2)?$/) {
                                                $_Ax = (defined $4) ? undef : $2;

                                                $_Iy = \%_yh;
                                                $_Iy->{$1}{'_parent'} = $_Iy;
                                                $_Iy = $_Iy->{$1};
                                                $_7i = 65;

                                                if (length $3) {
                                                  $_Iy->{'[|' . chr ($_7i++) . '|]' . $3}{'_parent'} = $_Iy;
                                                }
                                              }
                                              elsif (defined $_Ax) {
                                                if ($_ec =~ m/(.+?)?\Q$_Ax\E$/) {
                                                  if (defined $1) {
                                                    $_Iy->{'[|' . chr ($_7i) . '|]' . $1}{'_parent'} = $_Iy;
                                                  }
                                                  $_Ax = undef;
                                                }
                                                else {
                                                  $_Iy->{'[|' . chr ($_7i++) . '|]' . $_ec}{'_parent'} = $_Iy;
                                                }
                                              }
                                              else {
                                                if ($_ec !~ m/^(exit|end)/i) {
                                                  if (not $_32) {
                                                    %_JU = (0 => 0);
                                                    $_Iy = \%_yh;
                                                  }
                                                  if ($_32 > $_S9) {
                                                    $_JU{$_32} = ++$_H6;
                                                  }
                                                  elsif ($_32 < $_S9) {
                                                    $_H6 = (exists $_JU{$_32}) ? $_JU{$_32} : $_JU{$_S9};
                                                    if ($_32) {
                                                      for (my $_7X = 0; $_7X < ($_JU{$_S9} - $_H6) + 1; $_7X++) {
                                                        $_Iy = $_Iy->{'_parent'};
                                                      }
                                                    }
                                                  }
                                                  elsif ($_32) {
                                                    $_Iy = $_Iy->{'_parent'};
                                                  }
                                                  if (not exists $_Iy->{$_ec}) {
                                                    $_Iy->{$_ec}{'_parent'} = $_Iy;
                                                  }
                                                  $_Iy = $_Iy->{$_ec};
                                                  $_S9 = $_32;
                                                }
                                              }
                                            }
                                          }
                                        }
                                        return (\%_yh);
                                      }

                                      sub output_config_tree {
                                        my ($_N2, $_4a, $_xy, $_H6) = @_;

                                        $_H6 = 0 if (not defined $_H6);
                                        foreach my $_vK (sort keys %{$_4a}) {
                                          if ($_vK !~ m/^_parent$/) {
                                            $_vK =~ s/^\[\|[A-Z]\|\]//;

                                            if (defined $_xy) {
                                              print $_xy ' ' x $_H6 . $_vK . "\n";
                                            }
                                            else {
                                              print ' ' x $_H6 . $_vK . "\n";
                                            }
                                            if (keys (%{$_4a->{$_vK}}) ne 1) {
                                              &output_config_tree ($_N2, $_4a->{$_vK}, $_xy, $_H6 + 1);
                                            }
                                          }
                                        }
                                      }

                                      sub _za {
                                        my ($_N2, $_aj, $_Lz) = @_;

                                        foreach my $_vK (keys %{$_aj}) {
                                          if ($_vK !~ m/^_parent$/) {
                                            if (exists $_Lz->{$_vK}) {
                                              &_za ($_N2, $_aj->{$_vK}, $_Lz->{$_vK});
                                              if ((keys (%{$_aj->{$_vK}}) eq 1) and (keys (%{$_Lz->{$_vK}}) eq 1)) {
                                                delete ($_aj->{$_vK});
                                                delete ($_Lz->{$_vK});
                                              }
                                            }
                                          }
                                        }
                                      }

                                      sub _wg {
                                        my ($_N2, $_aj, $_Lz, $_nf, $_qb) = @_;

                                        foreach my $_vK (keys %{$_aj}) {
                                          if ($_vK !~ m/^_parent$/) {
                                            if (exists $_Lz->{$_vK}) {
                                              $_qb->{'|' . $_vK} ||= {};
                                              if (keys (%{$_aj->{$_vK}}) ne 1) {
                                                &_wg ($_N2, $_aj->{$_vK}, $_Lz->{$_vK}, $_nf, $_qb->{'|' . $_vK});
                                              }
                                            }
                                            else {
                                              $_qb->{$_nf . $_vK} = {};
                                              if (keys (%{$_aj->{$_vK}}) ne 1) {
                                                &_wg ($_N2, $_aj->{$_vK}, $_Lz->{$_vK}, $_nf, $_qb->{$_nf . $_vK});
                                              }
                                            }
                                          }
                                        }
                                      }

                                      sub diff_configs {
                                        my ($_N2, $_vY, $_KC) = @_;

                                        my %_qb = ();
                                        &_za ($_N2, $_vY, $_KC);
                                        &_wg ($_N2, $_vY, $_KC, '-', \%_qb);
                                        &_wg ($_N2, $_KC, $_vY, '+', \%_qb);
                                        return (\%_qb);
                                      }

                                      sub output_config_diff {
                                        my ($_N2, $_rA, $_xy, $_H6) = @_;

                                        if ((caller (1))[3] ne (caller (0))[3]) {
                                          $_R6 = 0;
                                          $_PX = 0;
                                        }

                                        $_H6 = 0 if (not defined $_H6);
                                        foreach my $_vK (
                                          map { $_->[1] }
                                          sort { $a->[0] cmp $b->[0] } 
                                          map { [ substr ($_, 1), $_ ] } 
                                          keys %{$_rA}
                                        ) {
                                          if (not $_H6 and $_R6) {
                                            if ($_PX or keys (%{$_rA->{$_vK}})) {
                                              if (defined $_xy) {
                                                print $_xy "\n";
                                              }
                                              else {
                                                print "\n";
                                              }
                                            }
                                          }

                                          $_R6++;
                                          $_PX = $_H6;

                                          if ($_vK =~ m/^([+|-])(?:\[\|[A-Z]\|\])?(.*)/) {
                                            my $_Gb = ($1 ne '|') ? $1 : ' ';
                                            if (defined $_xy) {
                                              print $_xy $_Gb . ' ' x ($_H6 + 1) . $2 . "\n";
                                            }
                                            else {
                                              print $_Gb . ' ' x ($_H6 + 1) . $2 . "\n";
                                            }
                                          }
                                          else {
                                            warn;
                                          }

                                          if (keys (%{$_rA->{$_vK}})) {
                                            &output_config_diff ($_N2, $_rA->{$_vK}, $_xy, $_H6 + 1);
                                          }
                                        }
                                      }
                                    }

                                    if (-e $_r3) {
                                      $_PD = &_6k (0, \$_pW);
                                    }
                                    else {
                                      my $_5A = undef;
                                      my $_9g = 0;

                                      {
                                        local $SIG{'ALRM'} = sub {
                                          die ('ALRM' . "\n");
                                        };
                                        no warnings;
                                        alarm ($_80{'script_timeout'});
                                        eval {
                                          $_5A = &main;
                                        };
                                        $_9g = 1;
                                        _END_EVAL_:
                                        alarm (0);
                                        if (not $_9g) {
                                          $_5A = $_PD;
                                        }
                                      }

                                      if ($@) {
                                        if ($@ =~ m/^ALRM/) {
                                          &$_v1 (160);
                                        }
                                        else {
                                          my $_Yf = $@;
                                          my $_Xl = '/tmp/.ns4-' . $$ . '.' . lc ($_EW) . '.syntax';
                                          if (sysopen (my $_EZ, $_Xl, O_WRONLY|O_CREAT)) {
                                            syswrite ($_EZ, $_Yf);
                                            close ($_EZ);
                                          }
                                          &$_v1 (159);
                                        }
                                        last;
                                      }
                                      else {
                                        if (defined $_5A) {
                                          $_PD = $_5A;
                                          if ($_PD !~ m/\D/) {
                                            if ($_PD == 103) {
                                              &$_v1 (103);
                                              last;
                                            }
                                            elsif ($_PD == 156) {
                                              &$_v1 (156);
                                              last;
                                            }
                                            elsif ($_PD != 100) {
                                              $_PD = '501:' . $_PD;
                                            }
                                          }
                                          else {
                                            if ($_PD !~ m/^100:.+$/) {
                                              $_PD = '501:' . $_PD;
                                            }
                                          }
                                        }
                                        else {
                                          &$_v1 ('500:Unknown Script Error');
                                          last;
                                        }
                                      }
                                    }
                                  }
                                  else {
                                    my @_1p = ();
                                    if (not exists $_80{'test'}) {
                                      if (exists $_80{'command'}) {
                                        @_1p = split (m/\s*,\s*/, $_80{'command'});
                                      }
                                      elsif (exists $_80{'list'}) {
                                        foreach my $_85 (@{$_80{'list'}}) {
                                          push (@_1p, $_85);
                                        }
                                      }
                                      elsif (exists $_fJ->{$_EW}{'command'}) {
                                        foreach my $_85 (@{$_fJ->{$_EW}{'command'}}) {
                                          push (@_1p, $_85);
                                        }
                                      }
                                    }

                                    if ($#_1p > -1) {
                                      CLOOP: foreach my $_85 (@_1p) {
                                        if ($_85 =~ m/^{(.+?)(\s*,\s*(.+))?}$/) {
                                          my $_9Q = $_RM->{$_fJ->{$_EW}{'cartridge'}}{'prompt'};
                                          $_9Q = (index ($_9Q, ' :!: ') > 0) ? substr ($_9Q, 0, index ($_9Q, ' :!: ')) : $_9Q;
                                          ($_85, my $_6r) = (defined $3) ? ($1, $3) : ($1, $_9Q);
                                          $_kW = &_G7 ($_6r, $_EW, $_Bw, 1, 0);

                                          &$_pV (__LINE__, $_EW, $_85);
                                          $_TL->send ($_85 . $_8X);
                                          $_TL->expect ($_x9, [ timeout => \&$_Ku ], [ qr/$_kW/im ]) or next (ILOOP);
                                        }
                                        elsif ($_85 =~ m/^(.+?)(\s*\((.+)\))?$/) {
                                          ($_85, my $_r7) = (defined $3) ? ($1, $3) : ($1, $1);

                                          &$_pV (__LINE__, $_EW, $_85);

                                          my $_kC = '';
                                          $_TL->clear_accum;
                                          $_TL->send ($_85 . $_8X);
                                          $_TL->expect ($_x9,
                                            [ qr/$_kW/im ],
                                            [ qr/^.{1024,}\r*\n/os, sub {
                                              my $_N2 = shift;

                                              my $_s1 = $_N2->match;
                                              $_s1 =~ s/$_IV/$_Ae->{'terminator'}/osg;
                                              $_kC .= $_s1;

                                              if ($_gY) {
                                                if (length ($_kC) >= ($_gY * 1024)) {
                                                  $_PD = 156;
                                                  return;
                                                }
                                              }
                                              return ($_N2->exp_continue_timeout);
                                            } 
                                            ],
                                            [ timeout => \&$_Ku ]
                                          ) or next (ILOOP);

                                          if ($_PD == 156) {
                                            &$_v1 (156);
                                            last (ILOOP);
                                          }

                                          my $_s1 = $_TL->before;
                                          $_s1 =~ s/$_IV/$_Ae->{'terminator'}/sg;
                                          $_kC .= $_s1;

                                          &_rE ($_fJ->{$_EW}{'raw'}, $_Ae->{'terminator'}, \$_kC);

                                          if (length $_kC) {
                                            my $_05 = $_EW . '.' . strftime ('%Y%m%d', localtime) . '.txt';
                                            my $_kg = strftime ('%Y%m%d', localtime) . '/' . $_fJ->{$_EW}{'location'} . '/' . $_r7;
                                            my $_gq = ($_85 ne $_r7) ? $_r7 . ' [' . $_85 . ']' : $_85;
                                            $_kg =~ s/\/+/\//g;

                                            $_kC = '--- ' . $_EW . ' (' . $_gq . ') - ' . strftime ($_9X, localtime) . ' ---' . $_Ae->{'terminator'} . $_Ae->{'terminator'} . $_kC;

                                            if (exists $_80{'file'}) {
                                              if ((not -e $_r3) or ((-s $_r3 != 3) and (-s $_r3 != 4))) {
                                                if (not &_G4 (0)) {
                                                  &_VG ('4444');
                                                  $_PD = 108;
                                                  last (CLOOP);
                                                }
                                                my ($_Qi, $_sr) = ($_fJ->{$_EW}{'ofile'} =~ m/^(.*\/)(.+)$/);
                                                if (not -d $_Qi) {
                                                  if (not mkpath ($_Qi)) {
                                                    &_VG ('333');
                                                    $_PD = 107;
                                                    &_PH (0);
                                                    last (CLOOP);
                                                  }
                                                }
                                                my $_Zs = (-e $_fJ->{$_EW}{'ofile'}) ? 1 : 0;
                                                if (sysopen (my $_xy, $_fJ->{$_EW}{'ofile'}, O_WRONLY|O_CREAT|O_APPEND, 0600)) {
                                                  if ($_Zs) {
                                                    syswrite ($_xy, $_Ae->{'terminator'} . $_Ae->{'terminator'});
                                                  }
                                                  syswrite ($_xy, $_kC);
                                                  close ($_xy);
                                                }
                                                else {
                                                  &_VG ('333');
                                                  $_PD = 107;
                                                  &_PH (0);
                                                  last (CLOOP);
                                                }
                                                &_PH (0);
                                              }
                                              else {
                                                $_PD = &_6k (0, \$_pW);
                                              }
                                            }
                                            else {
                                              my $_7m = '/tmp/.ns4-' . $$ . '.' . lc ($_EW) . '.tmp';
                                              if (sysopen (my $_Hd, $_7m, O_WRONLY|O_CREAT)) {
                                                syswrite ($_Hd, $_kC);
                                                close ($_Hd);
                                              }
                                              else {
                                                $_PD = 110;
                                                last (CLOOP);
                                              }

                                              if (exists $_fJ->{$_EW}{'gpg_keyid'}) {
                                                if (open (my $_U6, '<', $_Ae->{'gpg_path'} . ' --status-fd 1 -r ' . join (' -r ', @{$_fJ->{$_EW}{'gpg_keyid'}}) . ' -ea --batch --output ' . $_7m . '.gpg ' . $_7m . ' 2>/dev/null |')) {
                                                  my $_z6 = 0;
                                                  while (<$_U6>) {
                                                    if (m/END_ENCRYPTION/i) {
                                                      $_z6 = 1;
                                                      last;
                                                    }
                                                  }
                                                  close ($_U6);
                                                  if (not $_z6) {
                                                    unlink ($_7m);
                                                    $_PD = 112;
                                                    last (CLOOP);
                                                  }
                                                  unlink ($_7m);
                                                  $_7m .= '.gpg';
                                                  $_05 .= '.gpg';
                                                }
                                                else {
                                                  unlink ($_7m);
                                                  $_PD = 111;
                                                  last (CLOOP);
                                                }
                                              }

                                              if ((not -e $_r3) or (-s $_r3 != 2)) {
                                                foreach my $_xH (@{$_fJ->{$_EW}{'transport'}}) {
                                                  if (lc ($_xT->{$_xH}{'type'}) eq 'ftp') {
                                                    my $_Yr = (exists $_xT->{$_xH}{'max_retries'}) ? $_xT->{$_xH}{'max_retries'} : $_zV;

                                                    my $_ou = sub {
                                                      for (my $_7U = 0; $_7U < $_Yr; $_7U++) {
                                                        if ($_7U) {
                                                          sleep (int (rand (4)) + 1);
                                                        }

                                                        my $_De = new Net::FTP ($_xT->{$_xH}{'address'}, Passive => 1, Timeout => ($_CA + 5));

                                                        my $_X0 = sub {
                                                          local $SIG{'ALRM'} = sub {
                                                            die ('ALRM' . "\n");
                                                          };

                                                          alarm ($_CA);
                                                          my $_Y7 = eval ($_[0]);
                                                          alarm (0);
                                                          if ($@) {
                                                            if ($@ =~ m/^ALRM/) {
                                                              return (100);
                                                            }
                                                            $_Y7 = undef;
                                                          }
                                                          return (($_Y7) ? 0 : 1);
                                                        };

                                                        if (not $_De and ($_7U == ($_Yr - 1))) {
                                                          return ('500:Transport \'' . $_xH . '\' Failed - Connection Refused');
                                                        }
                                                        elsif ($_De) {
                                                          my $_1I = &$_X0 ('$_De->login ($_xT->{$_xH}{\'username\'}, $_xT->{$_xH}{\'password\'})');
                                                          if ($_1I == 100) {
                                                            if ($_7U == ($_Yr - 1)) {
                                                              return ('500:Transport \'' . $_xH . '\' Failed - Connection Timed Out');
                                                            }
                                                            else {
                                                              next;
                                                            }
                                                          }
                                                          elsif ($_1I == 1) {
                                                            $_De->quit;
                                                            return ('500:Transport \'' . $_xH . '\' Failed - Invalid Credentials');
                                                          }

                                                          $_1I = &$_X0 ('$_De->ascii');
                                                          if ($_1I == 100) {
                                                            if ($_7U == ($_Yr - 1)) {
                                                              return ('500:Transport \'' . $_xH . '\' Failed - Connection Timed Out');
                                                            }
                                                            else {
                                                              next;
                                                            }
                                                          }
                                                          elsif ($_1I == 1) {
                                                            $_De->quit;
                                                            return ('500:Transport \'' . $_xH . '\' Failed - ASCII Mode Failed');
                                                          }

                                                          $_1I = &$_X0 ('$_De->cwd ($_kg)');
                                                          if ($_1I == 100) {
                                                            if ($_7U == ($_Yr - 1)) {
                                                              return ('500:Transport \'' . $_xH . '\' Failed - Connection Timed Out');
                                                            }
                                                            else {
                                                              next;
                                                            }
                                                          }
                                                          elsif ($_1I == 1) {
                                                            $_1I = &$_X0 ('$_De->mkdir ($_kg, 1)');
                                                            if ($_1I == 100) {
                                                              if ($_7U == ($_Yr - 1)) {
                                                                return ('500:Transport \'' . $_xH . '\' Failed - Connection Timed Out');
                                                              }
                                                              else {
                                                                next;
                                                              }
                                                            }
                                                            elsif ($_1I == 1) {
                                                              $_De->quit;
                                                              return ('500:Transport \'' . $_xH . '\' Failed - Permission Denied');
                                                            }
                                                            else {
                                                              $_1I = &$_X0 ('$_De->cwd ($_kg)');
                                                              if ($_1I == 100) {
                                                                if ($_7U == ($_Yr - 1)) {
                                                                  return ('500:Transport \'' . $_xH . '\' Failed - Connection Timed Out');
                                                                }
                                                                else {
                                                                  next;
                                                                }
                                                              }
                                                              elsif ($_1I == 1) {
                                                                $_De->quit;
                                                                return ('500:Transport \'' . $_xH . '\' Failed - Permission Denied');
                                                              }
                                                            }
                                                          }

                                                          $_1I = &$_X0 ('$_De->put ($_7m, $_05)');
                                                          if ($_1I == 100) {
                                                            if ($_7U == ($_Yr - 1)) {
                                                              return ('500:Transport \'' . $_xH . '\' Failed - Connection Timed Out');
                                                            }
                                                            else {
                                                              next;
                                                            }
                                                          }
                                                          elsif ($_1I == 1) {
                                                            $_1I = &$_X0 ('$_De->delete ($_05)');
                                                            if ($_1I == 100) {
                                                              if ($_7U == ($_Yr - 1)) {
                                                                return ('500:Transport \'' . $_xH . '\' Failed - Connection Timed Out');
                                                              }
                                                              else {
                                                                next;
                                                              }
                                                            }
                                                            else {
                                                              $_De->quit;
                                                              next;
                                                            }
                                                          }
                                                          $_De->quit;
                                                          return (100);
                                                        }
                                                      }
                                                      return ('500:Transport \'' . $_xH . '\' Failed - Transfer Failed');
                                                    };
                                                    $_PD = &$_ou;
                                                    if (($_PD =~ m/\D/) or ($_PD != 100)) {
                                                      unlink ($_7m);
                                                      last (CLOOP);
                                                    }
                                                  }
                                                  elsif (lc ($_xT->{$_xH}{'type'}) eq 'sftp') {
                                                    my $_Yr = (exists $_xT->{$_xH}{'max_retries'}) ? $_xT->{$_xH}{'max_retries'} : $_zV;

                                                    my $_bz = sub {
                                                      for (my $_7U = 0; $_7U < $_Yr; $_7U++) {
                                                        if ($_7U) {
                                                          sleep (int (rand (4)) + 1);
                                                        }

                                                        my $_De = new Net::SSH2;

                                                        my $_B4 = sub {
                                                          local $SIG{'ALRM'} = sub {
                                                            die ('ALRM' . "\n");
                                                          };

                                                          alarm ($_vl);
                                                          my $_Y7 = eval ($_[0]);
                                                          alarm (0);
                                                          if ($@) {
                                                            if ($@ =~ m/^ALRM/) {
                                                              return (100);
                                                            }
                                                            $_Y7 = undef;
                                                          }
                                                          return (($_Y7) ? 0 : 1);
                                                        };

                                                        my $_1I = &$_B4 ('$_De->connect ($_xT->{$_xH}{\'address\'})');
                                                        if ($_1I == 100) {
                                                          if ($_7U == ($_Yr - 1)) {
                                                            return ('500:Transport \'' . $_xH . '\' Failed - Connection Timed Out');
                                                          }
                                                          else {
                                                            next;
                                                          }
                                                        }
                                                        elsif ($_1I == 1) {
                                                          if ($_7U == ($_Yr - 1)) {
                                                            return ('500:Transport \'' . $_xH . '\' Failed - Connection Refused');
                                                          }
                                                          else {
                                                            next;
                                                          }
                                                        }
                                                        else {
                                                          if (not $_De->auth (username => $_xT->{$_xH}{'username'}, password => $_xT->{$_xH}{'password'})) {
                                                            $_De->disconnect;
                                                            return ('500:Transport \'' . $_xH . '\' Failed - Invalid Credentials');
                                                          }

                                                          my $_tF = '';
                                                          my $_Ca = $_De->sftp;

                                                          if (not $_Ca) {
                                                            $_De->disconnect;
                                                            return ('500:Transport \'' . $_xH . '\' Failed - SFTP Failed');
                                                          }

                                                          if (not $_Ca->realpath ($_kg . '/')) {
                                                            my @_Tu = split(m/\//o, $_kg);

                                                            foreach my $_RG (@_Tu) {
                                                              $_tF .= $_RG . '/';
                                                              $_Ca->mkdir ($_tF);
                                                            }
                                                          }
                                                          else {
                                                            $_tF = $_kg . '/';
                                                          }

                                                          if ($_Ca->realpath ($_tF)) {
                                                            if (not $_De->scp_put ($_7m, quotemeta ($_tF . $_05))) {
                                                              $_Ca->unlink ($_05);
                                                              $_De->disconnect;
                                                              next;
                                                            }
                                                            $_De->disconnect;
                                                            return (100);
                                                          }
                                                          else {
                                                            $_De->disconnect;
                                                            return ('500:Transport \'' . $_xH . '\' Failed - Permission Denied');
                                                          }
                                                          $_De->disconnect;
                                                          return (100);
                                                        }
                                                      }
                                                      return ('500:Transport \'' . $_xH . '\' Failed - Transfer Failed');
                                                    };
                                                    $_PD = &$_bz;
                                                    if (($_PD =~ m/\D/) or ($_PD != 100)) {
                                                      unlink ($_7m);
                                                      last (CLOOP);
                                                    }
                                                  }
                                                }
                                              }
                                              unlink ($_7m);
                                            }
                                          }
                                        }
                                      }
                                    }
                                  }
                                }
                                else {
                                  $_PD = &_6k (0, \$_pW);
                                }

                                if (exists $_RM->{$_fJ->{$_EW}{'cartridge'}}{'post'}) {
                                  my $_dD = $#{$_RM->{$_fJ->{$_EW}{'cartridge'}}{'post'}};
                                  my $_Zq = 0;
                                  my $_3L = 0;

                                  foreach my $_85 (@{$_RM->{$_fJ->{$_EW}{'cartridge'}}{'post'}}) {
                                    my %_5E = ();
                                    my ($_lP, $_85) = &_ih ($_85, $_EW, $_Bw, undef, undef, \%_5E, $_8X);

                                    if ($_Zq == $_dD) {
                                      $_3L = 1;
                                    }

                                    if ($_85 =~ m/^(.+?)(\s\((.+)\))?$/) {
                                      ($_85, my $_6r) = (defined $3) ? ($1, $3) : ($1, undef);

                                      if ($_3L and $_Bw eq 'null') {
                                        $_kW = '_EOF_EXPECTED_';
                                      }
                                      elsif ($_3L) {
                                        my $_qo = undef;
                                        if ($#_TC > -1) {
                                          my $_Mm = $_TC[-1];
                                          $_qo = $_Qm->{$_Mm}{'prompt'};
                                        }
                                        else {
                                          if ($_Bw ne 'null') {
                                            $_qo = $_Qm->{$_Bw}{'prompt'};
                                          }
                                        }
                                        $_kW = &_G7 ($_qo, $_EW, $_Bw, 1, 0);
                                      }
                                      elsif (defined $_6r) {
                                        $_kW = &_G7 ($_6r, $_EW, $_Bw, 1, 0);
                                      }

                                      &$_pV (__LINE__, $_EW, $_85);
                                      $_TL->send ($_85 . $_8X);
                                      push (@{$_lP}, [qr/$_kW/im, sub { }]);

                                      my $_7r = 0;
                                      if (not $_TL->expect ($_x9, [ timeout => \&$_Ku ], [ eof => sub { $_7r = 1 } ], @{$_lP})) {
                                        if ($_7r and ($_Bw eq 'null') and $_3L) {
                                          $_TL->soft_close;
                                        }
                                        elsif ($_7r) {
                                          $_PD = 115;
                                          next (ILOOP);
                                        }
                                        else {
                                          next (ILOOP);
                                        }
                                      }
                                      $_Zq++;
                                    }
                                  }
                                }
                                else {
                                  if (exists $_RM->{$_fJ->{$_EW}{'cartridge'}}{'logout_cmd'}) {
                                    &$_pV (__LINE__, $_EW, $_RM->{$_fJ->{$_EW}{'cartridge'}}{'logout_cmd'});
                                    $_TL->send ($_RM->{$_fJ->{$_EW}{'cartridge'}}{'logout_cmd'} . $_8X);
                                  }
                                  else {
                                    &$_pV (__LINE__, $_EW, $_ch);
                                    $_TL->send ($_ch . $_8X);
                                  }
                                  if ($#_TC > -1) {
                                    my $_Mm = $_TC[-1];
                                    $_TL->expect ($_x9, [ timeout => \&$_Ku ], [ qr/$_Qm->{$_Mm}{'prompt'}/im ]) or next;
                                  }
                                  else {
                                    if ($_Bw eq 'null') {
                                      $_TL->soft_close;
                                    }
                                    else {
                                      $_TL->expect ($_x9, [ timeout => \&$_Ku ], [ qr/$_Qm->{$_Bw}{'prompt'}/im ]) or next;
                                    }
                                  }
                                }
                                last;
                              }
                              elsif (($_PD =~ m/\D/) or ($_PD >= 150)) {
                                last;
                              }
                            }
                            else {
                              $_PD = &_6k (0, \$_pW);
                              last;
                            }
                          }
                          else {
                            $_PD = &_6k (0, \$_pW);
                            last;
                          }
                        }
                      }
                    }
                    else {
                      $_PD = &_6k (0, \$_pW);
                    }

                    if ($_PD =~ m/\D/) {
                      $_PD =~ s/\|/_/g;
                    }
                    else {
                      $_PD += 100;
                    }

                    while (not $_iv->send ($$ . '|' . $_EW . '|' . $_PD)) {
                      sleep (1);
                    }
                  }

                  for (; $_wJ < ($_Hb + ($_lx ? 1 : 0)); $_wJ++, $_7U++) {
                    while (not $_iv->send ($$ . '|' . $_Qm->{$_vj}{'nodes'}[$_7U] . '|' . $_qH)) {
                      sleep (1);
                    }
                  }

                  if ($_TL) {
                    my $_vv = 100;
                    if ($#_TC > -1) {
                      if ($#_TC) {
                        for (my $_fh = $#_TC; $_fh > 0; $_fh--) {
                          my $_fm = $_TC[$_fh - 1];

                          $_vv = 0;
                          if (exists $_Qm->{$_TC[$_fh]}{'logout_cmd'}) {
                            $_TL->send ($_Qm->{$_TC[$_fh]}{'logout_cmd'} . $_Qm->{$_TC[$_fh]}{'terminator'});
                          }
                          else {
                            $_TL->send ($_ch . $_Qm->{$_TC[$_fh]}{'terminator'});
                          }
                          $_TL->expect ($_iN, [ qr/$_Qm->{$_fm}{'prompt'}/im, sub { $_vv = 100 } ]);

                          if (not $_vv) {
                            $_TL->hard_close;
                            last;
                          }
                        }
                      }

                      if ($_vv) {
                        $_vv = 0;
                        if (exists $_Qm->{$_TC[0]}{'logout_cmd'}) {
                          $_TL->send ($_Qm->{$_TC[0]}{'logout_cmd'} . $_Qm->{$_TC[0]}{'terminator'});
                        }
                        else {
                          $_TL->send ($_ch . $_Qm->{$_TC[0]}{'terminator'});
                        }
                        $_TL->expect ($_iN, [ qr/$_Qm->{$_Bw}{'prompt'}/im, sub { $_vv = 100 } ]);
                        if (not $_vv) {
                          $_TL->hard_close;
                        }
                      }
                    }

                    if ($_vv and not length ($_Rx)) {
                      if (exists $_Qm->{$_Bw}{'logout_cmd'}) {
                        $_TL->send ($_Qm->{$_Bw}{'logout_cmd'} . $_Qm->{$_Bw}{'terminator'});
                      }
                      else {
                        if ($_Bw ne 'null') {
                          $_TL->send ($_ch . $_Qm->{$_Bw}{'terminator'});
                        }
                      }
                      $_TL->soft_close;
                    }
                  }
                  close ($_iv);
                  exit;
                }
                else {
                  close (CHILD);
                  $_Ko{$_uj} = 1;
                  close (PARENT);
                }
              }
            }
          }
        }
        while (keys %_Ko) {
          sleep (1);
        }
        if (length ($_Rx)) {
          kill ('TERM', $_BS);
          while (keys %_iu) {
            sleep (1);
          }
        }
        exit;
      }
      else {
        close (PCHILD);
        $_sw{$_uj} = 1;
        close (PPARENT);
      }
    }
  }
}

my $_cu = new IO::Select ($_xL);
while (keys (%_sw) or $_cu->can_read (0)) {
  while ($_cu->can_read (1)) {
    $_xL->recv (my $_uT, BUFSIZ);
    if ($_uT =~ m/^(\d+)\|(.+)\|(.+)$/) {
      my ($_5N, $_EW, $_yS) = ($1, $2, $3);
      &_Pd ($_5N, $_EW, $_yS, $_y6);
    }
  }
}

$SIG{'CHLD'} = '';
  
close ($_xL);
unlink ($_Hk);
unlink ($_r3);

foreach my $_EW (sort keys %{$_fJ}) {
  if (not exists $_fJ->{$_EW}{'status'}) {
    print '>> ' . $_EW . ' ' . '.' x (($_y6 - length ($_EW)) + 2) . ' ' . &_j6 (299) . "\n";
    $_fJ->{$_EW}{'status'} = 299;
    $_gE++;
    $_6W++;
  }
}

if (not $_XA) {
  if (defined &post) {
    if (exists $_80{'script_pre_failure'}) {
      print '>> S/POST ' . '.' x (($_y6 - 6) + 2) . ' ' . '[Global] Skipped' . "\n";
      $_80{'script_post_failure'} = '[Global] Skipped';
    }
    else {
      my $_4N = undef;

      {
        local $SIG{'ALRM'} = sub {
          die ('ALRM' . "\n");
        };
        no warnings;
        alarm ($_80{'script_timeout'});
        eval {
          $_4N = &post;
        };
        alarm (0);
      }

      if ($@) {
        if ($@ =~ m/^ALRM/) {
          print '>> S/POST ' . '.' x (($_y6 - 6) + 2) . ' ' . '[Global] Script Timed Out' . "\n";
          $_80{'script_post_failure'} = '[Global] Script Timed Out';
        }
        else {
          print '---' . "\n";
          print $@;
          print '---' . "\n";
          print '>> S/POST ' . '.' x (($_y6 - 6) + 2) . ' ' . '[Global] Script Syntax Error' . "\n";
          $_80{'script_post_failure'} = '[Global] Script Syntax Error';
        }
      }
      else {
        if (not defined $_4N) {
          print '>> S/POST ' . '.' x (($_y6 - 6) + 2) . ' ' . '[Global] Unknown Script Error' . "\n";
          $_80{'script_post_failure'} = '[Global] Unknown Script Error';
        }
        elsif ($_4N =~ m/^100(?::(.+))?$/) {
          if (defined $1) {
            print '>> S/POST ' . '.' x (($_y6 - 6) + 2) . ' ' . '[Global] OK (' . $1 . ')' . "\n";
          }
          else {
            print '>> S/POST ' . '.' x (($_y6 - 6) + 2) . ' ' . '[Global] OK' . "\n";
          }
        }
        else {
          print '>> S/POST ' . '.' x (($_y6 - 6) + 2) . ' ' . '[Global] [CSR] ' . $_4N . "\n";
          $_80{'script_post_failure'} = '[Global] [CSR] ' . $_4N;
        }
      }
    }
  }
}

my $_ID = $_CC;
$_CC = time - $_CC;

if ((exists $_80{'alerts'}) and (not $_XA)) {
  foreach my $_wN (sort keys %{$_K2}) {
    if (exists $_K2->{$_wN}{'nodes'}) {
      my @_1K = ();

      $_y6 = 0;
      foreach my $_EW (sort @{$_K2->{$_wN}{'nodes'}}) {
        if ($_fJ->{$_EW}{'status'} =~ m/\D/ or ($_fJ->{$_EW}{'status'} !~ m/^(200|204|253)$/)) {
          $_y6 = (length ($_EW) > $_y6) ? length ($_EW) : $_y6;
        }
      }

      if (exists $_80{'script_post_failure'}) {
        $_y6 = (6 > $_y6) ? 6 : $_y6;
      }

      if (exists $_80{'script_pre_failure'}) {
        $_y6 = (5 > $_y6) ? 5 : $_y6;
        push (@_1K, 'S/PRE ' . '.' x (($_y6 - 5) + 2) . ' ' . $_80{'script_pre_failure'});
      }

      foreach my $_EW (sort @{$_K2->{$_wN}{'nodes'}}) {
        if ($_fJ->{$_EW}{'status'} =~ m/\D/ or ($_fJ->{$_EW}{'status'} !~ m/^(200|204|253)$/)) {
          push (@_1K, $_EW . ' ' . '.' x (($_y6 - length ($_EW)) + 2) . ' ' . &_j6 ($_fJ->{$_EW}{'status'}));
        }
      }

      if (exists $_80{'script_post_failure'}) {
        push (@_1K, 'S/POST ' . '.' x (($_y6 - 6) + 2) . ' ' . $_80{'script_post_failure'});
      }

      if ($#_1K > -1) {
        if ($_K2->{$_wN}{'type'} eq 'smtp') {
          eval { require Net::SMTP };

          if ($@) {
            warn ('Warning: Unable to send alert - can\'t locate module Net::SMTP' . "\n");
            last;
          }

          my $_iY = (exists $_K2->{$_wN}{'timeout'}) ? $_K2->{$_wN}{'timeout'} : $_IG;

          my $_oA = sub {
            my $_CD = new Net::SMTP ($_K2->{$_wN}{'relay'}, Timeout => $_iY);
            if ($_CD) {
              if (exists $_K2->{$_wN}{'username'} and exists $_K2->{$_wN}{'password'}) {
                $_CD->auth ($_K2->{$_wN}{'username'}, $_K2->{$_wN}{'password'});
                if (not $_CD->ok) {
                  (my $_Ur = $_CD->message) =~ s/^\s*(.*?)\s*$/$1/s;
                  $_CD->quit;
                  return (0, $_Ur);
                }
              }

              $_CD->mail ($_K2->{$_wN}{'from'});
              if (not $_CD->ok) {
                (my $_Ur = $_CD->message) =~ s/^\s*(.*?)\s*$/$1/s;
                $_CD->quit;
                return (0, $_Ur);
              }

              foreach my $_1I (@{$_K2->{$_wN}{'to'}}) {
                $_CD->to ($_1I);
                if (not $_CD->ok) {
                  (my $_Ur = $_CD->message) =~ s/^\s*(.*?)\s*$/$1/s;
                  $_CD->quit;
                  return (0, $_Ur);
                }
              }

              if (exists $_K2->{$_wN}{'cc'}) {
                foreach my $_1I (@{$_K2->{$_wN}{'cc'}}) {
                  $_CD->cc ($_1I);
                  if (not $_CD->ok) {
                    (my $_Ur = $_CD->message) =~ s/^\s*(.*?)\s*$/$1/s;
                    $_CD->quit;
                    return (0, $_Ur);
                  }
                }
              }

              $_CD->data;
              if (not $_CD->ok) {
                (my $_Ur = $_CD->message) =~ s/^\s*(.*?)\s*$/$1/s;
                $_CD->quit;
                return (0, $_Ur);
              }

              $_CD->datasend ('X-Priority: 1' . "\n");
              $_CD->datasend ('From: ' . $_K2->{$_wN}{'from'} . "\n");
              foreach my $_1I (@{$_K2->{$_wN}{'to'}}) {
                $_CD->datasend ('To: ' . $_1I . "\n");
              }
              if (exists $_K2->{$_wN}{'cc'}) {
                foreach my $_1I (@{$_K2->{$_wN}{'cc'}}) {
                  $_CD->datasend ('Cc: ' . $_1I . "\n");
                }
              }
              $_CD->datasend ('Subject: ' . &_NG ($0) . ' ' . $_ZE . "\n\n");
              $_CD->datasend ('Start Time: ' . strftime ($_9X, localtime ($_ID)) . "\n");
              $_CD->datasend ('Elapsed Time: ' . &_70 ($_CC) . "\n\n");
              foreach my $_7U (@_1K) {
                $_CD->datasend ($_7U . "\n");
              }
              $_CD->dataend;

              if (not $_CD->ok) {
                (my $_Ur = $_CD->message) =~ s/^\s*(.*?)\s*$/$1/s;
                $_CD->quit;
                return (0, $_Ur);
              }

              $_CD->quit;
              return (1, undef);
            }
            else {
              return (0, 'connection refused');
            }
          };

          my ($_Vj, $_eP) = &$_oA;
          if (not $_Vj) {
            warn ('Warning: Unable to send message to smtp alert \'' . $_wN . '\' - ' . $_eP . "\n");
          }
        }
        elsif ($_K2->{$_wN}{'type'} eq 'http') {
          eval { require LWP::UserAgent };

          if ($@) {
            warn ('Warning: Unable to send alert - can\'t locate module LWP::UserAgent' . "\n");
            last;
          }

          my $_Ll = (exists $_K2->{$_wN}{'timeout'}) ? $_K2->{$_wN}{'timeout'} : $_yp;

          my $_64 = new LWP::UserAgent (timeout => $_Ll);

          if (exists $_K2->{$_wN}{'proxy_url'}) {
            $_64->proxy (['http', 'https'], $_K2->{$_wN}{'proxy_url'});
          }

          my $_7w = $_64->post ($_K2->{$_wN}{'post_url'},
            Content_Type => 'form-data',
            Content => [
              start_time => strftime ($_9X, localtime ($_ID)),
              elapsed_time => &_70 ($_CC),
              cmd_line => &_NG ($0) . ' ' . $_ZE,
              data => join ("\n", @_1K)
            ]
          );

          if (not $_7w->is_success) {
            (my $_Ur = $_7w->status_line) =~ s/^\s*(.*?)\s*$/$1/s;
            warn ('Warning: Unable to post to http alert \'' . $_wN . '\' - ' . $_Ur . "\n");
          }
          else {
            (my $_Ur = $_7w->content) =~ s/^\s*(.*?)\s*$/$1/s;
            if ($_Ur ne 'OK') {
              warn ('Warning: Unable to post to http alert \'' . $_wN . '\' - ' . $_Ur . "\n");
            }
          }
        }
      }
    }
  }
}

print "\n";

if ($_gE) {
  my @_2A = ();
  my $_Or = 0;

  foreach my $_EW (sort keys %{$_fJ}) {
    if ($_fJ->{$_EW}{'status'} =~ m/\D/ or ($_fJ->{$_EW}{'status'} !~ m/^(200|204|253)$/)) {
      if ($_fJ->{$_EW}{'status'} !~ m/^100:/) {
        my $_FP = length ($_EW) + length ($_fJ->{$_EW}{'address'});
        $_Or = ($_FP > $_Or) ? $_FP : $_Or;
        push (@_2A, $_EW);
      }
    }
  }

  my $_O4 = 0;
  my $_av = undef;
  if (exists $_80{'failed'}) {
    $_av = (length $_80{'failed'}) ? $_80{'failed'} : 'ns4.' . $$ . '.failed';
    if (open (my $_xy, '>', $_av)) {
      foreach my $_7U (@_2A) {
        syswrite ($_xy, $_7U . "\n");
      }
      close ($_xy);
      $_O4++;
    }
    else {
      warn ('Warning: Unable to write failed node list file \'' . $_av . '\' - ' . $! . "\n");
    }
  }

  print '---' . "\n";
  print $_gE . ' Node' . (($_gE != 1) ? 's' : '') . ' Failed' . (($_O4) ? ' (Node List File: \'' . $_av . '\')' : '') . ':' . "\n";

  for (my $_7X = 0; $_7X < $#_2A + 1; $_7X++) {
    my $_EW = $_2A[$_7X];
    my $_fi = $_fJ->{$_EW}{'address'};
    my $_Yu = &_j6 ($_fJ->{$_EW}{'status'});
    print ' ' . $_EW . ' .' . ('.' x ($_Or - (length ($_EW) + length ($_fi)))) . '. ' . $_fi . ' - ' . $_Yu . "\n";
  }

  print '---' . "\n";
}

print 'Total Nodes: ' . $_6W . "\n";
print 'Elapsed Time: ' . &_70 ($_CC) . "\n";
exit ($_gE == $_6W ? 2 : ($_gE) ? 10 : 0);



# ----- YAML Functions -----

sub _SU {
  my ($_E1, $_Fy, $_me, $_Om) = @_;
  my $_13 = (&_NP (qr/$_E1/, @_ZX) and $_Fy);
  my @_lY = ();

  my $_an = sub {
    my ($_5V, $_WD) = @_;

    if ($_5V eq 'rot13') {
      $_WD =~ tr/a-zA-Z/n-za-mN-ZA-M/;
      return ($_WD);
    }
    elsif ($_5V eq 'base64') {
      eval { require MIME::Base64 };

      if ($@) {
        warn ('Warning: \'base64\' encoding scheme not supported without MIME::Base64' . "\n");
        $_Ah++;
        return (undef);
      }
      else {
        return (&MIME::Base64::decode_base64 ($_WD));
      }
    }
    else {
      warn ('Warning: Unknown encoding scheme \'' . $_5V . '\'' . "\n");
      $_Ah++;
      return (undef);
    }
  };

  if (ref ($_me) eq 'ARRAY') {
    if ($_13 and not $_Om) {
      foreach my $_8w (@{$_me}) {
        my $_xZ = &_SU ($_E1, 0, $_8w, 0);
        if (defined $_xZ) {
          push (@_lY, $_xZ);
        }
      }
      return (($#_lY > -1) ? \@_lY : undef);
    }
    else {
      if ($_Om) {
        warn ('Warning: Custom key \'' . $_E1 . '\' cannot have multiple values' . "\n");
      }
      else {
        warn ('Warning: Key \'' . $_E1 . '\' cannot have multiple values' . "\n");
      }
      $_Ah++;
      return (undef);
    }
  }
  elsif (ref ($_me) eq 'HASH') {
    my $_0t = 0;
    if (($_E1 eq 'pre') or ($_E1 eq 'post')) {
      $_0t = 3;
    }
    elsif ((&_NP (qr/$_E1/, @_ZQ))
      or (&_NP (qr/$_E1/, @_pY))
      or (&_NP (qr/$_E1/, @_5o))
      or (&_NP (qr/$_E1/, @_UX))
      or (&_NP (qr/$_E1/, @_Yi))
      or ($_Om)) {
      $_0t = 2;
    }
    else {
      $_0t = 1;
    }

    if ((exists $_me->{'value'} or exists $_me->{'ask'}) and (keys (%$_me) <= $_0t)) {
      if (exists $_me->{'encoding'}) {
        if ($_Om or &_NP (qr/$_E1/, @_UX)) {
          my $_lt = '<' . lc ($_me->{'encoding'}) . '>' . $_me->{'value'} . '</' . lc ($_me->{'encoding'}) . '>';

          if ($_13) {
            warn ('Warning: \'encoding\' attribute not allowed on array keys' . "\n");
            $_Ah++;
            return (undef);
          }
          return ('!|!|!' . $_lt . '!|!|!' . &$_an ($_me->{'encoding'}, $_me->{'value'}));
        }
        else {
          warn ('Warning: \'encoding\' attribute not allowed on key \'' . $_E1 . '\'' . "\n");
          $_Ah++;
          return (undef);
        }
      }
      elsif (exists $_me->{'ask'}) {
        if ($_Om or &_NP (qr/$_E1/, @_Yi)) {
          if ($_13) {
            warn ('Warning: \'ask\' attribute not allowed on array keys' . "\n");
            $_Ah++;
            return (undef);
          }

          my $_d6 = undef;
          if ($_me->{'ask'} =~ m/^(.+?)\|/) {
            $_d6 = $1;
            $_me->{'ask'} =~ s/^.+?\|//;
          }
          else {
            $_d6 = $_me->{'ask'};
          }

          if (exists $_UF{$_me->{'ask'}}) {
            if ($_UF{$_me->{'ask'}}{'key'} ne $_d6) {
              warn ('Warning: \'ask\' attribute has a different order key then \'ask\' attribute with the same name on key \'' . $_E1 . '\'' . "\n");
              $_Ah++;
              return (undef);
            }
          }

          if (exists $_me->{'type'}) {
            if ($_me->{'type'} eq 'password') {
              if (exists $_UF{$_me->{'ask'}}) {
                if ($_UF{$_me->{'ask'}}{'type'} ne 'password') {
                  warn ('Warning: \'ask\' attribute has a different \'type\' than \'ask\' attribute with the same name on key \'' . $_E1 . '\'' . "\n");
                  $_Ah++;
                  return (undef);
                }
              }
              else {
                $_UF{$_me->{'ask'}}{'type'} = 'password';
                $_UF{$_me->{'ask'}}{'key'} = $_d6;
              }
            }
            else {
              warn ('Warning: \'ask\' attribute has an invalid \'type\' on key \'' . $_E1 . '\'' . "\n");
              $_Ah++;
              return (undef);
            }
          }
          else {
            if (exists $_UF{$_me->{'ask'}}) {
              if ($_UF{$_me->{'ask'}}{'type'} ne 'normal') {
                warn ('Warning: \'ask\' attribute has a different \'type\' then \'ask\' attribute with the same name on key \'' . $_E1 . '\'' . "\n");
                $_Ah++;
                return (undef);
              }
            }
            else {
              $_UF{$_me->{'ask'}}{'type'} = 'normal';
              $_UF{$_me->{'ask'}}{'key'} = $_d6;
            }
          }
          return ('x|X|' . $_me->{'ask'} . '|X|x');
        }
        else {
          warn ('Warning: \'ask\' attribute not allowed on key \'' . $_E1 . '\'' . "\n");
          $_Ah++;
          return (undef);
        }
      }
      elsif (exists $_me->{'expect'}) {
        if (not $_Om or &_NP (qr/$_E1/, @_5o)) {
          my $_Wh = (exists $_me->{'prompt'}) ? ' (' . $_me->{'prompt'} . ')' : '';
          my $_gU = '';

          if (ref ($_me->{'expect'}) eq 'ARRAY') {
            foreach my $_8f (@{$_me->{'expect'}}) {
              $_gU .= ' :!: ' . $_8f->{'value'} . ' :,: ' . $_8f->{'send'};
            }
          }
          else {
            $_gU .= ' :!: ' . $_me->{'expect'}{'value'} . ' :,: ' . $_me->{'expect'}{'send'};
          }
          if ($_13 and not $_Om) {
            push (@_lY, $_me->{'value'} . $_Wh . $_gU);
            return (\@_lY);
          }
          return ($_me->{'value'} . $_Wh . $_gU);
        }
        else {
          if ($_Om) {
            warn ('Warning: \'expect\' attribute not allowed on custom key \'' . $_E1 . '\'' . "\n");
          }
          else {
            warn ('Warning: \'expect\' attribute not allowed on key \'' . $_E1 . '\'' . "\n");
          }
          $_Ah++;
          return (undef);
        }
      }
      elsif (exists $_me->{'alias'}) {
        if (not $_Om or &_NP (qr/$_E1/, @_ZQ)) {
          if ($_13) {
            push (@_lY, $_me->{'value'} . ' (' . $_me->{'alias'} . ')');
            return (\@_lY);
          }
          return ($_me->{'value'} . ' (' . $_me->{'alias'} . ')');
        }
        else {
          if ($_Om) {
            warn ('Warning: \'alias\' attribute not allowed on custom key \'' . $_E1 . '\'' . "\n");
          }
          else {
            warn ('Warning: \'alias\' attribute not allowed on key \'' . $_E1 . '\'' . "\n");
          }
          $_Ah++;
          return (undef);
        }
      }
      elsif (exists $_me->{'prompt'}) {
        if (not $_Om or &_NP (qr/$_E1/, @_pY)) {
          if ($_13) {
            push (@_lY, $_me->{'value'} . ' (' . $_me->{'prompt'} . ')');
            return (\@_lY);
          }
          return ($_me->{'value'} . ' (' . $_me->{'prompt'} . ')');
        }
        else {
          if ($_Om) {
            warn ('Warning: \'prompt\' attribute not allowed on custom key \'' . $_E1 . '\'' . "\n");
          }
          else {
            warn ('Warning: \'prompt\' attribute not allowed on key \'' . $_E1 . '\'' . "\n");
          }
          $_Ah++;
          return (undef);
        }
      }
      elsif (keys (%$_me) > 1) {
        if ($_Om) {
          warn ('Warning: Unknown attributes detected under custom key \'' . $_E1 . '\'' . "\n");
        }
        else {
          warn ('Warning: Unknown attributes detected under key \'' . $_E1 . '\'' . "\n");
        }
        $_Ah++;
        return (undef);
      }
      else {
        if ($_13 and not $_Om) {
          push (@_lY, $_me->{'value'});
          return (\@_lY);
        }
        return ($_me->{'value'});
      }
    }
    elsif (exists $_me->{'value'}) {
      if ($_Om) {
        warn ('Warning: Unknown attributes detected under custom key \'' . $_E1 . '\'' . "\n");
      }
      else {
        warn ('Warning: Unknown attributes detected under key \'' . $_E1 . '\'' . "\n");
      }
      $_Ah++;
      return (undef);
    }
    else {
      if ($_Om) {
        warn ('Warning: \'value\' attribute missing from custom key \'' . $_E1 . '\'' . "\n");
      }
      else {
        warn ('Warning: \'value\' attribute missing from key \'' . $_E1 . '\'' . "\n");
      }
      $_Ah++;
      return (undef);
    }
  }
  else {
    if ($_13 and not $_Om) {
      if ((defined $_me) and (length ($_me) > 0)) {
        push (@_lY, $_me);
      }
      return (\@_lY);
    }
    return ($_me);
  }
}

sub _Nj {
  my ($_YC, $_By, $_E1, $_me) = @_;

  if (exists $_me->{'id'}) {
    my $_Mu = $_me->{'id'};

    if (exists $_me->{'oid'}) {
      $_YC->{$_By}{'snmp_oids'}{$_Mu} = $_me->{'oid'};
    }
    else {
      warn ('Warning: \'oid\' attribute missing from key \'' . $_E1 . '\'' . "\n");
      $_Ah++;
    }
  }
  else {
    warn ('Warning: \'id\' attribute missing from key \'' . $_E1 . '\'' . "\n");
    $_Ah++;
  }
}

sub _4y {
  my ($_YC, $_By, $_me) = @_;

  if (ref ($_me) eq 'ARRAY') {
    warn ('Warning: Key \'options\' cannot have multiple values' . "\n");
    $_Ah++;
  }
  else {
    foreach my $_8w (keys %$_me) {
      if (&_NP (qr/$_8w/, keys (%{$_iO{'options'}}))) {
        if ($_8w eq 'custom') {
          if (ref ($_me->{$_8w}) ne 'HASH') {
            warn ('Warning: Custom key \'' . $_8w . '\' contained within object \'options\' is invalid' . "\n");
            $_Ah++;
          }
          else {
            foreach my $_E1 (keys %{$_me->{$_8w}}) {
              my $_xZ = &_SU ($_E1, 1, $_me->{$_8w}{$_E1}, 1);
              if (defined $_xZ) {
                if ($_xZ =~ m/^!\|!\|!(.+?)!\|!\|!(.+)$/) {
                  $_YC->{$_By}{'custom_' . lc ($_E1)} = $2;
                  $_YC->{$_By}{'enc:custom_' . lc ($_E1)} = $1;
                }
                else {
                  $_YC->{$_By}{'custom_' . lc ($_E1)} = $_xZ;
                }
              }
            }
          }
        }
        elsif ($_8w eq 'snmp_oids') {
          if (ref ($_me->{$_8w}) eq 'ARRAY') {
            foreach my $_ps (@{$_me->{$_8w}}) {
              &_Nj ($_YC, $_By, $_8w, $_ps);
            }
          }
          elsif (ref ($_me->{$_8w}) eq 'HASH') {
            &_Nj ($_YC, $_By, $_8w, $_me->{$_8w});
          }
          else {
            warn ('Warning: Key \'' . $_8w . '\' contained within object \'options\' is invalid' . "\n");
            $_Ah++;
          }
        }
        else {
          my $_xZ = &_SU ($_8w, 1, $_me->{$_8w}, 0);
          if (defined $_xZ) {
            if ($_xZ =~ m/^!\|!\|!(.+?)!\|!\|!(.+)$/) {
              $_YC->{$_By}{$_8w} = $2;
              $_YC->{$_By}{'enc:' . $_8w} = $1;
            }
            else {
              $_YC->{$_By}{$_8w} = $_xZ;
            }
          }
        }
      }
      else {
        warn ('Warning: Invalid object \'' . $_8w . '\' contained within object \'options\'' . "\n");
        $_Ah++;
      }
    }
  }
}

sub _Y4 {
  my ($_YC, $_me) = @_;

  if (ref ($_me) eq 'ARRAY') {
    warn ('Warning: Key \'options\' cannot have multiple values' . "\n");
    $_Ah++;
  }
  else {
    foreach my $_8w (keys %$_me) {
      if (&_NP (qr/$_8w/, keys (%{$_I3{'options'}}))) {
        my $_xZ = &_SU ($_8w, 1, $_me->{$_8w}, 0);
        if (defined $_xZ) {
          if ($_xZ =~ m/^!\|!\|!(.+?)!\|!\|!(.+)$/) {
            $_YC->{$_8w} = $2;
            $_YC->{'enc:' . $_8w} = $1;
          }
          else {
            $_YC->{$_8w} = $_xZ;
          }
        }
      }
      else {
        warn ('Warning: Invalid object \'' . $_8w . '\' contained within object \'options\'' . "\n");
        $_Ah++;
      }
    }
  }
}

sub _yd {
  my ($_Bp, $_E1, $_me) = @_;

  if (ref ($_me) eq 'ARRAY') {
    foreach my $_Yw (@{$_me}) {
      &_yd ($_Bp, $_E1, $_Yw);
    }
  }
  else {
    if (exists $_me->{'id'}) {
      my $_ic = $_me->{'id'};

      if (not exists $_Bp->{$_ic}) {
        if (keys (%$_me) > 1) {
          my %_u8 = ();
          if (exists $_me->{'options'}) {
            &_Y4 (\%_u8, $_me->{'options'});
          }
          foreach my $_8w (keys %$_me) {
            if ($_8w ne 'id') {
              if (&_NP (qr/$_8w/, keys (%{$_I3{$_E1}}))) {
                if ($_8w ne 'options') {
                  my $_xZ = &_SU ($_8w, 1, $_me->{$_8w}, 0);
                  if (defined $_xZ) {
                    if ($_xZ =~ m/^!\|!\|!(.+?)!\|!\|!(.+)$/) {
                      $_Bp->{$_ic}{$_8w} = $2;
                      $_Bp->{$_ic}{'enc:' . $_8w} = $1;
                    }
                    else {
                      $_Bp->{$_ic}{$_8w} = $_xZ;
                    }
                  }
                }
              }
              else {
                warn ('Warning: Invalid object \'' . $_8w . '\' contained within object \'' . $_E1 . '\'' . "\n");
                $_Ah++;
              }
            }
          }
          foreach my $_E1 (keys %_u8) {
            if (not exists $_Bp->{$_ic}{$_E1}) {
              $_Bp->{$_ic}{$_E1} = $_u8{$_E1};
            }
          }
        }
        else {
          warn ('Warning: ' . $_E1 . ' \'' . $_ic . '\' has no attributes' . "\n");
          $_Ah++;
        }
      }
      else {
        warn ('Warning: ' . $_E1 . ' \'' . $_ic . '\' already exists' . "\n");
        $_Ah++;
      }
    }
  }
}

sub _ZL {
  my ($_YC, $_BX, $_R5, $_E1, $_me) = @_;

  if (ref ($_me) eq 'ARRAY') {
    foreach my $_Yw (@{$_me}) {
      &_ZL ($_YC, $_BX, $_R5, $_E1, $_Yw);
    }
  }
  else {
    if (exists $_me->{'id'}) {
      my $_ic = $_me->{'id'};

      if (not exists $_YC->{$_ic}) {
        if (keys (%$_me) > 1) {
          if ($_E1 =~ m/^(alert|transport)_(\S+)$/i) {
            $_YC->{$_ic}{'type'} = $2;
          }
          foreach my $_8w (keys %$_me) {
            if ($_8w ne 'id') {
              if (&_NP (qr/$_8w/, keys (%{$_iO{$_E1}}))) {
                my $_xZ = &_SU ($_8w, 1, $_me->{$_8w}, 0);
                if (defined $_xZ) {
                  if ($_xZ =~ m/^!\|!\|!(.+?)!\|!\|!(.+)$/) {
                    $_YC->{$_ic}{$_8w} = $2;
                    $_YC->{$_ic}{'enc:' . $_8w} = $1;
                  }
                  else {
                    $_YC->{$_ic}{$_8w} = $_xZ;
                  }
                }
              }
              else {
                warn ('Warning: Invalid object \'' . $_8w . '\' contained within object \'' . $_E1 . '\'' . "\n");
                $_Ah++;
              }
            }
          }
        }
        else {
          warn ('Warning: ' . $_E1 . ' \'' . $_ic . '\' has no attributes' . "\n");
          $_Ah++;
        }
      }
      else {
        if ($_E1 =~ m/^(alert|transport)_/i) {
          warn ('Warning: ' . $1 . ' \'' . $_ic . '\' already exists' . "\n");
        }
        else {
          warn ('Warning: ' . $_E1 . ' \'' . $_ic . '\' already exists' . "\n");
        }
        $_Ah++;
      }
    }
    else {
      warn ('Warning: \'id\' attribute missing from key \'' . $_E1 . '\'' . "\n");
      $_Ah++;
    }
  }
}

sub _WK {
  my ($_G5, $_BX, $_me) = @_;

  if (ref ($_me) eq 'ARRAY') {
    foreach my $_Yw (@{$_me}) {
      &_WK ($_G5, $_BX, $_Yw);
    }
  }
  else {
    if (exists $_me->{'id'}) {
      if (not exists $_me->{'address'}) {
        $_me->{'address'} = $_me->{'id'};
        $_me->{'_usedns_'} = 1;
      }

      my $_ic = $_me->{'id'};
      my $_On = $_me->{'address'};

      my @_Ul = ();
      my @_Zr = ();
      
      if ($_ic =~ m/\{\s*\d+\s*,\s*\d+\s*(?:,\s*\-?\d+\s*)?\}/) {
        my $_H2 = 0;
        while ($_ic =~ m/\{\s*\d+\s*,\s*(\d+)\s*(?:,\s*\-?\d+\s*)?\}/g) {
          unless (not $_H2) {
            if ($_H2 != $1) {
              warn ('Warning: [id = \'' . $_ic . '\'] Dynamic transformations must have a consistent count within entries' . "\n");
              $_Ah++;
            }
          }
          $_H2 = $1;
        }
        while ($_On =~ m/\{\s*\d+\s*,\s*(\d+)\s*(?:,\s*\-?\d+\s*)?\}/g) {
          if ($_H2 != $1) {
            warn ('Warning: [id = \'' . $_ic . '\'] Dynamic transformations must have a consistent count within entries' . "\n");
            $_Ah++;
          }
        }
        for (my $_7X = 0; $_7X < $_H2; $_7X++) {
          my ($_Ul, $_Zr) = ($_ic, $_On);
          foreach ($_Ul, $_Zr) {
            s/\{\s*(\d+)\s*,\s*\d+\s*(?:,\s*(\-?\d+)\s*)?\}/
              if (defined $2) {
                sprintf ('%0' . length ($1) . 'd', ($1 + ($_7X * $2)));
              }
              else {
                sprintf ('%0' . length ($1) . 'd', ($1 + ($_7X * 1)));
              }
            /ge;
          }
          push (@_Ul, $_Ul);
          push (@_Zr, $_Zr);
        }
      }
      else {
        push (@_Ul, $_ic);
        push (@_Zr, $_On);
      }

      for (my $_7U = 0; $_7U < $#_Ul + 1; $_7U++) {
        if (not exists $_G5->{$_Ul[$_7U]}) {
          if (keys (%$_me) > 1) {
            foreach my $_8w (keys %$_me) {
              if ($_8w ne 'id') {
                if ($_8w eq 'address') {
                  $_G5->{$_Ul[$_7U]}{'address'} = $_Zr[$_7U];
                }
                else {
                  if (&_NP (qr/$_8w/, keys (%{$_iO{'node'}}))) {
                    my $_xZ = &_SU ($_8w, 1, $_me->{$_8w}, 0);
                    if (defined $_xZ) {
                      if ($_xZ =~ m/^!\|!\|!(.+?)!\|!\|!(.+)$/) {
                        $_G5->{$_Ul[$_7U]}{$_8w} = $2;
                        $_G5->{$_Ul[$_7U]}{'enc:' . $_8w} = $1;
                      }
                      else {
                        $_G5->{$_Ul[$_7U]}{$_8w} = $_xZ;
                      }
                    }
                  }
                  else {
                    warn ('Warning: Invalid object \'' . $_8w . '\' contained within object \'node\'' . "\n");
                    $_Ah++;
                  }
                }
              }
            }

            foreach my $_R5 (reverse sort { $a cmp $b } (keys %$_BX)) {
              foreach my $_E1 (keys %{$_BX->{$_R5}}) {
                if (not exists $_G5->{$_Ul[$_7U]}{$_E1}) {
                  if (ref ($_BX->{$_R5}{$_E1}) eq 'ARRAY') {
                    my @_5J = map (@$_, $_BX->{$_R5}{$_E1});
                    my @_Mw = ('__null__');
                    $_G5->{$_Ul[$_7U]}{$_E1} = ($#_5J > -1) ? \@_5J : \@_Mw;
                  }
                  else {
                    $_G5->{$_Ul[$_7U]}{$_E1} = (length $_BX->{$_R5}{$_E1}) ? $_BX->{$_R5}{$_E1} : 'null';
                  }
                }
              }
            }
            foreach my $_E1 (keys %{$_G5->{$_Ul[$_7U]}}) {
              if (ref ($_G5->{$_Ul[$_7U]}{$_E1}) eq 'ARRAY') {
                if ($_G5->{$_Ul[$_7U]}{$_E1}[0] eq '__null__') {
                  delete ($_G5->{$_Ul[$_7U]}{$_E1});
                }
              }
              else {
                if ($_G5->{$_Ul[$_7U]}{$_E1} eq '__null__') {
                  delete ($_G5->{$_Ul[$_7U]}{$_E1});
                }
              }
            }
          }
          else {
            warn ('Warning: Node \'' . $_Ul[$_7U] . '\' has no attributes' . "\n");
            $_Ah++;
          }
        }
        else {
          warn ('Warning: Node \'' . $_Ul[$_7U] . '\' already exists' . "\n");
          $_Ah++;
        }
      }
    }
    else {
      warn ('Warning: \'id\' attribute missing from key \'node\'' . "\n");
      $_Ah++;
    }
  }
}

sub _fV {
  my ($_G5, $_Wf, $_5D, $_BX, $_R5, $_me) = @_;

  if (ref ($_me) eq 'ARRAY') {
    foreach my $_Yw (@{$_me}) {
      &_fV ($_G5, $_Wf, $_5D, $_BX, $_R5, $_Yw);
    }
  }
  else {
    if (exists $_me->{'options'}) {
      &_4y ($_BX, $_R5, $_me->{'options'});
    }

    foreach my $_8w (keys %$_me) {
      if (&_NP (qr/$_8w/, keys (%{$_iO{'container'}}))) {
        if ($_8w eq 'node') {
          &_WK ($_G5, $_BX, $_me->{$_8w});
        }
        elsif ($_8w eq 'container') {
          &_fV ($_G5, $_Wf, $_5D, $_BX, $_R5 + 1, $_me->{$_8w});
        }
      }
      else {
        warn ('Warning: Invalid object \'' . $_8w . '\' contained within object \'container\'' . "\n");
        $_Ah++;
      }
    }
  }

  foreach my $_c6 (keys %$_BX) {
    if ($_c6 >= $_R5) {
      delete ($_BX->{$_c6});
    }
  }
}

sub _Cl {
  my ($_Ae, $_RM, $_xT, $_K2, $_fJ, $_Qm) = @_;
  my $_bZ = 0;
  my %_7T = ();

  foreach my $_CK (keys %{$_iO{'root'}}) {
    if ($_iO{'root'}{$_CK} and not exists $_Ae->{$_CK}) {
      warn ('Error: Mandatory global attribute \'' . $_CK . '\' not defined' . "\n");
      $_bZ++;
    }
  }

  if (exists $_Ae->{'gpg_path'} and not -x $_Ae->{'gpg_path'}) {
    warn ('Warning: Global attribute \'gpg_path\' specified, but unable to execute \'' . $_Ae->{'gpg_path'} . '\'' . "\n");
    $_bZ++;
  }

  if (exists $_Ae->{'syslog_facility'}) {
    eval { use Sys::Syslog };

    if ($@) {
      warn ('Warning: Global attribute \'syslog_facility\' specified, but Sys::Syslog module not found' . "\n");
      $_bZ++;
    }
  }

  foreach my $_LQ (keys %{$_RM}) {
    foreach my $_EI (keys %{$_I3{'cartridge'}}) {
      if ($_I3{'cartridge'}{$_EI} and not exists $_RM->{$_LQ}{$_EI}) {
        warn ('Warning: [cartridge id = \'' . $_LQ . '\'] Mandatory cartridge attribute \'' . $_EI . '\' not defined' . "\n");
        $_bZ++;
      }
    }
    if (not exists $_RM->{$_LQ}{'terminator'}) {
      $_RM->{$_LQ}{'terminator'} = $_4D;
    }
    else {
      $_RM->{$_LQ}{'terminator'} =~ s/cr/\r/gi;
      $_RM->{$_LQ}{'terminator'} =~ s/lf/\n/gi;
    }

    if (exists $_RM->{$_LQ}{'prompt'}) {
      my @_JV = split (m/\s*:!:\s*/, $_RM->{$_LQ}{'prompt'});

      foreach my $_Mk (@_JV) {
        my @_Bm = split (m/\s*:,:\s*/, $_Mk);
        eval { qr/$_Bm[0]/ };

        if ($@) {
          (my $_Yf = $@) =~ s/\s+at\s+.*//sg;
          warn ('Warning: [cartridge id = \'' . $_LQ . '\'] Invalid regular expression for \'prompt\' element - ' . $_Yf . "\n");
          $_bZ++;
        }
      }
    }

    if (exists $_RM->{$_LQ}{'alt_username_prompt'}) {
      eval { qr/$_RM->{$_LQ}{'alt_username_prompt'}/im };

      if ($@) {
        (my $_Yf = $@) =~ s/\s+at\s+.*//sg;
        warn ('Warning: [cartridge id = \'' . $_LQ . '\'] Invalid regular expression for \'alt_username_prompt\' element - ' . $_Yf . "\n");
        $_bZ++;
      }
    }

    if (exists $_RM->{$_LQ}{'alt_password_prompt'}) {
      eval { qr/$_RM->{$_LQ}{'alt_password_prompt'}/im };

      if ($@) {
        (my $_Yf = $@) =~ s/\s+at\s+.*//sg;
        warn ('Warning: [cartridge id = \'' . $_LQ . '\'] Invalid regular expression for \'alt_password_prompt\' element - ' . $_Yf . "\n");
        $_bZ++;
      }
    }
  }

  if (exists $_xT->{'null'}) {
    warn ('Error: [transport id = \'null\'] Internal use only (reserved)' . "\n");
    exit (1);
  }
  elsif (exists $_K2->{'null'}) {
    warn ('Error: [alert id = \'null\'] Internal use only (reserved)' . "\n");
    exit (1);
  }

  foreach my $_xH (keys %{$_xT}) {
    foreach my $_6w (keys %{$_iO{'transport_' . $_xT->{$_xH}{'type'}}}) {
      if ($_6w ne 'type') {
        if ($_iO{'transport_' . $_xT->{$_xH}{'type'}}{$_6w} and not exists $_xT->{$_xH}{$_6w}) {
          warn ('Warning: [transport_' . $_xT->{$_xH}{'type'} . ' id = \'' . $_xH . '\'] Mandatory transport attribute \'' . $_6w . '\' not defined' . "\n");
          $_bZ++;
        }
      }
    }
  }

  foreach my $_wN (keys %{$_K2}) {
    foreach my $_ZU (keys %{$_iO{'alert_' . $_K2->{$_wN}{'type'}}}) {
      if ($_ZU ne 'type') {
        if ($_iO{'alert_' . $_K2->{$_wN}{'type'}}{$_ZU} and not exists $_K2->{$_wN}{$_ZU}) {
          warn ('Warning: [alert_' . $_K2->{$_wN}{'type'} . ' id = \'' . $_wN . '\'] Mandatory alert attribute \'' . $_ZU . '\' not defined' . "\n");
          $_bZ++;
        }
      }
    }
  }

  if (exists $_Qm->{'null'}) {
    warn ('Error: [proxy id = \'null\'] Internal use only (reserved)' . "\n");
    exit (1);
  }
  else {
    $_Qm->{'null'}{'null'} = 0;
  }

  foreach my $_Bw (keys %{$_Qm}) {
    if ($_Bw =~ m/[|'~]/) {
      warn ('Warning: [proxy id = \'' . $_Bw . '\'] Illegal characters detected within proxy name' . "\n");
      $_bZ++;
    }
    if ($_Bw ne 'null') {
      if (not exists $_Qm->{$_Bw}{'address'}) {
        $_Qm->{$_Bw}{'address'} = $_Bw;
      }
      foreach my $_PR (keys %{$_iO{'proxy'}}) {
        if ($_iO{'proxy'}{$_PR} and not exists $_Qm->{$_Bw}{$_PR}) {
          warn ('Warning: [proxy id = \'' . $_Bw . '\'] Mandatory proxy attribute \'' . $_PR . '\' not defined' . "\n");
          $_bZ++;
        }
      }

      if (not exists $_Qm->{$_Bw}{'terminator'}) {
        $_Qm->{$_Bw}{'terminator'} = $_4D;
      }
      else {
        $_Qm->{$_Bw}{'terminator'} =~ s/cr/\r/gi;
        $_Qm->{$_Bw}{'terminator'} =~ s/lf/\n/gi;
      }
    }

    if (exists $_Qm->{$_Bw}{'prompt'}) {
      eval { qr/$_Qm->{$_Bw}{'prompt'}/ };

      if ($@) {
        (my $_Yf = $@) =~ s/\s+at\s+.*//sg;
        warn ('Warning: [proxy id = \'' . $_Bw . '\'] Invalid regular expression for \'prompt\' element - ' . $_Yf . "\n");
        $_bZ++;
      }
    }

    if (exists $_Qm->{$_Bw}{'alt_username_prompt'}) {
      eval { qr/$_Qm->{$_Bw}{'alt_username_prompt'}/im };

      if ($@) {
        (my $_Yf = $@) =~ s/\s+at\s+.*//sg;
        warn ('Warning: [proxy id = \'' . $_Bw . '\'] Invalid regular expression for \'alt_username_prompt\' element - ' . $_Yf . "\n");
        $_bZ++;
      }
    }

    if (exists $_Qm->{$_Bw}{'alt_password_prompt'}) {
      eval { qr/$_Qm->{$_Bw}{'alt_password_prompt'}/im };

      if ($@) {
        (my $_Yf = $@) =~ s/\s+at\s+.*//sg;
        warn ('Warning: [proxy id = \'' . $_Bw . '\'] Invalid regular expression for \'alt_password_prompt\' element - ' . $_Yf . "\n");
        $_bZ++;
      }
    }
  }

  foreach my $_EW (keys %{$_fJ}) {
    if (not exists $_fJ->{$_EW}{'proxy'}) {
      push (@{$_fJ->{$_EW}{'proxy'}}, 'null');
      if (exists $_Ae->{'explicit_null_tag'}) {
        unshift (@{$_fJ->{$_EW}{'tag'}}, 'NULL');
      }
    }

    if ($_EW =~ m/[}{\s\\\/*?:]+/) {
      warn ('Warning: [node id = \'' . $_EW . '\'] Illegal characters detected within node name' . "\n");
      $_bZ++;
    }

    foreach my $_B8 (keys %{$_iO{'node'}}) {
      if ($_iO{'node'}{$_B8} and not exists $_fJ->{$_EW}{$_B8}) {
        warn ('Warning: [node id = \'' . $_EW . '\'] Mandatory node attribute \'' . $_B8 . '\' not defined' . "\n");
        $_bZ++;
      }
    }

    foreach my $_B8 (keys %{$_iO{'options'}}) {
      if ($_iO{'options'}{$_B8} and not exists $_fJ->{$_EW}{$_B8}) {
        warn ('Warning: [node id = \'' . $_EW . '\'] Mandatory node option \'' . $_B8 . '\' not defined' . "\n");
        $_bZ++;
      }
    }

    if (exists $_fJ->{$_EW}{'cartridge'}) {
      if (not exists $_RM->{$_fJ->{$_EW}{'cartridge'}}) {
        warn ('Warning: [node id = \'' . $_EW . '\'] Invalid reference to cartridge \'' . $_fJ->{$_EW}{'cartridge'} . '\'' . "\n");
        $_bZ++;
      }

      if (exists $_RM->{$_fJ->{$_EW}{'cartridge'}}{'rawpty'}) {
        if (lc ($_RM->{$_fJ->{$_EW}{'cartridge'}}{'rawpty'}) eq 'yes') {
          if (exists $_Qm->{$_fJ->{$_EW}{'proxy'}}{'rawpty'}) {
            if (lc ($_Qm->{$_fJ->{$_EW}{'proxy'}}{'rawpty'}) eq 'no') {
              warn ('Warning: [node id = \'' . $_EW . '\'] Cartridge option \'rawpty\' enabled, but proxy \'' . $_fJ->{$_EW}{'proxy'} . '\' has it disabled' . "\n");
              $_bZ++;
            }
          }
        }
      }

      if ((not exists $_RM->{$_fJ->{$_EW}{'cartridge'}}{'rawpty'})
          or (lc ($_RM->{$_fJ->{$_EW}{'cartridge'}}{'rawpty'}) eq 'no')) {
        $_fJ->{$_EW}{'raw'} = 1;
      }
      else {
        $_fJ->{$_EW}{'raw'} = 0;
      }

      if (exists $_RM->{$_fJ->{$_EW}{'cartridge'}}{'tag'}) {
        foreach my $_bg (@{$_RM->{$_fJ->{$_EW}{'cartridge'}}{'tag'}}) {
          if (not &_NP (qr/$_bg/i, @{$_fJ->{$_EW}{'tag'}})) {
            unshift (@{$_fJ->{$_EW}{'tag'}}, $_bg);
          }
        }
      }
    }

    if (exists $_fJ->{$_EW}{'gpg_keyid'} and not exists $_Ae->{'gpg_path'}) {
      warn ('Warning: [node id = \'' . $_EW . '\'] Option \'gpg_keyid\' specified, but global option \'gpg_path\' not set' . "\n");
      $_bZ++;
    }

    if (exists $_fJ->{$_EW}{'snmp_oids'} and not exists $_fJ->{$_EW}{'snmp_community'}) {
      warn ('Warning: [node id = \'' . $_EW . '\'] Option \'snmp_oids\' specified, but node option \'snmp_community\' not set' . "\n");
      $_bZ++;
    }

    if (exists $_fJ->{$_EW}{'address'} and exists $_fJ->{$_EW}{'method'}) {
      my ($_to, @_SC) = &_vf ($_fJ->{$_EW}{'method'}, $_fJ->{$_EW}{'address'}, $_fJ->{$_EW}{'username'});

      if (not $_to) {
        warn ('Warning: [node id = \'' . $_EW . '\'] Node has an invalid method specified' . "\n");
        $_bZ++;
      }
      else {
        $_fJ->{$_EW}{'comp_method'} = $_to;
        @{$_fJ->{$_EW}{'method_args'}} = ();
        foreach my $_Pi (@_SC) {
          push (@{$_fJ->{$_EW}{'method_args'}}, $_Pi);
        }
      }
    }

    if (not exists $_fJ->{$_EW}{'location'}) {
      $_fJ->{$_EW}{'location'} = '';
    }

    my $_5t = sub {
      my ($_EW) = @_;

      my $_ex = 1;
      foreach my $_oW (@{$_80{'tag'}}) {
        if (not &_in ($_oW, @{$_fJ->{$_EW}{'tag'}})) {
          $_ex = 0;
          last;
        }
      }
      if ($_ex) {
        if (exists $_80{'nodelist'}) {
          if (&_NP (qr/$_EW/i, keys (%{$_80{'nodelist'}}))) {
            return (1);
          }
        }
        else {
          if ($_EW =~ $_80{'node'}) {
            return (1);
          }
        }
      }
      return (0);
    };

    if (exists $_fJ->{$_EW}{'transport'}) {
      for (my $_Ew = 0; $_Ew < $#{$_fJ->{$_EW}{'transport'}} + 1; $_Ew++) {
        if (not exists $_xT->{${$_fJ->{$_EW}{'transport'}}[$_Ew]}) {
          warn ('Warning: [node id = \'' . $_EW . '\'] Transport doesn\'t exist \'' . ${$_fJ->{$_EW}{'transport'}}[$_Ew] . '\'' . "\n");
          $_bZ++;
          last;
        }

        if (&$_5t ($_EW)) {
          push (@{$_xT->{${$_fJ->{$_EW}{'transport'}}[$_Ew]}{'nodes'}}, $_EW);
        }
      }
    }

    if (exists $_fJ->{$_EW}{'alert'}) {
      for (my $_Ew = 0; $_Ew < $#{$_fJ->{$_EW}{'alert'}} + 1; $_Ew++) {
        if (not $#{$_fJ->{$_EW}{'alert'}}) {
          if (${$_fJ->{$_EW}{'alert'}}[$_Ew] eq 'null') {
            delete ($_fJ->{$_EW}{'alert'});
            last;
          }
        }

        if (not exists $_K2->{${$_fJ->{$_EW}{'alert'}}[$_Ew]}) {
          warn ('Warning: [node id = \'' . $_EW . '\'] Alert doesn\'t exist \'' . ${$_fJ->{$_EW}{'alert'}}[$_Ew] . '\'' . "\n");
          $_bZ++;
          last;
        }

        if (&$_5t ($_EW)) {
          push (@{$_K2->{${$_fJ->{$_EW}{'alert'}}[$_Ew]}{'nodes'}}, $_EW);
        }
      }
    }
    elsif ((not $_bZ) and (keys %{$_K2})) {
      warn ('Warning: [node id = \'' . $_EW . '\'] Alerts defined but not used - use an alert of \'null\' to suppress this message' . "\n");
      $_7l++;
    }

    if (not exists $_fJ->{$_EW}{'transport'} and exists $_fJ->{$_EW}{'command'}) {
      if ((exists $_80{'default'}) and (not length $_80{'default'})) {
        warn ('Warning: [node id = \'' . $_EW . '\'] Node doesn\'t have any valid transports defined, but has commands defined' . "\n");
        $_bZ++;
      }
    }

    my @_TC = @{$_fJ->{$_EW}{'proxy'}};
    for (my $_vK = 0; $_vK < $#_TC + 1; $_vK++) {
      foreach my $_SS (split (m/\|/, $_TC[$_vK])) {
        if (not exists $_Qm->{$_SS}) {
          warn ('Warning: [node id = \'' . $_EW . '\'] Invalid reference to proxy \'' . $_SS . '\'' . "\n");
          $_bZ++;
        }
        else {
          if (exists $_Qm->{$_SS}{'tag'}) {
            foreach my $_73 (@{$_Qm->{$_SS}{'tag'}}) {
              if (not &_NP (qr/$_73/i, @{$_fJ->{$_EW}{'tag'}})) {
                unshift (@{$_fJ->{$_EW}{'tag'}}, $_73);
              }
            }
          }
        }
      }
    }

    if (not exists $_fJ->{$_EW}{'tag'}) {
      push (@{$_fJ->{$_EW}{'tag'}}, '');
    }

    my $_jt = sub {
      my ($_EW) = @_;

      foreach my $_Ep (keys %{$_fJ->{$_EW}}) {
        if ($_Ep =~ m/^(username$|password$|custom_)/) {
          if ($_fJ->{$_EW}{$_Ep} =~ m/^x\|X\|(.+)\|X\|x$/) {
            $_UF{$1}{'valid'} = 1;
          }
        }
      }
    };

    my $_ex = 1;
    foreach my $_oW (@{$_80{'tag'}}) {
      if (not &_in ($_oW, @{$_fJ->{$_EW}{'tag'}})) {
        $_ex = 0;
        last;
      }
    }

    if ($_ex) {
      my $_Qd = sub {
        for (my $_vK = 0; $_vK < $#_TC + 1; $_vK++) {
          if ($_TC[$_vK] =~ m/\|/) {
            my @_pG = split (m/\|/, $_TC[$_vK]);
            if (not exists $_7T{$_TC[$_vK]}) {
              $_7T{$_TC[$_vK]} = 0;
            }
            $_TC[$_vK] = $_pG[$_7T{$_TC[$_vK]}++ % ($#_pG + 1)];
          }
        }
      };

      if (exists $_80{'nodelist'}) {
        if (&_NP (qr/$_EW/i, keys (%{$_80{'nodelist'}}))) {
          $_y6 = (length ($_EW) > $_y6) ? length ($_EW) : $_y6;
          &$_Qd;
          $_fJ->{$_EW}{'proxy'} = $_TC[0];
          push (@{$_Qm->{join ('|', @_TC)}{'nodes'}}, $_EW);
          &$_jt ($_EW);
        }
        else {
          delete ($_fJ->{$_EW});
        }
      }
      else {
        if ($_EW =~ $_80{'node'}) {
          $_y6 = (length ($_EW) > $_y6) ? length ($_EW) : $_y6;
          &$_Qd;
          $_fJ->{$_EW}{'proxy'} = $_TC[0];
          $_fJ->{$_EW}{'phops'} = join (' -> ', @_TC);
          push (@{$_Qm->{join ('|', @_TC)}{'nodes'}}, $_EW);
          &$_jt ($_EW);
        }
        else {
          delete ($_fJ->{$_EW});
        }
      }
    }
    else {
      delete ($_fJ->{$_EW});
    }
  }

  foreach my $_wN (keys %{$_K2}) {
    if (exists $_K2->{$_wN}{'nodes'}) {
      foreach my $_Ep ('username', 'password') {
        if (exists ($_K2->{$_wN}{$_Ep}) and ($_K2->{$_wN}{$_Ep} =~ m/^x\|X\|(.+)\|X\|x$/)) {
          $_UF{$1}{'valid'} = 1;
        }
      }
    }
  }

  my %_dv = ();
  foreach my $_DN (keys %{$_xT}) {
    if (exists $_xT->{$_DN}{'nodes'}) {
      foreach my $_Ep ('username', 'password') {
        if (exists ($_xT->{$_DN}{$_Ep}) and ($_xT->{$_DN}{$_Ep} =~ m/^x\|X\|(.+)\|X\|x$/)) {
          $_UF{$1}{'valid'} = 1;
        }
      }
      $_dv{$_xT->{$_DN}{'type'}} = 1;
    }
  }

  if (exists $_dv{'ftp'}) {
    eval { require Net::FTP };

    if ($@) {
      warn ('Error: Transport type \'ftp\' is being used, but Net::FTP can\'t be found' . "\n");
      $_bZ++;
    }
  }

  if (exists $_dv{'sftp'}) {
    eval { require Net::SSH2 };

    if ($@) {
      warn ('Error: Transport type \'sftp\' is being used, but Net::SSH2 can\'t be found' . "\n");
      $_bZ++;
    }
  }

  foreach my $_Bw (keys %{$_Qm}) {
    if (exists $_Qm->{$_Bw}{'address'} and exists $_Qm->{$_Bw}{'method'}) {
      my ($_L3, @_3n) = &_vf ($_Qm->{$_Bw}{'method'}, $_Qm->{$_Bw}{'address'}, $_Qm->{$_Bw}{'username'});

      if (not $_L3) {
        warn ('Warning: [proxy id = \'' . $_Bw . '\'] Proxy has an invalid method specified' . "\n");
        $_bZ++;
      }
      else {
        $_Qm->{$_Bw}{'comp_method'} = $_L3;
        @{$_Qm->{$_Bw}{'method_args'}} = ();
        foreach my $_Ff (@_3n) {
          push (@{$_Qm->{$_Bw}{'method_args'}}, $_Ff);
        }
      }
    }

    if (exists $_Qm->{$_Bw}{'nodes'}) {
      foreach my $_Ep ('username', 'password') {
        if (exists ($_Qm->{$_Bw}{$_Ep}) and ($_Qm->{$_Bw}{$_Ep} =~ m/^x\|X\|(.+)\|X\|x$/)) {
          $_UF{$1}{'valid'} = 1;
        }
      }
      if (exists $_Ae->{'socks_wrapper'} and not exists $_Qm->{$_Bw}{'socks_wrapper'}) {
        $_Qm->{$_Bw}{'socks_wrapper'} = $_Ae->{'socks_wrapper'};
      }
      if (exists $_Qm->{$_Bw}{'socks_wrapper'}) {
        if (not -x $_Qm->{$_Bw}{'socks_wrapper'}) {
          warn ('Warning: [proxy id = \'' . $_Bw . '\'] \'socks_wrapper\' specified, but unable to execute \'' . $_Qm->{$_Bw}{'socks_wrapper'} . '\'' . "\n");
          $_bZ++;
        }
        elsif ($_Bw !~ m/\|/ and ($_Qm->{$_Bw}{'method'} =~ m/ssh/i)) {
          my @_mp = ();
          my @_tG = ();

          foreach my $_EW (sort @{$_Qm->{$_Bw}{'nodes'}}) {
            if ($_fJ->{$_EW}{'method'} =~ m/ssh/i) {
              $_fJ->{$_EW}{'_socks_'} = 1;
              push (@_mp, $_EW);
            }
            else {
              push (@_tG, $_EW);
            }
          }
          if (not exists $_80{'report'}) {
            if (($#_mp > -1) and ($#_tG > -1)) {
              foreach my $_wJ (keys %{$_Qm->{$_Bw}}) {
                if (lc ($_wJ) ne 'nodes') {
                  $_Qm->{$_Bw . '~'}{$_wJ} = $_Qm->{$_Bw}{$_wJ};
                }
              }
              $_Qm->{$_Bw}{'nodes'} = \@_mp;
              $_Qm->{$_Bw}{'socks_supported'} = 1;
              $_Qm->{$_Bw . '~'}{'nodes'} = \@_tG;
              delete ($_Qm->{$_Bw . '~'}{'socks_wrapper'});
            }
            elsif ($#_mp > -1) {
              $_Qm->{$_Bw}{'nodes'} = \@_mp;
              $_Qm->{$_Bw}{'socks_supported'} = 1;
            }
            elsif ($#_tG > -1) {
              $_Qm->{$_Bw}{'nodes'} = \@_tG;
              delete ($_Qm->{$_Bw}{'socks_wrapper'});
            }
          }
        }
      }
      elsif (exists $_Qm->{$_Bw}{'local_socks_port'} and not exists $_Qm->{$_Bw}{'socks_wrapper'}) {
        warn ('Warning: [proxy id = \'' . $_Bw . '\'] \'local_socks_port\' is not supported without \'socks_wrapper\'' . "\n");
        $_bZ++;
      }
      else {
        my @_U9 = sort (@{$_Qm->{$_Bw}{'nodes'}});
        $_Qm->{$_Bw}{'nodes'} = \@_U9;
      }
    }
  }

  if ($_bZ) {
    warn ('Error: Warnings have been detected within the configuration' . "\n");
    exit (1);
  }

  if (not keys %$_fJ) {
    warn ('Error: No valid nodes selected' . "\n");
    exit (1);
  }
}

sub _qR {
  my $_0b = &_NG ($_Jo);
  my %_RM = ();

  if (not -f $_Jo) {
    warn ('Error: (' . $_Jo . '): File doesn\'t exist' . "\n");
    exit (1);
  }

  my $_yC;
  eval { $_yC = LoadFile ($_Jo) };

  if ($@) {
    (my $_Oe = $@) =~ s/\s+at\s+\/.+$//s;
    if ($_Oe =~ m/\Q$_0b\E/) {
      warn ('Error: ' . $_Oe . "\n");
      exit (1);
    }
    else {
      warn ('Error: (' . $_Jo . '): ' . $_Oe . "\n");
      exit (1);
    }
  }

  foreach my $_E1 (keys %$_yC) {
    if (&_NP (qr/$_E1/, keys (%{$_I3{'root'}}))) {
      if ($_E1 eq 'cartridge') {
        &_yd (\%_RM, $_E1, $_yC->{$_E1});
      }
    }
    else {
      warn ('Warning: (' . &_NG ($_Jo) . '): Invalid root object \'' . $_E1 . '\' - skipping object' . "\n");
      $_Ah++;
    }
  }
  return (\%_RM);
}

sub _P2 {
  my $_0b = &_NG ($_2z);
  my %_Ae = ();
  my %_xT = ();
  my %_fJ = ();
  my %_K2 = ();
  my %_Qm = ();
  my %_u8 = ();

  if (not -f $_2z) {
    warn ('Error: (' . $_2z . '): File doesn\'t exist' . "\n");
    exit (1);
  }

  my $_yC;
  eval { $_yC = LoadFile ($_2z) };

  if ($@) {
    (my $_Oe = $@) =~ s/\s+at\s+\/.+$//s;
    if ($_Oe =~ m/\Q$_0b\E/) {
      warn ('Error: ' . $_Oe . "\n");
      exit (1);
    }
    else {
      warn ('Error: (' . $_2z . '): ' . $_Oe . "\n");
      exit (1);
    }
  }

  foreach my $_E1 (sort {
    if ($a =~ m/^alert_/) { -1 }
      elsif ($b =~ m/^alert_/) { 1 }
      elsif ($a =~ m/^transport_/) { -1 }
      elsif ($b =~ m/^transport_/) { 1 }
      elsif ($a eq 'proxy') { -1 }
      elsif ($b eq 'proxy') { 1 }
      else { 1 }
    } keys %$_yC) {
    if (&_NP (qr/$_E1/, keys (%{$_iO{'root'}}))) {
      if ($_E1 eq 'proxy') {
        &_ZL (\%_Qm, \%_u8, 0, $_E1, $_yC->{$_E1});
      }
      elsif ($_E1 eq 'container') {
        &_fV (\%_fJ, \%_xT, \%_K2, \%_u8, 1, $_yC->{$_E1});
      }
      elsif ($_E1 =~ m/^transport_/) {
        &_ZL (\%_xT, \%_u8, 0, $_E1, $_yC->{$_E1});
      }
      elsif ($_E1 =~ m/^alert_/) {
        &_ZL (\%_K2, \%_u8, 0, $_E1, $_yC->{$_E1});
      }
      else {
        my $_xZ = &_SU ($_E1, 1, $_yC->{$_E1}, 0);
        if (defined $_xZ) {
          if ($_xZ =~ m/^!\|!\|!(.+?)!\|!\|!(.+)$/) {
            $_Ae{$_E1} = $2;
            $_Ae{'enc:' . $_E1} = $1;
          }
          else {
            $_Ae{$_E1} = $_xZ;
          }
        }
      }
    }
    else {
      warn ('Warning: (' . &_NG ($_2z) . '): Invalid root object \'' . $_E1 . '\' - skipping object' . "\n");
      $_Ah++;
    }
  }
  return (\%_Ae, \%_xT, \%_K2, \%_fJ, \%_Qm);
}


# ----- Core Functions -----

sub _Rd {
  while ((my $_uj = waitpid (-1, WNOHANG)) > 0) {
    if (exists $_sw{$_uj}) {
      delete ($_sw{$_uj});
    }
  }
  $SIG{'CHLD'} = \&_Rd;
}

sub _RR {
  while ((my $_uj = waitpid (-1, WNOHANG)) > 0) {
    if (exists $_Ko{$_uj}) {
      delete ($_Ko{$_uj});
    }
    elsif (exists $_iu{$_uj}) {
      delete ($_iu{$_uj});
    }
  }
  $SIG{'CHLD'} = \&_RR;
}

sub _QT {
  my $_1n = 8;
  my @_EY = ();
  my %_EY = ('ns4' => $_nn);

  foreach my $_y9 (@_B2) {
    eval ('require ' . $_y9);
    if ($@) {
      $_EY{$_y9} = 'N';
      $_1n = ((length ($_y9) + 1) > $_1n) ? (length ($_y9) + 1) : $_1n;
      push (@_EY, $_y9);
    }
  }

  eval { use Config qw(myconfig) };
  if (not $@) {
    (my $_pG = myconfig) =~ s/^\s*(.*?)\s*$/$1/s;
    print $_pG . "\n\n";
  }

  print 'Loaded modules:' . "\n";

  foreach my $_y9 (keys %INC) {
    if ($_y9 =~ m/\.pm$/i) {
      $_y9 =~ s/\//::/g; $_y9 =~ s/\.pm$//i;
      my $_Ep = $_y9->VERSION;
      if (defined $_Ep) {
        $_EY{$_y9} = $_Ep;
        $_1n = ((length ($_y9) + length ($_Ep)) > $_1n) ? (length ($_y9) + length ($_Ep)) : $_1n;
      }
      else {
        $_EY{$_y9} = 'U';
        $_1n = ((length ($_y9) + 1) > $_1n) ? (length ($_y9) + 1) : $_1n;
      }
      push (@_EY, $_y9);
    }
  }

  @_EY = sort @_EY;
  unshift (@_EY, 'ns4');

  my $_KL = 3;
  for (my $_7X = 0, my $_KT = 1; $_7X < $#_EY + 1; $_7X++, $_KT++) {
    my $_B8 = $_EY[$_7X] . ' .' . ('.' x ($_1n - (length ($_EY[$_7X]) + length ($_EY{$_EY[$_7X]})))) . '. ' . $_EY{$_EY[$_7X]};

    if ($_KT == 1) {
      print '  ' . $_B8 . ((($_7X ne $#_EY) and ($_KT ne $_KL)) ? ' | ' : "\n");
      if ($_KT eq $_KL) {
        $_KT = 0;
      }
    }
    elsif ($_KT eq $_KL) {
      print $_B8 . "\n";
      $_KT = 0;
    }
    else {
      print $_B8 . (($_7X ne $#_EY) ? ' | ' : "\n");
    }
  }

  print "\n";
  print '@INC:' . "\n";

  foreach my $_7X (@INC) {
    print '  ' . $_7X . "\n";
  }
}

sub _VG {
  my ($_h7) = @_;
  if (open (my $_xy, '>', $_r3)) {
    syswrite ($_xy, $_h7);
    close ($_xy);
  }
}

sub _in {
  my $_D0 = shift;

  if (not @_) {
    if ('' =~ $_D0) {
      return (1);
    }
  }
  else {
    foreach my $_Ep (@_) {
      if ($_Ep =~ $_D0) {
        return (1);
      }
    }
  }
  return (0);
}

sub _NP {
  my $_D0 = shift;
  my ($_WM, $_g8) = (undef, undef);

  if ($_D0 =~ m/^\(\?(\S*)\-(\S*):(.+)\)$/) {
    ($_WM, $_g8, $_D0) = ($1, $2, $3);
  }

  foreach my $_Ep (@_) {
    if (defined $_WM and $_WM =~ m/i/) {
      if (lc ($_D0) eq lc ($_Ep)) {
        return (1);
      }
    }
    else {
      if ($_D0 eq $_Ep) {
        return (1);
      }
    }
  }
  return (0);
}

sub _G4 {
  my ($_lV) = @_;
  for (my $_7X = 0; $_7X < 10; $_7X++) {
    if (mkdir ($_wK . $_lV, 0000)) {
      return (1);
    }
    if ($_7X != 9) {
      sleep (1);
    }
  }
  return (0);
}

sub _PH {
  my ($_lV) = @_;
  rmdir ($_wK . $_lV);
}

sub _X2 {
  my ($_TL, $_Ku, $_EW, $_ND, $_Bw, $_7P, $_cP, $_gT, $_u1, $_8X, $_KE) = @_;
  my $_k2 = $_Qm->{$_Bw}{'terminator'};
  my $_CW = qr/^.*(username|login):\s*$/im;
  my $_0h = qr/^.*password:\s*$/im;
  my ($_sE, $_mC) = (0, 0);
  my $_Nv = 0;
  my %_5E = ();
  my $_Zg = undef;

  my ($_lP, $_6r) = &_ih ($_u1, $_EW, $_ND, \$_Nv, \$_Zg, \%_5E, $_8X);

  if (defined $_EW) {
    my $_fc = $_fJ->{$_EW}{'cartridge'};
    if (exists $_RM->{$_fc}{'alt_username_prompt'}) {
      $_CW = qr/$_RM->{$_fc}{'alt_username_prompt'}/im;
    }
    if (exists $_RM->{$_fc}{'alt_password_prompt'}) {
      $_0h = qr/$_RM->{$_fc}{'alt_password_prompt'}/im;
    }
  }
  else {
    if (exists $_Qm->{$_Bw}{'alt_username_prompt'}) {
      $_CW = qr/$_Qm->{$_Bw}{'alt_username_prompt'}/im;
    }
    if (exists $_Qm->{$_Bw}{'alt_password_prompt'}) {
      $_0h = qr/$_Qm->{$_Bw}{'alt_password_prompt'}/im;
    }
  }

  $$_TL->expect ($_Ku,
    [ $_CW,
      sub {
        my $_N2 = shift;
        if (not $_Nv) {
          if (not $_sE++) {
            if (defined $_EW) {
              $_N2->send ($_cP . $_8X);
            }
            else {
              $_N2->send ($_cP . $_k2);
            }
            return ($_N2->exp_continue_timeout);
          }
          else {
            $_Zg = 152;
          }
        }
        else {
          for (my $_7X = 0; $_7X < $#{$_lP} + 1; $_7X++) {
            my @_t6 = @{$$_lP[$_7X]};
            if ($_N2->match =~ $_t6[0]) {
              return (&{$_t6[1]}($_N2));
            }
          }
          $_Zg = 158;
        }
      }
    ],
    [ $_0h,
      sub {
        my $_N2 = shift;
        if (not $_Nv) {
          if (not $_mC++) {
            if ((defined $_EW) and ($_KE !~ m/ssh/i)) {
              $_N2->send ($_gT . $_8X);
            }
            elsif ((defined $_EW) and ($_Bw ne 'null')) {
              $_N2->send ($_gT . $_k2);
            }
            elsif ($_KE !~ m/ssh/i) {
              $_N2->send ($_gT . $_k2);
            }
            elsif (defined $_7P) {
              $_N2->send ($_gT . $_Qm->{$_7P}{'terminator'});
            }
            else {
              $_N2->send ($_gT . $_4D);
            }
            return ($_N2->exp_continue_timeout);
          }
          else {
            $_Zg = 152;
          }
        }
        else {
          for (my $_7X = 0; $_7X < $#{$_lP} + 1; $_7X++) {
            my @_t6 = @{$$_lP[$_7X]};
            if ($_N2->match =~ $_t6[0]) {
              return (&{$_t6[1]}($_N2));
            }
          }
          $_Zg = 158;
        }
      }
    ],
    [ qr/continue connecting/im,
      sub {
        my $_N2 = shift;
        if ((defined $_EW) and ($_Bw ne 'null')) {
          $_N2->send ('yes' . $_k2);
        }
        elsif (defined $_7P) {
          $_N2->send ('yes' . $_Qm->{$_7P}{'terminator'});
        }
        else {
          $_N2->send ('yes' . $_4D);
        }
        return ($_N2->exp_continue_timeout);
      }
    ],
    [ qr/host key verification failed/im, sub { $_Zg = 151 } ],
    [ qr/Could not request local forwarding/im, sub { $_Zg = 155 } ],
    @{$_lP},
    [ qr/$_6r/im, sub { $_Zg = 100 } ],
    [ timeout => sub { $_Zg = 116 } ],
    [ eof => sub { $_Zg = 102 } ]
  );

  if (not defined $_Zg) {
    $_Zg = 102;
  }

  if ($_Zg == 116) {
    if ($_80{'verbose'}) {
      my @_Vn = split ($_IV, $$_TL->before);
      if ($#_Vn > -1) {
        if (defined $_EW) {
          &_Z2 (__LINE__, 'Node \'' . $_EW . '\' - Unmatched Last Line: \'' . $_Vn[-1] . '\'');
        }
        else {
          (my $_fm = $_Bw) =~ s/~$//;
          &_Z2 (__LINE__, 'Proxy \'' . $_fm . '\' - Unmatched Last Line: \'' . $_Vn[-1] . '\'');
        }
      }
    }
  }

  if ($_Zg !~ m/^10(0|2)$/) {
    if (defined $$_TL->pid) {
      kill ('KILL', $$_TL->pid);
    }
  }
  if ($_Zg != 100) {
    $$_TL = undef;
  }
  return ($_Zg);
}


# --- Helper Functions ---

sub _G7 {
  my ($_YV, $_EW, $_Bw, $_0V, $_lF) = @_;

  while ($_YV =~ m/\[([^\[]+?)\]/gi) {
    my $_3I = $1;
    my $_1I = &$_34 ($_3I, $_EW, $_Bw, $_lF);
    if (defined $_1I) {
      if ($_0V and ($_3I !~ m/n:prompt/i)) {
        $_YV =~ s/\[\Q$_3I\E\]/\Q$_1I\E/;
      }
      else {
        $_YV =~ s/\[\Q$_3I\E\]/$_1I/;
      }
    }
  }
  return ($_YV);
}

sub _x0 {
  my ($_D1, $_EW, $_Bw) = @_;

  my $_Ks = &_G7 ($_D1, $_EW, $_Bw, 0, 0);
  $_Ks =~ s/\/+/\//g;
  my ($_Qi, $_sr) = ($_Ks =~ m/^(.*\/)(.*)$/);

  if (length ($_Qi) and length ($_sr)) {
    if (not exists $_tP{$_Qi}) {
      $_tP{$_Qi} = 1;

      if (($_Qi =~ tr/\///) > 1) {
        if (not -d $_Qi) {
          my @_Ok = split (m/\//, $_Qi);

          for (my $_7X = 1; $_7X < $#_Ok + 1; $_7X++) {
            my $_yR = (-w join ('/', @_Ok[0..($_7X-1)]) . '/') ? 1 : 0;

            if ((not -d join ('/', @_Ok[0..$_7X])) and not $_yR) {
              return (10, $_Qi);
            }
            elsif (not -d join ('/', @_Ok[0..$_7X])) {
              last;
            }
          }
        }
        elsif (not -w $_Qi) {
          return (10, $_Qi);
        }
      }
      elsif (not -w $_Qi) {
        return (10, $_Qi);
      }
    }

    if (-e $_Ks) {
      if (-w $_Ks and -f $_Ks) {
        return (20, $_Ks);
      }
      else {
        return (30, $_Ks);
      }
    }
    return (0, $_Ks);
  }
  else {
    return (99, '');
  }
}

sub _rE {
  my ($_oa, $_Fe, $_ra) = @_;

  if ($_oa) {
    $$_ra =~ s/^.+?$_Fe//s;
  }

  $$_ra =~ s/^(?:\s*?$_Fe)+//s;
  $$_ra =~ s/$_Fe(?:\s*?$_Fe)+$/$_Fe/s;
  return (1);
}

sub _vf {
  my ($_49, $_wB, $_i5) = @_;
  my ($_1H, $_fl) = (undef, undef);

  if ($_wB =~ m/(\S+):(\S+)/) {
    ($_1H, $_fl) = ($1, $2);
  }
  else {
    $_1H = $_wB;
  }

  if ($_49 =~ m/^(\S+)\s+(.+)/) {
    my ($_Cv, $_Va) = ($1, $2);

    if ($_Va !~ m/\[host\]/i) {
      return (undef); 
    }

    if ($_Cv =~ m/(ssh|telnet)/i) {
      if (not defined $_fl) {
        if ($_Cv =~ m/ssh/i) {
          $_fl = 22;
        }
        elsif ($_Cv =~ m/telnet/i) {
          $_fl = 23;
        }
      }
      elsif ($_Va !~ m/\[port\]/i) {
        return (undef);
      }

      $_Va =~ s/\[host\]/$_1H/gi;
      $_Va =~ s/\[port\]/$_fl/gi;
      $_Va =~ s/\[user\]/$_i5/gi;

      my @_cM = split (m/\s*,\s*/, $_Va);
      return ($_Cv, @_cM);
    }
  }
  return (undef);
}

sub _Pd {
  my ($_5N, $_EW, $_yS, $_y6) = @_;

  if (($_yS !~ m/\D/) and ($_yS == 259)) {
    my $_Xl = '/tmp/.ns4-' . $_5N . '.' . lc ($_EW) . '.syntax';
    if (open (my $_EZ, '<', $_Xl)) {
      my $_l2 = <$_EZ>;
      close ($_EZ);
      unlink ($_Xl);

      my $_gB = 0;
      foreach my $_tZ (@_ut) {
        if ($_l2 eq $_tZ) {
          $_gB = 1;
          last;
        }
      }
      if (not $_gB) {
        print '---' . "\n";
        print $_l2;
        print '---' . "\n";
        push (@_ut, $_l2);
      }
    }
    else {
      print '---' . "\n";
      print 'File Not Found - \'' . $_Xl . '\'' . "\n";
      print '---' . "\n";
    }
  }

  print '>> ' . $_EW . ' ' . '.' x (($_y6 - length ($_EW)) + 2) . ' ' . &_j6 ($_yS) . "\n";

  if ($_yS =~ m/\D/) {
    if ($_yS !~ m/^100:.+/) {
      $_gE++;
    }
  }
  elsif ($_yS !~ m/^(200|204|253)$/) {
    $_gE++;
  }

  $_fJ->{$_EW}{'status'} = $_yS;
  $_6W++;
}

sub _NG {
  return ($_[0] =~ m/[\\\/]([^\\\/]+)$/) ? $1 : $_[0];
}

sub _yH {
  my ($_MR, $_MP, $_K9) = @_;

  if (&_G4 (1)) {
    print $_K9 . "\n";
    if (defined $_MP) {
      if (sysopen (my $_xy, $_MP, O_WRONLY|O_CREAT|O_APPEND, 0644)) {
        syswrite ($_xy, $_K9 . "\n");
        close ($_xy);
      }
      else {
        warn ('Warning: Logfile \'' . $_MP . '\' failed to open for writing - ' . $! . "\n");
      }
    }
    &_PH (1);
  }
  else {
    warn ('Warning: mLock function failed - this shouldn\'t happen' . "\n");
  }
}

sub _Z2 {
  my ($_MR, $_K9) = @_;
  my $_rg = strftime ('%H:%M:%S', localtime);
  print '[' . $_rg . '] ' . $_K9 . "\n";
}

sub _ih {
  my ($_qp, $_EW, $_Bw, $_Nv, $_Zg, $_5E, $_8X) = @_;
  my @_lP = ();

  my @_KR = split (m/\s:!:\s/, $_qp);

  if ($#_KR > 0) {
    foreach my $_QK (@_KR[1..$#_KR]) {
      my @_cN = split (m/\s:,:\s/, $_QK);
      $_cN[1] = '' if (not defined $_cN[1]);

      if ($#_cN == 1) {
        $_cN[0] = &_G7 ($_cN[0], $_EW, $_Bw, 1, 0);
        $_cN[1] = &_G7 ($_cN[1], $_EW, $_Bw, 1, 0);
        push (@_lP, [qr/$_cN[0]/im, sub {
            my $_N2 = shift;
            if ($_cN[1] =~ m/^\\cC$/i) {
              if (defined $_N2->pid) {
                kill ('KILL', $_N2->pid);
              }
              if (defined $_Zg) {
                $$_Zg = 153;
              }
            }
            else {
              if (not exists $$_5E{$_cN[1]}) {
                $_N2->send ($_cN[1] . $_8X);
                $$_5E{$_cN[1]} = 1;
                if (defined $_Nv) {
                  $$_Nv++;
                }
                return ($_N2->exp_continue_timeout);
              }
              elsif (defined $_Zg) {
                $$_Zg = 158;
              }
            }
          }]);
      }
    }
  }
  return (\@_lP, $_KR[0]);
}

sub _70 {
  my ($_6e) = @_;

  my $_QH = floor ($_6e / (60 * 60 * 24 * 7 * 52));
  my $_3B = ($_6e / (60 * 60 * 24 * 7)) % 52;
  my $_Aj = ($_6e / (60 * 60 * 24)) % 7;
  my $_m9 = ($_6e / (60 * 60)) % 24;
  my $_W8 = ($_6e / 60) % 60;
  my $_Sp = $_6e % 60;
      
  my $_Pr = ($_QH > 1) ? $_QH . ' years, ' : ($_QH ? $_QH . ' year, ' : '');
  my $_es = ($_3B > 1) ? $_3B . ' weeks, ' : ($_3B ? $_3B . ' week, ' : '');
  my $_tS = ($_Aj > 1) ? $_Aj . ' days, ' : ($_Aj ? $_Aj . ' day, ' : '');
  my $_7L = ($_m9 > 1) ? $_m9 . ' hours, ' : ($_m9 ? $_m9 . ' hour, ' : '');
  my $_zi = ($_W8 > 1) ? $_W8 . ' minutes, ' : ($_W8 ? $_W8 . ' minute, ' : '');
  my $_4E = ($_Sp > 1) ? $_Sp . ' seconds' : ($_Sp ? $_Sp . ' second' : '');
  my $_CS = $_Pr . $_es . $_tS . $_7L . $_zi . $_4E;
  
  $_CS = (rindex ($_CS, ',') == (length $_CS) - 2) ? substr ($_CS, 0, (length $_CS) - 2) : $_CS;
  return ((not length $_CS) ? '0 seconds' : $_CS);
}

sub _6k {
  my ($_7K, $_G9) = @_;

  if (not $$_G9) {
    for (my $_y9 = 0; $_y9 < 3; $_y9++) {
      if (-s $_r3) {
        last;
      }
      sleep (1);
    }
  }
  if (-s $_r3 == 1) {
    return ($_7K + 104);
  }
  elsif (-s $_r3 == 3) {
    return ($_7K + 107);
  }
  elsif (-s $_r3 == 4) {
    return ($_7K + 108);
  }
  else {
    $$_G9 = 1;
    return ($_7K + 113);
  }
}

sub _j6 {
  my ($_sV) = @_;
  my %_a7 = (
    '101' => '[Proxy] Connection Timed Out',
    '102' => '[Proxy] Connection Refused',
    '116' => '[Proxy] Login Timed Out',
    '118' => '[Proxy] IPC Failed',
    '151' => '[Proxy] Host Key Failed',
    '152' => '[Proxy] Invalid Username/Password',
    '155' => '[Proxy] Port Forwarding Failed',
    '162' => '[Proxy] Unknown Error',
    '199' => '[Proxy] Couldn\'t Spawn Command',
    '200' => '[Node] OK',
    '201' => '[Node] Connection Timed Out',
    '202' => '[Node] Connection Refused',
    '203' => '[Node] Command Timed Out',
    '204' => '[Node] Break Signal',
    '207' => '[Node] Local File Permission Problem',
    '208' => '[Node] Lock File Failed - Dead Lock',
    '210' => '[Node] Temporary Storage Failed',
    '211' => '[Node] GnuPG Failure',
    '212' => '[Node] GnuPG Encryption Failure',
    '213' => '[Node] Unknown Semaphore Set',
    '215' => '[Node] Cartridge Processing Prematurely Terminated',
    '216' => '[Node] Login Timed Out',
    '217' => '[Node] Skipped',
    '218' => '[Node] IPC Failed',
    '251' => '[Node] Host Key Failed',
    '252' => '[Node] Invalid Username/Password',
    '253' => '[Node] OK',
    '254' => '[Node] Script Not Suitable',
    '256' => '[Node] Buffer Space Exceeded',
    '258' => '[Node] Pre/Post Command Failed',
    '259' => '[Node] Script Syntax Error',
    '260' => '[Node] Script Timed Out',
    '298' => '[Node] Couldn\'t Spawn Command',
    '299' => '[Node] Unknown Status'
  );

  if ($_sV =~ m/\D/) {
    if ($_sV =~ m/^(\d{3}):(.*)$/) {
      my ($_9E, $_XS) = ($1, $2);

      if ($_9E eq '100') {
        return ('[Node] OK (' . $_XS . ')');
      }
      elsif ($_9E eq '500') {
        return ('[Node] ' . $_XS);
      }
      elsif ($_9E eq '501') {
        return ('[Node] [CSR] ' . $_XS);
      }
    }
  }

  if (not exists $_a7{$_sV}) {
    return ('Unknown Status Code (Status = ' . $_sV . ')');
  }
  return ($_a7{$_sV});
}

