#! perl.exe
########################################################################################
##
## Server Service
##
########################################################################################
use Win32;
use Win32::Daemon; #Manipulate the Win32 Service
use Socket; #Create and Manipulate Sockets
use IO::Socket; #Create and Manipulate Sockets
use IO::Select; #Use for Non-Blocking Sockets
use strict;
use warnings;
########################################################################################
#Service Variables
my ($Result, $PrevState, $State);
#Socket Variables
my ($remote, $port, $sock, @client_list, $sel);
#Misc Variables
my ($VERSION, $logfile, $timeout);
########################################################################################
$VERSION = "1.0";
$logfile = "c:/Logs/SockSrv.log";
$port = 54321;
$timeout = 2;
#Open Log File
if (open( LOG, ">>$logfile" ) ) {
my $TempSelect = select( LOG );
$| = 1;
select( $TempSelect );
print LOG "\n# Date: " . localtime() . "\n================================\n";
}
if( ! Win32::Daemon::StartService()) {
if( fileno( LOG ) ) {
&Update_Log("Failed to start this script as a Win32 service.\n");
&Update_Log("Error: " . GetError());
close($sock);
close( LOG );
}
exit();
}
$PrevState = "SERVICE_STARTING";
while( SERVICE_STOPPED != ( $State = Win32::Daemon::State() ) ) {
if( SERVICE_START_PENDING == $State ) {
# Initialization code
Win32::Daemon::State( SERVICE_RUNNING );
@client_list = ();
&Create_Socket();
&Debug_Log("DEBUG - Service is Running\n");
$PrevState = SERVICE_RUNNING;
} elsif( SERVICE_PAUSE_PENDING == $State ) {
# "Pausing...";
Win32::Daemon::State( SERVICE_PAUSED );
&Debug_Log("DEBUG - Service is Paused\n");
#Clean Up Memory and Sockets
if ($remote) { close($remote); }
close($sock);
&Debug_Log("DEBUG - Socket Closed\n");
$PrevState = SERVICE_PAUSED;
next;
} elsif( SERVICE_CONTINUE_PENDING == $State ) {
# "Resuming...";
Win32::Daemon::State( SERVICE_RUNNING );
&Debug_Log("DEBUG - Service Continue\n");
#Setup Socket
&Create_Socket();
&Debug_Log("DEBUG - Socket RE-Created\n");
$PrevState = SERVICE_RUNNING;
next;
} elsif ( SERVICE_STOP_PENDING == $State ) {
# "Stopping...";
Win32::Daemon::State( SERVICE_STOPPED );
$PrevState = SERVICE_STOPPED;
#Clean Up Memory and Sockets
if ($remote) { close($remote); }
close($sock);
#Backup ExistCalls into ExistCalls File
&Debug_Log("DEBUG - Socket Closed\n");
&Update_Log("Service is Stoped\n");
next;
} elsif( SERVICE_RUNNING == $State ) {
# The service is running as normal...
$PrevState = SERVICE_RUNNING;
my $read_buffer = 1024;
while (@client_list = $sel->can_read(1)) {
foreach $remote(@client_list) {
if ($remote == $sock) {
my $new_remote = $sock->accept;
$sel->add($new_remote) if ($new_remote);
&Update_Log("Accepted new Client\n");
} else {
my $msg = <$remote>;
chomp($msg);
#Look at what we received from the Client
&Update_Log("\nRECEIVED FROM CLIENT - $msg\n");
$sel->remove($remote) or Debug_Log("Could Not Clean Up the Select:$!\n");
close($remote);
}
}
}
} else {
# We have some unknown state...
# reset it back to what we last knew the state to be...
Win32::Daemon::State( $PrevState );
sleep( $timeout );
}
}
#Stop the Service
Win32::Daemon::StopService();
if( fileno( LOG ) )
{
&Update_Log("================================\n");
&Update_Log("Service Stopped.\n" . localtime());
close LOG;
}
########################################################################################
##
## SUB ROUTINES
##
########################################################################################
#Create a Socket to listen on
sub Create_Socket
{
&Update_Log("Socket Created");
my $max_length = 1024;
my $max_clients = 10;
$sock = IO::Socket::INET->new(
LocalPort => $port,
Proto => 'tcp',
Listen => $max_clients
) or die &Debug_Log("...Failed\nCould Not Create Socket: $@\n");
$sel = IO::Select->new($sock);
&Update_Log(" ... Successful\n");
&Update_Log("Awaiting messages on: $port\n");
return(0);
}
#Update Log file
sub Update_Log
{
if (! $_[0]) { return (0); }
print LOG "$_[0]";
return(0);
}
####
#! perl.exe -w
########################################################################################
##
## Client_Skeleton
##
########################################################################################
use strict;
use Getopt::Long qw (GetOptions);
use IO::Socket;
#List of variables used in this program
my (%opts, $VERSION,);
$VERSION = "1.0";
#Set the options for GetOpt
Getopt::Long::Configure( "pass_through", "no_ignore_case", "prefix_pattern=(-|\/)" );
#What to expect on the command line
%opts = ();
GetOptions (\%opts,
'help|h|?',
'port=s',
'server=s',
'msg=s',
);
#Set help option on if the correct parameters are not inserted
$opts{help} = 1 unless (defined $opts{port} && defined $opts{server} && defined $opts{msg});
if( $opts{help} )
{
Syntax();
exit();
}
&Transmit_Msg($opts{msg});
########################################################################################
##
## SUB ROUTINES
##
########################################################################################
#Create socket connection and send message to server.
sub Transmit_Msg($msg)
{
my $MAXLEN = 1024;
my $msg = shift;
my $sock = IO::Socket::INET->new(
Proto => 'tcp',
PeerPort => $opts{port},
PeerAddr => $opts{server},
) or die "Could Not Connect to Server Socket(Check Service is Running): $!\n";
print $sock "$msg\n";
# &Notify("Sent $msg");
close ($sock);
}
#Print out the proper syntax if some parameters are missing.
sub Syntax
{
my( $Script ) = ( $0 =~ m#([^\\/]+)$# );
my $Scriptdetails = "$Script - Version: $VERSION";
my $Line = "-" x length( $Scriptdetails );
print << "EOT";
$Scriptdetails
$Line
This program will send a TCP message to the server. You Must add Port and Server Address as well
as the Message to send in Quotes
Syntax:
$0 [-p|--port=] [-s|--server=] [-m|--msg=<"Message To Send"[-h|--help|?]
EOT
}
####
#X-CallInstall
use strict;
use warnings;
use Win32;
use Win32::Daemon;
use Getopt::Long;
my ($VERSION, %Config);
$VERSION = "1.0";
%Config = (timeout_value => 2,
log_file => join( "", Win32::GetFullPathName( $0 ) ),
);
$Config{log_file} =~ s/[^.]*?$/log/;
Getopt::Long::Configure( "prefix_pattern=(-|\/)" );
my $Result = GetOptions( \%Config,
qw(
install|i
remove|r
account_id|user=s
account_password|pass=s
help|?|h
) );
$Config{help} = 1 if( ! $Result || scalar @ARGV );
if( $Config{install}) {
&Install();
exit();
} elsif ( $Config{remove}) {
&Remove();
exit();
} elsif( $Config{help}) {
&Syntax();
exit();
}
#Configuration for Service
sub GetServiceConfig
{
my $script_path = join("",Win32::GetFullPathName($0));
my %hash = (
name => 'Skeleton Socket Server',
display => 'Skeleton Socket Server',
description => "Skeleton Socket Server v$VERSION",
path => $^X,
user => $Config{account_id},
password => $Config{account_password},
parameters => "C:\\Pathtoscript\\skelserv.pl",
);
return(\%hash);
}
#Install Service
sub Install
{
my $svc_cfg = &GetServiceConfig();
if (Win32::Daemon::CreateService($svc_cfg)) {
print "The $svc_cfg->{display} was Successfully installed.\n";
} else {
print "Failed to Install $svc_cfg->{display} service.\nError: " . GetError() . "\n";
}
}
#Remove Service
sub Remove
{
my $service_config = GetServiceConfig();
if( Win32::Daemon::DeleteService( $service_config->{name} ) ) {
print "The $service_config->{display} was successfully removed.\n";
} else {
print "Failed to remove the $service_config->{display} service.\nError: " . GetError() . "\n";
}
}
#Display if no Command Line Arguments Found!
sub Syntax
{
print << "EOT";
A Win32 service that Create a Socket to listen on for X-Transport Messages.
Syntax:
[-l ] [-t