#!/usr/bin/perl
# $Id: relay-socket-server-1.0.pl,v 1.6 2024/04/30 10:30:56 sqko Exp $
use strict;
use Socket;
use IO::Socket;
use IO::Interface::Simple;
use POSIX qw(:sys_wait_h strftime);
use SocketClient;
my $VERSION = 0.2;
my $PROGRAM = 'relay-socket-server.pl';
my $debug = 0;
if (scalar(@ARGV) > 0)
{
    for(my $x = 0; $x < scalar(@ARGV);$x++)
    {
	if ($ARGV[$x] =~ /--version/)
	{
	    print "$PROGRAM is: $VERSION\n";
	    exit 0;
	}
	if ($ARGV[$x] =~ /--debug/)
	{
	    $debug = 1;
	}
    } 
}
if (scalar(@ARGV) < 3)
{
    die "not enough parameters for $PROGRAM\nUsage: $PROGRAM tty_to_emulate remote_host remote_port [opt localhost]\nIf the localhost argument is specified it forces bind to localhost instead of external IP!\n\n"; 
}


#### Base port number is 202020, added to this is the ttys nr ###
#### EG ttyS0 => 202020, ttyS4 => 202024 etc.                 ###
my $portbase = 202020;
#### Try to get ip address of netwrok interface ###
my @ilst = ('eth','em','en','lo');
my $local = '';
my @ifl = IO::Interface::Simple->interfaces();
OUTER:
foreach my $try (@ilst)
{
    foreach my $interface (@ifl)
    {
        if ($interface =~ /$try/)
        {
            my $if = IO::Interface::Simple->new($interface);
            $local = $if->address();
            last OUTER if ($local);
        }
    }
}
### Use localhost if everything else fails ###
$local = 'localhost' unless ($local);
$| = 1;
my $tty = shift;
my $remote = shift;
my $remote_port = shift;
$local = 'localhost' if (@ARGV);

our $port    =  202020;
if ($tty =~ /(\d+)/)
{
    $port += $1;
}
our $user      = "nobody";

$port = $port & 0xffff;
# Get userid for $user. Abort if userid is zero (superuser) or
# non-existent. #
unless ( our $uid = ( getpwnam($user) )[2] ) {
    die "Attempt to run server as non-existent or superuser\n";
}


### Bind to socket ###
my $sock = new IO::Socket::INET(
    LocalHost => $local,
    LocalPort => $port,
    Proto  => 'tcp',
    Listen => 10,
    Reuse  => 1
				);
die "Could not create socket: $!\n" unless $sock;
$| = 1;
my $new_sock;
while ( $new_sock = $sock->accept() ) 
{
    if ($debug)
    {
        print strftime "%Y:%m:%d:%H:%M:%S", localtime;
    }
    my $other_end = getpeername($new_sock);
    my ( $port, $iaddr ) = unpack_sockaddr_in($other_end);
    my $ip_address = inet_ntoa($iaddr);
    print "  ",$ip_address, "\n" if ($debug);
    if (my $str = <$new_sock>) {
        my (@args) = split (/[\s\t]+/,$str);
	my $res = SocketClient::socket_client($remote,$remote_port,@args);
	print "Result: $res\n\n" if ($debug);
	print $new_sock $res if (defined($res));
        close $new_sock;
    }
    else
    {
        close $new_sock;
    }
}
close($sock);
exit;


