扫描二维码关注官方公众号
返回列表 发布新帖

[盒子/seedbox] MKS2g MTR出问题

 
1656 6
发表于 2013-4-21 10:52:48 | 显示全部楼层 阅读模式


如图, 给客服发了邮件一直没有回复,中间我重启两次不管用,重新装了次系统还是不管用。

按照FAQ给的方法安装:
How to install RTM?

RTM is included since release 1.60. You can also install it on other releases with the command:

# wget ftp://ftp.ovh.net/made-in-ovh/rtm/install_rtm.sh -O install_rtm.sh
# sh install_rtm.sh
运行命令后,第一行命令正常,第二条命令运行完出现如下提示:
2013-04-21 04:50:49 (3.67 MB/s) - `install_rtm.sh' saved [70097]

root@ks3****1:~# sh install_rtm.sh
install_rtm.sh: 14: [[: not found
install_rtm.sh: 48: function: not found
Generating update-report.pl...
install_rtm.sh: 51: cannot create /usr/local/rtm/bin/update-report.pl: Directory nonexistent
install_rtm.sh: 58: cannot create /usr/local/rtm/bin/update-report.pl: Directory nonexistent
install_rtm.sh: 64: cannot create /usr/local/rtm/bin/update-report.pl: Directory nonexistent
install_rtm.sh: 66: cannot create /usr/local/rtm/bin/update-report.pl: Directory nonexistent
chown: cannot access `/usr/local/rtm/bin/update-report.pl': No such file or directory
chmod: cannot access `/usr/local/rtm/bin/update-report.pl': No such file or directory
install_rtm.sh: 95: Syntax error: "}" unexpected
不知道是怎么回事。客服也不给解决。看看有没有高手指导我一下。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×

评论6

yk123456Lv.8 发表于 2013-4-21 11:06:31 | 显示全部楼层
不是很懂,试试
apt-get update

如果还是不行的话,把install_rtm.sh里面代码贴出来看看,14行和48喊少了什么?
论坛最快速获得金币办法:
1、去盒子区发评测贴,范例:
http://hd2pt.com/thread-133245-1-2.html
2、翻译国外友人的盒子评测贴,范例:
http://hd2pt.com/thread-134285-1-3.html
回复 点赞

使用道具 举报

pilot@2楼主Lv.3 发表于 2013-4-21 11:13:51 | 显示全部楼层
意思是把文件下载到本地然后看?
回复 点赞

使用道具 举报

pilot@2楼主Lv.3 发表于 2013-4-21 11:33:46 | 显示全部楼层
yk123456 发表于 2013-4-21 11:06
不是很懂,试试
apt-get update

#!/bin/bash

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH
export PATH

VERSION="0.9.4"
RELEASE_DATE="2011-12-06"

LC_ALL=POSIX

if [[ ! $(uname) =~ Linux ]]; then
  echo "This is version only for linux. Please install appropriate version from ftp://ftp.ovh.net/made-in-ovh/rtm/";
  exit 1;
fi

DIR="/usr/local/rtm"
DIR_SCRIPTS_DAILY="${DIR}/scripts/daily"
DIR_SCRIPTS_MIN="${DIR}/scripts/min"
DIR_SCRIPTS_HOUR="${DIR}/scripts/hour"
HDDTEMPDB_LINK="ftp://ftp.ovh.net/made-in-ovh/rtm/hddtemp.db"
HDDTEMP_LINK="ftp://ftp.ovh.net/made-in-ovh/rtm/hddtemp-0.3-beta12.tar.bz2"
DMIDECODE_LINK="ftp://ftp.ovh.net/made-in-ovh/rtm/dmidecode-2.4.tar.gz"
SLACK_HDDTEMP_LINK="ftp://ftp.ovh.net/made-in-ovh/rtm/utils/slackware/hddtemp"
SLACK_DMIDECODE_LINK="ftp://ftp.ovh.net/made-in-ovh/rtm/utils/slackware/dmidecode"
LSIUTIL_LINK="ftp://ftp.ovh.net/made-in-ovh/dedie/lsiutil"
DNSSERVER="213.186.33.99"
SCRIPTS_TO_INSTALL="check kernel release usage usage_root hwinfo hwinfo_root hddinfo smart raid raid_daily listen_ports"

RTM_PL=$DIR/bin/rtm-${VERSION}.pl
RTM_SH=$DIR/bin/rtm
RTM_UPDATE_IP=$DIR/bin/rtm-update-ip.sh

RTM_REPORT=$DIR/bin/update-report.pl

LSPCI=`which lspci 2>/dev/null`
CRONTAB=`which crontab 2>/dev/null`
SCREENDIR=`which screen 2>/dev/null`
if [ "$SCREENDIR" != "" ]; then SCREEN="$SCREENDIR -d -m"; fi
SCRIPTDIR="$DIR/scripts"
MPTSTATUS=`which mpt-status 2>/dev/null`
LSIUTIL=`which lsiutil 2>/dev/null`
HDDTEMP=`which hddtemp 2>/dev/null`
DMIDECODE=`which dmidecode 2>/dev/null`


#
# Generate update-report.pl file
function generate_update_report {
    echo "Generating update-report.pl..."
    cat << EOF > $RTM_REPORT
#! /usr/bin/perl
# version: $VERSION ($RELEASE_DATE)

\$ENV{"LC_ALL"} = "POSIX";

EOF
    cat <<'EOF' >> $RTM_REPORT
#!/usr/bin/perl

use strict;
use Socket;

EOF
    echo "my \$destination_ip = '$ip';" >> $RTM_REPORT
    cat <<'EOF' >> $RTM_REPORT
my $message = <>;
chomp($message);
exit if ($message eq '');

send_info($message);

sub send_info {
    my $message = shift;
    $message = "rtm dINFO_RTM_update|$message\n";
    my $port = 6100 + int(rand(100));
    my $ok = eval {
        local $SIG{ALRM} = sub { print "rtm timeout\n"; die; };
        alarm(10);

        my $proto = getprotobyname('udp');
        socket(Socket_Handle, PF_INET, SOCK_DGRAM, $proto);
        my $iaddr = gethostbyname($destination_ip);
        my $sin = sockaddr_in("$port", $iaddr);
        send(Socket_Handle, "$message", 10, $sin);
        print "$message";
        alarm(0);
    };
    if (!defined($ok)) {
        warn "error: $@\n";
    }
}
EOF
    chown root.root "$RTM_REPORT"
    chmod 750 "$RTM_REPORT"
}

# check if script dirs point to reasonable paths
for scr in "$DIR_SCRIPTS_DAILY", "$DIR_SCRIPTS_MIN", "$DIR_SCRIPTS_HOUR"; do
    if ! echo "$scr" | grep -q '^/usr/local/'; then
        echo "invalid script directory: $scr" >&2
        exit 1
    fi
done
# Remove old scripts dirs so there are no unwanted scripts hanging
# around
rm -rf "$DIR_SCRIPTS_DAILY"
rm -rf "$DIR_SCRIPTS_MIN"
rm -rf "$DIR_SCRIPTS_HOUR"

if [ ! -e "$DIR" ]; then mkdir -p $DIR; fi
if [ ! -e "$DIR_SCRIPTS_DAILY" ]; then mkdir -p "$DIR_SCRIPTS_DAILY"; fi
if [ ! -e "$DIR_SCRIPTS_MIN" ]; then mkdir -p "$DIR_SCRIPTS_MIN"; fi
if [ ! -e "$DIR_SCRIPTS_HOUR" ]; then mkdir -p "$DIR_SCRIPTS_HOUR"; fi
if [ ! -e "$DIR/bin" ]; then mkdir -p "$DIR/bin"; fi
if [ ! -e "$DIR/etc" ]; then mkdir -p "$DIR/etc"; fi

if [ ! -d "/usr/local/man/" ]; then mkdir -p  "/usr/local/man/"; fi

# main interface from route:
mainif=`route -n | grep "^0.0.0.0" | awk '{print $8}' | tail -1`

if test -n "$mainif"; then
  ips=`ifconfig $mainif | awk 'NR == 2 { print $2 }' | cut -f2 -d':' | egrep '[0-9]+(\.[0-9]+){3}'`
else
  for iface in 'eth0' 'eth1'; do
    ips=`ifconfig $iface 2>/dev/null | awk 'NR == 2 { print $2 }' | cut -f2 -d':' | egrep '[0-9]+(\.[0-9]+){3}'`
    if test -n "$ips"; then break; fi;
  done;
fi;

arpa=`echo "$ips" | sed "s/\./ /g" | awk '{print $3"."$2"."$1}'`;
ip=`host -t A mrtg.$arpa.in-addr.arpa $DNSSERVER 2>/dev/null | tail -n 1 | sed -ne 's/.*[\t ]\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\).*/\1/p'`
if [ -z "$ip" ]; then
  echo "No IP from OVH network or couldn't define MRTG server! Please contact OVH support."
  exit 1;
fi
echo $ip > "$DIR/etc/rtm-ip"


upgrade=$1
if [ "$upgrade" != "-u" ]; then
  if [ -z "$HDDTEMP" -o -z "$DMIDECODE" ]; then
    upgrade=""
  fi
fi

if [ -z "`which bzip2 2>/dev/null`" ]; then
  echo "bzip2 not found!!"
  echo "Please install bzip2."
  exit
fi


hostname=`hostname`
CWD=`pwd`

if [ "$update" != "-u" ]; then
  mkdir -p /rpms /usr/share/misc/

  # ###########################################
  # hddtemp check and compile/install:
  # ###########################################
  wget $HDDTEMPDB_LINK -O /usr/share/misc/hddtemp.db
  v=`hddtemp --version 2>/dev/null | cut -d' ' -f3`
  hddtempbeta=`echo $v | grep beta`
  if test "$hddtempbeta" != ""; then hddtempbeta='-beta'; fi;
  v=`echo $v | sed 's/-beta/ /'`
  hddtempmajor=`echo $v | cut -d' ' -f1`
  hddtempminor=`echo $v | cut -d' ' -f2`
  hddtempinstall=0

  if test "$hddtempbeta" == ""; then
    hddtempinstall=1
  else
    if test "$hddtempmajor" == ""; then
      hddtempinstall=1
    else
      echo "Found hddtemp version installed: ${hddtempmajor}${hddtempbeta}$hddtempminor. No new install needed."
    fi
  fi
  
  if test $hddtempinstall -ne 1; then
    if test "$hddtempmajor" == "0.3"; then
      case `echo "r=0;a=$hddtempmajor;b=0.3;if(a<b)r=1;r"|bc` in
        1) hddtempinstall=1
        ;;
      esac
    else
      case `echo "r=0;a=$hddtempmajor;b=0.3;if(a<b)r=1;r"|bc` in
        1) hddtempinstall=1
        ;;
      esac
    fi
  fi

  if test $hddtempinstall -eq 1; then
    if [ -f "/etc/slackware-version" ]; then
      wget $SLACK_HDDTEMP_LINK -O /usr/local/sbin/hddtemp
      chmod +x /usr/local/sbin/hddtemp
    else
      # compile and install:
      cd /rpms && \
      wget $HDDTEMP_LINK -O /rpms/hddtemp-0.3-beta12.tar.bz2 && \
      tar -xjf hddtemp-0.3-beta12.tar.bz2 && \
      cd hddtemp-0.3-beta12 && \
      ./configure && \
      make && \
      make install && \
      echo "hddtemp compilation and installation finished successfull."
    fi
  fi

  HDDTEMP=`which hddtemp 2>/dev/null`

  # ###########################################
  # dmidecode check and install if needed
  # ###########################################

  # check if version >= 2.4
  dmiver=`dmidecode --version 2>/dev/null`
  if test "$dmiver" == ""; then # for version 2.4:
    dmiver=`dmidecode | head -n1 | grep "# dmidecode" | cut -d' ' -f3 2>/dev/null`
  fi
  if test $? = 0; then
    case `echo "r=0;a=$dmiver;b=2.4;if(a<b)r=1;r" | bc` in
      0) echo "Found dmidecode v.$dmiver"
      ;;
      1) if [ -f "/etc/slackware-version" ]; then
           wget $SLACK_DMIDECODE_LINK -O /usr/local/sbin/dmidecode
           chmod +x /usr/local/sbin/dmidecode
         else
           cd /rpms/
           wget $DMIDECODE_LINK -O dmidecode-2.4.tar.gz
           tar xfz dmidecode-2.4.tar.gz
           cd dmidecode-2.4
           make
           make install
         fi
      ;;                                                                                                                                                                                                                                    
    esac
  fi

  DMIDECODE=`which dmidecode 2>/dev/null`

fi

echo "Checking for lsiutil ..."
if [ -z "$LSIUTIL" ]; then
  if [ -n "$LSPCI" -a "$LSPCI" ]; then
    PCIONBOARD=`$LSPCI -d 1000:`
  fi
  if [ -n "$PCIONBOARD" ]; then
    echo "Installing lsi-util ...";
    wget $LSIUTIL_LINK -O /usr/local/rtm/bin/lsiutil
    chmod 700 /usr/local/rtm/bin/lsiutil
  fi
fi

echo "Checking for mpt-status ..."
if [ -z "$MPTSTATUS" ]; then
  MPTADAPTERS=`cat /var/log/dmesg /var/log/boot.msg 2>/dev/null | grep "MPT" | grep "mptbase:" | cut -f2 -d" "`
  if [ -n "$MPTADAPTERS" -a "$MPTADAPTERS" != "0" ]; then
    echo "Installing mpt-status ...";
    wget ftp://ftp.ovh.net/made-in-ovh/dedie/mpt-status -O /usr/sbin/mpt-status
    chmod 700 /usr/sbin/mpt-status
  fi
fi

cd $CWD

#
# Generate /scripts/min/check.pl file
function generate_check {
    echo "Generating $DIR_SCRIPTS_MIN/check.pl..."
    cat << EOF > $DIR_SCRIPTS_MIN/check.pl
#! /usr/bin/perl
# version: $VERSION ($RELEASE_DATE)

\$ENV{"LC_ALL"} = "POSIX";

EOF
    cat <<'EOF' >> $DIR_SCRIPTS_MIN/check.pl
use strict;

if (`dmesg | grep -i "allocation failed"`) {
        print "mCHECK_vm|1\n";
} else {
        print "mCHECK_vm|\n";
}

if (`dmesg | grep -i "Oops"`) {
        print "mCHECK_oops|1\n";
} else {
        print "mCHECK_oops|\n";
}
EOF
    chown root.root "$DIR_SCRIPTS_MIN/check.pl"
    chmod 750 "$DIR_SCRIPTS_MIN/check.pl"
}

#
# Generate /scripts/day/kernel.sh file
function generate_kernel {
    echo "Generating $DIR_SCRIPTS_DAILY/kernel.sh..."
    cat << EOF > $DIR_SCRIPTS_DAILY/kernel.sh
#! /bin/bash
# version: $VERSION ($RELEASE_DATE)

LC_ALL=POSIX

EOF
    cat <<'EOF' >> $DIR_SCRIPTS_DAILY/kernel.sh
rel=`uname -r`
ver=`uname -v`

if [ ! -z "$ver" ]; then
    echo "dINFO_KERNEL_release|$rel";
    echo "dINFO_KERNEL_version|$ver"
fi
EOF
    chown 500.500 "$DIR_SCRIPTS_DAILY/kernel.sh"
    chmod 750 "$DIR_SCRIPTS_DAILY/kernel.sh"
}

#
# Generate /scripts/day/release.sh file
function generate_release {
    echo "Generating $DIR_SCRIPTS_DAILY/release.sh..."
    cat << EOF > $DIR_SCRIPTS_DAILY/release.sh
#! /bin/bash
# version: $VERSION ($RELEASE_DATE)

LC_ALL=POSIX

EOF
    cat <<'EOF' >> $DIR_SCRIPTS_DAILY/release.sh
test -f /etc/redhat-release && distro=`cat /etc/redhat-release`
test -f /etc/gentoo-release &&  distro=`cat /etc/gentoo-release`
test -f /etc/debian_version && distro="Debian "`cat /etc/debian_version`
test -f /etc/SuSE-release && distro=`cat /etc/SuSE-release`
test -f /etc/slackware-version && distro=`cat /etc/slackware-version`
test -f /etc/lsb-release && test -n "`grep -i ubuntu /etc/lsb-release`" && test -f /etc/lsb-release && uv=`grep DISTRIB_DESCRIPTION /etc/lsb-release | cut -d\= -f2` && test -n "$uv" && distro=$uv

test -f /etc/ovhrelease && release_ovh=`cat /etc/ovhrelease`


echo "dINFO_RELEASE_os|$distro"
echo "dINFO_RELEASE_ovh|$release_ovh"
EOF
    chown 500.500 "$DIR_SCRIPTS_DAILY/release.sh"
    chmod 750 "$DIR_SCRIPTS_DAILY/release.sh"
}

#
# Generate /scripts/day/raid-daily.pl file
function generate_raid_daily {
    echo "Generating $DIR_SCRIPTS_DAILY/raid-daily.pl..."
    cat << EOF > $DIR_SCRIPTS_DAILY/raid-daily.pl
#! /usr/bin/perl
# version: $VERSION ($RELEASE_DATE)

\$ENV{"LC_ALL"} = "POSIX";

EOF
    cat <<'EOF' >> $DIR_SCRIPTS_DAILY/raid-daily.pl
use strict;
use IO::Select;

my $dmesg = `cat /var/log/dmesg /var/log/boot.msg 2>/dev/null`;

#3Ware-9xxx
if ( $dmesg =~ m/3w-9xxx: scsi.: Found/) {
    my $MAX_FORKS = 3;

    my $TWCLI = `which tw_cli 2>/dev/null`;
    chomp($TWCLI);
    if ($TWCLI ne "") {
        my @twCliInfo = `$TWCLI info`;
        my @controlers = ();
        foreach my $line (@twCliInfo) {
            push @controlers, $1 if $line =~ /^c(\d+)\s+/;
        }
        foreach my $controler (@controlers) {
            my %units = ();
            @twCliInfo = `$TWCLI info c$controler`;
            foreach my $line (@twCliInfo) {
                if ( $line =~ m/^p(\d)\s+([^\s]+)\s+u([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)/) {
                    push @{$units{$3}}, $1 if $2 ne "NOT-PRESENT";
                }
            }
            foreach my $unit (keys %units) {
                my $read_set = IO::Select->new();
                my $n_forked = 0;
                my @units = @{$units{$unit}};
                while (@units > 0) {
                    my $phys = pop @units;
                    pipe my $P_READ, my $P_WRITE or die "pipe(): $!";
                    my $pid = fork();
                    die "cannot fork: $!" if $pid < 0;
                    if ($pid == 0) {
                        close $P_READ;
                        select($P_WRITE);
                        my $line = `$TWCLI info c$controler p$phys model`;
                        $line =~ m/Model\s=\s(.+)/;
                        print "dHW_SCSIRAID_PORT_c$controler\_u$unit\_phy$phys\_model|$1\n";
                        exit();
                    }
                    close $P_WRITE;
                    $read_set->add($P_READ);

                    ++$n_forked;
                    if ($n_forked > $MAX_FORKS || @units == 0) {
                        while (my @fds = $read_set->can_read()) {
                            foreach my $fd (@fds) {
                                my $line = <$fd>;
                                if (!$line) {
                                    $read_set->remove($fd);
                                    close $fd;
                                } else {
                                    print $line;
                                }
                            }
                        }
                        while (waitpid(-1, 0) > 0) {
                        }
                        $n_forked = 0;
                    }
                }
            }
        }
    }
}
EOF
    chown root.root "$DIR_SCRIPTS_DAILY/raid-daily.pl"
    chmod 750 "$DIR_SCRIPTS_DAILY/raid-daily.pl"
}

#
# Generate /scripts/hour/raid.pl file
function generate_raid {
    echo "Generating $DIR_SCRIPTS_HOUR/raid.pl..."
    cat << EOF > $DIR_SCRIPTS_HOUR/raid.pl
#! /usr/bin/perl
# version: $VERSION ($RELEASE_DATE)

\$ENV{"LC_ALL"} = "POSIX";

EOF
    cat <<'EOF' >> $DIR_SCRIPTS_HOUR/raid.pl
use strict;
use IO::Select;

chomp(my $MDADM=`which mdadm 2>/dev/null`);
chomp(my $MPTSTATUS = `which mpt-status 2>/dev/null`);
chomp(my $LSIUTIL = `which lsiutil 2>/dev/null`);
if($LSIUTIL eq '' and -e "/usr/local/rtm/bin/lsiutil"){
    $LSIUTIL = "/usr/local/rtm/bin/lsiutil";
  }
chomp(my $LSPCI = `which lspci 2>/dev/null`);


if ($LSPCI && `$LSPCI -d 1000:` && $MPTSTATUS) {
    my $SCSI_ID = `$MPTSTATUS -p 2>/dev/null | grep "Found SCSI" | cut -f1 -d, | cut -f2 -d=`;
    if ($SCSI_ID eq ""){
        $SCSI_ID = `cat /proc/scsi/scsi 2>/dev/null | grep Host | tail -n 1 | cut -d ' ' -f6`;
    }
    chomp $SCSI_ID;
    if ($SCSI_ID ne "") { $MPTSTATUS = "$MPTSTATUS -i $SCSI_ID"; }
} else {
    undef $MPTSTATUS;
}

my $dmesg = `cat /var/log/dmesg /var/log/boot.msg 2>/dev/null`;
my ($line, @mptInfo, @twCliInfo, $controler);

#SOFT RAID
my $mdstat;
if ( $MDADM ne "" && -e "/proc/mdstat" && `cat /proc/mdstat | grep md` ne "") {
    open(FILE, "/proc/mdstat");
    my $matrix;
    foreach $line (<FILE>) {
        if ( $line =~ /(md\d+)\s+:\s+([^\s]+)\s+([^\s]+)/ ) {
            $matrix = $1;
            $mdstat->{$matrix}{status}  = $2;
            $mdstat->{$matrix}{type}    = $3;
        }
        if ( $line =~ /\s+(\d+)/ ) {
            $mdstat->{$matrix}{capacity}    = $1;
        }
    }
    close(FILE);
    foreach $matrix (keys %{$mdstat}) {
        open(IN, "$MDADM -D /dev/$matrix |");
        foreach $line (<IN>) {
            if ( $line =~ /\s+\d+\s+\d+\s+\d+\s+(\d+)\s+(\w+)\s+(\w+)\s+\/dev\/(\w+)/ ) {
                $mdstat->{$matrix}{device}{$1}{state} = $2;
                $mdstat->{$matrix}{device}{$1}{flags} = $3;
                $mdstat->{$matrix}{device}{$1}{drive} = $4;
            }
            if ( $line =~ /^\s+State\s+:\s+([^\s]+)/ ) {
                $mdstat->{$matrix}{state}   = $1;
            }
        }
        close(IN);

        print "hHW_SCSIRAID_UNIT_$matrix\_vol0_capacity|".sprintf("%.1f", $mdstat->{$matrix}{capacity}/1024/1024)." GB\n";
        print "hHW_SCSIRAID_UNIT_$matrix\_vol0_phys|".(keys %{$mdstat})."\n";
        print "hHW_SCSIRAID_UNIT_$matrix\_vol0_type|$mdstat->{$matrix}{type}\n";
        print "hHW_SCSIRAID_UNIT_$matrix\_vol0_status|$mdstat->{$matrix}{status}\n";
        print "hHW_SCSIRAID_UNIT_$matrix\_vol0_flags|$mdstat->{$matrix}{state}\n";

        open(FILE, "/proc/partitions");
        my @file = <FILE>;
        close(FILE);
        foreach my $device (keys %{$mdstat->{$matrix}{device}}) {
            foreach $line (@file) {
                if ( $line =~ /\s+\d+\s+\d+\s+(\d+)\s+$mdstat->{$matrix}{device}{$device}{drive}/ ) {
                    $mdstat->{$matrix}{device}{$device}{capacity} = $1;
                }
            }
            print "hHW_SCSIRAID_PORT_$matrix\_vol0\_$mdstat->{$matrix}{device}{$device}{drive}\_capacity|".sprintf("%.1f", $mdstat->{$matrix}{device}{$device}{capacity}/1024/1024)." GB\n";
            print "hHW_SCSIRAID_PORT_$matrix\_vol0\_$mdstat->{$matrix}{device}{$device}{drive}\_status|$mdstat->{$matrix}{device}{$device}{state}\n";
            print "hHW_SCSIRAID_PORT_$matrix\_vol0\_$mdstat->{$matrix}{device}{$device}{drive}\_flags|$mdstat->{$matrix}{device}{$device}{flags}\n";
        }
    }
}


#SCSI-RAID
if ($MPTSTATUS and not $LSIUTIL) {
    my %mptStat;
    @mptInfo = `$MPTSTATUS 2>/dev/null`;
    foreach $line (@mptInfo) {
        if ( $line =~ m/(^[^\s]+)\s+([^\s]+)\s+(\d+)\s+type\s+([^,]+),\s+(\d+)\s+phy,\s+(\d+)\s+GB,\s+flags\s+([^,]+),\s+state\s+(.+)/) {
            $mptStat{cntrl} = $1;
            $mptStat{vol}   = "$2$3";
            $mptStat{cap}   = $6;
            $mptStat{phys}  = $5;
            $mptStat{type}  = $4;
            $mptStat{flags} = $7;
            $mptStat{status}= $8;
            $mptStat{vol}   =~ s/\_/-/g;
            print "hHW_SCSIRAID_UNIT_$mptStat{cntrl}\_$mptStat{vol}\_capacity|$mptStat{cap} GB\n";
            print "hHW_SCSIRAID_UNIT_$mptStat{cntrl}\_$mptStat{vol}\_phys|$mptStat{phys}\n";
            print "hHW_SCSIRAID_UNIT_$mptStat{cntrl}\_$mptStat{vol}\_type|$mptStat{type}\n";
            print "hHW_SCSIRAID_UNIT_$mptStat{cntrl}\_$mptStat{vol}\_status|$mptStat{status}\n";
            print "hHW_SCSIRAID_UNIT_$mptStat{cntrl}\_$mptStat{vol}\_flags|$mptStat{flags}\n";
            next;
        } elsif ( $line =~ m/(^[^\s]+)\s+([^\s]+)\s+(\d+)\s+type\s+([^,]+),\s+(\d+)\s+phy,\s+(\d+)\s+GB,\s+state\s+(.+),\s+flags\s+([^,]+)\n/) {
            $mptStat{cntrl} = $1;
            $mptStat{vol}   = "$2$3";
            $mptStat{cap}   = $6;
            $mptStat{phys}  = $5;
            $mptStat{type}  = $4;
            $mptStat{status}= $7;
            $mptStat{flags} = $8;
            $mptStat{vol}   =~ s/\_/-/g;
            print "hHW_SCSIRAID_UNIT_$mptStat{cntrl}\_$mptStat{vol}\_capacity|$mptStat{cap} GB\n";
            print "hHW_SCSIRAID_UNIT_$mptStat{cntrl}\_$mptStat{vol}\_phys|$mptStat{phys}\n";
            print "hHW_SCSIRAID_UNIT_$mptStat{cntrl}\_$mptStat{vol}\_type|$mptStat{type}\n";
            print "hHW_SCSIRAID_UNIT_$mptStat{cntrl}\_$mptStat{vol}\_status|$mptStat{status}\n";
            print "hHW_SCSIRAID_UNIT_$mptStat{cntrl}\_$mptStat{vol}\_flags|$mptStat{flags}\n";
            next;
        }
        if ( $line =~ m/(^[^\s]+)\s+([^\s]+)\s+(\d+)\s+scsi_id\s+\d+\s+([^\s]+)\s+([^\s]+)[^,]+,\s+(\d+)[^,]+,\s+state\s+(.+), flags\s+(.+)/ ) {
            next if $6 == 0;        # ignore fake raid entries
            print "hHW_SCSIRAID_PORT_$1_$mptStat{vol}\_$2$3_capacity|$6 GB\n";
            print "hHW_SCSIRAID_PORT_$1_$mptStat{vol}\_$2$3_model|$4 $5\n";
            print "hHW_SCSIRAID_PORT_$1_$mptStat{vol}\_$2$3_status|$7\n";
            print "hHW_SCSIRAID_PORT_$1_$mptStat{vol}\_$2$3_flags|$8\n";
        } elsif ( $line =~ m/(^[^\s]+)\s+([^\s]+)\s+(\d+)\s+([^\s]+)\s+([^\s]+)[^,]+,\s+(\d+)[^,]+,\s+state\s+(.+)/ ) {
            next if $6 == 0;
            print "dHW_SCSIRAID_PORT_$1_$mptStat{vol}\_$2$3_capacity|$6 GB\n";
            print "dHW_SCSIRAID_PORT_$1_$mptStat{vol}\_$2$3_model|$4 $5\n";
            print "dHW_SCSIRAID_PORT_$1_$mptStat{vol}\_$2$3_status|$7\n";
        } elsif ( $line =~ m/(^[^\s]+)\s+([^\s]+)\s+(\d+)\s+([^\s]+)\s+([^\s]+)[^,]+,\s+(\d+)[^,]+,\s+state\s+(.+), flags\s+(.+)/ ) {
            next if $6 == 0;
            print "hHW_SCSIRAID_PORT_$1_$mptStat{vol}\_$2$3_capacity|$6 GB\n";
            print "hHW_SCSIRAID_PORT_$1_$mptStat{vol}\_$2$3_model|$4 $5\n";
            print "hHW_SCSIRAID_PORT_$1_$mptStat{vol}\_$2$3_status|$7\n";
            print "hHW_SCSIRAID_PORT_$1_$mptStat{vol}\_$2$3_flags|$8\n";
        } elsif ( $line =~ m/(^[^\s]+)\s+([^\s]+)\s+(\d+)\s+([^\s]+)\s+([^\s]+)[^,]+,\s+(\d+)[^,]+,\s+flags\s+([^,]+),\s+state\s+(.+)/ ) {
            next if $6 == 0;
            print "hHW_SCSIRAID_PORT_$1_$mptStat{vol}\_$2$3_capacity|$6 GB\n";
            print "hHW_SCSIRAID_PORT_$1_$mptStat{vol}\_$2$3_model|$4 $5\n";
            print "hHW_SCSIRAID_PORT_$1_$mptStat{vol}\_$2$3_status|$8\n";
            print "hHW_SCSIRAID_PORT_$1_$mptStat{vol}\_$2$3_flags|$7\n";
        }
    }
}

# LSI:
if($LSIUTIL) {
  my %data;
  chomp(my @devs = `cat /proc/mpt/summary`);

  # foreach ioc device:
  foreach (@devs){
    m/^(.*?):.*Ports=(\d+),/;
    my ($unit, $ports) = ($1, $2);

    # foreach ports:
    for (my $port=1; $port <= $ports; $port++){
      chomp(my @diskDetails = `$LSIUTIL -p$port -a 21,2,0,0,0`);
      chomp(my @LSIRES = `$LSIUTIL -p$port -a 21,1,0,0,0`);

      # each line:
      my ($vol, $bus, $target, $type);
      $vol = -1;
      foreach my $line (@LSIRES){
        #Volume 0 is Bus 0 Target 2, Type IM (Integrated Mirroring)
        if($line =~ /^Volume (\d+) is Bus (\d+) Target (\d+), Type (\w+) /) {
          ($vol, $bus, $target, $type) = ($1, $2, $3, $4);
          $data{$unit}{$port}{$vol}{$bus}{$target}{type} = $type;
          # Warning: $target is a scsi id (vol_id$target) in RTM
        }
        # skip all till Volume.. line
        next if $vol == -1;

        #  Volume State:  optimal, enabled
        if($line =~ /Volume State:  (.+?), (.*)$/) {
          $data{$unit}{$port}{$vol}{$bus}{$target}{status} = uc $1;
          $data{$unit}{$port}{$vol}{$bus}{$target}{flags} = uc $2;
          if($2 =~ /resync in progress/i){
            chomp(my @lsitmp = `$LSIUTIL -p$port -a 21,3,0,0,0`);
            my $checkNextLine = 0;
            foreach(@lsitmp){
              # Resync Progress:  total blocks 4394526720, blocks remaining 3298477568, 75%
              if($checkNextLine and /^\s*Resync Progress:.*?,\s*(\d+)%\s*/){
                $data{$unit}{$port}{$vol}{$bus}{$target}{syncprogress} = $1;
              }
              next unless /Volume $vol State:/i;
              $checkNextLine = 1;
            }
          }
        }

        #Volume Size 417708 MB, Stripe Size 64 KB, 6 Members
        if($line =~ /Volume Size (\d+ \w+), Stripe Size (\d+ \w+), (\d+) Members/){
          $data{$unit}{$port}{$vol}{$bus}{$target}{capacity} = $1;
          $data{$unit}{$port}{$vol}{$bus}{$target}{stripe} = $2; # NEW
          $data{$unit}{$port}{$vol}{$bus}{$target}{phys} = $3;
        }elsif($line =~ /Volume Size (\d+ \w+), (\d+) Members/){
        #Volume Size 417708 MB, 2 Members
          $data{$unit}{$port}{$vol}{$bus}{$target}{capacity} = $1;
          $data{$unit}{$port}{$vol}{$bus}{$target}{phys} = $2;
        }

        if($line =~ /is PhysDisk (\d+)/){
          my %disk;
          $disk{nr} = $1;

          # now we know which disk is here, so find it:
          my $stop = 0;
          foreach(@diskDetails) {
            $stop = 1 and next
              if(/PhysDisk $disk{nr} is Bus/);
              #PhysDisk 0 is Bus 0 Target 3

            next unless $stop;

            #PhysDisk State:  online
            if(/PhysDisk State: (.*)/){
              $disk{status} = uc $1;
              $disk{status} =~ s/^\s+|\s+$//g;
            }
            
            #PhysDisk Size 238475 MB, Inquiry Data:  ATA      ST3250410AS      A
            if(/PhysDisk Size (\d+ \w+), Inquiry Data:\s+(.*)/){
              $disk{capacity} = $1;
              $disk{model} = $2;
              $disk{model} =~ s/\s+/ /g;
              $disk{model} =~ s/^\s+|\s+$//g;
              $disk{model} =~ s/(\w+ \w+) \w+/\1/g; # delete rev, for backward compatibility
            }

           # fix for 2 SSD IM sizes
            if( $data{$unit}{$port}{$vol}{$bus}{$target}{type} eq 'IM'
                and $data{$unit}{$port}{$vol}{$bus}{$target}{phys} == 2
                and $disk{capacity} > $data{$unit}{$port}{$vol}{$bus}{$target}{capacity} * 1.01 ){
              my $old_model = $disk{model};
              my $d = scan4LsiDisks($port);
              my $new_model = $d->{$disk{nr}}{model};
              $new_model =~ s/\s+/ /g;
              $new_model =~ s/^\s+|\s+$//g;
              $new_model = $d->{$disk{nr}}{vendor} . ' ' . $new_model;
              if($old_model ne $new_model){
                $disk{model} = $new_model;
                $disk{capacity} = $data{$unit}{$port}{$vol}{$bus}{$target}{capacity}; # ugly
              }
            }

          }
          push @{$data{$unit}{$port}{$vol}{$bus}{$target}{disks}}, \%disk;
        }
      }
    }
  }

  #@{$data{$unit}{$port}{$vol}{$bus}{$target}{disks}}
  foreach my $unit (keys %data){
    foreach my $port (keys %{$data{$unit}}){
       foreach my $vol (keys %{$data{$unit}{$port}}){
          foreach my $bus (keys %{$data{$unit}{$port}{$vol}}){
            foreach my $target (keys %{$data{$unit}{$port}{$vol}{$bus}}){
              foreach my $key (keys %{$data{$unit}{$port}{$vol}{$bus}{$target}}){
                if($key eq 'capacity'){
                  print "hHW_SCSIRAID_UNIT_$unit\_vol-id$vol\_$key|".changeSizeUnit($data{$unit}{$port}{$vol}{$bus}{$target}{$key})."\n";
                } elsif($key eq 'disks') {
                  foreach my $d (@{$data{$unit}{$port}{$vol}{$bus}{$target}{$key}}){
                      next unless $d->{status};
                      print "hHW_SCSIRAID_PORT_$unit\_vol-id$vol\_phy".$d->{nr}."\_model|".$d->{model}."\n";
                      print "hHW_SCSIRAID_PORT_$unit\_vol-id$vol\_phy".$d->{nr}."\_capacity|".changeSizeUnit($d->{capacity})."\n";
                      print "hHW_SCSIRAID_PORT_$unit\_vol-id$vol\_phy".$d->{nr}."\_status|".$d->{status}."\n";
                      # TODO: no idea from where get the disk flags
                      print "hHW_SCSIRAID_PORT_$unit\_vol-id$vol\_phy".$d->{nr}."\_flags|".(($d->{flags})?$d->{flags}:"NONE")."\n";
                  }
                } else {
                  print "hHW_SCSIRAID_UNIT_$unit\_vol-id$vol\_$key|$data{$unit}{$port}{$vol}{$bus}{$target}{$key}\n";
                }
              }
            }
          }
       }
    }
  }
}

#3Ware
if (( $dmesg =~ m/3w-xxxx: scsi/) || ( $dmesg =~ m/scsi. : Found a 3ware/)) {
    my (%units, @controlers);

    my $TWCLI = `which tw_cli 2>/dev/null`;
    chomp($TWCLI);
    if ($TWCLI ne "") {
        @twCliInfo = `$TWCLI info`;
        foreach $line (@twCliInfo) {
            if ($line =~ m/Controller (\d+):/ || $line =~ /^c(\d+).*$/)  { push @controlers, $1;}
        }
        foreach $controler (@controlers) {
            @twCliInfo = `$TWCLI info c$controler`;
            foreach $line (@twCliInfo) {
                if ( $line =~ m/Unit\s(\d):\s+(RAID\s+\d+|[^\s]+)\s([^\s]+)\s([^\s]+)[^:]+:\s(.+)/) {
                    print "hHW_SCSIRAID_UNIT_c$controler\_u$1_capacity|$3 $4\n";
                    print "hHW_SCSIRAID_UNIT_c$controler\_u$1_type|$2\n";
                    print "hHW_SCSIRAID_UNIT_c$controler\_u$1_status|$5\n";
                }
                if ( $line =~ m/Port\s(\d+):\s([^\s]+)\s([^\s]+)\s([^\s]+)\s([^\s]+)\s([^\s]+)[^:]+:\s([^\(]+)\(unit\s(\d+)/) {
                    print "hHW_SCSIRAID_PORT_c$controler\_u$8_phy$1_capacity|$5 $6\n";
                    print "hHW_SCSIRAID_PORT_c$controler\_u$8_phy$1_model|$2 $3\n";
                    print "hHW_SCSIRAID_PORT_c$controler\_u$8_phy$1_status|$7\n";
                    if (! exists $units{$controler}{$8}) {$units{$controler}{$8} = 0;}
                    $units{$controler}{$8} = $units{$controler}{$8} + 1;
                }
                if (  $line =~ /^u(\d+)\s+(RAID\-\d+)\s+(\S+)\s+\S+\s+\S+\s+(\S+)\s.*/ )
                {
                    print "hHW_SCSIRAID_UNIT_c$controler\_u$1_capacity|$4 GB\n";
                    print "hHW_SCSIRAID_UNIT_c$controler\_u$1_type|$2\n";
                    print "hHW_SCSIRAID_UNIT_c$controler\_u$1_status|$3\n";
                }
                if ( $line =~ /^p(\d+)\s+(\S+)\s+(\S+)\s+(\S+\s\S+)\s+(\d+)\s+(\S+)\s*$/ )
                {
                    print "hHW_SCSIRAID_PORT_c$controler\_$3_phy$1_capacity|$4\n";
                    print "hHW_SCSIRAID_PORT_c$controler\_$3_phy$1_model|$6\n";
                    print "hHW_SCSIRAID_PORT_c$controler\_$3_phy$1_status|$2\n";
                    if (! exists $units{$controler}{$3}) {$units{$controler}{$3} = 0;}
                    $units{$controler}{$3} = $units{$controler}{$3} + 1;
                }
            }
            foreach (keys %{$units{$controler}}) {print "hHW_SCSIRAID_UNIT_c$controler\_$_\_phys|".($units{$controler}{$_})."\n";}
        }
    }
}


#3Ware-9xxx
if ( $dmesg =~ m/3w-9xxx: scsi.: Found/) {
    if (open my $FP, "tw_cli info |") {
        my (%units, @controlers);
        while (my $line = <$FP>) {
            if ($line =~ m/^c(\d+)\s+/) {push @controlers, $1;}
        }
        close $FP;
        foreach $controler (@controlers) {
            open my $FP, "tw_cli info c$controler |" or next;
            while (my $line = <$FP>) {
                if ( $line =~ m/^u(\d)\s+([A-Z0-9\-]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+/ ) {
                    print "hHW_SCSIRAID_UNIT_c$controler\_u$1_capacity|$6\n";
                    print "hHW_SCSIRAID_UNIT_c$controler\_u$1_type|$2\n";
                    print "hHW_SCSIRAID_UNIT_c$controler\_u$1_status|$3\n";
                }
                if ( $line =~ m/^p(\d)\s+([^\s]+)\s+u([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)/) {
                    print "hHW_SCSIRAID_PORT_c$controler\_u$3_phy$1_capacity|$4 $5\n";
                    print "hHW_SCSIRAID_PORT_c$controler\_u$3_phy$1_status|$2\n";
                    push @{$units{$3}}, $1 if ($2 ne "NOT-PRESENT");
                }
            }
            foreach my $unit (keys %units) {
                print "hHW_SCSIRAID_UNIT_c$controler\_u$unit\_phys|".(scalar @{$units{$unit}})."\n";
            }
            close $FP;
        }
    }
}

#Mylex
if ( $dmesg =~ m/Mylex AcceleRAID 160 PCI RAID Controller/) {
    my( @dirContents, $dirContent, @info, $line, $unit, $i, $sectorSize, $count);
    if ( ! -e "/proc/rd") {exit;}
    $count = 0;
    opendir(DIR,"/proc/rd");
    @dirContents=readdir(DIR);
    closedir(DIR);

    $unit = 0;
    foreach $dirContent (@dirContents) {
        if (( $dirContent =~ m/\./ ) || (! -d "/proc/rd/".$controler )) {next;}
        $controler = $dirContent;
        $controler =~ s/c//g;
        open(FILE, "/proc/rd/c$controler/current_status") or exit;
        @info = <FILE>;
        close(FILE);

        for ($i=-1; $i<=scalar @info; $i++) {
            $line = $info[$i];
            chomp($line);
            if ( $line =~ m/\/dev\/rd\/c(\d+)d(\d+):\s+([^,]+),\s+([^,]+),\s+(\d+)/ ) {
                my $capacity = $5;
                my $type = $3;
                my $status = $4;

                $capacity = $capacity * 512 / 1024 / 1024 / 1024;
                print "hHW_SCSIRAID_UNIT_c$controler\_u$unit\_capacity|".sprintf("%.2f",$capacity)." GB\n";
                print "hHW_SCSIRAID_UNIT_c$controler\_u$unit\_type|$type\n";
                print "hHW_SCSIRAID_UNIT_c$controler\_u$unit\_status|$status\n";
            }
            if ( $line =~ m/\s+(\d+):(\d+)\s+Vendor:\s+([^\s]+)\s+Model:\s+([^\s]+)/ ) {
                my $unit = $1;
                my $phys = $2;
                my $vendor = $3;
                my $model = $4;
                next if $model eq 'AcceleRAID'; # it's the controller, not disk
                $count++;
                $line = @info[$i+3];
                $line =~ /Disk Status:\s+([^,]+),\s+(\d+)\sblocks/;

                my $status = $1;
                my $capacity = $2 * 512 / 1024 / 1024 / 1024;

                print "hHW_SCSIRAID_PORT_c$controler\_u$unit\_phy$phys\_capacity|".sprintf("%.2f",$capacity)." GB\n" if ($status ne "0");
                print "hHW_SCSIRAID_PORT_c$controler\_u$unit\_phy$phys\_status|$status\n" if ($status ne "0");
                print "hHW_SCSIRAID_PORT_c$controler\_u$unit\_phy$phys\_model|$model\n";
            }
        }
        print "hHW_SCSIRAID_UNIT_c$controler\_u$unit\_phys|$count\n";
    }
}

# sub to normalize units
sub changeSizeUnit {
  my $str = shift || return;

  $str =~ /^(\d+) (\w+)$/
    and $1 > 1024
    and uc $2 eq 'KB'
    and return int($1/1024)." MB";


  $str =~ /^(\d+) (\w+)$/
    and $1 > 1024
    and uc $2 eq 'MB'
    and return int($1/1024)." GB";
}

# sometimes we need to rescan disks in LSI (sas + ssd cofigurations mostly)
sub scan4LsiDisks {
  my $port = shift;
  return {} unless $port;
  my %disks;

  my @out = `$LSIUTIL -p$port -a8,0`;
# 0   1  PhysDisk 1     ATA      ST3750528AS      CC44  1221000001000000     1
# 0   3  PhysDisk 2     ATA      INTEL SSDSA2M080 02HD  1221000003000000     3
  foreach (@out){
    next unless /PhysDisk\s+(\d+)\s+(\w+)\s+(\w+(?:\s\w+)?)\s+([\da-zA-Z]+)\s+([\dABCDEF]+)\s+(\d+)\s+$/;
    $disks{$1} = {vendor=>$2, model=>$3, rev=>$4, phy=>$6};
  }

  return \%disks;
}


EOF
    chown root.root "$DIR_SCRIPTS_HOUR/raid.pl"
    chmod 750 "$DIR_SCRIPTS_HOUR/raid.pl"
}

#
# Generate /scripts/hour/smart.pl file
function generate_smart {
    echo "Generating $DIR_SCRIPTS_HOUR/smart.pl..."
    cat << EOF > $DIR_SCRIPTS_HOUR/smart.pl
#! /usr/bin/perl
# version: $VERSION ($RELEASE_DATE)

\$ENV{"LC_ALL"} = "POSIX";

EOF
    cat <<'EOF' >> $DIR_SCRIPTS_HOUR/smart.pl
use strict;
use IO::Select;

my %smartData;

sub parse_smartctl_line {
    my $line = shift;
    my $dev = shift;
        my $other_errors = 0;

    if ($line =~ /^196 Reallocated_Event_Count.*\s+(\d+)$/) {
        print "hINFO_HDD_$dev\_SMART_realocated-event-count|$1\n";
    }
    if ($line =~ /^197 Current_Pending_Sector.*\s+(\d+)$/) {
        print "hINFO_HDD_$dev\_SMART_current-pending-sector|$1\n";
    }
    if ($line =~ /^198 Offline_Uncorrectable.*\s+(\d+)$/) {
        print "hINFO_HDD_$dev\_SMART_offline-uncorrectable|$1\n";
    }
    if ($line =~ /^199 UDMA_CRC_Error_Count.*\s+(\d+)$/) {
        print "hINFO_HDD_$dev\_SMART_udma-crc-error|$1\n";
    }
    if ($line =~ /^200 Multi_Zone_Error_Rate.*\s+(\d+)$/) {
        print "hINFO_HDD_$dev\_SMART_multizone-error-rate|$1\n";
    }
    if ($line =~ /^209 Offline_Seek_Performnce.*\s+(\d+)$/) {
        print "hINFO_HDD_$dev\_SMART_offline-seek-performance|$1\n";
    }
    if ($line =~ m/^194 Temperature_Celsius .*\s+(\d+)(\s+\([\w\s\/]+\))?$/) {
        print "hINFO_HDD_$dev\_SMART_temperature-celsius|$1\n";
    }

    if ($line =~ /Error \d+ (occurred )?at /){
        $other_errors = 1;
    }

    return (other_errors=>$other_errors);
}

sub check_ide {
    opendir(DIR,"/proc/ide") or return;
    my @diskList = readdir(DIR);
    closedir(DIR);
    foreach my $dev (@diskList) {
        next unless $dev =~ /^hd.$/;
        my $smart_other_error = 0;
        my @smartctlData = `smartctl -a /dev/$dev`;
        foreach my $line (@smartctlData) {
            my %ret = parse_smartctl_line($line, $dev);
            $smart_other_error = 1 if $ret{other_errors};
        }
        print "hINFO_HDD_$dev\_SMART_other-errors|".int($smart_other_error)."\n";
    }
}

sub check_scsi {
    open PART, "/proc/partitions" or return;
    my @disks = ();
    while (<PART>) {
        chomp;
        next unless /\b(sd\D+)\b/;
        push @disks, $1;
    }
    close PART;
    return unless @disks > 0;

    foreach my $dev (@disks) {
        my @smartctlData = `smartctl -a /dev/$dev`;
        my $smart_other_error = 0;
        foreach my $line (@smartctlData) {
            my %ret = parse_smartctl_line($line, $dev);
            $smart_other_error = 1 if $ret{other_errors};

            if ($line =~ /^read:.+(\d+)$/) {
                print "hINFO_HDD_$dev\_SMART_uncorrected-read-errors|$1\n";
            }
            if ($line =~ /^write:.+(\d+)$/) {
                print "hINFO_HDD_$dev\_SMART_uncorrected-write-errors|$1\n";
            }
        }
        print "hINFO_HDD_$dev\_SMART_other-errors|".int($smart_other_error)."\n";
    }
}

sub _3ware_get_ports_for_disk {
    my $disk = shift;
    my @ports = ();
    open my $TWCLI_OUTPUT, "tw_cli info c$disk |" or die("failed to run 'tw_cli'");
    while (<$TWCLI_OUTPUT>) {
        next unless /^p(\d+) /;
        push @ports, $1;
    }
    close $TWCLI_OUTPUT;
    return @ports;
}

sub check_3ware {
    opendir(DIR,"/proc/scsi/3w-9xxx") or return;
    my @disk_list = readdir(DIR);
    closedir(DIR);

    my $read_set = IO::Select->new();

    foreach my $disk (@disk_list) {
        next unless $disk =~ /^\d+$/;
        foreach my $port (_3ware_get_ports_for_disk($disk)) {
            pipe my $P_READ, my $P_WRITE or die "pipe(): $!";
            my $pid = fork();
            die "cannot fork: $!" if $pid < 0;
            if ($pid == 0) {
                open my $SMARTCTL_OUTPUT, "smartctl --device=3ware,$port /dev/twa$disk -a |" or die("failed to run smartctl");
                close $P_READ;
                select($P_WRITE);
                while (<$SMARTCTL_OUTPUT>) {
                    parse_smartctl_line($_, "twa$disk-$port");
                }
                exit();
            }
            close $P_WRITE;
            $read_set->add($P_READ);
        }
    }
    while (my @fds = $read_set->can_read()) {
        foreach my $fd (@fds) {
            my @lines = <$fd>;
            if (!@lines) {
                close $fd;
                next;
            }
            print join('', @lines);
        }
    }
    while (waitpid(-1, 0) > 0) {
    }
}


check_ide();
check_scsi();
check_3ware();
EOF
    chown root.root "$DIR_SCRIPTS_HOUR/smart.pl"
    chmod 750 "$DIR_SCRIPTS_HOUR/smart.pl"
}

#
# Generate /scripts/hour/listen_ports.pl file
function generate_listen_ports {
    echo "Generating $DIR_SCRIPTS_HOUR/listen_ports.pl..."
    cat << EOF > $DIR_SCRIPTS_HOUR/listen_ports.pl
#! /usr/bin/perl
# version: $VERSION ($RELEASE_DATE)

\$ENV{"LC_ALL"} = "POSIX";

EOF
    cat <<'EOF' >> $DIR_SCRIPTS_HOUR/listen_ports.pl
use strict;
use utf8; # for \x{nnn} regex

my (@netstatTable, $line, $socketInfo, $procInfo, @tempTable, $port, $pid, $procName, $ip, $cmdline, $exe, @status, $statusLine, $uid, @passwd, $passwdLine, %passwdHash);

chomp(@netstatTable = `netstat -tlenp | grep LISTEN | awk '{print \$4"|"\$9}'`);

open(FILE, "/etc/passwd");
chomp(@passwd = <FILE>);
close(FILE);

foreach $passwdLine (@passwd) {
    $passwdLine =~ /^([^:]+):[^:+]:(\d+):/;
    $passwdHash{$2} = $1;
}

foreach $line (@netstatTable) {

    @tempTable = split(/\|/, $line);
    $socketInfo = $tempTable[0];
    $procInfo = $tempTable[1];

    $socketInfo =~ /:(\d+)$/;
    $port = $1;
    $socketInfo =~ /(.+):\d+$/;
    $ip = $1;
    $ip =~ s/\./-/g;
    $ip =~ s/[^0-9\-]//g;
    if ($ip eq "") {$ip = 0;}
    @tempTable = split(/\//, $procInfo);
    $pid = $tempTable[0];
    open(FILE, "/proc/$pid/cmdline");
    chomp($cmdline = <FILE>);
    $cmdline =~ s/\x{0}/ /g;
    close(FILE);

    open(FILE, "/proc/$pid/status");
    chomp(@status = <FILE>);
    close(FILE);
    $statusLine = join("|", @status);
    $statusLine =~ /Uid:\s(\d+)/;
    $uid = $1;

    my $username = '';
    if (defined $passwdHash{$uid}) {
        $username = $passwdHash{$uid};
    }

    $procName = $tempTable[1];
    $exe = readlink("/proc/$pid/exe");

    print "hINFO_TCP_LISTEN_IP-$ip\_PORT-$port\_pid\|$pid\n";
    print "hINFO_TCP_LISTEN_IP-$ip\_PORT-$port\_procname\|$procName\n";
    print "hINFO_TCP_LISTEN_IP-$ip\_PORT-$port\_cmdline\|$cmdline\n";
    print "hINFO_TCP_LISTEN_IP-$ip\_PORT-$port\_exe\|$exe\n";
    print "hINFO_TCP_LISTEN_IP-$ip\_PORT-$port\_username\|$username\n";
    print "hINFO_TCP_LISTEN_IP-$ip\_PORT-$port\_uid\|$uid\n";
}
EOF
    chown root.root "$DIR_SCRIPTS_HOUR/listen_ports.pl"
    chmod 750 "$DIR_SCRIPTS_HOUR/listen_ports.pl"
}

#
# Generate /scripts/min/usage.pl file
function generate_usage {
    echo "Generating $DIR_SCRIPTS_MIN/usage.pl..."
    cat << EOF > $DIR_SCRIPTS_MIN/usage.pl
#! /usr/bin/perl
# version: $VERSION ($RELEASE_DATE)

\$ENV{"LC_ALL"} = "POSIX";

EOF
    cat <<'EOF' >> $DIR_SCRIPTS_MIN/usage.pl
use strict;

# tmp file for storing cpu stats from /proc/stat
my $CPU_STATS = "/tmp/cpu_stats";

sub send_loadavg {
    my %loadavg = get_loadavg();
    print "mINFO_LOAD_loadavg1|" . $loadavg{'loadavg1'} . "\n";
    print "mINFO_LOAD_loadavg2|" . $loadavg{'loadavg2'} . "\n";
    print "mINFO_LOAD_loadavg3|" . $loadavg{'loadavg3'} . "\n";
}

sub send_mem_swap_usage {
    my %mem_swap_usage = get_mem_swap_usage();
    print "mINFO_MEM_memusage|" . $mem_swap_usage{'mem_used_pr'} . "\n";
    print "mINFO_MEM_swapusage|" . $mem_swap_usage{'swap_used_pr'} . "\n";
}

sub send_cpu_usage {
    my $cpu_usage = get_cpu_usage();
    print "mINFO_CPU_usage|" . $cpu_usage . "\n";
}

sub send_hdd_usage {
    my %hdd_usage = get_hdd_usage();
    foreach (keys %{$hdd_usage{'usage'}}) {
        print "mINFO_PART_$_\_mount|" . $hdd_usage{'mount'}{$_} . "\n";
        print "mINFO_PART_$_\_usage|" . $hdd_usage{'usage'}{$_} . "\n";
        print "mINFO_PART_$_\_inodes|" . $hdd_usage{'inodes'}{$_} . "\n";
    }
}

sub get_loadavg {
    open(CONF, "/proc/loadavg") or die "loadavg: $!\n";
    chomp(my @load = split(/\s/, <CONF>));
    close(CONF);
    return ('loadavg1' => $load[0],
            'loadavg2' => $load[1],
            'loadavg3' => $load[2],);
}

sub get_cpu_usage {
    my ($cpu_usage, @cpu_usage1, @cpu_usage2, $delta);
    @cpu_usage1 = (0, 0, 0, 0);
    @cpu_usage2 = (0, 0, 0, 0);


    open(STAT, "/proc/stat") or die "/proc/stat: $!\n";
    my @stats = <STAT>;
    close (STAT);

    foreach (@stats) {
        if (/^cpu\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/i) {
            @cpu_usage2 = ($1, $2, $3, $4);
        }
    }

    # it can happen after reboot
    if( ! -e $CPU_STATS) {
       open(TMP, ">$CPU_STATS") or die "$CPU_STATS: $!\n";
       print TMP @stats;
       close(TMP);
       return 0;
    }

    open(TMP, '+<', $CPU_STATS) or die "$CPU_STATS: $!\n";
    while (<TMP>) {
        if (/^cpu\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/i) {
            @cpu_usage1 = ($1, $2, $3, $4);
        }
    }
    seek(TMP, 0, 0);
    print TMP @stats;
    close (TMP);

    $delta = $cpu_usage2[0]+$cpu_usage2[1]+$cpu_usage2[2]+$cpu_usage2[3]-
        ($cpu_usage1[0]+$cpu_usage1[1]+$cpu_usage1[2]+$cpu_usage1[3]);
    if ($delta > 0) {
        $cpu_usage = sprintf("%d", 100-(($cpu_usage2[3]-$cpu_usage1[3])/$delta*100));
    } else {
        $cpu_usage = 0;
    }
    return $cpu_usage;
}

sub get_mem_swap_usage {
    my %mem_swap_usage = ();
    my @free = `free`;
    foreach (@free) {
        if (/^Swap:\s+(\d+)\s+(\d+)\s+(\d+)/i) {
            $mem_swap_usage{'swap_total'} = $1;
            $mem_swap_usage{'swap_used'} = $2;
            if ($1 == 0) {
                # prevent division by zero
                $mem_swap_usage{'swap_used_pr'} = 0;
            } else {
                $mem_swap_usage{'swap_used_pr'} = sprintf("%d", $2/$1*100);
            }
        }
        if (/^Mem:\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/i) {
            $mem_swap_usage{'mem_total'} = $1;
            $mem_swap_usage{'mem_used'} = $2;
            $mem_swap_usage{'mem_free'} = $3;
            $mem_swap_usage{'mem_shared'} = $4;
            $mem_swap_usage{'mem_buffers'} = $5;
            $mem_swap_usage{'mem_cached'} = $6;
            $mem_swap_usage{'mem_used_pr'} = sprintf("%d", (($2-$5-$6)/$1*100));
        }
    }
    return %mem_swap_usage;
}

sub get_hdd_usage {
    my %hdd_usage = ();
    my @df = `df -l`;
    foreach (@df){
        if (/^(\/dev\/\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(\S+)/i) {
            my $hdd_name = $1;
            my $hdd_usage = $5;
            my $hdd_mount = $6;
            $hdd_name =~ s!^/dev/!!g;
            $hdd_name =~ s!/!-!g;
            $hdd_usage{'usage'}{$hdd_name} = $hdd_usage;
            $hdd_usage{'usage'}{$hdd_name} =~ s/%//;
            $hdd_usage{'mount'}{$hdd_name} = $hdd_mount;
        }
    }

    # inodes
    @df = `df -li`;
    foreach (@df) {
        if (/^(\/dev\/\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(\S+)/i) {
            my $hdd_name = $1;
            my $hdd_usage = $5;
            $hdd_usage =~ s/%//;
            $hdd_usage = 0 unless $hdd_usage =~ /^\d+$/;
            $hdd_name =~ s/^\/dev\///g;
            $hdd_name =~ s!/!-!g;
            $hdd_usage{'inodes'}{$hdd_name} = $hdd_usage;
        }
    }
    return %hdd_usage;
}

send_hdd_usage();
send_mem_swap_usage();
send_loadavg();
send_cpu_usage();
EOF
    chown 500.500 "$DIR_SCRIPTS_MIN/usage.pl"
    chmod 750 "$DIR_SCRIPTS_MIN/usage.pl"
}

#
# Generate /scripts/min/usage-root.pl file
function generate_usage_root {
    echo "Generating $DIR_SCRIPTS_MIN/usage-root.pl..."
    cat << EOF > $DIR_SCRIPTS_MIN/usage-root.pl
#! /usr/bin/perl
# version: $VERSION ($RELEASE_DATE)

\$ENV{"LC_ALL"} = "POSIX";

EOF
    cat <<'EOF' >> $DIR_SCRIPTS_MIN/usage-root.pl
use strict;

sub send_process {
    my %processes = get_processes();
    print "mINFO_LOAD_processesactive|" . $processes{'processesactive'} . "\n";
    print "mINFO_LOAD_processesup|" . $processes{'processesup'} . "\n";
}

sub send_top_rss {
    my $top = get_top_mem_procs();
    my $n = 1;
    foreach my $info (@$top) {
        my $vsz = $info->[0];
        my $cmd = $info->[1];
        printf "mINFO_MEM_top_mem_%02d_name|%s\n", $n, $cmd;
        printf "mINFO_MEM_top_mem_%02d_size|%s\n", $n, $vsz;
        ++$n;
    }
}

sub get_processes {
    chomp(my @rtm_sids = `ps --no-headers -C rtm -o sess | sort -n | uniq`);
    my @ps_output = `ps --no-headers -A -o sess,state,command`;
    my $active = 0;
    my $total = 0;
    my $rtm_procs = 0;
    foreach my $line (@ps_output) {
        next if $line !~ /(\d+)\s+(\S+)/;
        my $sid = $1;
        my $state = $2;
        if (grep $sid == $_, @rtm_sids) {
            ++$rtm_procs;
            next;
        }
        ++$total;
        ++$active if $state =~ /^R/;
    }
    return ('processesactive' => $active, 'processesup' => $total);
}

sub get_top_mem_procs {
    my @top;
    my @output = `ps -A -o vsz,cmd --sort=-vsz --no-headers | head -n 5`;
    return [] unless $? == 0;
    foreach (@output) {
        next unless m/\s*(\d+)\s+(.+)/;
        push @top, [$1, $2];
    }
    return \@top;
}

send_process();
send_top_rss();
EOF
    chown root.root "$DIR_SCRIPTS_MIN/usage-root.pl"
    chmod 750 "$DIR_SCRIPTS_MIN/usage-root.pl"
}

#
# Generate /scripts/hour/hwinfo.pl file
function generate_hwinfo {
    echo "Generating $DIR_SCRIPTS_HOUR/hwinfo.pl..."
    cat << EOF > $DIR_SCRIPTS_HOUR/hwinfo.pl
#! /usr/bin/perl
# version: $VERSION ($RELEASE_DATE)

\$ENV{"LC_ALL"} = "POSIX";

EOF
    cat <<'EOF' >> $DIR_SCRIPTS_HOUR/hwinfo.pl
use strict;

sub send_cpu_info {
    my %cpu_info = get_cpu_info();
    print "dHW_CPU_name|" . $cpu_info{'cpu_name'} . "\n";
    print "dHW_CPU_mhz|" . $cpu_info{'cpu_mhz'} . "\n";
    print "dHW_CPU_cache|" . $cpu_info{'cpu_cache'} . "\n";
    print "dHW_CPU_number|" . $cpu_info{'cpu_no'} . "\n";
}

sub send_lspci_info {
    my %lspci_info = get_lspci_info();
    foreach (keys %lspci_info) {
        my $tempKey = $_;
        $tempKey =~ s/\:|\.|\_/-/g;
        print "dHW_LSPCI_PCI-$tempKey|" . $lspci_info{$_} . "\n";
    }
}


sub get_cpu_info {
    my %cpu_info = ( 'cpu_no' => 0 );
    open(CONF,"/proc/cpuinfo") or die "loadavg: $!\n";
    while( <CONF> ) {
        chomp($_);
        if ($_ =~ /^model name\s+:\s(.*)/) {
            $cpu_info{'cpu_name'} = $1;
            $cpu_info{'cpu_no'} += 1;
        }
        if ($_ =~ /^cpu MHz/) {
            s/cpu MHz\s+:\s*//g;
            $cpu_info{'cpu_mhz'} = $_;
        }
        if ($_ =~ /^cache size/) {
            s/cache size\s+:\s*//g;
            $cpu_info{'cpu_cache'} = $_;
        }
    }
    $cpu_info{'cpu_no'} = $cpu_info{'cpu_no'};
    close(CONF);
    return %cpu_info;
}


sub get_lspci_info {
    my %lspci_info = ();
    my @lspci = `lspci -n 2>/dev/null`;
    if ($? == 0) {
        foreach (@lspci) {
            if (/^(\S+).+:\s+(.+:.+)\s+\(/i) {
                $lspci_info{$1} = $2;
            }
            elsif (/^(\S+).+:\s+(.+:.+$)/i){
                $lspci_info{$1} = $2;
            }
        }
    }
    return %lspci_info;
}

send_cpu_info();
send_lspci_info();
EOF
    chown 500.500 "$DIR_SCRIPTS_HOUR/hwinfo.pl"
    chmod 750 "$DIR_SCRIPTS_HOUR/hwinfo.pl"
}

#
# Generate /scripts/hour/hwinfo-root.pl file
function generate_hwinfo_root {
    echo "Generating $DIR_SCRIPTS_HOUR/hwinfo-root.pl..."
    cat << EOF > $DIR_SCRIPTS_HOUR/hwinfo-root.pl
#! /usr/bin/perl
# version: $VERSION ($RELEASE_DATE)

\$ENV{"LC_ALL"} = "POSIX";

EOF
    cat <<'EOF' >> $DIR_SCRIPTS_HOUR/hwinfo-root.pl
use strict;

sub send_mainboard_memory_info {
    my %mainboard_memory_info = get_mainboard_memory_info();
    print "dHW_MB_manufacture|" . $mainboard_memory_info{'mainboard'}{'manufacture'} . "\n";
    print "dHW_MB_name|" . $mainboard_memory_info{'mainboard'}{'name'} . "\n";
    foreach (keys %{$mainboard_memory_info{'memory'}}) {
        print "dHW_MEM_BANK-$_|" . $mainboard_memory_info{'memory'}{$_} . "\n";
    }
}

sub send_hdd_info {
    my %hdd_info = get_hdd_info();
    get_hdd_info_scsi(\%hdd_info);
    foreach (keys %{$hdd_info{'model'}}) {
        print "dHW_HDD_$_\_capacity|" . $hdd_info{'capacity'}{$_} . " GB" . "\n";
        print "dHW_HDD_$_\_model|" . $hdd_info{'model'}{$_} . "\n";
    }
}

sub get_mainboard_memory_info {
    my %mainboard_memory_info = ();
    my @dmidecode = `dmidecode 2>/dev/null`;
    if ($? == 0) {
        my $module = "";
        for (my $i = 0; $i < @dmidecode; $i++) {
            if($dmidecode[$i] =~ /^\s*Base Board Information/i) {
                $dmidecode[$i+1] =~ s/Manufacturer://g;
                $dmidecode[$i+2] =~ s/Product Name://g;
                $mainboard_memory_info{'mainboard'}{'manufacture'} = $dmidecode[$i+1];
                $mainboard_memory_info{'mainboard'}{'name'} = $dmidecode[$i+2];
            }
            if($dmidecode[$i] =~ /^\s*Memory Module Information/i) {
                $dmidecode[$i+1] =~ /^\s+(\S+)\s+(\S+)\s+(.+)$/i;
                $module = $3;
                $module =~ s/\W/-/g;
                chomp($module);
            }
            if(($dmidecode[$i] =~ /^\s+Installed Size:/i)  && ($module =~ /\S+/)) {
                $module =~ s/#/_/;
                $dmidecode[$i] =~ s/Installed Size://g;
                $mainboard_memory_info{'memory'}{$module} = $dmidecode[$i];
                $mainboard_memory_info{'memory'}{$module} =~ s/^\s+//;
                chomp($mainboard_memory_info{'memory'}{$module});
                $module = "";
            }
        }
        if (!defined $mainboard_memory_info{'memory'}) {
            for (my $i = 0; $i < @dmidecode; $i++){
                if($dmidecode[$i] =~ /^\s*Memory Device/i) {
                    my $bank = $dmidecode[$i+9];
                    $bank =~ /Bank Locator:\s+(.*)/;
                    $bank = $1;
                    next if !$bank;
                    $bank =~ s/\s//g;
                    $bank =~ s/[\s\.\/\\_]/-/g;
                    my $locator = $dmidecode[$i+8];
                    $locator =~ /Locator:\s+(.*)/;
                    $locator = $1;
                    next if !$locator;
                    $locator =~ s/\s//g;
                    $locator =~ s![\s./\\_#]!-!g;
                    my $size = $dmidecode[$i+5];
                    $size =~ /Size:\s+(.*)/;
                    $size = $1;
                    next if !$size;
                    $size =~ s/\s*MB\s*//g;
                    chomp($size);
                    if ($bank . $locator ne "") {
                        $mainboard_memory_info{'memory'}{$bank . "-" . $locator} = $size;
                    }
                }
            }
        }
        $mainboard_memory_info{'mainboard'}{'manufacture'} =~ s/^\s+//;
        $mainboard_memory_info{'mainboard'}{'name'} =~ s/^\s+//;
        chomp($mainboard_memory_info{'mainboard'}{'manufacture'});
        chomp($mainboard_memory_info{'mainboard'}{'name'});
    } else {
        $mainboard_memory_info{'mainboard'}{'manufacture'} = "dmidecode not installed";
        $mainboard_memory_info{'mainboard'}{'name'} = "dmidecode not installed";
    }
    return %mainboard_memory_info;
}

sub has_raid {
    my $dmesg = `cat /var/log/dmesg`;
    return ((-e "/proc/mdstat" && `grep md /proc/mdstat` ne "") ||
            ($dmesg =~ m/3w-xxxx: scsi/) ||
            (`lspci -d 1000: 2>&1` ne "") ||
            ($dmesg =~ m/scsi. : Found a 3ware/) ||
            ($dmesg =~ m/3w-9xxx: scsi.: Found/) ||
            ($dmesg =~ m/LSISAS1064 A3/) ||
            ($dmesg =~ m/Mylex AcceleRAID 160 PCI RAID Controller/));
}

sub get_scsi_disk_capacity {
    my $device = shift;
    my $capacity = "0";
    open my $FP, "fdisk -l $device |" or return "0";
    while (my $line = <$FP>) {
        next unless $line =~ /^Disk\s+$device:\s+([^,]+)/;
        $capacity = $1;
        $capacity =~ s/\s//g;
        $capacity =~ s/GB$//g;
        last;
    }
    return "0" unless close $FP;
    return $capacity;
}

sub get_hdd_info_scsi {
    return () if has_raid();
    my $hdd_info = shift;
    open my $FP, "/proc/scsi/scsi" or return ();
    chomp(my $scsi = join('', <$FP>));
    close $FP;
    my @letters = ('a'..'z');
    while ($scsi =~ /^\s*Vendor:\s*.+Model:\s*(.+?)\s*Rev:/mg) {
        my $l = shift @letters;
        $hdd_info->{'model'}{"sd$l"} = $1;
        $hdd_info->{'capacity'}{"sd$l"} = get_scsi_disk_capacity("/dev/sd$l");
    }
}

sub get_hdd_info {
    my %hdd_info = ();
    my $ide = `ls /proc/ide`;
    my @ide = split(/\s+/, $ide);
    foreach (@ide) {
        if (/^hd/) {
            $ide = $_;
            if (-e "/proc/ide/$ide/model") {
                open(FILE, "/proc/ide/$ide/model");
                while (<FILE>) {
                    chomp($_);
                    $hdd_info{'model'}{$ide} = $_;
                }
                close(FILE);
            } else {
                $hdd_info{'model'}{$ide} = "";
            }
            if (-e "/proc/ide/$ide/capacity") {
                open(FILE, "/proc/ide/$ide/capacity");
                while (<FILE>) {
                    chomp($_);
                    $hdd_info{'capacity'}{$ide} = sprintf("%d",$_*512/1000000000);
                }
                close(FILE);
            }  else {
                $hdd_info{'capacity'}{$ide} = ""
            };
        }
    }
    return %hdd_info;
}


send_mainboard_memory_info();
send_hdd_info();
EOF
    chown root.root "$DIR_SCRIPTS_HOUR/hwinfo-root.pl"
    chmod 750 "$DIR_SCRIPTS_HOUR/hwinfo-root.pl"
}

#
# Generate /scripts/min/hddinfo.pl file
function generate_hddinfo {
    echo "Generating $DIR_SCRIPTS_MIN/hddinfo.pl..."
    cat << EOF > $DIR_SCRIPTS_MIN/hddinfo.pl
#! /usr/bin/perl
# version: $VERSION ($RELEASE_DATE)

\$ENV{"LC_ALL"} = "POSIX";

EOF
    cat <<'EOF' >> $DIR_SCRIPTS_MIN/hddinfo.pl
use strict;

sub send_hdd_status {
    chomp(my $ide = `ls /proc/ide`);
    chomp(my @status = `\/bin\/dmesg \| grep -i \"error\\\|drive not ready\" \| grep -i \"\^hd\" \| cut -f 1 -d \":\" \| sort \| uniq`);
    my @ide = split(/\s+/, $ide);
    foreach $ide (@ide) {
        my $error = 0;
        if ($ide =~ /^hd/) {
            foreach (@status) {
                $error = 1 if $_ eq $ide;
            }
            if ($error == 1) {
                print "mHW_HDD_$ide\_status|ERROR\n";
            } else {
                print "mHW_HDD_$ide\_status|OK\n";
            }
        }
    }

    # check of scsi errors
    my $scsi_available = `grep '^Host:' /proc/scsi/scsi 2>/dev/null`;
    my $possible_error;
    if ($scsi_available) {
        open my $dmesg, "dmesg |" or die "Can't launch dmesg: $!";
        my $status = 'OK';
        while (<$dmesg>) {
            if (/Info fld=([^,]+), Deferred (\S+?): sense key (.+ Error)/) {
                $status = $3;
            }
            if (/^sd.: .+?: sense key: (.+ Error)/) {
                $status = $1;
            }
            if (/^(sd.+?): *rw=\d+/) {
                $possible_error = $1;
                next;
            }
            if (defined($possible_error) && /^attempt to access beyond/) {
                $status = 'BAD_ACCESS';
            }
            $possible_error = undef;
        }
        print "mHW_HDD_scsi_status|$status\n";
    }
}

