#! /bin/sh
. /usr/lib/innshellvars

##  Script to execute checkgroups text; results to stdout.
##
##  Usage: docheckgroups [-u] [include-pattern [exclude-pattern]] < message
##
##  If the -u flag is given, the newsgroups descriptions are automatically
##  updated.

T=${TMPDIR}
UPDATEDESC=false

cat /dev/null >${T}/$$out

##  Parse arguments.
if [ $# -gt 0 ]; then
    case $1 in
    -u)
        shift
        UPDATEDESC=true
        ;;
    esac
fi

##  Copy the message without excluded newsgroups and append local newsgroups.
cat | ${PERL} -e 'while (<STDIN>) { my @fields = split();
          print $_ if ((scalar(@fields) > 0) && ($fields[0] !~ /'${2:-^#}'/)
              && ($fields[0] !~ /^#/)); }' >${T}/$$msg
test -f ${LOCALGROUPS} && cat ${LOCALGROUPS} | ${EGREP} -v "^#" >>${T}/$$msg

##  Exit if there is no matching newsgroup (otherwise docheckgroups is eager
##  to delete everything).
test -s ${T}/$$msg || {
    rm -f ${T}/$$*
    exit 0
}

##  Make sure we do not have duplicates in the resulting concatenation of
##  the checkgroups and the localgroups file.
${SORT} -u ${T}/$$msg >${T}/$$msg2
mv -f ${T}/$$msg2 ${T}/$$msg

##  Get the top-level newsgroup names from the message and turn it into
##  a regexp.
PATS=$(${SED} <${T}/$$msg \
    -e 's/[ 	].*//' -e 's/\..*//' \
    -e 's/^!//' -e '/^$/d' \
    -e 's/^/^/' -e 's/$/[\.\w]/' \
    | ${SORT} -u \
    | (
        tr '\012' '|'
        echo ''
    ) \
    | ${SED} -e 's/|$//')

##  Check for missing and obsolete newsgroups in active.
cat ${ACTIVE} | ${PERL} -e 'while (<STDIN>) { my @fields = split();
    print $fields[0]."\n" if ((scalar(@fields) > 0) && ($fields[0] =~ /'${1:-.}'/)
        && ($fields[0] =~ /'${PATS}'/)); }' | ${SORT} >${T}/$$active
cat ${T}/$$msg | ${PERL} -e 'while (<STDIN>) { my @fields = split();
    print $fields[0]."\n" if ((scalar(@fields) > 0) && ($fields[0] =~ /'${1:-.}'/)
        && ($fields[0] =~ /'${PATS}'/)); }' | ${SORT} >${T}/$$newsgrps

comm -13 ${T}/$$active ${T}/$$newsgrps >${T}/$$missing
comm -23 ${T}/$$active ${T}/$$newsgrps >${T}/$$remove

##  Check for proper moderation flags in active (we need to be careful
##  when dealing with wire-formatted articles manually fed from the spool).
cat ${ACTIVE} | ${PERL} -e 'while (<STDIN>) { my @fields = split();
    print $fields[0]."\n" if ((scalar(@fields) > 0) && ($fields[0] =~ /'${1:-.}'/)
        && ($fields[0] =~ /'${PATS}'/) && ($_ =~ / m$/)); }' | ${SORT} >${T}/$$amod.all
cat ${T}/$$msg | ${PERL} -e 'while (<STDIN>) { my @fields = split();
    print $fields[0]."\n" if ((scalar(@fields) > 0) && ($fields[0] =~ /'${1:-.}'/)
        && ($fields[0] =~ /'${PATS}'/) && ($_ =~ / \(Moderated\)\r?$/)); }' \
    | ${SORT} >${T}/$$ng.mod

comm -12 ${T}/$$missing ${T}/$$ng.mod >${T}/$$add.mod
comm -23 ${T}/$$missing ${T}/$$ng.mod >${T}/$$add.unmod
cat ${T}/$$add.mod ${T}/$$add.unmod >>${T}/$$add

comm -23 ${T}/$$amod.all ${T}/$$remove >${T}/$$amod
comm -13 ${T}/$$ng.mod ${T}/$$amod >${T}/$$ismod
comm -23 ${T}/$$ng.mod ${T}/$$amod >${T}/$$nm.all
comm -23 ${T}/$$nm.all ${T}/$$add >${T}/$$notmod

##  Check for missing and obsolete newsgroups descriptions (possibly
##  in wire format).  A few sed implementations do not recognize
##  "[	]\+", so we use "	[	]*" instead.
cat ${NEWSGROUPS} | ${PERL} -e 'while (<STDIN>) { my @fields = split();
    print $_ if ((scalar(@fields) > 0) && ($fields[0] =~ /'${1:-.}'/)
        && ($fields[0] =~ /'${PATS}'/)); }' \
    | ${SED} 's/	[	]*/	/' | ${SORT} >${T}/$$localdesc
cat ${T}/$$msg | ${PERL} -e 'while (<STDIN>) { my @fields = split();
    print $_ if ((scalar(@fields) > 0) && ($fields[0] =~ /'${1:-.}'/)
        && ($fields[0] =~ /'${PATS}'/)); }' \
    | ${SED} 's/\r\?$//' \
    | ${SED} 's/	[	]*/	/' | ${SORT} >${T}/$$newdesc

comm -13 ${T}/$$localdesc ${T}/$$newdesc >${T}/$$missingdesc
comm -23 ${T}/$$localdesc ${T}/$$newdesc >${T}/$$removedesc

##  If the -u flag is given, update the newsgroups descriptions.
if [ "${UPDATEDESC}" = "true" ]; then
    cat ${NEWSGROUPS} | ${PERL} -e 'while (<STDIN>) { my @fields = split();
        print $_ if ((scalar(@fields) > 0) && ($fields[0] !~ /'${PATS}'/)); }' \
        >${T}/$$updatednewsgroups
    cat ${NEWSGROUPS} | ${PERL} -e 'while (<STDIN>) { my @fields = split();
        print $_ if ((scalar(@fields) > 0) && ($fields[0] !~ /'${1:-.}'/)
        && ($fields[0] =~ /'${PATS}'/)); }' \
        >>${T}/$$updatednewsgroups
    cat ${T}/$$newdesc >>${T}/$$updatednewsgroups
    mv -f ${NEWSGROUPS} ${NEWSGROUPS}.old
    ${SORT} ${T}/$$updatednewsgroups | ${SED} 's/	[	]*/	/' \
        | ${PERL} -e 'while (<STDIN>) { my @fields = split("\t", $_, 2);
            next if (scalar(@fields) == 0);
            my $length = length("$fields[0]");
            my $desc;
            if (scalar(@fields) == 2) { $desc = "$fields[1]"; } else { $desc = ""; }
            if ($length < 8) { print $fields[0]."\t\t\t".$desc; }
            elsif ($length < 16) { print $fields[0]."\t\t".$desc; }
            else { print $fields[0]."\t".$desc; } }' >${NEWSGROUPS}
    chmod 0664 ${NEWSGROUPS} ${NEWSGROUPS}.old
fi

##  Display information on newsgroups which need to be removed/added/changed.
if [ -s ${T}/$$remove ]; then
    (
        echo "# The following newsgroups are non-standard and should be removed:"
        echo "#"
        ${SED} "s/^/#	/" ${T}/$$remove
        echo "#"
        echo "# You can remove them by executing the command(s):"
        echo ""
        for i in $(cat ${T}/$$remove); do
            echo "	${PATHBIN}/ctlinnd rmgroup $i"
        done
        echo ""
    ) >>${T}/$$out
fi

if [ -s ${T}/$$add ]; then
    (
        echo "# The following newsgroups are missing and should be added:"
        echo "#"
        ${SED} "s/^/#	/" ${T}/$$add
        echo "#"
        echo "# You can add them by executing the command(s):"
        echo ""
        for i in $(cat ${T}/$$add.unmod); do
            echo "	${PATHBIN}/ctlinnd newgroup $i y ${FROM}"
        done
        for i in $(cat ${T}/$$add.mod); do
            echo "	${PATHBIN}/ctlinnd newgroup $i m ${FROM}"
        done
        echo ""
    ) >>${T}/$$out
fi

if [ -s ${T}/$$ismod ]; then
    (
        echo "# The following newsgroups are incorrectly marked as moderated"
        echo "# and should have their status changed:"
        echo "#"
        ${SED} "s/^/#	/" ${T}/$$ismod
        echo "#"
        echo "# You can correct this by executing the command(s):"
        echo ""
        for i in $(cat ${T}/$$ismod); do
            echo "	${PATHBIN}/ctlinnd changegroup $i y"
        done
        echo ""
    ) >>${T}/$$out
fi

if [ -s ${T}/$$notmod ]; then
    (
        echo "# The following newsgroups are incorrectly marked as unmoderated"
        echo "# and should have their status changed:"
        echo "#"
        ${SED} "s/^/#	/" ${T}/$$notmod
        echo "#"
        echo "# You can correct this by executing the command(s):"
        echo ""
        for i in $(cat ${T}/$$notmod); do
            echo "	${PATHBIN}/ctlinnd changegroup $i m"
        done
        echo ""
    ) >>${T}/$$out
fi

##  Display information on descriptions which need to be removed/added.
if [ -s ${T}/$$removedesc ]; then
    (
        echo "# The following newsgroups descriptions are obsolete and should be removed:"
        echo "#"
        ${SED} "s/^/#	/" ${T}/$$removedesc
        echo "#"
        if [ "${UPDATEDESC}" = "true" ]; then
            echo "# The file ${NEWSGROUPS} has just been updated accordingly."
        else
            echo "# You can remove them by editing ${NEWSGROUPS}"
            echo "# or by using the -u flag with docheckgroups."
        fi
        echo ""
    ) >>${T}/$$out
fi

if [ -s ${T}/$$missingdesc ]; then
    (
        echo "# The following newsgroups descriptions are missing and should be added:"
        echo "#"
        ${SED} "s/^/#	/" ${T}/$$missingdesc
        echo "#"
        if [ "${UPDATEDESC}" = "true" ]; then
            echo "# The file ${NEWSGROUPS} has just been updated accordingly."
        else
            echo "# You can add them by editing ${NEWSGROUPS}"
            echo "# or by using the -u flag with docheckgroups."
        fi
        echo ""
    ) >>${T}/$$out
fi

##  We're done.
test -s ${T}/$$out && {
    cat ${T}/$$out
    echo "exit # so you can feed this message into the shell (as well as mod-active)."
    echo ""
}

rm -f ${T}/$$*
