--- /dev/null
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use DBI;
+
+my $dsn = $ENV{'DBI_DSN'};
+$dsn = 'dbi:Pg:dbname=news' unless defined $dsn;
+
+my $db = DBI->connect($dsn,'','',{AutoCommit => 0,RaiseError=>1});
+
+die unless $db;
+
+$db->do("set CLIENT_ENCODING to 'SQL_ASCII'");
+
+
+sub wildmat_to_re {
+ my ($wildmat) = @_;
+
+ $wildmat =~ s/\./\\\./g;
+ $wildmat =~ s/\?/\./g;
+ $wildmat =~ s/\*/\.\*/g;
+ return $wildmat;
+}
+
+sub wildmat {
+ my ($wildmat) = @_;
+
+ my @pats = split(/,/,$wildmat); # TODO look for escaped commas
+
+ my $sql = '';
+ # TODO special case '*' since it always matches
+
+ while ($pats[0] =~ /^!/) { shift @pats } # init neg can't match
+
+ my $negated;
+ foreach (@pats) {
+ $negated = s/^!//;
+ my $like = wildmat_to_re($_);
+ if (!$negated) {
+ $sql .= '|' . $like;
+ } else {
+ $sql =~ s/^\|//;
+ $sql = "(^(?!$like)($sql)\$)";
+ }
+ }
+ $sql =~ s/^\|//;
+ $sql = "^($sql)\$" unless $negated;
+ return $sql;
+}
+
+my ($peer, $feed, $port) = @ARGV;
+
+$feed = '*,!control,!junk' unless $feed;
+my $feedre = wildmat($feed);
+
+my $add = $db->prepare('insert into feeds (name) values (?)');
+my $setport = $db->prepare('update feeds set port = ? where name = ?');
+my $setfeed = $db->prepare('update feeds set wildmat = ?, wildmatre = ? where name = ?');
+my $exists = $db->prepare('select * from feeds where name = ?');
+
+$exists->execute($peer);
+
+if (!$exists->fetchrow_array) {
+ $add->execute($peer);
+};
+
+$setport->execute($port,$peer) if $port;
+$setfeed->execute($feed,$feedre,$peer) if $feed;
+
+$db->commit;
+$db->disconnect;
+
+__END__
+
+create table feeds (
+ host text primary key, -- TODO just make this a url? mailto:
+ port integer default 119,
+ enabled boolean not null default true,
+ stream boolean not null default false, -- use CHECK/TAKETHIS
+ groups text default '*', -- wildmat
+ wildmat text default '*',
+ wildmatre text default '.', -- parsed wildmat
+ noxposts text,
+ noxpostsre text,
+ distribution text,
+ distributionre text,
+ -- TODO feed moderated/unmoderated
+ -- see http://www.faqs.org/docs/linux_network/x18341.html
+ maxsize integer, -- maximum article size to feed
+ localonly boolean default false,
+ path text, -- regular expression default host?
+ frequency interval default '1 hour'::interval, -- int secs?
+ feedtime timestamp
+
+);
+