]> git.ipfire.org Git - people/stevee/guardian.git/blob - modules/Socket.pm
Merge branch 'parser-httpd'
[people/stevee/guardian.git] / modules / Socket.pm
1 package Guardian::Socket;
2 use strict;
3 use warnings;
4
5 use Exporter qw(import);
6
7 our @EXPORT_OK = qw(Server Client Message_Parser RemoveSocketFile);
8
9 use IO::Socket::UNIX qw( SOCK_STREAM SOMAXCONN );
10
11 # The path and filename to the UNIX socket.
12 my $socketpath = "/run/guardian";
13 my $socketfile = "/run/guardian/guardian.sock";
14
15 # Hash with all supported socket commands and events which should
16 # be returned by the parser.
17 my %supported_commands = (
18 'block' => 'block',
19 'unblock' => 'unblock',
20 'flush' => 'flush',
21 'reload' => 'reload',
22 'logrotate' => 'logrotate',
23 );
24
25 #
26 ## Socket server function.
27 #
28 ## It is used to create the server component to provide an IPC
29 ## mechanism for guardian. The server function creates an UNIX
30 ## socket.
31 #
32 sub Server ($) {
33 my $socket_owner = shift;
34
35 # If the path for the socketfile does not exist, try to
36 # create it.
37 unless (-d "$socketpath") {
38 mkdir("$socketpath") or die "Could not create $socketpath: $!";
39 }
40
41 # Delete an existing socket file.
42 if (-e "$socketfile") {
43 unlink $socketfile
44 or die "Could not release existing socket file: $!";
45 }
46
47 # Create a new UNIX socket.
48 my $server = IO::Socket::UNIX->new(
49 Local => $socketfile,
50 Listen => SOMAXCONN,
51 Type => SOCK_STREAM,
52 ) or die "Could not create socket: $!";
53
54
55 # Translate the given user/group name into ID values.
56 if (defined ($socket_owner)) {
57 # Splitt provided user/group into single arguments.
58 my ($username, $groupname) = split(/:/, $socket_owner);
59
60 # Get the ID for the given user name.
61 my $uid = getpwnam($username) or die "Could not get an UID for $username: $!";
62
63 # Get the ID for given group name.
64 my $gid = getgrnam($groupname) or die "Could not get a GID for $groupname: $!";
65
66 # Set new ownership for the socket file.
67 chown($uid, $gid, "$socketfile") or die "Could not change ownership to ($uid:$gid) for $socketfile: $!";
68 }
69
70 # Return the server object.
71 return $server;
72 }
73
74 #
75 ## A client for the socket server.
76 #
77 ## This function provides a simple client to connect to the server socket
78 ## and send messages through it to a running guardian process.
79 #
80 sub Client($) {
81 my ($message) = @_;
82
83 # Create the client and connect to the server socket.
84 my $client = IO::Socket::UNIX->new(
85 Type => SOCK_STREAM,
86 Peer => $socketfile,
87 ) or die "Could not connect to socketfile: $!\n";
88
89 # Remove any newline.
90 chomp($message);
91
92 # Send the message through the socket.
93 print $client "$message\n";
94 }
95
96 #
97 ## The Socket message parser.
98 #
99 ## This subfunction is responsible for parsing any data or messages
100 ## which have been recieved through the server socket.
101 #
102 sub Message_Parser ($) {
103 # Splitt the message into single parts.
104 # The first part contains the command, the second
105 # one an optional argument.
106 my @message = split(/ /, $_[0]);
107 my ($command, $optarg, $unsupported) = @message;
108
109 # Currently only socket messages with two arguments (command and
110 # the additional argument which is required for some commands)
111 # are supported. If a third argument is passed, the message
112 # is invalid and the parser returns false.
113 if ($unsupported) {
114 return undef;
115 }
116
117 # Check if we got a supported command.
118 if (exists $supported_commands{$command}) {
119 # Check an optional argument has been given.
120 if ($optarg) {
121 # The message is valid, return the event and
122 # the optional argument.
123 return "$supported_commands{$command} $optarg Socket User-requested action.";
124 } else {
125 # Only return the event for the recieved command.
126 return "$supported_commands{$command}";
127 }
128 }
129
130 # If we got here, the command was not supported or something different
131 # went wrong. In such cases the function will return undef (False).
132 return undef;
133 }
134
135 #
136 ## RemoveSocketFile function.
137 #
138 ## A tiny function which just removes an existing Socket file.
139 #
140 sub RemoveSocketFile () {
141 # Check if a socketfile exists.
142 if (-e $socketfile) {
143 # Delete the socket file.
144 unlink($socketfile);
145 }
146 }
147
148 1;