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