Skip to content

Commit

Permalink
New INN::ovsqlite_client Perl module
Browse files Browse the repository at this point in the history
INN::ovsqlite_client permits accessing an ovsqlite overview database
through ovsqlite-server from a Perl script.

This module provides search, add, remove and expire functions for
information stored in an ovsqlite database (newsgroups and overview
data associated to articles in these newsgroups).

Many thanks to Bo Lindbergh for it!  That's a great and useful work.

Two samples are also provided in the contrib directory (ovsqlite-dump
and ovsqlite-undump) to show how to use the module.
  • Loading branch information
Julien-Elie committed Dec 23, 2023
1 parent 5207ccd commit c31453f
Show file tree
Hide file tree
Showing 11 changed files with 1,598 additions and 4 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@
/contrib/mlockfile
/contrib/newsresp
/contrib/nnrp.access2readers.conf
/contrib/ovsqlite-dump
/contrib/ovsqlite-undump
/contrib/pullart
/contrib/reset-cnfs
/contrib/respool
Expand Down
4 changes: 4 additions & 0 deletions MANIFEST
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ contrib/mlockfile.c Lock files into memory using mlock
contrib/mm_ckpasswd Check passwords against Mailman db
contrib/newsresp.c Measure responsiveness of remote server
contrib/nnrp.access2readers.conf.in Convert nnrp.access file to readers.conf
contrib/ovsqlite-dump.in Dump the contents of an ovsqlite database
contrib/ovsqlite-undump.in Restore an ovsqlite database from a dump
contrib/pullart.c Recover articles from cyclic buffers
contrib/reset-cnfs.c Reset the state parts of a CNFS buffer
contrib/respool.c Respool articles in the storage manager
Expand Down Expand Up @@ -122,6 +124,7 @@ doc/hook-python Python hook notes
doc/man nroff documentation (Directory)
doc/man/INN__Config.3pm Manpage for INN::Config Perl module
doc/man/INN__Utils__Shlock.3pm Manpage for INN::Utils::Shlock Perl module
doc/man/INN__ovsqlite_client.3pm Manpage for INN::ovsqlite_client module
doc/man/Makefile Makefile for nroff documentation
doc/man/active.5 Manpage for active database
doc/man/active.times.5 Manpage for active.times file
Expand Down Expand Up @@ -663,6 +666,7 @@ perl/INN INN Perl modules (Directory)
perl/INN/Config.pm.in INN::Config module
perl/INN/Utils INN::Utils Perl modules (Directory)
perl/INN/Utils/Shlock.pm.in INN::Utils::Shlock module
perl/INN/ovsqlite_client.pm INN::ovsqlite_client module
perl/Makefile Makefile for perl libraries
readme.pod Master file for README
samples Prototype INN config files (Directory)
Expand Down
5 changes: 4 additions & 1 deletion contrib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ ALL = analyze-traffic archivegz authmysql auth_pass backlogstat \
cleannewsgroups count_overview delayer expirectl \
findreadgroups fixhist innconfcheck makeexpctl makestorconf \
mkbuf mlockfile newsresp \
nnrp.access2readers.conf pullart reset-cnfs respool \
nnrp.access2readers.conf ovsqlite-dump ovsqlite-undump \
pullart reset-cnfs respool \
stathist thdexpire \
tunefeed

Expand Down Expand Up @@ -59,6 +60,8 @@ makestorconf: makestorconf.in $(FIXSCRIPT) ; $(FIX) makestorconf.in
mkbuf: mkbuf.in $(FIXSCRIPT) ; $(FIX) -i mkbuf.in
nnrp.access2readers.conf: nnrp.access2readers.conf.in $(FIXSCRIPT)
$(FIX) -i nnrp.access2readers.conf.in
ovsqlite-dump: ovsqlite-dump.in $(FIXSCRIPT) ; $(FIX) ovsqlite-dump.in
ovsqlite-undump: ovsqlite-undump.in $(FIXSCRIPT) ; $(FIX) ovsqlite-undump.in
stathist: stathist.in $(FIXSCRIPT) ; $(FIX) -i stathist.in
thdexpire: thdexpire.in $(FIXSCRIPT) ; $(FIX) thdexpire.in
tunefeed: tunefeed.in $(FIXSCRIPT) ; $(FIX) -i tunefeed.in
11 changes: 11 additions & 0 deletions contrib/README
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,17 @@ nnrp.access2readers.conf
Converts an old-style nnrp.access file to readers.conf format.
(readers.conf replaced nnrp.access, starting with INN 2.3.0.)