sub send_hdd_temp {
    my %hdd_temp = get_hdd_temp();
    foreach (keys %hdd_temp) {
        print "mINFO_HDD_$_\_temperature|" . $hdd_temp{$_} . "\n";
    }
}


sub get_hdd_temp {
    my %hdd_temp = ();
    my $ide = `ls /proc/ide`;
    my @ide = split(/\s+/, $ide);
    foreach (@ide) {
        if (/^hd/) {
            $ide = $_;
            my $temp = `hddtemp /dev/$ide 2>/dev/null`;
            if ($? == 0) {
                if ($temp =~ m/.*:.*:\s(\d+)/) {
                    $temp = $1;
                } else {
                    $temp = "-1";
                }
                $hdd_temp{$ide} = $temp;
            } else {
                $hdd_temp{$ide} = "-2";
            }
        }
    }
    return %hdd_temp;
}


send_hdd_status();
send_hdd_temp();
EOF
    chown root.root "$DIR_SCRIPTS_MIN/hddinfo.pl"
    chmod 750 "$DIR_SCRIPTS_MIN/hddinfo.pl"
}

#
# Generate rtm.pl file
function generate_rtm {
    echo "Generating rtm.pl..."
    cat << EOF > $RTM_PL
#! /usr/bin/perl
# version: $VERSION ($RELEASE_DATE)

\$ENV{"LC_ALL"} = "POSIX";

EOF
    cat <<'EOF' >> $RTM_PL
use Fcntl;
use strict;
use Socket;
use Time::localtime;
use Symbol qw(gensym);
use IO::Select;
use POSIX qw(dup2);

# Check for root permission
if ($) != 0) {
    die "You are not a root!";
}

