#!/usr/bin/perl # Monitor # Copyright (C) 1999 MandrakeSoft (damien@mandrakesoft.com) # # 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, 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. use Gtk; use lib qw(/usr/lib/libDrakX); use interactive; use standalone; use my_gtk qw(:helpers :wrappers); use Data::Dumper; use common qw(:common :file :functional :system); use strict; use netconnect; my $default_intf; init Gtk; $::isEmbedded = ($::XID, $::CCPID) = "@ARGV" =~ /--embedded (\w+) (\w+)/; ($default_intf) = "@ARGV" =~ /--defaultintf (\w+)/; my $window1 = $::isEmbedded ? new Gtk::Plug ($::XID) : new Gtk::Window -toplevel; $window1->signal_connect ( delete_event => sub { Gtk->exit(0); }); $window1->set_position(1); $window1->set_title(_("Network monitoring")); $window1->set_policy(0, 0, 0); $window1->set_border_width(5); #$::isEmbedded or $window1->set_usize(500, 400); my @anim; ($anim[$_]->[0], $anim[$_]->[1]) = gtkcreate_png("/usr/share/icons/anim_" . ($_ + 1) . ".png") foreach (0..9); my $isconnected=0; my @interfaces; my $monitor = {}; gtkadd($window1, gtkpack_(new Gtk::VBox(0,5), 0, _("Network Monitoring"), 1, gtkpack_(new Gtk::HBox(0,5), 1, my $notebook = new Gtk::Notebook, 0, gtkpack_(new Gtk::VBox(0,5), 1, gtkadd(gtkset_shadow_type(new Gtk::Frame(_("Statistics")), 'etched_out'), gtkpack__(gtkset_border_width(new Gtk::VBox(0,5),5), gtkpack__(new Gtk::HBox(0,0), _("Sending Speed : "), my $label_st = new Gtk::Label("")), gtkpack__(new Gtk::HBox(0,0), _("Receiving Speed : "), my $label_sr = new Gtk::Label("")), ) ), 0, gtksignal_connect(my $button_connect = new Gtk::Button(), clicked => \&connection), 0, new Gtk::HSeparator, 0, gtksignal_connect(new Gtk::Button(_("Close")), clicked => sub { Gtk->exit(0) }) ) ), 0, my $statusbar = new Gtk::Statusbar ) ); my ($pix_c_map, $pix_c_mask) = gtkcreate_png("net_c.png"); my ($pix_d_map, $pix_d_mask) = gtkcreate_png("net_d.png"); $button_connect->add(gtkpack__(new Gtk::VBox(0,3), my $pix_c = new Gtk::Pixmap($pix_d_map, $pix_d_mask), my $label_c = new Gtk::Label(_("Connect to internet")) )); $statusbar->push(1, "Not connected"); $window1->show_all(); $window1->set_policy (1, 1, 1); update(); my ($labelr, $labelt); my $time_tag = Gtk->timeout_add(1000, \&rescan); my $time_tag2 = Gtk->timeout_add(5000, \&update); rescan(); Gtk->main; Gtk->exit(0); sub connection { my $dialog = new Gtk::Dialog(); $dialog->set_position(1); $dialog->vbox->set_border_width(10); my $darea1= new Gtk::DrawingArea(); $darea1->size(350,12); $darea1->set_usize(350,12); gtkpack_($dialog->vbox, 0, $isconnected ? _("Deconnecting from internet ...") : _("Connecting to internet ..."), 1, my $frame = gtkadd(gtkset_shadow_type(new Gtk::Frame(""), 'etched_out'), $darea1) ); my $bbox_dialog = new Gtk::HButtonBox; $dialog->action_area->add($bbox_dialog); $bbox_dialog->set_layout(-spread); my $button_ok = gtksignal_connect(new Gtk::Button (_("OK")), clicked => sub { $dialog->set_modal(0); $dialog->destroy; update(); }); $button_ok->set_sensitive(0); $bbox_dialog->add($button_ok ); $dialog->show_all; $dialog->set_modal(1); $darea1->realize(); my $anim_nb=0; my $tag = Gtk->timeout_add(100, sub { $darea1->window->draw_pixmap ($darea1->style->white_gc, $anim[$anim_nb]->[0], 0, 0, ($darea1->allocation->[2]-340)/2, ($darea1->allocation->[3]-15)/2, 350, 13); $anim_nb++; $anim_nb > 9 and $anim_nb=0; 1; }); my $netc = {}; my $tag2 = Gtk->timeout_add(7000, sub { Gtk->timeout_remove($tag); $frame->destroy; gtkpack_($dialog->vbox, 1, $isconnected ? ( netconnect::connected('', $netc) ? _("Deconnection from internet failed.") : _("Deconnection from internet complete.")) : ( netconnect::connected('', $netc) ? _("Connection complete.") : _("Connection failed.\nVerify your configuration in the Mandrake Control Center.")) ); $dialog->vbox->show_all; $button_ok->set_sensitive(1); 0; }); $isconnected ? netconnect::disconnect_backend('') : netconnect::connect_backend(''); } sub rescan { get_val(); foreach(@interfaces) { my $intf = $_; my $recv = $monitor->{$intf}{val}->[0]; my $transmit = $monitor->{$intf}{val}->[8]; my $refr = $monitor->{$intf}{referencer}; my $reft = $monitor->{$intf}{referencet}; $monitor->{sr} += $recv - $refr; $monitor->{st} += $transmit - $reft; push(@{$monitor->{$intf}{stack_r}}, $recv - $refr); shift @{$monitor->{$intf}{stack_r}} if @{$monitor->{$intf}{stack_r}} > 250; $labelr->set(formatXiB($recv - $monitor->{$intf}{initialr})); $monitor->{$intf}{referencer} = $recv; push(@{$monitor->{$intf}{stack_t}}, $transmit - $reft); shift @{$monitor->{$intf}{stack_t}} if @{$monitor->{$intf}{stack_t}} > 250; $monitor->{$intf}{referencet} = $transmit; $labelt->set(formatXiB($transmit - $monitor->{$intf}{initialt})); draw_monitor($monitor->{$intf}); } $label_sr->set(formatXiB($monitor->{sr}) . "/s"); $label_st->set(formatXiB($monitor->{st}) . "/s"); $monitor->{$_} = 0 foreach ('sr', 'st'); 1; } sub get_val { my @ret; my $a = cat_("/proc/net/dev"); $a =~ s/^.*?\n.*?\n//; $a =~ s/^\s*lo:.*?\n//; my @line = split(/\n/, $a); foreach(@line) { s/\s*(\w*)://; my $intf=$1; push (@ret,$intf); $monitor->{$intf}{val} = [split()]; $monitor->{$intf}{intf} = $intf; } @ret; } sub update { my @intfs = get_val(); foreach(@intfs) { my $intf = $_; if(!member($intf,@interfaces)) { push (@interfaces, $intf); $default_intf = $intf; $monitor->{$intf}{initialr} = $monitor->{$intf}{val}->[0]; $monitor->{$intf}{initialt} = $monitor->{$intf}{val}->[8]; $notebook->append_page(gtkshow(my $page = gtkpack_(new Gtk::VBox(0,0), 0, gtkpack__(gtkset_border_width(new Gtk::HBox(0,0), 5), gtksize(my $darea = $monitor->{$intf}{darea} = new Gtk::DrawingArea(),300, 150)), 0, gtkpack__(gtkset_border_width(new Gtk::HBox(0,0), 5), _("sent : "), $labelt = new Gtk::Label("0")), 0, gtkpack__(gtkset_border_width(new Gtk::HBox(0,0), 5), _("received : "), $labelr = new Gtk::Label(_("0"))), )), new Gtk::Label($intf)); $notebook->set_page($notebook->page_num($page)); $monitor->{$intf}{page}=($notebook->page_num($page)); $monitor->{$intf}{pixmap_db} = new Gtk::Gdk::Pixmap($darea->window, 300, 150); $monitor->{$intf}{referencer} = $monitor->{$intf}{val}->[0]; $monitor->{$intf}{referencet} = $monitor->{$intf}{val}->[8]; $monitor->{$intf}{pixmap_db}->draw_rectangle ($monitor->{$intf}{darea}->style->black_gc, 1, 0, 0, 300, 150); $darea->signal_connect( expose_event => sub { $darea->window->draw_pixmap ($darea->style->bg_gc('normal'), $monitor->{$intf}{pixmap_db}, 0, 0, 0, 0, 300, 150); }); } } foreach(@interfaces) { my $intf = $_; if(!member($intf,@intfs)) { $notebook->remove_page($monitor->{$intf}{page}); @interfaces = map { $_ if($_ ne $intf)} @interfaces; } } my $netc={}; if(netconnect::connected('', $netc) == !$isconnected) { $isconnected = $isconnected ? 0 : 1; $label_c->set($isconnected ? _("Disconnect") : _("Connect")); $isconnected ? $pix_c->set($pix_c_map, $pix_c_mask) : $pix_c->set($pix_d_map, $pix_d_mask); } 1; } sub draw_monitor { my ($o) = @_; $o->{pixmap_db}->draw_rectangle ($o->{darea}->style->black_gc, 1, 0, 0, 300, 150); # my @c = map { $step+=2; ($step, $_); } @{$o->{stack_r}}; # print "\n##\n" . Data::Dumper->Dump([@c],['$c']) . "\n##\n"; # $o->{pixmap_db}->draw_segments($o->{darea}->style->white_gc, @c); my $maxr = 0; foreach (@{$o->{stack_r}}) { $maxr = $_ if $_>$maxr; } my $maxt = 0; foreach (@{$o->{stack_t}}) { $maxt = $_ if $_>$maxt; } my $ech = $maxr + $maxt; $ech == 0 and $ech = 1; my $colorr = my_gtk::gtkcolor(50400, 655, 20000); my $gcr = new Gtk::Gdk::GC($o->{darea}->window); $gcr->set_foreground($colorr); my $colort = my_gtk::gtkcolor(55400, 65400, 655); my $gct = new Gtk::Gdk::GC($o->{darea}->window); $gct->set_foreground($colort); my $step=50; foreach (@{$o->{stack_t}}) { $o->{pixmap_db}->draw_rectangle($gct, 1, $step, 0, 1, $_*150/$ech); $step++; } $step=50; foreach (@{$o->{stack_r}}) { $o->{pixmap_db}->draw_rectangle($gcr, 1, $step, 151-$_*150/$ech, 1, $_*150/$ech); $step++; } my $gcl = new Gtk::Gdk::GC($o->{darea}->window); $gcl->set_foreground($o->{darea}->window->get_colormap->color_white()); $gcl->set_line_attributes (1, 'on-off-dash', 'not-last', 'round'); my $style= new Gtk::Style; $style->font(Gtk::Gdk::Font->fontset_load("-adobe-times-medium-r-normal-*-12-*-75-75-p-*-iso8859-*,*-r-*")); for (my $i = 30;$i<=120;$i+=30) { $o->{pixmap_db}->draw_line($gcl, 50, $i, 300, $i); my ($gc2, $text); my $dif1 = abs(150-@{$o->{stack_r}}[@{$o->{stack_r}}-1]*150/$ech - $i); my $dif2 = abs(@{$o->{stack_t}}[@{$o->{stack_t}}-1]*150/$ech - $i); if ($dif1 < $dif2) { $text = formatXiB((150-$i)*$ech/150); $gc2=$gcr; } else { $text = formatXiB($i*$ech/150); $gc2=$gct; } # $text = formatXiB((150-$i)*$ech/150); # $gc2 = $o->{darea}->style->white_gc; my $w = $style->font->string_width($text); $o->{pixmap_db}->draw_string($style->font, $gc2, 45-$w, $i+5, ($text) ); } $o->{darea}->draw(undef); }