ovsqlite-dump

Dumps the contents of an ovsqlite overview database (groups and overview
data of articles in these groups), using INN::ovsqlite_client.

ovsqlite-undump

Creates groups and overview data for articles in these groups in an
ovsqlite overview database, from a dump previously generated with the
ovsqlite-dump script.

pullart

Attempts to pull news articles out of CNFS cycbuffs. Useful for
Expand Down
108 changes: 108 additions & 0 deletions contrib/ovsqlite-dump.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
#! /usr/bin/perl -w
# fixscript will replace this line with code to load INN::Config

## Example of use of INN::ovsqlite_client to dump the contents of an ovsqlite
## overview database (groups and overview data of articles in these groups).
##
## Progress and errors are written to STDERR, and data to STDOUT.
## Run for instance:
## ovsqlite-dump > dump
##
## Lines beginning with "g" in the output correspond to overview information
## about groups, whereas lines beginning with "a" correspond to the overview
## data of articles.
##
## Sample written by Bo Lindbergh in December 2023.

use strict;
use warnings;

use INN::ovsqlite_client qw(:all);

sub dump_articles {
my ($sock, $dst, $groupname) = @_;
my ($code, $errmsg, $low, $articles);
my ($count);

print STDERR $groupname, "... ";
$count = 0;
$low = 1;
for (;;) {
$code = $sock->search_group(
groupname => $groupname,
low => $low,
cols => search_col_arrived | search_col_expires
| search_col_token | search_col_overview,
readsize => 0xFFFFF,
articles => $articles,
errmsg => $errmsg
);
defined($errmsg)
and die "search_group: $errmsg";
$code != response_artlist && $code != response_artlist_done
and die "search_group: Unexpected response code $code";
foreach my $article (@{$articles}) {
print $dst join(
"\t",
"a",
@{$article}{qw(artnum arrived expires)},
'@' . unpack("H*", $article->{token}) . '@',
$article->{overview}
);
$count++;
}
$code == response_artlist_done
and last;
$low = $articles->[-1]->{artnum} + 1;
}
print STDERR $count, "\n";
}

sub dump_groups {
my ($sock, $dst) = @_;
my ($code, $errmsg, $groupid, $groups);

$groupid = 0;
for (;;) {
$code = $sock->list_groups(
groupid => $groupid,
groups => $groups,
errmsg => $errmsg
);
defined($errmsg)
and die "list_groups: $errmsg";
$code != response_grouplist && $code != response_grouplist_done
and die "list_groups: Unexpected response code $code\n";
foreach my $group (@{$groups}) {
print $dst (
join(
"\t",
"g",
@{$group}{qw(groupname low high count flag_alias)}
),
"\n"
);
dump_articles($sock, $dst, $group->{groupname});
}
last if $code == response_grouplist_done;
}
}

sub server_connect {
my ($mode) = @_;

foreach my $leaf (qw(ovsqlite.sock ovsqlite.port)) {
my ($path);

$path = "$INN::Config::pathrun/$leaf";
if (-e $path) {
return INN::ovsqlite_client::->new(
path => $path,
mode => $mode
);
}
}
die "No ovsqlite-server running?";
}

dump_groups(server_connect(0), \*STDOUT);
97 changes: 97 additions & 0 deletions contrib/ovsqlite-undump.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#! /usr/bin/perl -w
# fixscript will replace this line with code to load INN::Config

## Example of use of INN::ovsqlite_client to create groups and overview data
## for articles in these groups in an ovsqlite overview database, from a dump
## previously generated with the ovsqlite-dump script.
##
## Progress and errors are written to STDERR, and data is read from STDIN.
## Run for instance:
## ovsqlite-undump < dump
##
## Already existing articles in your ovsqlite database will be reported as
## an error.
##
## Sample written by Bo Lindbergh in December 2023.

use strict;
use warnings;

use INN::ovsqlite_client qw(:all);

sub undump_all {
my ($sock, $src) = @_;
my ($code, $errmsg, $lastname, $count);

$count = 0;
while (defined(my $line = readline($src))) {
if ($line =~ /^g/) {
my ($groupname, $low, $high, $flag_alias);

chomp $line;
(undef, $groupname, $low, $high, undef, $flag_alias)
= split(/\t/, $line);
$code = $sock->add_group(
groupname => $groupname,
low => $low,
high => $high,
flag_alias => $flag_alias,
errmsg => $errmsg
);
defined($errmsg)
and die "add_group($groupname): $errmsg";
if (defined($lastname)) {
print STDERR $count, "\n";
}
print STDERR $groupname, "... ";
$lastname = $groupname;
$count = 0;
} elsif ($line =~ /^a/) {
my ($artnum, $arrived, $expires, $token, $overview);

defined($lastname)
or die "$.: Bad input";
(undef, $artnum, $arrived, $expires, $token, $overview)
= split(/\t/, $line, 6);
$token =~ /^\@[0-9A-Za-z]{36}\@$/
or die "$.: Bad input";
$token = pack("H*", substr($token, 1, 36));
$code = $sock->add_article(
groupname => $lastname,
artnum => $artnum,
token => $token,
arrived => $arrived,
expires => $expires,
overview => $overview,
errmsg => $errmsg
);
defined($errmsg)
and die "add_article($lastname,$artnum): $errmsg";
$count++;
} else {
die "$.: Bad input";
}
}
if (defined($lastname)) {
print STDERR $count, "\n";
}
}

sub server_connect {
my ($mode) = @_;

foreach my $leaf (qw(ovsqlite.sock ovsqlite.port)) {
my ($path);

$path = "$INN::Config::pathrun/$leaf";
if (-e $path) {
return INN::ovsqlite_client::->new(
path => $path,
mode => $mode
);
}
}
die "No ovsqlite-server running?";
}

undump_all(server_connect(1), \*STDIN);
10 changes: 10 additions & 0 deletions doc/pod/news.pod
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@ previous releases, that number was ten times the value of I<icdsynccount>.)

=item *

Added the C<INN::ovsqlite_client> Perl module to access an ovsqlite overview
database through B<ovsqlite-server> from a Perl script. This module provides
search, add, remove and expire functions for information stored in an ovsqlite
database (newsgroups and overview data associated to articles in these
newsgroups). Many thanks to Bo Lindbergh for it, as well as for two samples
in the F<contrib> directory (B<ovsqlite-dump> and B<ovsqlite-undump>) showing
how to use the module.

=item *

B<innreport> now supports high-precision timestamps like
C<2023-07-29T04:15:01.889064+02:00> that syslog can be parameterized to use;
daily Usenet reports otherwise indicated all these logs as unknown entries,
Expand Down
6 changes: 5 additions & 1 deletion doc/pod/ovsqlite-server.pod
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ overview database. B<ovsqlite-server> is normally invoked automatically by
B<rc.news> when starting the news system. It is also stopped automatically by
B<rc.news> when stopping the news system.

In case you need to talk to this daemon from Perl, the binary protocol used to
communicate with it has been implemented in the C<INN::ovsqlite_client> Perl
module. See its manual page for more information about its possibilities.

=head1 OPTIONS

=over 4
Expand Down Expand Up @@ -68,6 +72,6 @@ Initial implementation of ovsqlite written by Bo Lindbergh

=head1 SEE ALSO

ovsqlite(5), rc.news(8).
INN::ovsqlite_client(3pm), ovsqlite(5), rc.news(8).

=cut
Loading

0 comments on commit c31453f

Please sign in to comment.