#!/usr/bin/perl

# The joo daemon
use Digest::MD5;
use Sys::Syslog qw(:DEFAULT setlogsock);

use FindBin;
chdir( $FindBin::Bin );

# Max prot level to take
$PROTO_LEVEL = 1;

# Unix sock logging
setlogsock('unix');

# Hot grits in my pipes!
$| = 1;

# Read config
%dmap = ();
open( IN, "bangkorgd.conf" ) ||
	open( IN, "/etc/bangkorgd.conf" ) ||
	die( "Unable to open config /etc/bangkorgd.conf" );
while( $line = <IN> )
{
	chomp( $line );
	$line =~ s/#.*//;

	( $key, $dir ) = $line =~ /^(\S+)\s+(\S.*)/;
	if( $key )
	{
		$dmap{ $key } = $dir;
	}
}

# Conf loaded, now do our stuff.
# First line is the connectfo line
# Comma sep'd, starts with joo:request(,user,pass...)
@l = getjoo();

# This is the request, check if it's there
if( ( ! -d $dmap{ $l[ 0 ] } ) &&
	( ! -f $dmap{ $l[ 0 ] } . "/.bangkorg_list" ) )
{
	saybad( 'INVALID REQUEST' );
	exit;
}

if( $l[ 1 ] > $PROTO_LEVEL )
{
	saybad( 'PROTO TOO HIGH' );
	exit;
}

# log it quickie
sayok();
syslog( 'info', "Processing $l[0] ($dmap{$l[0]})" );

# Now just do the main loop proc
# Read the files, make an MD5, request the other MD5,
# and send updates if necessary
chdir( $dmap{ $l[ 0 ] } );
open( IN, ".bangkorg_list" );

while( $line = <IN> )
{
	chomp( $line );

	if( -f $line )
	{
		process_file( $line );
	}elsif( -d $line )
	{
		say( "dir", $line );
	}

	# Perm thing
	@stats = stat( $line );
	say( "perm", $line, $stats[ 2 ] );
}

say( 'end' );

exit;







sub getjoo
{
	my $l = <STDIN>;
	if( $l !~ /^joo:/ )
	{
		# Lost connection or protocol error
		exit;
	}

	chomp( $l );
	#syslog( 'debug', "read: " . $l );
	$l =~ s/^joo://;
	return( split( /\t/, $l ) );
}

sub say
{
	#syslog( 'debug', "write: " . join( "\t", @_ ) );
	print "joo:" . join( "\t", @_ ) . "\n";
}

sub sayok
{
	say( "OK" );
}

sub saybad
{
	say( "FAIL", @_ );
}

sub process_file
{
	my $filename = shift;
	my( @l, $md5, @stats, $fline );

	say( 'file', $filename );

	# Make an MD5
	$dgst = Digest::MD5 -> new();
	open( MD5, $filename ) || die( "could not open file $filename" );
	$dgst -> addfile( MD5 );
	$md5 = $dgst -> hexdigest();
	close( MD5 );

	# Get the MD5 the client thinks it is
	@l = getjoo();
	if( $l[ 0 ] ne $md5 )
	{
		# No match, send file
		@stats = stat( $line );
		say( 'size', $stats[ 7 ] );

		open( FILE, $line );
		while( $fline = <FILE> )
		{
			print $fline;
		}
		close( FILE );
	}else
	{
		# OK, send ok
		sayok();
	}
}

