package Foswiki::Plugins::StatSyncPlugin; # Always use strict to enforce variable scoping use strict; use utf8; use DBI; use Data::Dumper; # $VERSION is referred to by Foswiki, and is the only global variable that # *must* exist in this package use vars qw( $VERSION $RELEASE $debug $dbstat $dbrstat $wiki_user $pluginName ); use Foswiki::Func (); # The plugins API use Foswiki::Plugins (); # For the API version # This should always be $Rev: 8713$ so that Foswiki can determine the checked-in # status of the plugin. It is used by the build automation tools, so # you should leave it alone. $VERSION = '$Rev: 8713$'; # This is a free-form string you can use to "name" your own plugin version. # It is *not* used by the build automation tools, but is reported as part # of the version number in PLUGINDESCRIPTIONS. $RELEASE = '1.01'; # Name of this Plugin, only used in this module $pluginName = 'StatSyncPlugin'; =pod ---++ initPlugin($topic, $web, $user, $installWeb) -> $boolean * =$topic= - the name of the topic in the current CGI query * =$web= - the name of the web in the current CGI query * =$user= - the login name of the user * =$installWeb= - the name of the web the plugin is installed in REQUIRED Called to initialise the plugin. If everything is OK, should return a non-zero value. On non-fatal failure, should write a message using Foswiki::Func::writeWarning and return 0. In this case %FAILEDPLUGINS% will indicate which plugins failed. In the case of a catastrophic failure that will prevent the whole installation from working safely, this handler may use 'die', which will be trapped and reported in the browser. You may also call =Foswiki::Func::registerTagHandler= here to register a function to handle tags that have standard Foswiki syntax - for example, =%MYTAG{"my param" myarg="My Arg"}%. You can also override internal Foswiki tag handling functions this way, though this practice is unsupported and highly dangerous! =cut sub initPlugin { my( $topic, $web, $user ) = @_; $wiki_user = "wiki: ".$user; # check for Plugins.pm versions if( $Foswiki::Plugins::VERSION < 1.026 ) { Foswiki::Func::writeWarning( "Version mismatch between $pluginName and Plugins.pm" ); return 0; } return 0 unless $Foswiki::cfg{Plugins}{DatabasePlugin}{ConfigSource}; if ( $Foswiki::cfg{Plugins}{DatabasePlugin}{ConfigSource} eq 'Local' ) { foreach my $info ( @{ $Foswiki::cfg{Plugins}{DatabasePlugin}{Databases} } ) { # next if ($info->{description} ne "stat"); # $dbstat = $info; # last; if ($info->{description} eq "stat") { $dbstat = $info; next; } if ($info->{description} eq "rstat") { $dbrstat = $info; next; } } } return 0 if (!$dbstat or !$dbrstat); # register the _EXAMPLETAG function to handle %EXAMPLETAG{...}% Foswiki::Func::registerTagHandler( 'STATSYNC', \&_STATSYNC ); # Plugin correctly initialized return 1; } #--------------------------------------------------------------------------------------------------------------- sub GetNowTime { my ($sec,$min,$hour,$day,$month,$year,$zone) = localtime(time()); $month += 1; $year += 1900; my $now_str=sprintf "%04d-%02d-%02d %02d:%02d:%02d",$year,$month,$day,$hour,$min,$sec; return $now_str; } #--------------------------------------------------------------------------------------------------------------- sub StrToIp{ return unpack('N',pack('C4',split(/\./,$_[0]))); } #--------------------------------------------------------------------------------------------------------------- sub write_db_log { my $dbh=shift; my $msg=shift; return if (!$dbh); return if (!$msg); $msg=~s/[\'\"]//g; if (!$wiki_user) { $wiki_user = 'wiki'; } my $history_sql="INSERT INTO syslog(customer,message,level,auth_id) VALUES('".$wiki_user."',".$dbh->quote($msg).",3,0)"; my $history_rf=$dbh->prepare($history_sql); $history_rf->execute; } #--------------------------------------------------------------------------------------------------------------- sub do_sql { my $dbh=shift; my $sql=shift; return if (!$dbh); return if (!$sql); my $sql_prep = $dbh->prepare($sql); my $sql_ref; if ( !defined $sql_prep ) { die "Cannot prepare statement: $DBI::errstr\n"; } $sql_prep->execute; if ($sql!~/^select /i) { write_db_log($dbh,$sql); } if ($sql=~/^insert/i) { $sql_ref = $sql_prep->{mysql_insertid}; } if ($sql=~/^select /i) { $sql_ref = $sql_prep->fetchall_arrayref(); }; $sql_prep->finish(); return $sql_ref; } #--------------------------------------------------------------------------------------------------------------- sub get_record_sql { my $dbh = shift; my $tsql = shift; my @result; return @result if (!$dbh); return @result if (!$tsql); my $list = $dbh->prepare( $tsql . ' LIMIT 1' ); if ( !defined $list ) { die "Cannot prepare statement: $DBI::errstr\n"; } $list->execute; my $row_ref = $list ->fetchrow_hashref; $list->finish(); return $row_ref; } #--------------------------------------------------------------------------------------------------------------- sub update_record { my $dbh = shift; my $table = shift; my $record = shift; my $filter = shift; return if (!$dbh); return if (!$table); return if (!$filter); my $old_record = get_record_sql($dbh,"SELECT * FROM $table WHERE $filter"); my $diff=''; my $change_str=''; my $found_changed=0; my $auth_id = 0; foreach my $field (keys %$record) { if (!defined $record->{$field}) { $record->{$field}=''; } if (!defined $old_record->{$field}) { $old_record->{$field}=''; } my $old_value = quotemeta($old_record->{$field}); my $new_value = $record->{$field}; $new_value=~s/\'//g; $new_value=~s/\"//g; if ($new_value!~/^$old_value$/) { $diff = $diff." $field => $record->{$field} (old: $old_record->{$field}),"; $change_str = $change_str." `$field`=".$dbh->quote($record->{$field}).","; $found_changed++; } } if ($found_changed) { $change_str=~s/\,$//; $diff=~s/\,$//; if ($table eq 'User_auth') { $change_str .= ", `changed_time`='".GetNowTime()."'"; } my $sSQL = "UPDATE $table SET $change_str WHERE $filter"; do_sql($dbh,$sSQL); } } sub _STATSYNC { my($session, $params, $theTopic, $theWeb) = @_; ### parameters my $host = $params->{_DEFAULT} || $params->{host}; my $dnsname = $params->{dnsname}; my $comment = $params->{comment}; my $wikiname = $params->{wikiname}; #my $result="Runned: $host $dnsname $comment $wikiname
"; my $result=""; return $result if (!$host); my $host_aton=StrToIp($host); my $SQL = "SELECT * FROM User_auth WHERE ip_int=".$host_aton." and deleted=0 LIMIT 1"; my $connect_options = "dbi:$dbstat->{driver}:database=$dbstat->{database};host=$dbstat->{hostname}"; my $connect_user = "$dbstat->{username}"; my $connect_password = "$dbstat->{password}"; if ($theWeb=~/Internet/) { $connect_options = "dbi:$dbrstat->{driver}:database=$dbrstat->{database};host=$dbrstat->{hostname}"; $connect_user = "$dbrstat->{username}"; $connect_password = "$dbrstat->{password}"; } my $dbh = DBI->connect($connect_options,$connect_user,$connect_password); eval { if ( !defined $dbh ) { return "Cannot connect to mySQL server: $DBI::errstr\n"; } $dbh->do('SET NAMES utf8mb4'); $dbh->{'mysql_enable_utf8'} = 1; my $sth = $dbh->prepare($SQL); $sth->execute; my $res = $sth->fetchrow_hashref(); if ($res) { if ($dnsname and $res->{dns_name} ne $dnsname) { my $new_record; $new_record->{dns_name} = $dnsname; update_record($dbh,"User_auth",$new_record,"id=".$res->{id}); } if ($comment and $res->{comments} ne $comment) { my $new_record; $new_record->{comments} = $comment; update_record($dbh,"User_auth",$new_record,"id=".$res->{id}); } if ($wikiname and $res->{WikiName} ne $wikiname) { my $new_record; $new_record->{WikiName} = $wikiname; update_record($dbh,"User_auth",$new_record,"id=".$res->{id}); } } }; if ($@) { return "DBI error: $@"; } return $result; } 1;