#!/usr/bin/perl

# Distmp3, a program for distributing the encoding of music among several computers.
# Copyright (C) 2000  Martin Josefsson
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
#
# Author: Martin Josefsson <gandalf@wlug.westbo.se>
#

use IO::Socket;
use IO::Handle;
use Net::hostent;

$|=1;

#----------------------------
$version = "0.1.6";
#$debug = 1;
#$debug_file = "debug.file";

$remote_host = $ARGV[0];
$remote_port = 4600;
$wav_file = $ARGV[1];
$mp3_file = $ARGV[2];

$RTR = "hejhopp_rtr";
$RTS = "hejhopp_rts";
$ACK = "hejhopp_ack";

$SRV_ID = "hejhopp_server_id";
$CLI_ID = "hejhopp_client_id";

$DATA_SIZE = 16384;
#----------------------------

$SIG{INT} = sub { 
		if ( $debug || $debug_file ) {
			printd("Caught INT signal, going down in flames...\n");
		}
		if ( $debug_file ) {
			close DEBUG;
		}
		print "Exited gracefully...\n"; 
		shutdown $remote,2;
		close WAV_FILE; 
		close MP3_FILE;
		exit(1); 
		};

$SIG{TERM} = sub { 
		if ( $debug || $debug_file ) {
			printd("Caught TERM signal, going up in smoke...\n");
		}
		if ( $debug_file ) {
			close DEBUG;
		}
		print "Exited gracefully...\n"; 
		shutdown $remote,2;
		close WAV_FILE; 
		close MP3_FILE;
		exit(1); 
		};

sub open_remote_connection
{
printd('Opening remote connection');
$remote = IO::Socket::INET->new(Proto    => "tcp",
				    PeerAddr => $remote_host,
				    PeerPort => $remote_port)
	or die "Can't connect to $remote_host on port $remote_port: $!";

$remote->autoflush(1);
printd( "Connected to $remote_host on port $remote_port");
}

sub open_debug_file
{
open (DEBUG, ">>$debug_file") or die "Couldn't open debug-file $debug_file: $!";
}

sub close_debug_file
{
close DEBUG;
}

sub open_wav_file
{
printd('opening wav-file');
open (WAV_FILE, "<$wav_file") || die "Can't open file $wav_file for reading: $!";
WAV_FILE->autoflush(1);
$size_of_wavfile = sysseek(WAV_FILE,0,2);
sysseek(WAV_FILE,0,0);
}

sub open_mp3_file
{
printd('opening mp3-file');
open (MP3_FILE, ">$mp3_file") || die "Can't open file $mp3_file for writing: $!";
MP3_FILE->autoflush(1);
}

sub close_wav_file
{
printd('closing wav-file');
close WAV_FILE;
}

sub close_mp3_file
{
printd('closing mp3-file');
close MP3_FILE;
}

sub send_data
{
$data = $_[0];
print $remote $data;
}

sub recieve_data
{
read $remote,$rdata,$DATA_SIZE;
return $rdata;
} 

sub read_from_wav
{
read WAV_FILE,$wdata,$DATA_SIZE;
$data_read = $data_read + length($wdata);
$persent_read = ($data_read*100)/$size_of_wavfile;
printf "%.2f%% of $size_of_wavfile bytes done.\r", $persent_read;
return $wdata;
}

sub write_to_mp3
{
$mdata = $_[0];
print MP3_FILE $mdata;
}

sub handshake
{
printd('initiate handshake');

send_data($CLI_ID);
printd('sent Client id');

read $remote,$answer,length($SRV_ID);
printd('read Server id');

if ( $answer ne $SRV_ID ) { die "Server isn't who he should be..."; }
printd('Ok, server id is what it should be');

send_data($ACK);
printd('sent ack');
}


sub printd
{
if ( $debug ) {
	$message = $_[0];
	print "$message\n";
}
if ( $debug_file ) {
	$message = $_[0];
	print DEBUG "$message\n";
}
}

sub fork1
{
unless ($pid = fork) {
	printd('forking child to send shit');
	open_wav_file;
	while ( $data = read_from_wav ) {
		send_data($data);
	}
	close_wav_file;
	shutdown $remote,1;
	exit(0);
}
}

sub fork2
{
unless ($pid2 = fork) {
	printd('forking child to recieve shit');
	open_mp3_file;
	while ( $data2 = recieve_data ) {
		write_to_mp3($data2);
	}
	close_mp3_file;
	exit(0);
}
}


#Huvudprogram

unless (@ARGV == 3) { print "usage:  $0 host wav-file mp3-file\n"; exit(1); }

if ( $debug_file ) {
	open_debug_file;
}

printd("Distmp3 client version $version");

print "Encoding $wav_file into $mp3_file on host $remote_host\n";
printd("Encoding $wav_file into $mp3_file on host $remote_host");

open_remote_connection;

handshake;

printd('forking like hell');

read $remote,$answer,length($RTR);
read $remote,$answer2,length($RTR);
if ( $answer eq $RTR ) {
	fork1;
}
else
{
	fork2;
}
if ( $answer2 eq $RTS ) {
	fork2;
}
else
{
	fork1;
}

waitpid($pid,0);
waitpid($pid2,0);

if ( $debug_file ) {
	print DEBUG "Finished\n";
	close_debug_file;
}

print "\n";