# Version of script
EOF
    echo "my \$version = '$VERSION';" >> $RTM_PL
    echo "my \$release_date = '$RELEASE_DATE';" >> $RTM_PL
    cat <<'EOF' >> $RTM_PL

# at this hour all information will be send
my $HOUR = 2;

# get uptime
open(FILE, "/proc/uptime") || die("Cannot open /proc/uptime");
my $uptime = <FILE>;
close(FILE);
$uptime =~ /^(\d+)/;
$uptime = $1;

my $script_name = $0;
# get basename of the script
$script_name =~ s/(^.*\/)//;

EOF
    echo "my \$base_dir = '$DIR';" >> $RTM_PL
    echo "my \$scripts_dir_daily = '$DIR_SCRIPTS_DAILY';" >> $RTM_PL
    echo "my \$scripts_dir_hour = '$DIR_SCRIPTS_HOUR';" >> $RTM_PL
    echo "my \$scripts_dir_min = '$DIR_SCRIPTS_MIN';" >> $RTM_PL
    echo "my \$rtm_update_ip = '$RTM_UPDATE_IP';" >> $RTM_PL
    cat <<'EOF' >> $RTM_PL

chomp(my @scripts_daily = `/bin/ls -1 $scripts_dir_daily`);
chomp(my @scripts_hour = `/bin/ls -1 $scripts_dir_hour`);
chomp(my @scripts_min = `/bin/ls -1 $scripts_dir_min`);

