use IO::Socket;
use DBI;
use Data::Dumper;
use Net::Server::Prefork;
use Unix::Syslog qw(:macros :subs);
use strict;
use constant CONFIGFILE=>'/etc/notify_unix';
use constant USERS_TABLE => 'Users';
use constant USER_FLD => 'UserName';
use constant NOTIFY_FLD => 'NotifyAddr';
open (CONFIG, '<'.CONFIGFILE) || die 'Failed to open config file '.CONFIGFILE;
chomp (my ($D_DSN, $D_LOGIN, $D_PASSWORD) = <CONFIG>);
close CONFIG;
my ($dbh,$sth) = undef;
Unix::Syslog::openlog('notify_unix', LOG_PID | LOG_CONS, LOG_DAEMON);
my $Server = Net::Server::Prefork->new;
$Server->set_path('/var/imap/');
$Server->set_pid_name('notify_unix.pid');
$Server->set_socket_name('socket/notify');
$Server->set_log_name("notify_unix");
$Server->set_num_prefork(5);
$Server->set_user(scalar getpwnam('cyrus'));
$Server->set_group(scalar getgrnam('mail'));
$Server->set_on_connect(\&sql_notify);
$Server->start();
$sth->finish() if $sth;
$dbh->disconnect if $dbh;
sub db_connect {
if (!$dbh || $DBI::errstr || !$dbh->{Active}) {
Unix::Syslog::syslog LOG_INFO, "Connecting to database", 0;
$sth->finish() if $sth;
$dbh->disconnect() if $dbh;
$dbh = undef; $dbh = DBI->connect ($D_DSN, $D_LOGIN, $D_PASSWORD)
|| syslog LOG_ERR, 'Failed to connect to database';
if ($dbh) {
$sth = $dbh->prepare(
'SELECT ' .NOTIFY_FLD. ' FROM ' . USERS_TABLE . ' WHERE ' .USER_FLD. '=?'
) || syslog LOG_ERR, 'Failed to create statement handle';
}
}
if ($DBI::errstr) {
Unix::Syslog::syslog LOG_ERR, "No DB connection--reconnecting", 0;
sleep 10;
goto &db_connect;
}
}
sub get_rows {
my $username=$_[0];
my @rows=undef;
db_connect();
while (!$sth->execute($username)) {
sleep 10;
db_connect();
}
if (defined $DBI::errstr) {
Unix::Syslog::syslog LOG_ERR, $DBI::errstr;
return ();
}
@rows=$sth->fetchrow_array;
return @rows;
}
sub sql_notify {
my $sock = shift;
my $Class = $sock->getline();
my $Instance = $sock->getline();
my $User = $sock->getline();
my $Mailbox = $sock->getline();
my $Message = join("\n",$sock->getlines());
$User =~ s/\s$//;
my @rows = get_rows($User);
$ syslog LOG_ERR, "Non-unique rows for user $User";
my $row = $rows[0];
if ($row) {
syslog LOG_ERR, "Notification for $User with $row";
}
$sock->close;
}