1#!/usr/local/bin/perl 2use strict; 3use Irssi 20011210.0250 (); 4use vars qw($VERSION %IRSSI); 5$VERSION = "1.3"; 6%IRSSI = ( 7 authors => 'David Leadbeater', 8 contact => 'dgl@dgl.cx', 9 name => 'sysinfo-dg', 10 description => 'Adds a /sysinfo command which prints system information (linux only).', 11 license => 'GNU GPLv2 or later', 12 url => 'http://irssi.dgl.cx/', 13); 14 15#This script is mostly my own work but some ideas where taken from /sinfo by 16#Laurens Buhler and Alain van Acker. Please leave this credit in the script and 17#if you edit it and think the change is worthwhile tell me and i may add it into 18#the script and credit you 19 20use vars qw/$colour $graphs $graphs2 $colour2 $style/; 21Irssi::command_bind("sysinfo","sysinfo"); 22 23sub sysinfo{ 24 my @options = split(/ /,$_[0]); 25 my %info; 26 my($hostname,$uname,$procs) = basicinfo(); 27 my($distro) = distro(); 28 my($uptime,$users,$loadavg) = uptime(); 29 my($memsize,$memfree) = meminfo(); 30 my($swapsize,$swapfree) = swapinfo(); 31 my($cpumodel,$cpumhz,$cpucache,$bogomips) = cpuinfo(); 32 my %netinfo = netinfo(); 33 my($disktotal,$diskused,$hddtype) = df(); 34 my($videocard,$ethernet) = pciinfo(); 35 my($screenres,$screendepth); 36 ($screenres,$screendepth) = screenres() if $ENV{DISPLAY}; 37 38 ($colour,$graphs,$graphs2,$colour2,$style) = parseoptions(\%netinfo,@options); 39 40 %info = ( 41 'os' => "$uname - $distro", 42 'up' => $uptime, 43 'cpu' => "$cpumodel, $cpumhz MHz ($bogomips bogomips)", 44 'cache' => $cpucache, 45 'mem' => ($memsize-$memfree) . "/$memsize MB (" . percent(($memsize-$memfree),$memsize) . ")", 46 'host' => $hostname, 47 'users' => $users, 48 'load' => $loadavg, 49 'procs' => $procs, 50 'swap' => ($swapsize-$swapfree) . "/$swapsize MB (" . percent(($swapsize-$swapfree),$swapsize) . ")", 51 'disk' => "$diskused/$disktotal MB (" . percent($diskused,$disktotal) . ") ($hddtype)", 52 'video' => "$videocard at $screenres ($screendepth bits)", 53 'ethernet' => $ethernet, 54 ); 55 56 for(keys %netinfo){ 57 $info{$_} = "in: $netinfo{$_}{in} MB, out: $netinfo{$_}{out} MB"; 58 } 59 60 my $tmp; 61 for(split(/ /,$style)){ 62 $tmp .= ircbit($_,$info{$_}) . " "; 63 } 64 $tmp =~ s/ $//; 65 Irssi::active_win()->command('say ' . $tmp); 66 ($colour,$graphs,$graphs2,$colour2,$style) = undef; 67} 68 69sub parseoptions{ 70 my($netinfo,@options) = @_; 71 72 my $tmp = shift(@options) if $options[0] =~ /^\-/; 73 $tmp =~ s/^\-//; 74 for(split //,$tmp){ 75 if($_ eq "c"){ 76 $tmp =~ /c(\d+)/; 77 $colour = $1; 78 if(!$colour){ 79 $colour = 3; 80 } 81 }elsif($_ eq "g"){ 82 $tmp =~ /g(\d+)/; 83 $graphs = $1; 84 if(!$graphs){ 85 $graphs = 9; 86 } 87 }elsif($_ eq "G"){ 88 $tmp =~ /G(\d+)/; 89 $graphs2 = $1; 90 }elsif($_ eq "C"){ 91 $tmp =~ /C(\d+)/; 92 $colour2 = $1; 93 } 94 } 95 if(!defined $colour2 && $colour){ 96 $colour2 = 15; 97 } 98 if(defined $graphs && !defined $graphs2){ 99 $graphs2 = 3; 100 } 101 102# We got the names on the command line 103 if($options[1]){ 104 $style = join(" ",@options); 105# style name 106 }elsif($options[0]){ 107 if($options[0] eq "std"){ 108 $style = "os up cpu mem video"; 109 }elsif($options[0] eq "bigger"){ 110 $style = "os up cpu cache mem load procs disk video"; 111 }elsif($options[0] eq "full"){ 112 $style = "host os up cpu cache mem users load procs swap disk video ethernet ".join(" ",keys %{$netinfo}); 113 }elsif($options[0] eq "net"){ 114 $style = join(" ",keys %{$netinfo}); 115 }elsif($options[0] eq "uptime"){ 116 $style = "os up"; 117 }elsif($options[0] eq "use"){ 118 $style = "mem swap disk"; 119 } 120 }else{ 121# no input - default 122 $style = "os up cpu mem video"; 123 } 124 125 return($colour,$graphs,$graphs2,$colour2,$style); 126} 127 128sub ircbit{ 129 my($name,$text) = @_; 130 $name = " " . $name if $name =~ /^\d/; 131 $text = " " . $text if $text =~ /^\d/; 132 if($colour){ 133 return "$colour$name$colour2\[$text$colour2\]"; 134 }else{ 135 return "$name\[$text\]"; 136 } 137} 138 139sub percent{ 140 my $percent = ($_[1] != 0) ? sprintf("%.1f",(($_[0]/$_[1])*100)) : 0; 141 if($graphs){ 142 my $tmp = "["; 143 for(1..10){ 144 if($_ > sprintf("%.0f",$percent / 10)){ 145 $tmp .= "-" if !defined $colour; 146 $tmp .= "$graphs2-" if defined $colour; 147 }else{ 148 $tmp .= "|" if !defined $colour; 149 $tmp .= "$graphs|" if defined $colour; 150 } 151 } 152 $tmp .= "]"; 153 return $percent."% ".$tmp; 154 } 155 return $percent."%"; 156} 157 158sub uptime{ 159 my $uptimeinfo = `uptime`; 160 if ($uptimeinfo =~ /^\s+(\d+:\d+\w+|\d+:\d+:\d+)\s+up\s+(\d+)\s+day.?\W\s+(\d+):(\d+)\W\s+(\d+)\s+\w+\W\s+\w+\s+\w+\W\s+(\d+).(\d+)/igx) { 161 return("$2 days, $3 hours, $4 minutes", $5, "$6.$7"); 162 }elsif ($uptimeinfo =~ /^\s+(\d+:\d+\w+|\d+:\d+:\d+)\s+up+\s+(\d+):(\d+)\W\s+(\d+)\s+\w+\W\s+\w+\s+\w+\W\s+(\d+).(\d+)/igx) { 163 return("$2 hours, $3 minutes", $4, "$5.$6"); 164 }elsif ($uptimeinfo =~ /^\s+(\d+:\d+\w+|\d+:\d+:\d+)\s+up\s+(\d+)\s+day.?\W\s+(\d+)\s+min\W\s+(\d+)\s+\w+\W\s+\w+\s+\w+\W\s+(\d+).(\d+)/igx) { 165 return("$2 days, $3 minutes", $4, "$5.$6"); 166 }elsif ($uptimeinfo =~ /^\s+(\d+:\d+\w+|\d+:\d+:\d+)\s+up+\s+(\d+)\s+min\W\s+(\d+)\s+\w+\W\s+\w+\s+\w+\W\s+(\d+).(\d+)/igx) { 167 return("$2 minutes", $3, "$4.$5"); 168 } 169 return undef; 170} 171 172sub meminfo{ 173 my($memsize,$memfree); 174 open(MEMINFO, "<", "/proc/meminfo") or return undef; 175 while(<MEMINFO>){ 176 chomp; 177 if(/^MemTotal:\s+(\d+)/){ 178 $memsize = sprintf("%.2f",$1/1024); 179 }elsif(/^MemFree:\s+(\d+)/){ 180 $memfree = sprintf("%.2f",$1/1024); 181 } 182 } 183 close(MEMINFO); 184 return($memsize,$memfree); 185} 186 187sub swapinfo{ 188 my($swapsize,$swapused); 189 open(SWAPINFO, "<", "/proc/swaps"); 190 while(<SWAPINFO>){ 191 chomp; 192 next if !/^\//; 193 /\S+\s+\S+\s+(\S+)\s+(\S+)/; 194 $swapsize += $1; 195 $swapused += $2; 196 } 197 close(SWAPINFO); 198 my $swapfree = sprintf("%.2f",($swapsize - $swapused) / 1024); 199 $swapsize = sprintf("%.2f", $swapsize / 1024); 200 return($swapsize,$swapfree); 201} 202 203sub netinfo{ 204 my(%netinfo); 205 open(NETINFO, "<", "/proc/net/dev") or return undef; 206 while(<NETINFO>){ 207 chomp; 208 next if /^(\s+)?(Inter|face|lo)/; 209 /^\s*(\w+):\s*(\d+)\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+(\d+)\s+/; 210 $netinfo{$1}{in} = sprintf("%.2f",$2 / 1048576); 211 $netinfo{$1}{out} = sprintf("%.2f",$3 / 1048576); 212 } 213 close(NETINFO); 214 return %netinfo; 215} 216 217sub distro{ 218 my $distro; 219 if(-f "/etc/coas"){ 220 $distro = firstline("/etc/coas"); 221 }elsif(-f "/etc/environment.corel"){ 222 $distro = firstline("/etc/environment.corel"); 223 }elsif(-f "/etc/debian_version"){ 224 $distro = "Debian ".firstline("/etc/debian_version"); 225 }elsif(-f "/etc/mandrake-release"){ 226 $distro = firstline("/etc/mandrake-release"); 227 }elsif(-f "/etc/SuSE-release"){ 228 $distro = firstline("/etc/SuSE-release"); 229 }elsif(-f "/etc/turbolinux-release"){ 230 $distro = firstline("/etc/turbolinux-release"); 231 }elsif(-f "/etc/slackware-release"){ 232 $distro = firstline("/etc/slackware-release"); 233 }elsif(-f "/etc/redhat-release"){ 234 $distro = firstline("/etc/redhat-release"); 235 } 236 return $distro; 237} 238 239sub df{ 240 my($disktotal,$diskused,$mainhd); 241 for(`df`){ 242 chomp; 243 next if !/^\/dev\/\S+/; 244 next if /(cd|cdrom|fd|floppy)/; 245 /^(\S+)\s+(\S+)\s+(\S+)/; 246 $mainhd = $1 if !defined $mainhd; 247 next if not defined $1 or not defined $2; 248 $disktotal += $2; 249 $diskused += $3; 250 } 251 $disktotal = sprintf("%.2f",$disktotal / 1024); 252 $diskused = sprintf("%.2f",$diskused / 1024); 253 254 $mainhd =~ s/\/dev\/([a-z]+)\d+/$1/; 255 my $hddtype = firstline("/proc/ide/$mainhd/model"); 256 257 return($disktotal,$diskused,$hddtype); 258} 259 260sub basicinfo{ 261 my($hostname,$sysinfo,$procs); 262 chomp($hostname = `hostname`); 263 chomp($sysinfo = `uname -sr`); 264 opendir(PROC, "/proc"); 265 $procs = scalar grep(/^\d/,readdir PROC); 266 return($hostname,$sysinfo,$procs); 267} 268 269sub cpuinfo{ 270 my($cpumodel,$cpusmp,$cpumhz,$cpucache,$bogomips); 271 open(CPUINFO, "<", "/proc/cpuinfo") or return undef; 272 while(<CPUINFO>){ 273 if(/^model name\s+\:\s+(.*?)$/){ 274 if(defined $cpumodel){ 275 if(defined $cpusmp){ 276 $cpusmp++; 277 }else{ 278 $cpusmp=2; 279 } 280 }else{ 281 $cpumodel = $1; 282 } 283 }elsif(/^cpu MHz\s+:\s+([\d\.]*)/){ 284 $cpumhz = $1; 285 }elsif(/^cache size\s+:\s+(.*)/){ 286 $cpucache = $1; 287 }elsif(/^bogomips\s+:\s+([\d\.]*)/){ 288 $bogomips += $1; 289 } 290 } 291 $cpumodel .= " SMP ($cpusmp processors)" if defined $cpusmp; 292 return($cpumodel,$cpumhz,$cpucache,$bogomips); 293} 294 295sub pciinfo{ 296 my($videocard,$ethernet); 297 open(PCI, "-|", "/sbin/lspci") or return undef; 298 while(<PCI>){ 299 chomp; 300 if(/VGA compatible controller: (.*?)$/){ 301 $videocard .= "${1}+ "; 302 }elsif(/(Ethernet|Network) controller: (.*?)$/){ 303 $ethernet = $1; 304 } 305 } 306 close(PCI); 307 $videocard =~ s/\+ $//; 308 return($videocard,$ethernet); 309} 310 311sub screenres{ 312 my ($res,$depth); 313 for(`xdpyinfo`){ 314 if(/\s+dimensions:\s+(\S+)/){ 315 $res = $1; 316 }elsif(/\s+depth:\s+(\S+)/){ 317 $depth = $1; 318 } 319 } 320 return($res,$depth); 321} 322 323sub firstline{ 324 my $file = shift; 325 open(FILE, "<", $file) or return undef; 326 chomp(my $line = <FILE>); 327 close(FILE); 328 return $line; 329} 330 331