ПЕРЕКУСИМ ПЕРЛОВКОЙ?
DemiurG (arkhangel@mail.ru)
Спецвыпуск Xakep, номер #033, стр. 033-062-2
use strict;
use DBI;
## в переменную $mtime мы заносим текущее время
$mtime=`date +%H`;
chomp $mtime;
## это кусок кода проверяет, какое время, и "включает интернет" путем вызова ipa; согласись, если уже 9 вечера, то на фирме сотрудников нет, и инет никому не нужен, а в 9 утра мы как раз его включаем
if ($mtime == "09") {
system '/usr/local/bin/ipa';
}
elsif ($mtime == "21") {
system '/usr/local/bin/ipa -k shutdown';
}
## в базу падают последние данные
system '/usr/local/bin/ipa -k dump';
## получаем текущее время
$now = `date +%Y.%m.%d`;
$nows = $now;
chomp $now;
$nows =~s /\./-/g;
## получаем данные от ipa путем вызова ipastat с текущим выводом
open (FILE, "/usr/local/bin/ipastat -x -R . -i $now -n |") || die "Cannot ipastat -x -R $!\n";
## первая строка нам не нужна (удаляем ее)
$line=<FILE>;
## обрабатываем полученный вывод
while ($line=<FILE>) {
$line =~ s/\s+/ /;
chomp $line;
## разбиваем вывод на несколько переменных, из которых создаем массивы. В базе (которая состоит из одной таблицы) находятся имена пользователей, их ip-адреса (по ним происходит идентификация), сколько они выкачали в байтах, сколько они выкачали в мегабайтах.
my ($user, $ip, $sum) =split (/ /, $line);
## мегабайты получаются делением байт на 1048576=1024*1024 . Хотя может делить на 1000000
$mb=$sum/(1024*1024);
push @users, $user;
push @sums, $sum;
push @ips, $ip;
push @mbs, $mb;
}
## выполняем подключение к базе данных (traff2) с логином root и пустым паролем (нехорошо). Не забудь изменить.
my ($dsn) = "DBI:mysql:traff2";
my ($user_name) = "root";
my ($password) ="";
my ($dbh, $rows, $row);
my (@ary);
$dbh = DBI->connect ($dsn, $user_name, $password, {RaiseError => 1});
## кидаем полученные данные в базу
foreach $users (@users) {
$sums = shift (@sums);
$ips = shift (@ips);
$mbs = shift (@mbs);
## при каждом запуске мы проверяем, есть ли за такую дату и для такого пользователя данные, и если их нет, делаем insert, а если есть - update .
$query = "select count(*) from traffik where date='$nows' and name='$users'" or die;
$rule = $dbh->selectrow_array($query);
if ( $rule==0) {
## вся база состоит из одной таблицы (traffik), с нею мы и работаем
$rows = $dbh->prepare (qq { insert into traffik values (?,?,?,?,?)}) or die;
$rows->execute("$now", "$users", "$ips", "$sums", "$mbs");
} else {
$rows = $dbh->prepare (qq {update traffik set info ='$sums', mb='$mbs' where name='$users' and date='$nows'}) or die;
$rows->execute();
}
}
close FILE;
Разумеется, для того чтобы все работало, создай базу:
create database traff2;
и таблицу:
CREATE TABLE traffik (
date date default '0000-00-00',
name varchar(15) NOT NULL default '',
ip varchar(15) NOT NULL default '',
info int(15) NOT NULL default '0',
mb float(4,2) NOT NULL default '0.00'
) TYPE=MyISAM;
Отлично, база у нас есть. Теперь, для того чтобы делать из нее выборку, создадим web-интерфейс (mysql.cgi). Он будет представлять собой cgi приложение, написанное на Перле - текст слишком длинный, поэтому привожу отдельные части. Он разбит на две части - код для юзеров (непривилегированные) и для боссов с админом (привилегированные). Отличаются они тем, что боссы (или админ) могут выбирать пользователя и смотреть, какой у него трафик. Пользователь может смотреть только у себя (не пойми превратно). Все распознавание делается на уровне ip-адреса, то есть если ты админ и у тебя ip-адрес 192.168.6.200, то скрипт коннектится к базе, делает выборку за последнее число и говорит: "Да ты admin", и перенаправляет на код "для боссов". Все это делается в строках: