App-Bondage

 view release on metacpan or  search on metacpan

lib/App/Bondage.pm  view on Meta::CPAN

BEGIN {
  $App::Bondage::AUTHORITY = 'cpan:HINRIK';
}
BEGIN {
  $App::Bondage::VERSION = '0.4.11';
}

use strict;
use warnings FATAL => 'all';
use Carp;
use Config;
use App::Bondage::Away;
use App::Bondage::Client;
use App::Bondage::Recall;
use App::Bondage::State;
use Digest::MD5 qw(md5_hex);
use File::Spec::Functions qw(catdir catfile);
use POE qw(Filter::Line Filter::Stackable Wheel::ReadWrite Wheel::SocketFactory);
use POE::Filter::IRCD;
use POE::Component::Client::DNS;
use POE::Component::IRC::State;
use POE::Component::IRC::Plugin::AutoJoin;
use POE::Component::IRC::Plugin::Connector;
use POE::Component::IRC::Plugin::CTCP;
use POE::Component::IRC::Plugin::CycleEmpty;
use POE::Component::IRC::Plugin::Logger;
use POE::Component::IRC::Plugin::NickReclaim;
use POE::Component::IRC::Plugin::NickServID;
use Socket qw(inet_ntoa);
use YAML::XS qw(LoadFile);

our $HOMEPAGE   = 'http://search.cpan.org/perldoc?App::Bondage';
our $CRYPT_SALT = 'erxpnUyerCerugbaNgfhW';

sub new {
    my ($package, %params) = @_;
    my $self = bless \%params, $package;
    $self->_load_config();
    
    POE::Session->create(
        object_states => [
            $self => [ qw(_start _client_error _client_input _listener_accept _listener_failed _exit) ],
        ],
    );
    return $self;
}