my $env_path = $ENV{'PATH'};
$ENV{'PATH'} = "/usr/local/sbin:/usr/local/bin:$env_path";

# global variable used to report errors from failed scripts
my $script_error = 0;

# determine rtm server ip from mrtg config
my $ipfile = "$base_dir/etc/rtm-ip";
open FP, "$ipfile" or die("failed to open '$ipfile' for reading: $!");
chomp(my $destination_ip = <FP>);
close FP;
if ($destination_ip !~ /^\d+\.\d+\.\d+\.\d+$/) {
    die "failed to read destination ip from '$ipfile': invalid ip: $destination_ip";
}

my $LOCK_FILE = "/var/lock/rtm.flock";
lockProcess();

my $TIMEOUT = 45;
my $MAX_UDP_BUFFER_SIZE = 200;
my $udp_buffer = '';

my $tm = localtime(time);
my $hour = $tm->hour;
my $min = $tm->min;

my @scripts_to_run = ();

# per minute data
push @scripts_to_run, map { "$scripts_dir_min/$_" } @scripts_min;

# hourly data
if ((scalar @ARGV == 0) or (($min >= 0) && ($min <= 5)) or $uptime < 900) {
    send_info("hINFO_uptime|" . $uptime);
    push @scripts_to_run, map { "$scripts_dir_hour/$_" } @scripts_hour;
}

