--- /dev/null
+package Guardian::Socket;
+use strict;
+use warnings;
+
+use Exporter qw(import);
+
+our @EXPORT_OK = qw(Server Client Message_Parser);
+
+use IO::Socket::UNIX qw( SOCK_STREAM SOMAXCONN );
+
+# The path and filename to the UNIX socket.
+my $socketpath = "/run/guardian";
+my $socketfile = "/run/guardian/guardian.sock";
+
+# Hash with all supported socket commands and events which should
+# be returned by the parser.
+my %supported_commands = (
+ 'block' => 'block',
+ 'unblock' => 'unblock',
+ 'flush' => 'flush',
+ 'reload' => 'reload',
+ 'logrotate' => 'logrotate',
+);
+
+#
+## Socket server function.
+#
+## It is used to create the server component to provide an IPC
+## mechanism for guardian. The server function creates an UNIX
+## socket.
+#
+sub Server () {
+ # If the path for the socketfile does not exist, try to
+ # create it.
+ unless (-d "$socketpath") {
+ mkdir("$socketpath") or die "Could not create $socketpath: $@\n";
+ }
+
+ # Delete an existing socket file.
+ if (-s "$socketfile") {
+ unlink "$socketfile"
+ or die "Could not release existing socket file: $@\n";
+ }
+
+ # Create a new UNIX socket.
+ my $server = IO::Socket::UNIX->new(
+ Local => $socketfile,
+ Listen => SOMAXCONN,
+ Type => SOCK_STREAM,
+ ) or die "Could not create socket: $@\n";
+
+ # Return the server object.
+ return $server;
+}
+
+#
+## A client for the socket server.
+#
+## This function provides a simple client to connect to the server socket
+## and send messages through it to a running guardian process.
+#
+sub Client($) {
+ my ($message) = @_;
+
+ # Create the client and connect to the server socket.
+ my $client = IO::Socket::UNIX->new(
+ Type => SOCK_STREAM,
+ Peer => $socketfile,
+ ) or die "Could not connect to socketfile: $!\n";
+
+ # Remove any newline.
+ chomp($message);
+
+ # Send the message through the socket.
+ print $client "$message\n";
+}
+
+#
+## The Socket message parser.
+#
+## This subfunction is responsible for parsing any data or messages
+## which have been recieved through the server socket.
+#
+sub Message_Parser ($) {
+ # Splitt the message into single parts.
+ # The first part contains the command, the second
+ # one an optional argument.
+ my @message = split(/ /, $_[0]);
+ my ($command, $optarg, $unsupported) = @message;
+
+ # Currently only socket messages with two arguments (command and
+ # the additional argument which is required for some commands)
+ # are supported. If a third argument is passed, the message
+ # is invalid and the parser returns false.
+ if ($unsupported) {
+ return undef;
+ }
+
+ # Check if we got a supported command.
+ if (exists $supported_commands{$command}) {
+ # Check an optional argument has been given.
+ if ($optarg) {
+ # The message is valid, return the event and
+ # the optional argument.
+ return "$supported_commands{$command} $optarg";
+ } else {
+ # Only return the event for the recieved command.
+ return "$supported_commands{$command}";
+ }
+ }
+
+ # If we got here, the command was not supported or something different
+ # went wrong. In such cases the function will return undef (False).
+ return undef;
+}
+
+1;