sub _start {
    my $self = $_[OBJECT];
    
    $self->{resolver} = POE::Component::Client::DNS->spawn();
    $self->{filter} = POE::Filter::Stackable->new(
        Filters => [
            POE::Filter::Line->new(),
            POE::Filter::IRCD->new()
        ]
    );
    
    while (my ($network_name, $network) = each %{ $self->{config}{networks} }) {
        my $irc = $self->{ircs}{$network_name} = POE::Component::IRC::State->spawn(
            LocalAddr    => $network->{bind_host},
            Server       => $network->{server_host},
            Port         => $network->{server_port},
            Password     => $network->{server_pass},
            UseSSL       => $network->{use_ssl},
            Useipv6      => $network->{use_ipv6},
            Nick         => $network->{nickname},
            Username     => $network->{username},
            Ircname      => $network->{realname},
            AwayPoll     => $network->{away_poll},
            Flood        => $network->{flood},
            Resolver     => $self->{resolver},
            Debug        => $self->{Debug},
            plugin_debug => $self->{Debug},
        );
        
        my $version;
        {
            no strict 'vars';
            $version = defined $App::Bondage::VERSION
                ? "Bondage $VERSION running on $Config{osname} $Config{osvers} -- $HOMEPAGE"
                : "Bondage dev-git running on $Config{osname} $Config{osvers}";
        }
        $irc->plugin_add('CTCP',        POE::Component::IRC::Plugin::CTCP->new(
            Version => $version,
        ));
        $irc->plugin_add('Cycle',       POE::Component::IRC::Plugin::CycleEmpty->new()) if $network->{cycle_empty};
        $irc->plugin_add('NickReclaim', POE::Component::IRC::Plugin::NickReclaim->new());
        $irc->plugin_add('Connector',   POE::Component::IRC::Plugin::Connector->new( Delay => 120 ));
        $irc->plugin_add('AutoJoin',    POE::Component::IRC::Plugin::AutoJoin->new(
            Channels => $network->{channels},
            RejoinOnKick => $network->{kick_rejoin},
        ));
        
        if (defined $network->{nickserv_pass}) {
            $irc->plugin_add('NickServID', POE::Component::IRC::Plugin::NickServID->new(
                Password => $network->{nickserv_pass}
            ));
        }
        
        if ($network->{log_public} || $network->{log_private}) {
            my $log_dir = catdir($self->{Work_dir}, 'logs');
            if (! -d $log_dir) {
                mkdir $log_dir or die "Cannot create directory $log_dir; $!; aborted";
            }

            $irc->plugin_add('Logger', POE::Component::IRC::Plugin::Logger->new(
                Path         => catdir($log_dir, $network_name),
                Private      => (defined $network->{log_private}    ? $network->{log_private}    : 0),
                Public       => (defined $network->{log_public}     ? $network->{log_public}     : 0),
                Sort_by_date => (defined $network->{log_sortbydate} ? $network->{log_sortbydate} : 0),
                Restricted   => (defined $network->{log_restricted} ? $network->{log_restricted} : 0),
                DCC          => (defined $network->{log_dcc}        ? $network->{log_dcc}        : 0),
                Notices      => (defined $network->{log_notices}    ? $network->{log_notices}    : 0),
            ));
        }

        $irc->plugin_add('State',  App::Bondage::State->new());
        $irc->plugin_add('Away',   App::Bondage::Away->new(
                Message => $network->{away_msg}
        ));

lib/App/Bondage.pm  view on Meta::CPAN

=head2 Reclaim nickname

Bondage will periodically try to change to your preferred nickname if it is
taken.

=head2 Flood protection

Bondage utilizes POE::Component::IRC's flood protection to ensure that you
never flood yourself off the IRC server.

=head2 NickServ support

Bondage can identify with NickServ for you when needed.

=head2 Rejoins channels if kicked

Bondage can try to rejoin a channel if you get kicked from it.

=head2 Encrypted passwords

Bondage supports encrypted passwords in its configuration file for added
security.

=head2 SSL support

You can connect to SSL-enabled IRC servers, and make Bondage require SSL for
client connections.

=head2 IPv6 support

Bondage can connect to IPv6 IRC servers, and also listen for client
connections via IPv6.

=head2 Cycles empty channels

Bondage can cycle (part and rejoin) channels for you when they become empty
in order to gain ops.

=head2 CTCP replies

Bondage will reply to CTCP VERSION requests when you are offline.

=head1 CONFIGURATION

The following options are recognized in the configuration file which is
called F<~/.bondage/config.yml>.

=head2 Global options

=head3 C<listen_host>

(optional, default: I<"0.0.0.0">)

The host that Bondage accepts connections from. This is the host you use to
connect to Bondage.

=head3 C<listen_port>

(required, no default)

The port Bondage binds to.

=head3 C<listen_ssl>

(optional, default: I<false>)

Set this to true if you want Bondage to require the use of SSL for client
connections. You'll need to have F<ssl.crt> and F<ssl.key> files in Bondage's
working directory. More information, see
L<http://www.akadia.com/services/ssh_test_certificate.html>

=head3 C<password>

(required, no default)

The password you use to connect to Bondage. If it is 32 characters, it is
assumed to be encrypted (see L<C<bondage -c>|bondage/"SYNOPSIS">);

=head3 C<networks>

(required, no default)

This should contain a list of network names, each pointing to a list of
relevant options as described in the following section.

 networks:
   freenode:
     option1: value
     option2: value
   ircnet
     option1: value
     option2: value

=head2 Network-specific options

=head3 C<bind_host>

(optional, default: I<"0.0.0.0">)

The host that Bondage binds to and connects to IRC from. Useful if you have
multiple IPs and want to choose which one to IRC from.

=head3 C<server_host>

(required, no default)

The IRC server you want Bondage to connect to.

=head3 C<server_port>

(optional, default: I<6667>)

The port on the IRC server you want to use.

=head3 C<server_pass>

(optional, no default)

The IRC server password, if there is one.

=head3 C<use_ssl>

(optional, default: I<false>)

Set this to true if you want to use SSL to communicate with the IRC server.

=head3 C<nickserv_pass>

(optional, no default)

Your NickServ password on the IRC network, if you have one. Bondage will
identify with NickServ with this password on connect, and whenever you switch
to your original nickname.

=head3 C<nickname>

(optional, default: your UNIX user name)

Your IRC nick name.

=head3 C<username>

(optional, default: your UNIX user name)

Your IRC user name.

=head3 C<realname>

(optional, default: your UNIX real name, if any)

Your IRC real name, or email, or whatever.

=head3 C<flood>

(optional, default: I<false>)

Set to a true value to allow flooding (disables flood protection).

=head3 C<channels>



( run in 0.555 second using v1.01-cache-2.11-cpan-2398b32b56e )