# daily data
if (scalar @ARGV == 0 || (($hour eq $HOUR || $uptime < 900) && $min % 10 == 0)) {
    send_info("dINFO_RTM_version|" . $version);
    push @scripts_to_run, map { "$scripts_dir_daily/$_" } @scripts_daily;
}

# update rtm-ip daily
if (@ARGV > 0 && $hour eq $HOUR && $ARGV[0] == $min) {
    system("$rtm_update_ip &");
}

# run collected scripts in separate processes
my $read_set = IO::Select->new();
my %scripts_output = ();
foreach my $script (@scripts_to_run) {
    my $P_STDOUT_READ = gensym();
    my $P_STDOUT_WRITE = gensym();
    my $P_STDERR_READ = gensym();
    my $P_STDERR_WRITE = gensym();
    pipe $P_STDOUT_READ, $P_STDOUT_WRITE or die "pipe(): $!";
    pipe $P_STDERR_READ, $P_STDERR_WRITE or die "pipe(): $!";
    my @stats = stat($script);
    my $uid =  $stats[4];

    my $pid = fork();
    die "cannot fork: $!" if $pid < 0;
    if ($pid == 0) {
        if($uid > 0) {
            my $gid =  $stats[5];
            drop_priv($uid, $gid)
        }

        dup2(fileno($P_STDOUT_WRITE), 1) or die "dup2(): $!";
        dup2(fileno($P_STDERR_WRITE), 2) or die "dup2(): $!";
        close $P_STDOUT_READ;
        close $P_STDERR_READ;
        close $P_STDOUT_WRITE;
        close $P_STDERR_WRITE;
        my $error = "timeout";
        my $ok = eval {
            local $SIG{ALRM} = sub { die; };
            alarm($TIMEOUT);
            system($script);
            if ($? == -1) {
                $error = "failed to execute '$script': $!";
                die;
            }
        };
        if (!defined($ok)) {
            print STDERR "$error";
            exit 1;
        }
        exit;
    }
    close $P_STDOUT_WRITE;
    close $P_STDERR_WRITE;
    $read_set->add($P_STDOUT_READ);
    $read_set->add($P_STDERR_READ);
    $scripts_output{$pid} = { 'script' => $script,
                              'stdout' => $P_STDOUT_READ,
                              'stderr' => $P_STDERR_READ,
                              'error' => [],
    };
}

