summaryrefslogtreecommitdiff
path: root/files/irc_bot/riseup-nagios-server.pl
blob: 7880dde36d44a11cc78370dca47e173d429469f8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#!/usr/bin/perl -w

# ##############################################################################
# a simple IRC bot which dispatches messages received via local domain sockets
# ##############################################################################

use strict;
use File::Basename;

BEGIN {
	unshift @INC, dirname($0);
}

my $VERSION = '0.2';
my $running = 1;

# Read a configuration file
#   The arg can be a relative or full path, or
#   it can be a file located somewhere in @INC.
sub ReadCfg
{
    my $file = $_[0];

    our $err;

    {   # Put config data into a separate namespace
        package CFG;

        # Process the contents of the config file
        my $rc = do($file);

        # Check for errors
        if ($@) {
            $::err = "ERROR: Failure compiling '$file' - $@";
        } elsif (! defined($rc)) {
            $::err = "ERROR: Failure reading '$file' - $!";
        } elsif (! $rc) {
            $::err = "ERROR: Failure processing '$file'";
        }
    }

    return ($err);
}

# Get our configuration information
if (my $err = ReadCfg('/etc/nagios_nsa.cfg')) {
    print(STDERR $err, "\n");
    exit(1);
}

use POSIX qw(setsid);
use IO::Socket;
use Net::IRC;

sub new {
	my $self = {
		socket => undef,
		irc => undef,
		conn => undef
	};

	return bless($self, __PACKAGE__);
}

sub daemonize {
	my $self = shift;
	my $pid;

	chdir '/' or die "Can't chdir to /: $!";

	open STDIN, '/dev/null' or die "Can't read /dev/null: $!";
	open STDOUT, '>/dev/null' or die "Can't write to /dev/null: $!";

	defined ($pid = fork) or die "Can't fork: $!";

	if ($pid && $CFG::Nsa{'pidfile'}) { # write pid of child
		open PID, ">$CFG::Nsa{'pidfile'}" or die "Can't open pid file: $!";
		print PID $pid;
		close PID;
	}
	exit if $pid;
	setsid or die "Can't start a new session: $!";

	#open STDERR, '>&STDOUT' or die "Can't dup stdout: $!";
}

sub run {
	my $self = shift;

	$self->{irc}->do_one_loop();
}

sub shutdown {
	my $sig = shift;

	print STDERR "Received SIG$sig, shutting down...\n";
	$running = 0;
}

sub socket_has_data {
    my $self = shift;
    
    $self->{socket}->recv(my $data, 1024);
    $self->{conn}->privmsg($CFG::Nsa{'channel'}, $data);
}

sub irc_on_connect {
	my $self = shift;

	print STDERR "Joining channel '$CFG::Nsa{'channel'}'...\n";
	$self->join($CFG::Nsa{'channel'});
}

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

my $bot = &new;

if (-e $CFG::Nsa{'socket'}) {
	die "Socket '$CFG::Nsa{'socket'}' exists!\n";
}

$bot->{socket} = IO::Socket::UNIX->new (
	Local  => $CFG::Nsa{'socket'},
	Type   => SOCK_DGRAM,
	Listen => 5
) || die "Can't create socket '$CFG::Nsa{'socket'}'!\n";

$SIG{INT} = $SIG{TERM} = \&shutdown;

$bot->daemonize();
$bot->{irc} = new Net::IRC;

$bot->{conn} = $bot->{irc}->newconn (
	Server   => $CFG::Nsa{'server'},
	Port     => $CFG::Nsa{'port'},
	Nick     => $CFG::Nsa{'nickname'},
	Username => $CFG::Nsa{'nickname'},
	Password => $CFG::Nsa{'password'},
	Ircname  => $CFG::Nsa{'realname'} . " (NSA $VERSION)",
) || die "Can't connect to server '$CFG::Nsa{'server'}'!\n";

$bot->{conn}->add_global_handler(376, \&irc_on_connect);
$bot->{conn}->add_global_handler('nomotd', \&irc_on_connect);
$bot->{irc}->addfh($bot->{socket}, \&socket_has_data, 'r', $bot);

while ($running) {
	$bot->run();
}

close($bot->{socket});
unlink($CFG::Nsa{'socket'});

exit(0);

1;

__END__