Newsgroups: alt.sources From: Olaf Titz Subject: gup4cnews - Converter between C News sys file and gup lists Organization: private Linux site, southern Germany Archive-Name: gup4cnews Submitted-By: Olaf Titz Environment: cnews, perl, unix Here are some scripts to maintain the C News sys file from gup lists and to convert between these formats. Written by Olaf Titz , Summer 1995. Public Domain. #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'gup4cnews/README' <<'END_OF_FILE' XThis is a set of small scripts I use to convert between the C News X"sys" file and the subscription lists used by "gup". In the form Xposted here, they are used to maintain a "changesys" and a "gup" Xsystem on a C News mill at once (there are UAs that directly generate Xchangesys requests, so there actually is a reason to still support Xit). X X! ! X! Do not experiment with this stuff without backing up your sys file! ! X! Try to understand how it works first! ! X! ! X XThe data flow for the complete system is as follows (all files Xunder /var/lib/news): X X chsys/sys gup/sites/*/groups X | | X |sys2feeds | X |splitfeeds v X +-------------> feeds/* feeds.excl X |makesys.pl | X hierarchies |<---------------+ X | sys.prot |feeds2sys X | | v X +-->+----------------> sys X XInput: X chsys/sys - the "sys" file for changesys (note that changesys X doesn't use the real sys file here!) X gup/sites/*/groups - the gup subscription files X sys.prot - contains entries that will go into the sys file unchanged X (where I feed all/all anyway, etc.) X feeds.excl - exclusions (lines like: uunet.uu.net/uunet) (optional) X hierarchies - list of hierarchies we accept (one at a line) X XOutput: X feeds/* - temporary gup lists. For removing a site, delete its file here X sys - ready to use for C News, don't edit X XAll that is driven by the "makesys" shell script. This one is really Xnot beautiful but simple enough to easily be customized. It assumes Xthe scripts live in "localbin". X XPrograms: X sys2feeds - Convert a sys file into a set of gup lists (perl) X feeds2sys - Convert a gup list to a sys file entry (perl) X splitfeeds - Split the result of sys2feeds into individual files (perl) X makesys.pl - Build a sys file from a set of gup files (perl) X makesys - glue to call everything else (sh) X(perl is perl 4 here.) X XThe most important thing are probably the feeds2sys and sys2feeds perl Xscripts, which convert between "sys file" and "gup groups file" Xformat. Caveat: the languages employed in these files are not Xequivalent and certain constructs can't be converted. If the usage of X"all" and "*" wildcarding is limited to the end of a pattern in both Xformats, the conversion does succeed. (Educate your users!) The Xpatterns generated by repeated conversion look over-verbose but they Xdo work, and more than two iterations do lead to a fixed point. X XWritten by Olaf Titz , Summer 1995. Public Domain. END_OF_FILE if test 2809 -ne `wc -c <'gup4cnews/README'`; then echo shar: \"'gup4cnews/README'\" unpacked with wrong size! fi # end of 'gup4cnews/README' fi if test -f 'gup4cnews/sys2feeds' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'gup4cnews/sys2feeds'\" else echo shar: Extracting \"'gup4cnews/sys2feeds'\" \(1429 characters\) sed "s/^X//" >'gup4cnews/sys2feeds' <<'END_OF_FILE' X#!/usr/bin/perl X# -*-perl-*- X X# Convert sys file entries to gup lists X X# sys file on std. input X# output is list of "# sysname", gup-list X Xrequire "getopts.pl"; X&Getopts("d"); X X# simplified sys file parser from "rebatch" Xwhile (<>) { X s/^\s+//; s/\s+$//; X /^$/ && next; /^\#/ && next; X $line = "" unless $cont; X $line .= $_; X $cont = $line=~s/\\$//; X if (!$cont) { X split(/:/, $line); X ($sys, $excl) = split(/\//, @_[0]); X next if ($sys eq "ME" || $sys eq $me); X ($groups, $distribs) = split(/\//, @_[1]); X $groups{$sys} = $groups ? $groups : "all"; X } X} X Xforeach $sys (sort keys %groups) { X print "# $sys\n"; X undef %S; X foreach $_ (split(",", $groups{$sys})) { X $a = s/^\!//; X $S{$_} = $a+1; # so 2 means negated X } X @S = sort keys %S; X foreach $i (0..$#S) { X $x0 = $x =$S[$i]; X $x0 || next; X $y0 = $y = $S[$i+1]; X $xs = ($S{$x}==2) ? "!" : ""; X $ys = ($S{$y}==2) ? "!" : ""; X print STDERR "$xs$x0,$ys$y0\n" if $opt_d; X X# a.b,!a.b.all -> a.b X if (("${x}.all" eq $y) && ($ys)) { X &emit("$x", 1); X $S[$i+1]=""; X next; X } X X# a.b.all -> a.b.* X# !a.b.all -> !a.b.* X if ($x0 =~ s/\.all$//) { X &emit("$xs$x0.*", 2); X next; X } X X# a.b -> a.b,a.b.* X# !a.b -> !a.b,!a.b.* X &emit("$xs$x\n$xs$x.*", 3); X next; X X die "Oops: no rule for $x,$y"; X } X} Xexit 0; X Xsub emit { X local($_,$z) = @_; X printf STDERR " %d -> %s\n", $z, $_ if $opt_d; X print "$_\n"; X} END_OF_FILE if test 1429 -ne `wc -c <'gup4cnews/sys2feeds'`; then echo shar: \"'gup4cnews/sys2feeds'\" unpacked with wrong size! fi chmod +x 'gup4cnews/sys2feeds' # end of 'gup4cnews/sys2feeds' fi if test -f 'gup4cnews/feeds2sys' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'gup4cnews/feeds2sys'\" else echo shar: Extracting \"'gup4cnews/feeds2sys'\" \(1839 characters\) sed "s/^X//" >'gup4cnews/feeds2sys' <<'END_OF_FILE' X#!/usr/bin/perl X# -*-perl-*- X X# Convert a gup list to a sys file entry X X# Call as: feeds2sys X# gup list on std. input X# emits a sys entry on std. output X X# Input syntax is limited to: X# line ::= ['!'] pattern X# pattern ::= {subpat} word [wild] X# subpat ::= {word '.'} X# wild ::= ['.'] '*' X Xrequire "getopts.pl"; X&Getopts("d"); X Xwhile () { X chop; X s/^\s+//; s/\s+$//; X /^$/ && next; /^\#/ && next; X /^t-netz/ && do { X $u=$_; X s/t-netz/z-netz.alt/; X $a=s/^\!//; $S{$_} = $a+1; X $_=$u; X }; X $a = s/^\!//; X $S{$_} = $a+1; # so 2 means negated X} X@S = sort keys %S; X$entry="inka"; # you'll always get... X$cols=6; X Xforeach $i (0..$#S) { X $x0 = $x =$S[$i]; X $x0 || next; X $y0 = $y = $S[$i+1]; X $xs = ($S{$x}==2) ? "!" : ""; X $ys = ($S{$y}==2) ? "!" : ""; X X print STDERR "$xs$x0,$ys$y0\n" if $opt_d; X X $x0=~s/\*$//; X $x0=~s/\.$//; X# a.b* -> a.b X# !a.b* -> !a.b X if ("${x0}*" eq $x) { X &emit("$xs$x0", 1); X next; X } X X# a.b.* -> a.b.all X# !a.b.* -> !a.b.all X if ("${x0}.*" eq $x) { X &emit("$xs$x0.all", 2); X next; X } X X $y0=~s/\.\*$//; X if ($y0 eq $x) { X# a.b,a.b.* -> a.b X if ($S{$y}==1) { X &emit("$x", 3); X } elsif ($xs) { X# !a.b,!a.b.* -> !a.b X &emit("!$x", 4); X } else { X# a.b,!a.b.* -> a.b,!a.b.all X &emit("$x,!$x.all", 5); X } X $S[$i+1]=""; X next; X } X X# a.b -> a.b,!a.b.all X# !a.b -> !a.b X if ($xs) { X &emit("!$x", 5); X } else { X &emit("$x,!$x.all", 6); X } X next; X X die "Oops: no rule for $x,$y"; X} X Xprintf "%s:\\\n %s/\\\n all,!local:%s:%s\n\n", X $ARGV[0], $entry, $ARGV[1], $ARGV[2]; Xexit 0; X Xsub emit { X local($_,$z) = @_; X printf STDERR " %d -> %s\n", $z, $_ if $opt_d; X $_=",".$_; X if (length($_)+$cols > 76) { X $entry.="\\\n "; X $cols=2; X } X $entry.=$_; X $cols+=length($_); X} END_OF_FILE if test 1839 -ne `wc -c <'gup4cnews/feeds2sys'`; then echo shar: \"'gup4cnews/feeds2sys'\" unpacked with wrong size! fi chmod +x 'gup4cnews/feeds2sys' # end of 'gup4cnews/feeds2sys' fi if test -f 'gup4cnews/splitfeeds' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'gup4cnews/splitfeeds'\" else echo shar: Extracting \"'gup4cnews/splitfeeds'\" \(196 characters\) sed "s/^X//" >'gup4cnews/splitfeeds' <<'END_OF_FILE' X#!/usr/bin/perl X X$lib="/var/lib/news"; Xopen(F, ">/dev/null") || die; X Xwhile() { X /^\# (.*)$/ && do { X open(F, ">$lib/feeds/$1") || die "open $lib/feeds/$1"; X next; X }; X print F; X} END_OF_FILE if test 196 -ne `wc -c <'gup4cnews/splitfeeds'`; then echo shar: \"'gup4cnews/splitfeeds'\" unpacked with wrong size! fi chmod +x 'gup4cnews/splitfeeds' # end of 'gup4cnews/splitfeeds' fi if test -f 'gup4cnews/makesys.pl' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'gup4cnews/makesys.pl'\" else echo shar: Extracting \"'gup4cnews/makesys.pl'\" \(497 characters\) sed "s/^X//" >'gup4cnews/makesys.pl' <<'END_OF_FILE' X#!/usr/bin/perl X Xchdir("/var/lib/news") || die "chdir"; X$spool="/var/spool/news"; X Xif (open(EX, ") { X chop; X ($s,$e) = split(/\//, $_, 2); X $excl{$s} = "/$e"; X } X close EX; X} X Xopen(SYS, ">sys.new") || die "open new"; Xprint SYS "\n# Feeds added by 'makesys'\n"; Xclose SYS; X Xopendir(FDIR, "feeds") || die "opendir feeds"; Xwhile($f=readdir(FDIR)) { X $f =~ /^\./ && next; X system "localbin/feeds2sys $f$excl{$f} f < feeds/$f >> sys.new"; X} Xclosedir FDIR; Xexit 0; END_OF_FILE if test 497 -ne `wc -c <'gup4cnews/makesys.pl'`; then echo shar: \"'gup4cnews/makesys.pl'\" unpacked with wrong size! fi chmod +x 'gup4cnews/makesys.pl' # end of 'gup4cnews/makesys.pl' fi if test -f 'gup4cnews/makesys' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'gup4cnews/makesys'\" else echo shar: Extracting \"'gup4cnews/makesys'\" \(933 characters\) sed "s/^X//" >'gup4cnews/makesys' <<'END_OF_FILE' X#!/bin/sh X X# =()<. ${NEWSCONFIG-@@}>()= X. ${NEWSCONFIG-/var/lib/news/bin/config} X XPATH=$NEWSCTL/bin:$NEWSBIN/maint:$NEWSBIN:$NEWSPATH ; export PATH Xumask $NEWSUMASK X Xif [ "$1" != "-islocked" ]; then X lock="$NEWSCTL/LOCK" X ltemp="$NEWSCTL/L.$$" X echo $$ >$ltemp X trap "rm \-f $ltemp ; exit 0" 0 1 2 15 X while true; do X if newslock $ltemp $lock; then X trap "rm \-f $ltemp $lock ; exit 0" 0 1 2 15 X break X fi X sleep 30 X done Xfi X Xcd /var/lib/news/gup/sites Xfor i in *; do X cp $i/groups /var/lib/news/feeds/$i Xdone X Xcd /var/lib/news Xlocalbin/sys2feeds sys.new+ Xperl -ne 'chop; print; print "," if (!eof)' hierarchies >> sys.new+ Xcat sys.prot sys.new >> sys.new+ Xrm -f sys && mv -f sys.new+ sys && rm -f sys.new X Xcd /var/lib/news/feeds Xfor i in *; do X [ -d /var/spool/news/out.going/$i ] || \ X mkdir /var/spool/news/out.going/$i Xdone END_OF_FILE if test 933 -ne `wc -c <'gup4cnews/makesys'`; then echo shar: \"'gup4cnews/makesys'\" unpacked with wrong size! fi chmod +x 'gup4cnews/makesys' # end of 'gup4cnews/makesys' fi echo shar: End of shell archive. exit 0 -- ___ Olaf.Titz@inka.de or @{stud,informatik}.uni-karlsruhe.de ____ __ o __/<_ >> Just as long as the wheels keep on turning round _)>(_)______________ I will live for the groove 'til the sun goes down << ____