# wait for all scripts to complete
while (my @fds = $read_set->can_read()) {
    foreach my $fd (@fds) {
        my $slot;
        foreach my $s (values %scripts_output) {
            if ($s->{'stdout'} == $fd || $s->{'stderr'} == $fd) {
                $slot = $s;
                last;
            }
        }
        unless (defined($slot)) {
            warn "FATAL: got event on unknown file descriptor!";
            $read_set->remove($fd);
            close $fd;
            next;
        }
        my $line = <$fd>;
        if (!$line) {
            $read_set->remove($fd);
            close $fd;
            next;
        }
        chomp($line);
        if ($fd == $slot->{'stderr'}) {
            push @{$slot->{'error'}}, $line;
            print STDERR "$line\n";
        } else {
            send_info($line);
        }
    }
}
while (1) {
    my $pid = waitpid(-1, 0);
    last unless $pid > 0;
    $scripts_output{$pid}->{'status'} = $? >> 8;
}

# find scripts which returned error
foreach my $slot (values %scripts_output) {
    next if $slot->{'status'} == 0;
    $slot->{'script'} =~ m!/([^/]+?)$ !;
    my $script_name = $1;
    my $stderr = join ' ', map { chomp; $_ } @{$slot->{'error'}}; # perl sucks
    if (length $stderr > 20) {
        $stderr = substr($stderr, 0, 150);
        $stderr .= '...';
    }
    chomp($stderr);
    $script_error = "1 $script_name $stderr";
    # TODO: it currently sends errors for the first failed script
    last;
}

send_info("mINFO_RTM_status|$script_error");

unlockProcess();
exit 0;


sub flush_info {
  return if length ($udp_buffer) == 0;
  my $port = 6100 + int(rand(100));

  my $ok = eval {
    local $SIG{ALRM} = sub { print "rtm timeout\n"; die; };
    alarm(10);

    my $proto = getprotobyname('udp');
    socket(Socket_Handle, PF_INET, SOCK_DGRAM, $proto);
    my $iaddr = gethostbyname($destination_ip);
    my $sin = sockaddr_in("$port", $iaddr);
    send(Socket_Handle, $udp_buffer, 10, $sin);
    print $udp_buffer;
    alarm(0);
  };
  if (!defined($ok)) {
    $script_error = "1 send_info() rtm timeout";
    warn "error: $@\n";
  }
  $udp_buffer = '';
}

sub send_info {
  my $message = shift;
  $message = "rtm $message\n";

  if(length($message) > $MAX_UDP_BUFFER_SIZE and length($udp_buffer) == 0){
    $udp_buffer = $message;
    flush_info();
  }elsif(length($message) + length($udp_buffer) >= $MAX_UDP_BUFFER_SIZE){
    flush_info();
  }

  $udp_buffer .= $message;
}

sub drop_priv {
    my ($uid, $gid) = @_;

    # set EGID
    $) = "$gid $gid";
    # set EUID
    $> = $uid + 0;
    if ($> != $uid) {
        die "Can't drop EUID.";
    }
}

sub lockProcess {
    my $pid = $$;

    if (-e "$LOCK_FILE") {
        open(LOCKFILE, $LOCK_FILE) or die "Impossible to open lock file: $LOCK_FILE !!!";
        my $lockPID=<LOCKFILE> || "";
        close(LOCKFILE);

        if ($lockPID !~ m/^\d+$/ ) {
            warn("There is no PID in lock. Something is broken...");
            exit 1;
        } elsif (-e "/proc/$lockPID") {
            exit 0;
        }
        warn("There is a lock file $LOCK_FILE, but no process for it. Overwritting lock file");
    }

    unlink($LOCK_FILE); # in case it's a symlink, sysopen below would refuse to open it, and we would always die()
    # open for writing, create file if it doesn't exist, truncate it if it does, never follow symlinks but fail instead:
    sysopen(LOCKFILE, $LOCK_FILE, O_WRONLY|O_CREAT|O_TRUNC|O_NOFOLLOW, 0600) or die "Impossible to open lock file for writting: $LOCK_FILE !!!";

    print LOCKFILE $pid;
    close(LOCKFILE);
}


sub unlockProcess {
    unlink($LOCK_FILE);
}
EOF
    chown root.root "$RTM_PL"
    chmod 750 "$RTM_PL"
}

#
# Generate rtm-update-ip.sh file
function generate_rtm_update_ip {
    echo "Generating rtm-update-ip.sh..."
    cat << EOF > $RTM_UPDATE_IP.tmp
#! /bin/bash
# version: $VERSION ($RELEASE_DATE)

LC_ALL=POSIX

EOF
    cat <<'EOF' >> $RTM_UPDATE_IP.tmp
EOF
    echo "DIR='$DIR'" >> $RTM_UPDATE_IP.tmp
    cat <<'EOF' >> $RTM_UPDATE_IP.tmp

# main interface from route:
mainif=`route -n | grep "^0.0.0.0" | awk '{print $8}' | tail -1`

if test -n "$mainif"; then
        ips=`ifconfig $mainif | awk 'NR == 2 { print $2 }' | cut -f2 -d':' | egrep '[0-9]+(\.[0-9]+){3}'`
else
        for iface in 'eth0' 'eth1'; do
                ips=`ifconfig $iface 2>/dev/null | awk 'NR == 2 { print $2 }' | cut -f2 -d':' | egrep '[0-9]+(\.[0-9]+){3}'`
                if test -n "$ips"; then break; fi;
        done;
fi;

arpa=`echo "$ips" | sed "s/\./ /g" | awk '{print $3"."$2"."$1}'`;
ip=`host -t A mrtg.$arpa.in-addr.arpa $DNSSERVER 2>/dev/null | tail -n 1 | sed -ne 's/.*[\t ]\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\).*/\1/p'`
if [ -z "$ip" ]; then
  echo "No IP from OVH network or couldn't define MRTG server! Please contact OVH support."
  exit 1;
fi
echo $ip > "$DIR/etc/rtm-ip"

EOF
    chown root.root "$RTM_UPDATE_IP.tmp"
    chmod 750 "$RTM_UPDATE_IP.tmp"
    mv "$RTM_UPDATE_IP.tmp" "$RTM_UPDATE_IP"
}

function lock_process {
    if [ -e "$lockfile" ]; then
        lockpid=`cat "$lockfile"`
        if [ -e "/proc/$lockpid" ]; then
            echo "there seems to be stale $scriptname process running. check \"ps aux | grep $scriptname\"" >&2
            exit 1;
        fi
        echo "Lock $lockfile with pid $lockpid exist for script $scriptname but no process not exist, replaced by new one!!" >&2
        echo $$ > "$lockfile"
    fi
    echo $$ > "$lockfile.$$"
    mv "$lockfile.$$" "$lockfile"
}

function unlock_process {
    rm -f "$lockfile"
}

function wait_for_lock {
    echo "Waiting for finish rtm running from CRON"
    for i in `seq 1 1 30`; do
        if [ -e "$lockfile" ]; then
            echo -n "."
            sleep 2
        else
            echo -e "\nFinished."
            break
        fi
    done
}

#
# RTM installation code

lockfile='/tmp/rtm.flock'
if [ -e "$lockfile" ]; then
    wait_for_lock
fi
lock_process

# Generate selected scripts
for script in $SCRIPTS_TO_INSTALL; do
    generate_$script
done
generate_rtm_update_ip
generate_rtm

unlock_process

if [ -e "$RTM_SH" ];then
    mv $RTM_SH $RTM_SH.old
fi
ln -s $RTM_PL $RTM_SH

rm -rf /rpms

let minute=$RANDOM%60
# treat dillo cron in a special way
is_dillo=`crond --version 2>/dev/null | grep dcron`
if [ -e /etc/slackware-version -a ! -z "$is_dillo" ]; then
    CRONTAB=/var/spool/cron/crontabs/root
    CRONTABLINE='*/1 * * * * '$RTM_SH' '$minute' > /dev/null 2> /dev/null'
else
    CRONTAB=/etc/crontab
    CRONTABLINE='*/1 * * * * root '$RTM_SH' '$minute' > /dev/null 2> /dev/null'
fi
if [ -z "`cat $CRONTAB | grep \"$RTM_SH\"`" ]; then
  echo "$CRONTABLINE" >> $CRONTAB
else
    perl -pe 's!>/dev/null!> /dev/null!g' -i "$CRONTAB"
fi

# List entries in crontab
echo ""
echo "Crontab entries:"
cat $CRONTAB
sleep 2
echo ""
# restarting CRON
for i in `seq 1 1 5` ; do
  echo "Restarting CRON. Try $i"
  if [ -x "/etc/rc.d/init.d/crond" ];then
    killall -9 crond
    screen -d -m /etc/rc.d/init.d/crond restart
  elif [ -x "/etc/init.d/cron" ];then
    killall -9 cron
    screen -d -m /etc/init.d/cron restart
  elif [ -x "/etc/init.d/crond" ];then
    killall -9 crond
    screen -d -m /etc/init.d/crond restart
  elif [ -x "/etc/rc.d/init.d/cron" ];then
    killall -9 cron
    screen -d -m /etc/rc.d/init.d/cron restart
  elif [ -e /etc/slackware-version ]; then
    killall -9 crond
    /usr/sbin/crond -l10 >>/var/log/crond 2>&1
  elif [ -x /etc/init.d/vixie-cron ]; then
      /etc/init.d/vixie-cron restart
  else
    echo "WARNING: Didn't find any method of restarting cron on your distribution!" >&2
  fi
  sleep 2
  if [ -z "`ps aux | grep -v grep | grep cron 2>/dev/null`" ]; then
    echo "Cron didn't start."
  else
    break
  fi
done

if [ -z "`ps aux | grep -v grep | grep cron 2>/dev/null`" ]; then
  echo "Please check it!"
  sleep 10
else
  echo "CRON restarted succefully."
  sleep 2
fi

echo ""
echo "NOTICE:"
echo "in $DIR_SCRIPTS_MIN/check.pl you can add more check that you are interested to monitor. The form should be:"
echo "When everything is fine:"
echo "CHECK_vm|"
echo "CHECK_oops|"
echo "On error:"
echo "CHECK_vm|1"
echo "CHECK_oops|1"
echo
echo "For example:"
echo "# $DIR_SCRIPTS_MIN/check.pl"
$DIR_SCRIPTS_MIN/check.pl
echo ""
echo "Sending all informations:"

$RTM_SH

# Local variables:
# page-delimiter: "^# *\f"
# sh-basic-offset: 4
# End:
回复 点赞

使用道具 举报

yk123456Lv.8 发表于 2013-4-21 11:44:33 | 显示全部楼层
cat install_rtm.sh
直接在盒子上看,你这样没有行号好蛋疼
论坛最快速获得金币办法:
1、去盒子区发评测贴,范例:
http://hd2pt.com/thread-133245-1-2.html
2、翻译国外友人的盒子评测贴,范例:
http://hd2pt.com/thread-134285-1-3.html
回复 点赞

使用道具 举报

pilot@2楼主Lv.3 发表于 2013-4-21 13:48:30 | 显示全部楼层
    print "mINFO_LOAD_loadavg3|" . $loadavg{'loadavg3'} . "\n";
}

sub send_mem_swap_usage {
    my %mem_swap_usage = get_mem_swap_usage();
    print "mINFO_MEM_memusage|" . $mem_swap_usage{'mem_used_pr'} . "\n";
    print "mINFO_MEM_swapusage|" . $mem_swap_usage{'swap_used_pr'} . "\n";
}

sub send_cpu_usage {
    my $cpu_usage = get_cpu_usage();
    print "mINFO_CPU_usage|" . $cpu_usage . "\n";
}

sub send_hdd_usage {
    my %hdd_usage = get_hdd_usage();
    foreach (keys %{$hdd_usage{'usage'}}) {
        print "mINFO_PART_$_\_mount|" . $hdd_usage{'mount'}{$_} . "\n";
        print "mINFO_PART_$_\_usage|" . $hdd_usage{'usage'}{$_} . "\n";
        print "mINFO_PART_$_\_inodes|" . $hdd_usage{'inodes'}{$_} . "\n";
    }
}

sub get_loadavg {
    open(CONF, "/proc/loadavg") or die "loadavg: $!\n";
    chomp(my @load = split(/\s/, <CONF>));
    close(CONF);
    return ('loadavg1' => $load[0],
            'loadavg2' => $load[1],
            'loadavg3' => $load[2],);
}

sub get_cpu_usage {
    my ($cpu_usage, @cpu_usage1, @cpu_usage2, $delta);
    @cpu_usage1 = (0, 0, 0, 0);
    @cpu_usage2 = (0, 0, 0, 0);


    open(STAT, "/proc/stat") or die "/proc/stat: $!\n";
    my @stats = <STAT>;
    close (STAT);

    foreach (@stats) {
        if (/^cpu\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/i) {
            @cpu_usage2 = ($1, $2, $3, $4);
        }
    }

    # it can happen after reboot
    if( ! -e $CPU_STATS) {
       open(TMP, ">$CPU_STATS") or die "$CPU_STATS: $!\n";
       print TMP @stats;
       close(TMP);
       return 0;
    }

    open(TMP, '+<', $CPU_STATS) or die "$CPU_STATS: $!\n";
    while (<TMP>) {
        if (/^cpu\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/i) {
            @cpu_usage1 = ($1, $2, $3, $4);
        }
    }
    seek(TMP, 0, 0);
    print TMP @stats;
    close (TMP);

    $delta = $cpu_usage2[0]+$cpu_usage2[1]+$cpu_usage2[2]+$cpu_usage2[3]-
        ($cpu_usage1[0]+$cpu_usage1[1]+$cpu_usage1[2]+$cpu_usage1[3]);
    if ($delta > 0) {
        $cpu_usage = sprintf("%d", 100-(($cpu_usage2[3]-$cpu_usage1[3])/$delta*100));
    } else {
        $cpu_usage = 0;
    }
    return $cpu_usage;
}

sub get_mem_swap_usage {
    my %mem_swap_usage = ();
    my @free = `free`;
    foreach (@free) {
        if (/^Swap:\s+(\d+)\s+(\d+)\s+(\d+)/i) {
            $mem_swap_usage{'swap_total'} = $1;
            $mem_swap_usage{'swap_used'} = $2;
            if ($1 == 0) {
                # prevent division by zero
                $mem_swap_usage{'swap_used_pr'} = 0;
            } else {
                $mem_swap_usage{'swap_used_pr'} = sprintf("%d", $2/$1*100);
            }
        }
        if (/^Mem:\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/i) {
            $mem_swap_usage{'mem_total'} = $1;
            $mem_swap_usage{'mem_used'} = $2;
            $mem_swap_usage{'mem_free'} = $3;
            $mem_swap_usage{'mem_shared'} = $4;
            $mem_swap_usage{'mem_buffers'} = $5;
            $mem_swap_usage{'mem_cached'} = $6;
            $mem_swap_usage{'mem_used_pr'} = sprintf("%d", (($2-$5-$6)/$1*100));
        }
    }
    return %mem_swap_usage;
}

