#!/usr/bin/perl # EvilBoss-api - API for creating FTN-tools # # EBLink.pm - work with links # # Copyright (c) 2004-2005 Alex Soukhotine, 2:5030/1157 # # 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. # # $Id$ package EvilBoss::Link; require Exporter; require EBDatabase; require EBAddress; require EBConfig; require EBCheck; use Carp; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $AUTOLOAD %ok_field); $VERSION = 1.01; @ISA=qw(Exporter); #@EXPORT = qw(&f1 &f3 &name); %EXPORT_TAGS=(); #@EXPORT_OK = qw(&name); # type definitions my %ATTRS = ( address => "addr", name => "str_d", session_pass => "str", # pkt_pass => "str", # tic_pass => "str", # afix_pass => "str", # ffix_pass => "str", # lctl_pass => "str", netmail => "yn", roudirect => "yn", roumode => "str_d", echoes => "yn", eaccess => "str", elimit => "num", egroup => "str", fechoes => "yn", feaccess => "str", felimit => "num", fegroup => "str", level => "num_d", packer => "str_d", frwrq => "yn", active => "yn", timelimit => "yn", hunter => "yn", maxnologin => "num", warncnt => "num", maxwarn => "num", utime => "num", putime => "num", p_name => "str_d", p_station => "str_d", p_location => "str_d", p_phone => "str_d", p_speed => "num_d", p_flags => "str" ); my %CHECKS = ( address => "address", name => "name", session_pass => "pass", # pkt_pass => "pass", # tic_pass => "pass", # afix_pass => "pass", # ffix_pass => "pass", # lctl_pass => "pass", netmail => "yn", roudirect => "yn", roumode => "roumode", echoes => "yn", eaccess => "groups", elimit => "num", egroup => "group", fechoes => "yn", feaccess => "groups", felimit => "num", fegroup => "group", level => "num", packer => "packer", frwrq => "yn", active => "yn", timelimit => "yn", hunter => "yn", maxnologin => "num", warncnt => "num", maxwarn => "num", utime => "num", putime => "num", p_name => "name", p_station => "station", p_location => "location", p_phone => "phone", p_speed => "speed", p_flags => "flags" ); # default values my %link_defauts = ( name => "SysOp", session_pass => "", pkt_pass => "", tic_pass => "", afix_pass => "", ffix_pass => "", lctl_pass => "", netmail => 'Y', roudirect => 'Y', roumode => 'h', echoes => 'Y', fechoes => 'N', timelimit => 'Y', hunter => 'N', maxnologin => 30, warncnt => 0, maxwarn => 0, utime => time, putime => time, elimit => 10, eaccess => "A", egroup => '', felimit => 2, feaccess => "Z", fegroup => '', level => 1, packer => "zip", frwrq => 'N', active => 'Y', p_name => "SysOp", p_station => "Unknown", p_location => "St.Petersburg", p_phone => "-Unpublished-", p_speed => 9600, p_flags => "MO" ); for my $attr (keys %ATTRS) { $ok_field{$attr}++;} sub new { my $classname = shift; my $self = {}; bless($self,$classname); $self->_init(@_); return $self; } sub DESTROY { my $self = shift; } sub load_from_db { my $self=shift; my $cfg=$_[0]; my $db=$_[1]; $self->{name} = ($db->dbh->selectrow_array("SELECT name FROM " . $cfg->{LinkNameTable} . " WHERE link=\'" . $self->address->string . "\'"))[0] || $self->name; my $tmp=$db->dbh->selectrow_hashref(sprintf("SELECT password,pkt_password,tic_password,afix_password,ffix_password,lctl_password FROM %s WHERE link=\'%s\'", $cfg->{MailerPasswdTable},$self->address->string)); $self->session_pass($$tmp{password}); # $self->pkt_pass($$tmp{pkt_password}); # $self->tic_pass($$tmp{tic_password}); # $self->afix_pass($$tmp{afix_password}); # $self->ffix_pass($$tmp{ffix_password}); # $self->lctl_pass($$tmp{lctl_password}); $self->{netmail} = 'Y'; # reserved my $tmp=$db->dbh->selectrow_hashref(sprintf("SELECT timelimit,echoes,fechoes,hunter,roudirect,roumode,active FROM %s WHERE link=\'%s\'", $cfg->{LinkOptionsTable},$self->address->string)); for my $i (keys %$tmp) { $self->{$i}=$$tmp{$i}; } my $tmp=$db->dbh->selectrow_hashref(sprintf("SELECT level,eaccess,feaccess,elimit,felimit,egroup,fegroup,packer,frwrq FROM %s WHERE link=\'%s\'", $cfg->{LinkTosserTable},$self->address->string)); for my $i (keys %$tmp) { $self->{$i}=$$tmp{$i}; } my $tmp=$db->dbh->selectrow_hashref(sprintf("SELECT utime,putime,warncnt,maxwarn,maxnologin FROM %s WHERE link=\'%s\'", $cfg->{MailerLastLoginTable},$self->address->string)); for my $i (keys %$tmp) { if ($i eq "maxnologin") { $self->{$i}=$$tmp{$i}/(60*60*24); } else { $self->{$i}=$$tmp{$i}; } } if ($self->address->point != 0) { my $tmp=$db->dbh->selectrow_hashref(sprintf("SELECT station,location,name,phone,speed,flags FROM %s WHERE point=\'%d\' AND aka=\'%s\'", $cfg->{PointListTable},$self->address->point,$self->address->string3d)); for my $i (keys %$tmp) { $self->{"p_$i"}=$$tmp{$i}; } } } sub remove_from_db { my $self=shift; my $cfg=$_[0]; my $db=$_[1]; for $i (qw(MailerPasswdTable LinkNameTable LinkOptionsTable LinkTosserTable MailerLastLoginTable)) { $db->dbh->do(sprintf("DELETE FROM %s WHERE link=\'%s\'",$cfg->{$i},$self->address->string)); } if ($self->address->point != 0) { $db->dbh->do(sprintf("DELETE FROM %s WHERE point=\'%d\' AND aka=\'%s\'", $cfg->{PointListTable}, $self->address->point, $self->address->string3d)); } } sub save_to_db { my $self=shift; my $cfg=$_[0]; my $db=$_[1]; if ($self->exists_in_db($cfg,$db) != 1) { $db->dbh->do(sprintf("INSERT INTO %s (link,password) VALUES(\'%s\',\'%s\')", $cfg->{MailerPasswdTable},$self->address->string,$self->session_pass)); $db->dbh->do(sprintf("INSERT INTO %s (link,name) VALUES(\'%s\',\'%s\')", $cfg->{LinkNameTable},$self->address->string,$self->name)); $db->dbh->do(sprintf("INSERT INTO %s (link,timelimit,echoes,fechoes,hunter,roudirect,roumode,active) VALUES(\'%s\')", $cfg->{LinkOptionsTable},join("\',\'",$self->address->string,$self->timelimit,$self->echoes,$self->fechoes, $self->hunter,$self->roudirect,$self->roumode,$self->active))); $db->dbh->do(sprintf("INSERT INTO %s (link,level,eaccess,feaccess,elimit,felimit,egroup,fegroup,packer,frwrq) VALUES(\'%s\',\'%d\',\'%s\',\'%s\',\'%d\',\'%d\',\'%s\',\'%s\',\'%s\',\'%s\')", $cfg->{LinkTosserTable},$self->address->string,sprintf("%d",$self->level),$self->eaccess,$self->feaccess, sprintf("%d",$self->elimit),sprintf("%d",$self->felimit),$self->egroup,$self->fegroup,$self->packer,$self->frwrq)); $db->dbh->do(sprintf("INSERT INTO %s (link,utime,putime,warncnt,maxwarn,maxnologin) VALUES(\'%s\',\'%d\',\'%d\',\'%d\',\'%d\',\'%d\')", $cfg->{MailerLastLoginTable},$self->address->string,$self->utime,$self->putime, $self->warncnt,$self->maxwarn,$self->maxnologin*60*60*24)); if ($self->address->point != 0) { $db->dbh->do(sprintf("INSERT INTO %s (point,station,location,name,phone,speed,flags,aka) VALUES (\'%s\')", $cfg->{PointListTable},join("\',\'",sprintf("%d",$self->address->point),$self->p_station,$self->p_location, $self->p_name,$self->p_phone,sprintf("%d",$self->p_speed),$self->p_flags,$self->address->string3d))); } } else { my $rc; $rc=$db->dbh->do("UPDATE ".$cfg->{MailerPasswdTable}." SET ". "password=\'". $self->session_pass . "\', ". # "pkt_password=\'". $self->pkt_pass . "\', ". # "tic_password=\'". $self->tic_pass . "\', ". # "afix_password=\'". $self->afix_pass . "\', ". # "ffix_password=\'". $self->ffix_pass . "\', ". # "lctl_password=\'". $self->lctl_pass . "\' ". "WHERE link=\'" . $self->address->string ."\'"); $rc=$db->dbh->do(sprintf("UPDATE %s SET name=\'%s\' WHERE link=\'%s\'", $cfg->{LinkNameTable},$self->name,$self->address->string)); $rc=$db->dbh->do("UPDATE " . $cfg->{LinkOptionsTable} . " SET ". "timelimit=\'".$self->timelimit."\', ". "echoes=\'".$self->echoes."\', ". "fechoes=\'".$self->fechoes."\', ". "hunter=\'".$self->hunter."\', ". "roudirect=\'".$self->roudirect."\', ". "roumode=\'".$self->roumode."\', ". "active=\'".$self->active."\' ". "WHERE link=\'" . $self->address->string ."\'"); $rc=$db->dbh->do("UPDATE " .$cfg->{LinkTosserTable}." SET ". "level=\'".sprintf("%d",$self->level)."\', ". "eaccess=\'".$self->eaccess."\', ". "feaccess=\'".$self->feaccess."\', ". "elimit=\'".sprintf("%d",$self->elimit)."\', ". "felimit=\'".sprintf("%d",$self->felimit)."\', ". "egroup=\'".$self->egroup."\', ". "fegroup=\'".$self->fegroup."\', ". "packer=\'".$self->packer."\', ". "frwrq=\'".$self->frwrq."\' ". "WHERE link=\'" . $self->address->string ."\'"); # print "maxnologin=".$self->maxnologin."
"; # print "utime=".$self->utime."
"; # print "putime=".$self->putime."
"; $rc=$db->dbh->do("UPDATE " .$cfg->{MailerLastLoginTable}." SET ". "utime=\'".sprintf("%d",$self->utime)."\', ". "putime=\'".sprintf("%d",$self->putime)."\', ". "warncnt=\'".sprintf("%d",$self->warncnt)."\', ". "maxwarn=\'".sprintf("%d",$self->maxwarn)."\', ". "maxnologin=\'".sprintf("%d",($self->maxnologin*60*60*24))."\' ". "WHERE link=\'" . $self->address->string ."\'"); # print "rc=$rc
"; if ($self->address->point != 0) { $db->dbh->do("UPDATE " .$cfg->{PointListTable}." SET ". "station=\'".$self->p_station."\', ". "location=\'".$self->p_location."\', ". "name=\'".$self->p_name."\', ". "phone=\'".$self->p_phone."\', ". "speed=\'".sprintf("%d",$self->p_speed)."\', ". "flags=\'".$self->p_flags."\' ". "WHERE point=\'" .$self->address->point."\' AND aka=\'" . $self->address->string3d ."\'"); } } } sub exists_in_db { my $self=shift; my $cfg=$_[0]; my $db=$_[1]; my $link=$db->dbh->selectrow_array(sprintf("SELECT link FROM %s WHERE link=\'%s\'", $cfg->{MailerPasswdTable},$self->address->string)); if ($link && ($link eq $self->address->string)) { return 1; } return 0; } sub load_from_hash { my $self=shift; my %tmp=@_; for $k (keys %ATTRS) { if ($ATTRS{$k} eq "yn") { $self->{$k} = $tmp{$k} ? "Y" : "N"; } elsif (($ATTRS{$k} eq "str_d")||($ATTRS{$k} eq "num_d")) { $self->{$k} = $tmp{$k} ? $tmp{$k} : $link_defaults{$k}; } elsif ($ATTRS{$k} ne "addr") { $self->{$k} = $tmp{$k}; } } } sub print_hash { my $self=shift; my %tmp; if (@_) { %tmp=@_; } else { %tmp=%$self; } for $k (keys %ATTRS) { print "$k=\"". $tmp{$k} ."\"
"; } } sub check_hash { my $self=shift; my @tmp; my %tmph=@_; my $addr=EvilBoss::Address->new(string => $tmph{address}); # print_hash(%tmph); # print "addr1=".$addr."
"; for $k (keys %CHECKS) { # print "debug k=\'$k\' c=\'".$CHECKS{$k}."\' val=\'" . $tmph{$k} ."\'
"; if (($addr->point!=0 && $k=~/^p_/) || ($k!~/^p_/)) { # print "match: $k
"; push(@tmp,$k) if (!check($CHECKS{$k},$tmph{$k})); } } return (@tmp); } #usage: check($arg,$value) sub check { # my $self=shift; my $rc; my $str=$_[0]; my $val=$_[1]; # print "str=$str val=$val
"; $rc=("EvilBoss::Check::".$str)->($val); return $rc; } sub _init { my $self = shift; $self->{address} = new EvilBoss::Address; for $k (keys %ATTRS) { if ($ATTRS{$k} ne "addr") { $self->{$k}=$link_defauts{$k}; } } if (@_) { my %extra = @_; @$self{keys %extra} = values %extra; } } sub AUTOLOAD { my $self = shift; my $attr = $AUTOLOAD; $attr =~ s/.*:://; return unless $attr =~ /[^A-Z]/; croak "invalid attribute method: ->$attr()" unless $ok_field{$attr}; $self->{lc $attr} = shift if (@_); return $self->{lc $attr}; } 1;