#!/usr/bin/perl use Pg; use IO::Select; use Socket qw(inet_aton); my $dbname = "xxxx"; my $dbhost = "::1"; my $dbuser = "xxxx"; my $dbpass = "xxxx"; my $max_ttl = 1800; my $ping_ttl = 60; my %notify = ("acl_user_insert" => "process_user_insert", "acl_user_update" => "check_user_update", "acl_user_delete" => "process_user_delete"); my $log = "/var/log/acl_change.log"; my $till = time() + $max_ttl - 3; my $last_ping = time(); #daemonize(); my $conn; for(;;) { if (time() > $till) { exit; } $conn = Pg::setdbLogin($dbhost, 5432, $pgoptions, "", $dbname, $dbuser, $dbpass); if (($conn->status != PGRES_CONNECTION_OK)) { _log("Err: $conn->errorMessage"); undef $conn; next; } foreach $event (keys(%notify)) { my $res = $conn->exec("LISTEN $event"); if ($res->resultStatus != PGRES_COMMAND_OK) { _log("LISTEN error: " . $conn->errorMessage . ""); next; } } my $s = IO::Select->new(); $s->add($conn->socket); for(;;) { if (time() > $till) { exit; } my @x = $s->can_read(2); if (@x > 0) { _log("a-ha! socket event"); $conn->consumeInput; while (my ($table, $pid) = $conn->notifies) { if (exists($notify{$table})) { _log("Got notify for $table!"); $notify{$table}(); sleep 1; # Filtering too many updates/sec } } } else { # _log("empty loop.."); # some kind of ping if (time() > $last_ping + $ping_ttl) { $last_ping = time(); my $res = $conn->exec("SELECT 42"); if ($res->resultStatus != PGRES_TUPLES_OK) { _log("DB connection failed (ping check)"); last; } } } if ($conn->status != PGRES_CONNECTION_OK) { _log("DB connection failed"); last; } } undef $s; } sub process_user_insert { print "process_user_insert\n"; } sub process_user_update { my $user_id = $_[0]; my $sql = "UPDATE phpbb_users SET ldap_task_status = 2 WHERE user_id = " . $user_id; $conn->exec($sql); } sub check_user_update { my $sql = "SELECT user_id FROM phpbb_users WHERE ldap_task_status = 0"; my $res = $conn->exec($sql); if ($res->resultStatus != PGRES_TUPLES_OK) { _log("SELECT error: $conn->errorMessage"); return -1; } my @rows; while (my @row = $res->fetchrow()) { push @rows, $row[0]; } foreach $user_id (@rows) { print "Processing user " . $user_id . "\n"; process_user_update($user_id); } print "process_user_update\n"; } sub process_user_delete { print "process_user_delete\n"; } sub _log { print localtime() . " " . join(" ", @_) . "\n"; }