#!/usr/bin/perl -w

use strict;
use DBI;
use IO::Handle;
use IO::Select;
use POSIX qw(strftime);

use vars qw($acctserver $user $pass $passwd_file);

$pass = "";

die "Usage: $0 configfile" unless $#ARGV == 0;
require $ARGV[0];

sub doconn() {
	my $dbh = DBI->connect($acctserver, $user, $pass, { RaiseError => 1, AutoCommit => 1, PrintError => 1 });
	unless (defined($dbh)) {
		printf STDERR "can't connect to database: %s\n", $DBI::errstr;
		exit 1;
	}
	
	$dbh->do("LISTEN syncusers");
	
	return $dbh;
}

sub dosync($) {
	my ($dbh) = @_;
	my $arr = $dbh->selectall_arrayref("SELECT username, uid, COALESCE(lmpw, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'), COALESCE(ntpw, 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'), acct_flags, 'LCT-00000001:'::text FROM samba");
	open (PASSWD, ">$passwd_file");
	foreach my $row (@{$arr}) {
		print PASSWD join (':', @{$row}), "\n";
	}
	close PASSWD;
}

my ($sel, $fd, $dbh);
for (; 1; sleep 10) {
	eval {
		print("connecting...\n");
		$dbh = doconn();
		print "doing initial sync...\n";
		dosync($dbh);
		$fd = IO::Handle->new_from_fd($dbh->func('getfd'), "r+");
		$sel = IO::Select->new($fd);
		while (1) {
			print "waiting for changes...\n";
			$sel->can_read();
			print "got something...\n";
			if (defined($dbh->func('pg_notifies'))) {
				print "doing sync...\n";
				dosync($dbh);
			}
			die "connection lost" unless ($dbh->ping);
		}
	};
	if ($@) {
		print $@;
		print "=> reseting!\n";
	}
	eval {
		$dbh->disconnect if defined($dbh);
	};
	print $@ if ($@);
	undef $dbh;
	print "connection lost. sleeping befor reconnect\n";
}

#### 

exit 0;
1;
