#!/usr/bin/perl
# ----------------------------------------------------------------
# sysinfo for xchat
# (c) 2002,2003 Sebastian Wenzler <sickathomedotanddotdrunkdotat>
# usage : /sys [-p] [<module>] [<module>] ...
# Optional requirements: xdpyinfo, nvclock, sensors, hddtemp, lspci ;)
#
# edited by mistery <mist3ry@pandora.be> A.k.a. pittaman a.k.a Aaron Lenoir
#
# Allright, this is version two of my sysinfo script. I decided to edit
# it again and clean up the code after I saw an edited version of my
# script on the net. I downloaded it, and copied some stuff from it
# to my own script and made it version two. You can find that script
# on: http://www.sh.nu/download/code/sysinfo.pl
#
# It says in the comments that the code is mostly stolen from here,
# but hat isn't really true anymore, as I stole from him and from Sebastian
# Wenzler.
#
# Critical change, this is xchat only. The irssi modifications had me crashing
# xchat most of the time, I'll make an irssi version of this script in the near
# future.
#
# So, nothing really new, just code clean up. For the hdd temperature checking
# you have to install a small utility hddtemp which can be found here:
# http://www.guzu.net/linux/hddtemp.php
# You have to have a SMART capable hard drive though.
#
# I did remove coloured output. Only colour you'll see is the memory usage "graph".
#
# BTW: If you're looking for the old version, I lost it, sorry :|
#
#
# You can find the original script at: http://drunk.at/sick/download/sysinfo.pl
#
# ----------------------------GNU/GPL-----------------------------
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ---
# Please see the file ./gpl.txt for the full license
#
my $VERSION = "2.0";
### SETTINGS HERE ###
#-- SET TO ONE FOR COLOR --#
# SET TO ONE IF YOU WANT COLOR!
my $color = 0;
# MAXIMUM ALLOWED TEXT LENGTH ON THE SERVER
my $maxtext = 500;
# S.M.A.R.T. HDD
my $SMARTDRIVE = "/dev/hda";
### YOU DON'T HAVE CHANGE ANYTHING BELOW ###
my $UNDERL_S = "\037";
my $UNDERL_E = "\037";
my $TITLE_S = "\002";
my $TITLE_E = "\002";
my $ALERT_S = "\002";
my $NORMAL_S = "";
my $ALERT_E = "\002";
my $NORMAL_E = "";
use strict;
BEGIN {
use vars '$xchat';
eval q {
IRC::get_info(1);
};
$xchat = !$@;
}
my $procloc = "/proc";
if ( $color ) {
$ALERT_E = "\003";
$NORMAL_E = "\003";
$ALERT_S = "\0034";
$NORMAL_S = "\0033";
}
sub file_executable
{
my $command = shift;
my @directories=split(/:/, $ENV{'PATH'} );
for (@directories) {
if ( -x "$_/$command" ) { return 1; }
}
return 0;
}
# All available modules.
my @modules = qw /
uname
distro
cpu
mem
hddtemp
diskspace
uptime
load
procs
graphic
screen
nvidia
netinfo
sensors
/;
sub uname
{
open (X, "${procloc}/version");
my $UNAME = <X>;
close (X);
$UNAME =~ s/^(\S+) \S+ (\S+) .*\n$/$1 $2/;
return "${TITLE_S}uname:${TITLE_E} ".$UNAME." ";
}
sub distro {
my $DIST = "";
$DIST = `cat /etc/*-version 2> /dev/null`;
chop $DIST;
$DIST = `cat /etc/*-release 2> /dev/null` if $DIST eq "";
chop $DIST;
return "${TITLE_S}Distro:${TITLE_E} " . (($DIST) ? $DIST : "Unknown") . " ";
}
sub cpu
{
my $NUM = 0;
my $MIPS = 0;
my ($MODEL,$SYSTEM);
my $CPU = 0;
open (X, "${procloc}/cpuinfo");
while (<X>) {
if (/^(cpu model|model name).*: (.*)\n$/) {
$MODEL = $2;
$NUM += 1;
} elsif (/^system type.*: (.*)\n$/) {
$SYSTEM = $1;
} elsif (!$CPU && /^cpu MHz.*: (.*)\n$/) {
$CPU = $1;
} elsif (/^bogomips.*: (.*)\n$/i) {
$MIPS += $1;
}
}
close (X);
#--SUPPORT FOR MULTIPLE PROCS--#
if ($NUM == 2 ) { $MODEL="Dual $MODEL"; }
if ($NUM == 4 ) { $MODEL="Quad $MODEL"; }
$MODEL = $SYSTEM . " " . $MODEL;
return "${TITLE_S}CPU:${TITLE_E}$MODEL $CPU MHz ${TITLE_S}Bogomips:${TITLE_E} $MIPS ";
}
sub mem
{
my($MEMTOTAL,$MEMFREE);
open(X, "${procloc}/meminfo") or $MEMTOTAL = 1;
while(<X>){
chomp;
if(/^MemTotal:\s+(\d+)/){
$MEMTOTAL = sprintf("%.0f",$1/1024);
} elsif(/^MemFree:\s+(\d+)/){
$MEMFREE = sprintf("%.0f",$1/1024);
} elsif(/^Buffers:\s+(\d+)/){
$MEMFREE += sprintf("%.0f",$1/1024);
} elsif(/^Cached:\s+(\d+)/){
$MEMFREE += sprintf("%.0f",$1/1024);
}
}
close(X);
#--PERCENTAGE OF MEMORY FREE--#
my $MEMPERCENT = sprintf("%.1f",(100/${MEMTOTAL}*${MEMFREE}));
#--BARGRAPH OF MEMORY FREE--#
my $FREEBAR = int(${MEMPERCENT}/10);
my $MEMBAR;
my $x;
$MEMBAR = "${TITLE_S}\[${NORMAL_S}";
for ($x = 0;$x < 10; $x++) {
if ( $x == $FREEBAR ) { $MEMBAR .= "${ALERT_S}"; }
$MEMBAR .= "\|";
}
$MEMBAR .= "${ALERT_E}]${TITLE_E}";
return "${TITLE_S}Mem:${TITLE_E} ${MEMFREE}/${MEMTOTAL}M $MEMBAR ";
}
sub diskspace
{
#--DISKSPACE--#
my $HDD = 0;
my $HDDFREE = 0;
my $SCSI = 0;
my $SCSIFREE = 0;
for (`df 2>/dev/null`) {
if (/^\/dev\/(ida\/c[0-9]d[0-9]p[0-9]|[sh]d[a-z][0-9]+)\s+(\d+)\s+\d+\s+(\d+)\s+\d+%/) {
$HDD += $2;
$HDDFREE += $3;
}
if (/^\/dev\/(ida\/c[0-9]d[0-9]p[0-9]|sd[a-z][0-9]+)\s+(\d+)\s+\d+\s+(\d+)\s+\d+%/) {
$SCSI += $2;
$SCSIFREE += $3;
}
}
my $ALL = $HDD;
$HDDFREE = sprintf("%.02f", $HDDFREE / 1048576)."G";
$HDD = sprintf("%.02f", $HDD / 1048576)."G";
return "${TITLE_S}Diskspace:${TITLE_E} $HDD ${TITLE_S}Free:${TITLE_E} $HDDFREE ";
}
sub diskspace
{
my $HDD = 0;
my $HDDFREE = 0;
my $SCSI = 0;
my $SCSIFREE = 0;
for (`df 2>/dev/null`) {
if (/^\/dev\/(ida\/c[0-9]d[0-9]p[0-9]|[sh]d[a-z][0-9]+)\s+(\d+)\s+\d+\s+(\d+)\s+\d+%/) {
$HDD += $2;
$HDDFREE += $3;
}
if (/^\/dev\/(ida\/c[0-9]d[0-9]p[0-9]|sd[a-z][0-9]+)\s+(\d+)\s+\d+\s+(\d+)\s+\d+%/) {
$SCSI += $2;
$SCSIFREE += $3;
}
}
my $ALL = $HDD;
$HDDFREE = sprintf("%.02f", $HDDFREE / 1048576)."G";
$HDD = sprintf("%.02f", $HDD / 1048576)."G";
return "${TITLE_S}Diskspace:${TITLE_E} $HDD ${TITLE_S}Free:${TITLE_E} $HDDFREE ";
}
sub procs
{
opendir(PROC, "${procloc}");
my $PROCS = scalar grep(/^\d/,readdir PROC);
return "${TITLE_S}Procs:${TITLE_E} $PROCS ";
}
sub uptime
{
#--UPTIME--#
open (X, "${procloc}/uptime");
my $up2 = "";
my $uptime = <X>;
close (X);
$uptime =~ s/(\d+\.\d+)\s\d+\.\d+/$1/;
my $years = sprintf ("%.d",$uptime/31536000) || 0;
my $yearbase = sprintf ($years * 31536000);
my $weeks = sprintf ("%.d",($uptime - $yearbase)/6048000) || 0;
my $weekbase = sprintf ($weeks * 6048000);
my $days = sprintf ("%.d",($uptime - $yearbase - $weekbase)/86400) || 0;
my $daybase = sprintf ($days * 86400);
my $hours = sprintf ("%.d",($uptime - $yearbase - $weekbase - $daybase)/3600) || 0;
my $hourbase = sprintf ($hours * 3600);
my $mins = sprintf ("%.d",($uptime - $yearbase - $weekbase - $daybase - $hourbase)/60) || 0;
my $minbase = sprintf ($mins * 60);
my $secs = sprintf ("%.d",($uptime - $yearbase - $weekbase - $daybase - $hourbase - $minbase)) ||0;
if ($years){$up2 .= $years =~ /^1$/ ? "$years yr " : "$years yrs ";}
if ($weeks){$up2 .= $weeks =~ /^1$/ ? "$weeks wk " : "$weeks wks ";}
if ($days){$up2 .= $days =~ /^1$/ ? "$days day " : "$days days ";}
if ($hours){$up2 .= $hours =~ /^1$/ ? "$hours hr " : "$hours hrs ";}
if ($mins){$up2 .= $mins =~/^[01]$/ ? "$mins min " : "$mins mins ";}
$up2 .= $secs =~ /^[01]$/ ? "$secs sec" : "$secs secs";
return "${TITLE_S}Uptime:${TITLE_E} $up2 ";
}
sub load()
{
if (open (X, "${procloc}/loadavg")) {
my $LOADAVG = <X>;
close (X);
$LOADAVG =~ s/^((\d+\.\d+\s){3}).*\n$/$1/;
return "${TITLE_S}Load:${TITLE_E} $LOADAVG ";
}
}
sub graphic()
{
#--GRAPHICSCARD--#
my $VGA = "unknown";
if (file_executable("lspci") == 1) {
for (`lspci 2>/dev/null`) {
if (/VGA compatible controller:\s(.*)$/) { $VGA = $1; }
}
}
elsif ( -e "${procloc}/pci" ) {
open(X, "${procloc}/pci") ;
while(<X>){
chomp;
if (/VGA compatible controller:\s(.*)\.$/){
$VGA = $1; }
}
close(X);
}
return "${TITLE_S}Graphic:${TITLE_E} ${VGA} ";
}
sub screen
{
#--SCREEN RESOLUTION--#
my ($DEPTH,$RES);
if (file_executable("xdpyinfo")) {
for(`xdpyinfo 2>/dev/null`) {
if(/\s+dimensions:\s+(\S+)/) {
$RES = $1;
} elsif(/\s+depth:\s+(\S+)/) {
$DEPTH = $1;
}
}
if ($DEPTH) { return "${TITLE_S}Screen:${TITLE_E} $RES ($DEPTH bpp) "; }
}
}
sub nvidia
{
my $NVCLOCK;
if (file_executable("nvclock") == 1) {
for (`nvclock -s 2>/dev/null`) {
if (/^C.*ore speed:\s+(\d+\.\d+\sMHz)$/) { $NVCLOCK = $1; }
}
return "${TITLE_S}Corespeed:${TITLE_E} $NVCLOCK";
}
}
sub netinfo
{
my $route = "";
my $netdev = "";
my $NETDEVICE = "lo";
open(X, "${procloc}/net/route") or $route = "NA";
while(<X>){
chomp;
if (/^(.*?)\s+\d+\s+.*\s+0003\s+\d\s+/) { $NETDEVICE = $1; }
}
close(X);
my $PACKIN;
my $PACKOUT;
if (open(X, "${procloc}/net/dev")) {
while(<X>) {
chomp;
if (/^(\s+)?$NETDEVICE/) {
/^\s+(.*?):(\s+|)(\d+)\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+(\d+)\s+/;
$PACKIN = sprintf("%.2f",$3 / 1048576);
$PACKOUT = sprintf("%.2f",$4 / 1048576);
}
}
close(X);
if($PACKIN < 1024) { $PACKIN .= "M"; } else { $PACKIN = sprintf("%.02f", $PACKIN / 1024)."G"; }
if($PACKOUT < 1024) { $PACKOUT .= "M"; } else { $PACKOUT = sprintf("%.02f", $PACKOUT / 1024)."G"; }
return "${TITLE_S}Netinfo:${TITLE_E} ${TITLE_S}$NETDEVICE${TITLE_E}: In:${TITLE_E} $PACKIN ${TITLE_S}Out:${TITLE_E} $PACKOUT";
}
}
sub sensors
{
my $SENSOR1 = "NA";
my $SENSOR2 = "NA";
my $SENSOR3 = "NA";
my $SENSOR4 = "NA";
if ( -e "${procloc}/sys/dev/sensors" && file_executable("sensors") == 1) {
for (`sensors 2>/dev/null`){
if (/^[tT]emp2.*:\s+(.*(\s|.|)[FC])\s+\(.*\)(\s+ALARM)?/) {
if (!$2) { $SENSOR1 = "${NORMAL_S} $1${NORMAL_E}"; }
else { $SENSOR1 = "${ALERT_S} $1${ALERT_E}"; }
} elsif (/^[tT]emp1.*:\s+(.*(\s|.|)[FC])\s+\(.*\)(\s+ALARM)?/) {
if (!$2) { $SENSOR2 = "${NORMAL_S} $1${NORMAL_E}"; }
else { $SENSOR2 = "${ALERT_S} $1${ALERT_E}"; }
} elsif (/^fan1:\s+(\d+\sRPM)\s+\(.*\)(\s+ALARM)?/) {
if (!$2) { $SENSOR3 = "${NORMAL_S} $1${NORMAL_E}"; }
else { $SENSOR3 = "${ALERT_S} $1${ALERT_E}"; }
} elsif (/^fan2:\s+(\d+\sRPM)\s+\(.*\)(\s+ALARM)?/) {
if (!$2) { $SENSOR4 = "${NORMAL_S} $1${NORMAL_E}"; }
else { $SENSOR4 = "${ALERT_S} $1${ALERT_E}"; }
}
}
return "${TITLE_S}CPU:${TITLE_E}$SENSOR1 ${TITLE_S}Fan:${TITLE_E}$SENSOR3 ${TITLE_S}Case:${TITLE_E}$SENSOR2 ${TITLE_S}Fan:${TITLE_E}$SENSOR4 ";
}
sub hddtemp
{
my $HDDTEMP;
if ( file_executable("hddtemp") == 1) {
for (`hddtemp $SMARTDRIVE 2>/dev/null`) {
if (/^\/dev\/[sh]da:\s+(.*):\s+(.*)$/) {
$HDDTEMP = $2;
}
}
return "${TITLE_S}HDD:${TITLE_E} $HDDTEMP ";
}
}
sub print_help
{
my $modlist = "";
my $len = @modules;
my $c = 0;
foreach my $arg(@modules) {
if($c == ($len - 1)) {
$modlist .= "and $arg.";
} elsif($c == ($len - 2)) {
$modlist .= "$arg ";
} else {
$modlist .= "$arg, ";
}
$c++;
}
IRC::print ("Usage: /sys [-h] [-p] [<module>] [<modules>] ...");
IRC::print ("-h: help");
IRC::print ("-p: Print public! (/say in current channel)");
IRC::print ("\002Available modules:\002 $modlist");
}
sub display_sys_info_ {
my $args = shift;
my $a = 0;
my $temp;
my @lines;
my $count = 0;
my $title = "${UNDERL_S}SysInfo:${UNDERL_E} ";
my $output;
if ($args =~ m/-h/) {
print_help();
return 1;
}
$lines[$count] = $title;
foreach my $arg (@modules) {
if ($args eq "" || $args =~ m/^-p$/ || $args =~ m/$arg/) {
$a = 1;
$temp = eval $arg;
$count++ if length ($lines[$count]) > $maxtext;
$lines[$count] .= $temp;
}
}
if ($a == 0) {
return 1;
}
$output = 1 if ($args !~ m/-p/);
if ($xchat && $lines[0] ne $title) {
if ($output) {
IRC::print ($_) for @lines;
} else {
IRC::command ($_) for @lines;
}
}
return 1;
}
}
#--END OF SUB--#
if($xchat) {
IRC::register("Sysinfo", "${VERSION}.0", "System info script", "System info script");
IRC::print ("Loading mistery's \0034sysinfo\003 script (original by sick boy)");
print_help();
IRC::add_command_handler("sys", "display_sys_info_");
} else {
display_sys_info();
}