sub get_hdd_usage {
    my %hdd_usage = ();
    my @df = `df -l`;
    foreach (@df){
        if (/^(\/dev\/\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(\S+)/i) {
            my $hdd_name = $1;
            my $hdd_usage = $5;
            my $hdd_mount = $6;
            $hdd_name =~ s!^/dev/!!g;
            $hdd_name =~ s!/!-!g;
            $hdd_usage{'usage'}{$hdd_name} = $hdd_usage;
            $hdd_usage{'usage'}{$hdd_name} =~ s/%//;
            $hdd_usage{'mount'}{$hdd_name} = $hdd_mount;
        }
    }

    # inodes
    @df = `df -li`;
    foreach (@df) {
        if (/^(\/dev\/\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(\S+)/i) {
            my $hdd_name = $1;
            my $hdd_usage = $5;
            $hdd_usage =~ s/%//;
            $hdd_usage = 0 unless $hdd_usage =~ /^\d+$/;
            $hdd_name =~ s/^\/dev\///g;
            $hdd_name =~ s!/!-!g;
            $hdd_usage{'inodes'}{$hdd_name} = $hdd_usage;
        }
    }
    return %hdd_usage;
}

send_hdd_usage();
send_mem_swap_usage();
send_loadavg();
send_cpu_usage();
EOF
    chown 500.500 "$DIR_SCRIPTS_MIN/usage.pl"
    chmod 750 "$DIR_SCRIPTS_MIN/usage.pl"
}

#

# Generate /scripts/min/usage-root.pl file
function generate_usage_root {
    echo "Generating $DIR_SCRIPTS_MIN/usage-root.pl..."
    cat << EOF > $DIR_SCRIPTS_MIN/usage-root.pl
#! /usr/bin/perl
# version: $VERSION ($RELEASE_DATE)

\$ENV{"LC_ALL"} = "POSIX";

EOF
    cat <<'EOF' >> $DIR_SCRIPTS_MIN/usage-root.pl
use strict;

sub send_process {
    my %processes = get_processes();
    print "mINFO_LOAD_processesactive|" . $processes{'processesactive'} . "\n";
    print "mINFO_LOAD_processesup|" . $processes{'processesup'} . "\n";
}

sub send_top_rss {
    my $top = get_top_mem_procs();
    my $n = 1;
    foreach my $info (@$top) {
        my $vsz = $info->[0];
        my $cmd = $info->[1];
        printf "mINFO_MEM_top_mem_%02d_name|%s\n", $n, $cmd;
        printf "mINFO_MEM_top_mem_%02d_size|%s\n", $n, $vsz;
        ++$n;
    }
}

sub get_processes {
    chomp(my @rtm_sids = `ps --no-headers -C rtm -o sess | sort -n | uniq`);
    my @ps_output = `ps --no-headers -A -o sess,state,command`;
    my $active = 0;
    my $total = 0;
    my $rtm_procs = 0;
    foreach my $line (@ps_output) {
        next if $line !~ /(\d+)\s+(\S+)/;
        my $sid = $1;
        my $state = $2;
        if (grep $sid == $_, @rtm_sids) {
            ++$rtm_procs;
            next;
        }
        ++$total;
        ++$active if $state =~ /^R/;
    }
    return ('processesactive' => $active, 'processesup' => $total);
}

sub get_top_mem_procs {
    my @top;
    my @output = `ps -A -o vsz,cmd --sort=-vsz --no-headers | head -n 5`;
    return [] unless $? == 0;
    foreach (@output) {
        next unless m/\s*(\d+)\s+(.+)/;
        push @top, [$1, $2];
    }
    return \@top;
}

send_process();
send_top_rss();
EOF
    chown root.root "$DIR_SCRIPTS_MIN/usage-root.pl"
    chmod 750 "$DIR_SCRIPTS_MIN/usage-root.pl"
}

#

# Generate /scripts/hour/hwinfo.pl file
function generate_hwinfo {
    echo "Generating $DIR_SCRIPTS_HOUR/hwinfo.pl..."
    cat << EOF > $DIR_SCRIPTS_HOUR/hwinfo.pl
#! /usr/bin/perl
# version: $VERSION ($RELEASE_DATE)

\$ENV{"LC_ALL"} = "POSIX";

EOF
    cat <<'EOF' >> $DIR_SCRIPTS_HOUR/hwinfo.pl
use strict;

sub send_cpu_info {
    my %cpu_info = get_cpu_info();
    print "dHW_CPU_name|" . $cpu_info{'cpu_name'} . "\n";
    print "dHW_CPU_mhz|" . $cpu_info{'cpu_mhz'} . "\n";
    print "dHW_CPU_cache|" . $cpu_info{'cpu_cache'} . "\n";
    print "dHW_CPU_number|" . $cpu_info{'cpu_no'} . "\n";
}

sub send_lspci_info {
    my %lspci_info = get_lspci_info();
    foreach (keys %lspci_info) {
        my $tempKey = $_;
        $tempKey =~ s/\:|\.|\_/-/g;
        print "dHW_LSPCI_PCI-$tempKey|" . $lspci_info{$_} . "\n";
    }
}


sub get_cpu_info {
    my %cpu_info = ( 'cpu_no' => 0 );
    open(CONF,"/proc/cpuinfo") or die "loadavg: $!\n";
    while( <CONF> ) {
        chomp($_);
        if ($_ =~ /^model name\s+:\s(.*)/) {
            $cpu_info{'cpu_name'} = $1;
            $cpu_info{'cpu_no'} += 1;
        }
        if ($_ =~ /^cpu MHz/) {
            s/cpu MHz\s+:\s*//g;
            $cpu_info{'cpu_mhz'} = $_;
        }
        if ($_ =~ /^cache size/) {
            s/cache size\s+:\s*//g;
            $cpu_info{'cpu_cache'} = $_;
        }
    }
    $cpu_info{'cpu_no'} = $cpu_info{'cpu_no'};
    close(CONF);
    return %cpu_info;
}


sub get_lspci_info {
    my %lspci_info = ();
    my @lspci = `lspci -n 2>/dev/null`;
    if ($? == 0) {
        foreach (@lspci) {
            if (/^(\S+).+:\s+(.+:.+)\s+\(/i) {
                $lspci_info{$1} = $2;
            }
            elsif (/^(\S+).+:\s+(.+:.+$)/i){
                $lspci_info{$1} = $2;
            }
        }
    }
    return %lspci_info;
}

send_cpu_info();
send_lspci_info();
EOF
    chown 500.500 "$DIR_SCRIPTS_HOUR/hwinfo.pl"
    chmod 750 "$DIR_SCRIPTS_HOUR/hwinfo.pl"
}

#

# Generate /scripts/hour/hwinfo-root.pl file
function generate_hwinfo_root {
    echo "Generating $DIR_SCRIPTS_HOUR/hwinfo-root.pl..."
    cat << EOF > $DIR_SCRIPTS_HOUR/hwinfo-root.pl
#! /usr/bin/perl
# version: $VERSION ($RELEASE_DATE)

\$ENV{"LC_ALL"} = "POSIX";

EOF
    cat <<'EOF' >> $DIR_SCRIPTS_HOUR/hwinfo-root.pl
use strict;

sub send_mainboard_memory_info {
    my %mainboard_memory_info = get_mainboard_memory_info();
    print "dHW_MB_manufacture|" . $mainboard_memory_info{'mainboard'}{'manufacture'} . "\n";
    print "dHW_MB_name|" . $mainboard_memory_info{'mainboard'}{'name'} . "\n";
    foreach (keys %{$mainboard_memory_info{'memory'}}) {
        print "dHW_MEM_BANK-$_|" . $mainboard_memory_info{'memory'}{$_} . "\n";
    }
}

sub send_hdd_info {
    my %hdd_info = get_hdd_info();
    get_hdd_info_scsi(\%hdd_info);
    foreach (keys %{$hdd_info{'model'}}) {
        print "dHW_HDD_$_\_capacity|" . $hdd_info{'capacity'}{$_} . " GB" . "\n";
        print "dHW_HDD_$_\_model|" . $hdd_info{'model'}{$_} . "\n";
    }
}

sub get_mainboard_memory_info {
    my %mainboard_memory_info = ();
    my @dmidecode = `dmidecode 2>/dev/null`;
    if ($? == 0) {
        my $module = "";
        for (my $i = 0; $i < @dmidecode; $i++) {
            if($dmidecode[$i] =~ /^\s*Base Board Information/i) {
                $dmidecode[$i+1] =~ s/Manufacturer://g;
                $dmidecode[$i+2] =~ s/Product Name://g;
                $mainboard_memory_info{'mainboard'}{'manufacture'} = $dmidecode[$i+1];
                $mainboard_memory_info{'mainboard'}{'name'} = $dmidecode[$i+2];
            }
            if($dmidecode[$i] =~ /^\s*Memory Module Information/i) {
                $dmidecode[$i+1] =~ /^\s+(\S+)\s+(\S+)\s+(.+)$/i;
                $module = $3;
                $module =~ s/\W/-/g;
                chomp($module);
            }
            if(($dmidecode[$i] =~ /^\s+Installed Size:/i)  && ($module =~ /\S+/)) {
                $module =~ s/#/_/;
                $dmidecode[$i] =~ s/Installed Size://g;
                $mainboard_memory_info{'memory'}{$module} = $dmidecode[$i];
                $mainboard_memory_info{'memory'}{$module} =~ s/^\s+//;
                chomp($mainboard_memory_info{'memory'}{$module});
                $module = "";
            }
        }
        if (!defined $mainboard_memory_info{'memory'}) {
            for (my $i = 0; $i < @dmidecode; $i++){
                if($dmidecode[$i] =~ /^\s*Memory Device/i) {
                    my $bank = $dmidecode[$i+9];
                    $bank =~ /Bank Locator:\s+(.*)/;
                    $bank = $1;
                    next if !$bank;
                    $bank =~ s/\s//g;
                    $bank =~ s/[\s\.\/\\_]/-/g;
                    my $locator = $dmidecode[$i+8];
                    $locator =~ /Locator:\s+(.*)/;
                    $locator = $1;
                    next if !$locator;
                    $locator =~ s/\s//g;
                    $locator =~ s![\s./\\_#]!-!g;
                    my $size = $dmidecode[$i+5];
                    $size =~ /Size:\s+(.*)/;
                    $size = $1;
                    next if !$size;
                    $size =~ s/\s*MB\s*//g;
                    chomp($size);
                    if ($bank . $locator ne "") {
                        $mainboard_memory_info{'memory'}{$bank . "-" . $locator} = $size;
                    }
                }
            }
        }
        $mainboard_memory_info{'mainboard'}{'manufacture'} =~ s/^\s+//;
        $mainboard_memory_info{'mainboard'}{'name'} =~ s/^\s+//;
        chomp($mainboard_memory_info{'mainboard'}{'manufacture'});
        chomp($mainboard_memory_info{'mainboard'}{'name'});
    } else {
        $mainboard_memory_info{'mainboard'}{'manufacture'} = "dmidecode not installed";
        $mainboard_memory_info{'mainboard'}{'name'} = "dmidecode not installed";
    }
    return %mainboard_memory_info;
}

sub has_raid {
    my $dmesg = `cat /var/log/dmesg`;
    return ((-e "/proc/mdstat" && `grep md /proc/mdstat` ne "") ||
            ($dmesg =~ m/3w-xxxx: scsi/) ||
            (`lspci -d 1000: 2>&1` ne "") ||
            ($dmesg =~ m/scsi. : Found a 3ware/) ||
            ($dmesg =~ m/3w-9xxx: scsi.: Found/) ||
            ($dmesg =~ m/LSISAS1064 A3/) ||
            ($dmesg =~ m/Mylex AcceleRAID 160 PCI RAID Controller/));
}

sub get_scsi_disk_capacity {
    my $device = shift;
    my $capacity = "0";
    open my $FP, "fdisk -l $device |" or return "0";
    while (my $line = <$FP>) {
        next unless $line =~ /^Disk\s+$device:\s+([^,]+)/;
        $capacity = $1;
        $capacity =~ s/\s//g;
        $capacity =~ s/GB$//g;
        last;
    }
    return "0" unless close $FP;
    return $capacity;
}

sub get_hdd_info_scsi {
    return () if has_raid();
    my $hdd_info = shift;
    open my $FP, "/proc/scsi/scsi" or return ();
    chomp(my $scsi = join('', <$FP>));
    close $FP;
    my @letters = ('a'..'z');
    while ($scsi =~ /^\s*Vendor:\s*.+Model:\s*(.+?)\s*Rev:/mg) {
        my $l = shift @letters;
        $hdd_info->{'model'}{"sd$l"} = $1;
        $hdd_info->{'capacity'}{"sd$l"} = get_scsi_disk_capacity("/dev/sd$l");
    }
}

sub get_hdd_info {
    my %hdd_info = ();
    my $ide = `ls /proc/ide`;
    my @ide = split(/\s+/, $ide);
    foreach (@ide) {
        if (/^hd/) {
            $ide = $_;
            if (-e "/proc/ide/$ide/model") {
                open(FILE, "/proc/ide/$ide/model");
                while (<FILE>) {
                    chomp($_);
                    $hdd_info{'model'}{$ide} = $_;
                }
                close(FILE);
            } else {
                $hdd_info{'model'}{$ide} = "";
            }
            if (-e "/proc/ide/$ide/capacity") {
                open(FILE, "/proc/ide/$ide/capacity");
                while (<FILE>) {
                    chomp($_);
                    $hdd_info{'capacity'}{$ide} = sprintf("%d",$_*512/1000000000);
                }
                close(FILE);
            }  else {
                $hdd_info{'capacity'}{$ide} = ""
            };
        }
    }
    return %hdd_info;
}


send_mainboard_memory_info();
send_hdd_info();
EOF
    chown root.root "$DIR_SCRIPTS_HOUR/hwinfo-root.pl"
    chmod 750 "$DIR_SCRIPTS_HOUR/hwinfo-root.pl"
}

#

# Generate /scripts/min/hddinfo.pl file
function generate_hddinfo {
    echo "Generating $DIR_SCRIPTS_MIN/hddinfo.pl..."
    cat << EOF > $DIR_SCRIPTS_MIN/hddinfo.pl
#! /usr/bin/perl
# version: $VERSION ($RELEASE_DATE)

\$ENV{"LC_ALL"} = "POSIX";

EOF
    cat <<'EOF' >> $DIR_SCRIPTS_MIN/hddinfo.pl
use strict;

sub send_hdd_status {
    chomp(my $ide = `ls /proc/ide`);
    chomp(my @status = `\/bin\/dmesg \| grep -i \"error\\\|drive not ready\" \| grep -i \"\^hd\" \| cut -f 1 -d \":\" \| sort \| uniq`);
    my @ide = split(/\s+/, $ide);
    foreach $ide (@ide) {
        my $error = 0;
        if ($ide =~ /^hd/) {
            foreach (@status) {
                $error = 1 if $_ eq $ide;
            }
            if ($error == 1) {
                print "mHW_HDD_$ide\_status|ERROR\n";
            } else {
                print "mHW_HDD_$ide\_status|OK\n";
            }
        }
    }

    # check of scsi errors
    my $scsi_available = `grep '^Host:' /proc/scsi/scsi 2>/dev/null`;
    my $possible_error;
    if ($scsi_available) {
        open my $dmesg, "dmesg |" or die "Can't launch dmesg: $!";
        my $status = 'OK';
        while (<$dmesg>) {
            if (/Info fld=([^,]+), Deferred (\S+?): sense key (.+ Error)/) {
                $status = $3;
            }
            if (/^sd.: .+?: sense key: (.+ Error)/) {
                $status = $1;
            }
            if (/^(sd.+?): *rw=\d+/) {
                $possible_error = $1;
                next;
            }
            if (defined($possible_error) && /^attempt to access beyond/) {
                $status = 'BAD_ACCESS';
            }
            $possible_error = undef;
        }
        print "mHW_HDD_scsi_status|$status\n";
    }
}

sub send_hdd_temp {
    my %hdd_temp = get_hdd_temp();
    foreach (keys %hdd_temp) {
        print "mINFO_HDD_$_\_temperature|" . $hdd_temp{$_} . "\n";
    }
}


sub get_hdd_temp {
    my %hdd_temp = ();
    my $ide = `ls /proc/ide`;
    my @ide = split(/\s+/, $ide);
    foreach (@ide) {
        if (/^hd/) {
            $ide = $_;
            my $temp = `hddtemp /dev/$ide 2>/dev/null`;
            if ($? == 0) {
                if ($temp =~ m/.*:.*:\s(\d+)/) {
                    $temp = $1;
                } else {
                    $temp = "-1";
                }
                $hdd_temp{$ide} = $temp;
            } else {
                $hdd_temp{$ide} = "-2";
            }
        }
    }
    return %hdd_temp;
}


send_hdd_status();
send_hdd_temp();
EOF
    chown root.root "$DIR_SCRIPTS_MIN/hddinfo.pl"
    chmod 750 "$DIR_SCRIPTS_MIN/hddinfo.pl"
}

#

# Generate rtm.pl file
function generate_rtm {
    echo "Generating rtm.pl..."
    cat << EOF > $RTM_PL
#! /usr/bin/perl
# version: $VERSION ($RELEASE_DATE)

\$ENV{"LC_ALL"} = "POSIX";

EOF
    cat <<'EOF' >> $RTM_PL
use Fcntl;
use strict;
use Socket;
use Time::localtime;
use Symbol qw(gensym);
use IO::Select;
use POSIX qw(dup2);

# Check for root permission
if ($) != 0) {
    die "You are not a root!";
}

# Version of script
EOF
    echo "my \$version = '$VERSION';" >> $RTM_PL
    echo "my \$release_date = '$RELEASE_DATE';" >> $RTM_PL
    cat <<'EOF' >> $RTM_PL

# at this hour all information will be send
my $HOUR = 2;

# get uptime
open(FILE, "/proc/uptime") || die("Cannot open /proc/uptime");
my $uptime = <FILE>;
close(FILE);
$uptime =~ /^(\d+)/;
$uptime = $1;

my $script_name = $0;
# get basename of the script
$script_name =~ s/(^.*\/)//;

EOF
    echo "my \$base_dir = '$DIR';" >> $RTM_PL
    echo "my \$scripts_dir_daily = '$DIR_SCRIPTS_DAILY';" >> $RTM_PL
    echo "my \$scripts_dir_hour = '$DIR_SCRIPTS_HOUR';" >> $RTM_PL
    echo "my \$scripts_dir_min = '$DIR_SCRIPTS_MIN';" >> $RTM_PL
    echo "my \$rtm_update_ip = '$RTM_UPDATE_IP';" >> $RTM_PL
    cat <<'EOF' >> $RTM_PL

chomp(my @scripts_daily = `/bin/ls -1 $scripts_dir_daily`);
chomp(my @scripts_hour = `/bin/ls -1 $scripts_dir_hour`);
chomp(my @scripts_min = `/bin/ls -1 $scripts_dir_min`);

my $env_path = $ENV{'PATH'};
$ENV{'PATH'} = "/usr/local/sbin:/usr/local/bin:$env_path";

# global variable used to report errors from failed scripts
my $script_error = 0;

# determine rtm server ip from mrtg config
my $ipfile = "$base_dir/etc/rtm-ip";
open FP, "$ipfile" or die("failed to open '$ipfile' for reading: $!");
chomp(my $destination_ip = <FP>);
close FP;
if ($destination_ip !~ /^\d+\.\d+\.\d+\.\d+$/) {
    die "failed to read destination ip from '$ipfile': invalid ip: $destination_ip";
}

my $LOCK_FILE = "/var/lock/rtm.flock";
lockProcess();

my $TIMEOUT = 45;
my $MAX_UDP_BUFFER_SIZE = 200;
my $udp_buffer = '';

my $tm = localtime(time);
my $hour = $tm->hour;
my $min = $tm->min;

my @scripts_to_run = ();

# per minute data
push @scripts_to_run, map { "$scripts_dir_min/$_" } @scripts_min;

# hourly data
if ((scalar @ARGV == 0) or (($min >= 0) && ($min <= 5)) or $uptime < 900) {
    send_info("hINFO_uptime|" . $uptime);
    push @scripts_to_run, map { "$scripts_dir_hour/$_" } @scripts_hour;
}

# daily data
if (scalar @ARGV == 0 || (($hour eq $HOUR || $uptime < 900) && $min % 10 == 0)) {
    send_info("dINFO_RTM_version|" . $version);
    push @scripts_to_run, map { "$scripts_dir_daily/$_" } @scripts_daily;
}

# update rtm-ip daily
if (@ARGV > 0 && $hour eq $HOUR && $ARGV[0] == $min) {
    system("$rtm_update_ip &");
}

# run collected scripts in separate processes
my $read_set = IO::Select->new();
my %scripts_output = ();
foreach my $script (@scripts_to_run) {
    my $P_STDOUT_READ = gensym();
    my $P_STDOUT_WRITE = gensym();
    my $P_STDERR_READ = gensym();
    my $P_STDERR_WRITE = gensym();
    pipe $P_STDOUT_READ, $P_STDOUT_WRITE or die "pipe(): $!";
    pipe $P_STDERR_READ, $P_STDERR_WRITE or die "pipe(): $!";
    my @stats = stat($script);
    my $uid =  $stats[4];

    my $pid = fork();
    die "cannot fork: $!" if $pid < 0;
    if ($pid == 0) {
        if($uid > 0) {
            my $gid =  $stats[5];
            drop_priv($uid, $gid)
        }

        dup2(fileno($P_STDOUT_WRITE), 1) or die "dup2(): $!";
        dup2(fileno($P_STDERR_WRITE), 2) or die "dup2(): $!";
        close $P_STDOUT_READ;
        close $P_STDERR_READ;
        close $P_STDOUT_WRITE;
        close $P_STDERR_WRITE;
        my $error = "timeout";
        my $ok = eval {
            local $SIG{ALRM} = sub { die; };
            alarm($TIMEOUT);
            system($script);
            if ($? == -1) {
                $error = "failed to execute '$script': $!";
                die;
            }
        };
        if (!defined($ok)) {
            print STDERR "$error";
            exit 1;
        }
        exit;
    }
    close $P_STDOUT_WRITE;
    close $P_STDERR_WRITE;
    $read_set->add($P_STDOUT_READ);
    $read_set->add($P_STDERR_READ);
    $scripts_output{$pid} = { 'script' => $script,
                              'stdout' => $P_STDOUT_READ,
                              'stderr' => $P_STDERR_READ,
                              'error' => [],
    };
}

# wait for all scripts to complete
while (my @fds = $read_set->can_read()) {
    foreach my $fd (@fds) {
        my $slot;
        foreach my $s (values %scripts_output) {
            if ($s->{'stdout'} == $fd || $s->{'stderr'} == $fd) {
                $slot = $s;
                last;
            }
        }
        unless (defined($slot)) {
            warn "FATAL: got event on unknown file descriptor!";
            $read_set->remove($fd);
            close $fd;
            next;
        }
        my $line = <$fd>;
        if (!$line) {
            $read_set->remove($fd);
            close $fd;
            next;
        }
        chomp($line);
        if ($fd == $slot->{'stderr'}) {
            push @{$slot->{'error'}}, $line;
            print STDERR "$line\n";
        } else {
            send_info($line);
        }
    }
}
while (1) {
    my $pid = waitpid(-1, 0);
    last unless $pid > 0;
    $scripts_output{$pid}->{'status'} = $? >> 8;
}

# find scripts which returned error
foreach my $slot (values %scripts_output) {
    next if $slot->{'status'} == 0;
    $slot->{'script'} =~ m!/([^/]+?)$ !;
    my $script_name = $1;
    my $stderr = join ' ', map { chomp; $_ } @{$slot->{'error'}}; # perl sucks
    if (length $stderr > 20) {
        $stderr = substr($stderr, 0, 150);
        $stderr .= '...';
    }
    chomp($stderr);
    $script_error = "1 $script_name $stderr";
    # TODO: it currently sends errors for the first failed script
    last;
}

send_info("mINFO_RTM_status|$script_error");

unlockProcess();
exit 0;


sub flush_info {
  return if length ($udp_buffer) == 0;
  my $port = 6100 + int(rand(100));

  my $ok = eval {
    local $SIG{ALRM} = sub { print "rtm timeout\n"; die; };
    alarm(10);

    my $proto = getprotobyname('udp');
    socket(Socket_Handle, PF_INET, SOCK_DGRAM, $proto);
    my $iaddr = gethostbyname($destination_ip);
    my $sin = sockaddr_in("$port", $iaddr);
    send(Socket_Handle, $udp_buffer, 10, $sin);
    print $udp_buffer;
    alarm(0);
  };
  if (!defined($ok)) {
    $script_error = "1 send_info() rtm timeout";
    warn "error: $@\n";
  }
  $udp_buffer = '';
}

sub send_info {
  my $message = shift;
  $message = "rtm $message\n";

  if(length($message) > $MAX_UDP_BUFFER_SIZE and length($udp_buffer) == 0){
    $udp_buffer = $message;
    flush_info();
  }elsif(length($message) + length($udp_buffer) >= $MAX_UDP_BUFFER_SIZE){
    flush_info();
  }

  $udp_buffer .= $message;
}

sub drop_priv {
    my ($uid, $gid) = @_;

    # set EGID
    $) = "$gid $gid";
    # set EUID
    $> = $uid + 0;
    if ($> != $uid) {
        die "Can't drop EUID.";
    }
}

sub lockProcess {
    my $pid = $$;

    if (-e "$LOCK_FILE") {
        open(LOCKFILE, $LOCK_FILE) or die "Impossible to open lock file: $LOCK_FILE !!!";
        my $lockPID=<LOCKFILE> || "";
        close(LOCKFILE);

        if ($lockPID !~ m/^\d+$/ ) {
            warn("There is no PID in lock. Something is broken...");
            exit 1;
        } elsif (-e "/proc/$lockPID") {
            exit 0;
        }
        warn("There is a lock file $LOCK_FILE, but no process for it. Overwritting lock file");
    }

    unlink($LOCK_FILE); # in case it's a symlink, sysopen below would refuse to open it, and we would always die()
    # open for writing, create file if it doesn't exist, truncate it if it does, never follow symlinks but fail instead:
    sysopen(LOCKFILE, $LOCK_FILE, O_WRONLY|O_CREAT|O_TRUNC|O_NOFOLLOW, 0600) or die "Impossible to open lock file for writting: $LOCK_FILE !!!";

    print LOCKFILE $pid;
    close(LOCKFILE);
}


sub unlockProcess {
    unlink($LOCK_FILE);
}
EOF
    chown root.root "$RTM_PL"
    chmod 750 "$RTM_PL"
}

#

# Generate rtm-update-ip.sh file
function generate_rtm_update_ip {
    echo "Generating rtm-update-ip.sh..."
    cat << EOF > $RTM_UPDATE_IP.tmp
#! /bin/bash
# version: $VERSION ($RELEASE_DATE)

LC_ALL=POSIX

EOF
    cat <<'EOF' >> $RTM_UPDATE_IP.tmp
EOF
    echo "DIR='$DIR'" >> $RTM_UPDATE_IP.tmp
    cat <<'EOF' >> $RTM_UPDATE_IP.tmp

# main interface from route:
mainif=`route -n | grep "^0.0.0.0" | awk '{print $8}' | tail -1`

if test -n "$mainif"; then
        ips=`ifconfig $mainif | awk 'NR == 2 { print $2 }' | cut -f2 -d':' | egrep '[0-9]+(\.[0-9]+){3}'`
else
        for iface in 'eth0' 'eth1'; do
                ips=`ifconfig $iface 2>/dev/null | awk 'NR == 2 { print $2 }' | cut -f2 -d':' | egrep '[0-9]+(\.[0-9]+){3}'`
                if test -n "$ips"; then break; fi;
        done;
fi;

arpa=`echo "$ips" | sed "s/\./ /g" | awk '{print $3"."$2"."$1}'`;
ip=`host -t A mrtg.$arpa.in-addr.arpa $DNSSERVER 2>/dev/null | tail -n 1 | sed -ne 's/.*[\t ]\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\).*/\1/p'`
if [ -z "$ip" ]; then
  echo "No IP from OVH network or couldn't define MRTG server! Please contact OVH support."
  exit 1;
fi
echo $ip > "$DIR/etc/rtm-ip"

EOF
    chown root.root "$RTM_UPDATE_IP.tmp"
    chmod 750 "$RTM_UPDATE_IP.tmp"
    mv "$RTM_UPDATE_IP.tmp" "$RTM_UPDATE_IP"
}

function lock_process {
    if [ -e "$lockfile" ]; then
        lockpid=`cat "$lockfile"`
        if [ -e "/proc/$lockpid" ]; then
            echo "there seems to be stale $scriptname process running. check \"ps aux | grep $scriptname\"" >&2
            exit 1;
        fi
        echo "Lock $lockfile with pid $lockpid exist for script $scriptname but no process not exist, replaced by new one!!" >&2
        echo $$ > "$lockfile"
    fi
    echo $$ > "$lockfile.$$"
    mv "$lockfile.$$" "$lockfile"
}

function unlock_process {
    rm -f "$lockfile"
}

function wait_for_lock {
    echo "Waiting for finish rtm running from CRON"
    for i in `seq 1 1 30`; do
        if [ -e "$lockfile" ]; then
            echo -n "."
            sleep 2
        else
            echo -e "\nFinished."
            break
        fi
    done
}

#

# RTM installation code

lockfile='/tmp/rtm.flock'
if [ -e "$lockfile" ]; then
    wait_for_lock
fi
lock_process

# Generate selected scripts
for script in $SCRIPTS_TO_INSTALL; do
    generate_$script
done
generate_rtm_update_ip
generate_rtm

unlock_process

if [ -e "$RTM_SH" ];then
    mv $RTM_SH $RTM_SH.old
fi
ln -s $RTM_PL $RTM_SH

rm -rf /rpms

let minute=$RANDOM%60
# treat dillo cron in a special way
is_dillo=`crond --version 2>/dev/null | grep dcron`
if [ -e /etc/slackware-version -a ! -z "$is_dillo" ]; then
    CRONTAB=/var/spool/cron/crontabs/root
    CRONTABLINE='*/1 * * * * '$RTM_SH' '$minute' > /dev/null 2> /dev/null'
else
    CRONTAB=/etc/crontab
    CRONTABLINE='*/1 * * * * root '$RTM_SH' '$minute' > /dev/null 2> /dev/null'
fi
if [ -z "`cat $CRONTAB | grep \"$RTM_SH\"`" ]; then
  echo "$CRONTABLINE" >> $CRONTAB
else
    perl -pe 's!>/dev/null!> /dev/null!g' -i "$CRONTAB"
fi

# List entries in crontab
echo ""
echo "Crontab entries:"
cat $CRONTAB
sleep 2
echo ""
# restarting CRON
for i in `seq 1 1 5` ; do
  echo "Restarting CRON. Try $i"
  if [ -x "/etc/rc.d/init.d/crond" ];then
    killall -9 crond
    screen -d -m /etc/rc.d/init.d/crond restart
  elif [ -x "/etc/init.d/cron" ];then
    killall -9 cron
    screen -d -m /etc/init.d/cron restart
  elif [ -x "/etc/init.d/crond" ];then
    killall -9 crond
    screen -d -m /etc/init.d/crond restart
  elif [ -x "/etc/rc.d/init.d/cron" ];then
    killall -9 cron
    screen -d -m /etc/rc.d/init.d/cron restart
  elif [ -e /etc/slackware-version ]; then
    killall -9 crond
    /usr/sbin/crond -l10 >>/var/log/crond 2>&1
  elif [ -x /etc/init.d/vixie-cron ]; then
      /etc/init.d/vixie-cron restart
  else
    echo "WARNING: Didn't find any method of restarting cron on your distribution!" >&2
  fi
  sleep 2
  if [ -z "`ps aux | grep -v grep | grep cron 2>/dev/null`" ]; then
    echo "Cron didn't start."
  else
    break
  fi
done

if [ -z "`ps aux | grep -v grep | grep cron 2>/dev/null`" ]; then
  echo "Please check it!"
  sleep 10
else
  echo "CRON restarted succefully."
  sleep 2
fi

echo ""
echo "NOTICE:"
echo "in $DIR_SCRIPTS_MIN/check.pl you can add more check that you are interested to monitor. The form should be:"
echo "When everything is fine:"
echo "CHECK_vm|"
echo "CHECK_oops|"
echo "On error:"
echo "CHECK_vm|1"
echo "CHECK_oops|1"
echo
echo "For example:"
echo "# $DIR_SCRIPTS_MIN/check.pl"
$DIR_SCRIPTS_MIN/check.pl
echo ""
echo "Sending all informations:"

$RTM_SH

# Local variables:
# page-delimiter: "^# *\f"
# sh-basic-offset: 4
# End:
回复 点赞

使用道具 举报

pilot@2楼主Lv.3 发表于 2013-4-21 13:50:13 | 显示全部楼层
这个我也没看到行号啊  不懂  我是按照你给的命令输入的  然后出来的内容copy了下。
回复 点赞

使用道具 举报

回复

懒得打字嘛,点击右侧快捷回复 【本站酷狼4T,750元】
您需要登录后才可以回帖 登录 | 注册

本版积分规则

投诉/建议联系

support@gebi1.cn

未经授权禁止转载,复制和建立镜像,
如有违反,追究法律责任
  • 关注公众号
  • 添加微信客服
Copyright © 2001-2024 隔壁网 版权所有 All Rights Reserved. 粤ICP备14056481号-1
关灯 在本版发帖
扫一扫添加微信客服
返回顶部
快速回复 返回顶部 返回列表