]> Sergey Matveev's repositories - public-inbox.git/blobdiff - public-inbox-nntpd
www: make interface more OO
[public-inbox.git] / public-inbox-nntpd
old mode 100644 (file)
new mode 100755 (executable)
index 7fec840..23d269d
@@ -1,77 +1,69 @@
 #!/usr/bin/perl -w
 # Copyright (C) 2015 all contributors <meta@public-inbox.org>
 # License: AGPLv3 or later (https://www.gnu.org/licenses/agpl-3.0.txt)
+#
+# Standalone NNTP server for public-inbox.
 use strict;
 use warnings;
-require Danga::Socket;
-use IO::Socket;
-use Socket qw(SO_KEEPALIVE IPPROTO_TCP TCP_NODELAY);
-require PublicInbox::NNTP;
+require PublicInbox::Daemon;
 require PublicInbox::NewsGroup;
+require PublicInbox::NNTP;
+require PublicInbox::Config;
 my $nntpd = PublicInbox::NNTPD->new;
-my $refresh = sub { $nntpd->refresh_groups };
-
-my %opts = (
-       LocalAddr => '127.0.0.1:1133',
-       Type => SOCK_STREAM,
-       Proto => 'tcp',
-       Blocking => 0,
-       Reuse => 1,
-       Listen => 1024,
-);
-my $s = IO::Socket::INET->new(%opts) or die "Error creating socket: $@\n";
-$s->sockopt(SO_KEEPALIVE, 1);
-$s->setsockopt(IPPROTO_TCP, TCP_NODELAY, 1);
-
-$SIG{PIPE} = 'IGNORE';
-$SIG{HUP} = $refresh;
-$refresh->();
-
-Danga::Socket->AddOtherFds(fileno($s) => sub {
-       while (my $c = $s->accept) {
-               $c->blocking(0); # no accept4 :<
-               PublicInbox::NNTP->new($c, $nntpd);
-       }
-});
-Danga::Socket->EventLoop();
+daemon_run('0.0.0.0:119',
+       sub { $nntpd->refresh_groups }, # refresh
+       sub ($$$) { PublicInbox::NNTP->new($_[0], $nntpd) }); # post_accept
 
+1;
 package PublicInbox::NNTPD;
 use strict;
 use warnings;
-use fields qw(groups err out);
 
 sub new {
        my ($class) = @_;
-       my $self = fields::new($class);
-       $self->{groups} = {};
-       $self;
+       bless {
+               groups => {},
+               err => \*STDERR,
+               out => \*STDOUT,
+               grouplist => [],
+       }, $class;
 }
 
-sub refresh_groups {
+sub refresh_groups () {
        my ($self) = @_;
-       require PublicInbox::Config;
        my $pi_config = PublicInbox::Config->new;
        my $new = {};
+       my @list;
        foreach my $k (keys %$pi_config) {
                $k =~ /\Apublicinbox\.([^\.]+)\.mainrepo\z/ or next;
                my $g = $1;
                my $git_dir = $pi_config->{$k};
-               my $address = $pi_config->{"publicinbox.$g.address"};
-               my $ng = PublicInbox::NewsGroup->new($g, $git_dir, $address);
+               my $addr = $pi_config->{"publicinbox.$g.address"};
+               my $ngname = $pi_config->{"publicinbox.$g.newsgroup"};
+               if (defined $ngname) {
+                       next if ($ngname eq ''); # disabled
+                       $g = $ngname;
+               }
+               my $ng = PublicInbox::NewsGroup->new($g, $git_dir, $addr);
                my $old_ng = $self->{groups}->{$g};
 
-               # Reuse the old one if possible since it can hold references
-               # to valid mm and gcf objects
+               # Reuse the old one if possible since it can hold
+               # references to valid mm and gcf objects
                if ($old_ng) {
                        $old_ng->update($ng);
                        $ng = $old_ng;
                }
 
-               # Only valid if Msgmap works
-               $new->{$g} = $ng if $ng->mm;
+               # Only valid if msgmap and search works
+               if ($ng->usable) {
+                       $new->{$g} = $ng;
+                       push @list, $ng;
+               }
        }
+       @list = sort { $a->{name} cmp $b->{name} } @list;
+       $self->{grouplist} = \@list;
        # this will destroy old groups that got deleted
        %{$self->{groups}} = %$new;
-};
+}
 
 1;