[comp.sources.misc] v17i016: Modified newgroup for c-news, Part01/01

news@iddth.dk (Nick Sandru) (02/24/91)

Submitted-by: Nick Sandru <news@iddth.dk>
Posting-number: Volume 17, Issue 16
Archive-name: newgroup/part01

	Modified 'newgroup' for c-news (patch level of 7-Sep-90)

			Nick Sandru, 1991

This is a modified 'newgroup' set, which allows the news administrator
to decide whether he/she wants or not to create a new group required
by a 'newgroup' control message. If the news administrator decides to
create the group, all the articles which may have come since the
'newgroup' control has been received are collected from 'junk' and
from the groups where they may have been cross-posted.

The modified 'newgroup' also prevents the unauthorized changing of
a group's moderated or unmoderated status.

I made these changes after beeing tired of removing bogus newsgroups
and restoring the status of some groups to moderated after some people
(not authorized to do that) had changed it to unmoderated.

USAGE:

The modified 'newgroup' mails any received 'newgroup' controls to the
news administrator (specified in 'config'), changing the 'Distribution:'
to 'local' and the 'Sender:' to the news adminstrator's e-mail address.
If you decide to create the group, save the message into a file and 
do the following:

1. Remove any lines inserted by the sendmail program before the
   'Message-Id:' line;
2. Check the 'Sender:' line - the address MUST be identical to the
   news admin's address sepcified in 'config' ($NEWSMASTER);
3. Feed the modified file into the news system by:

   inews -h file

The original 'Message-Id:' and 'Path:' lines are commented out by the
'newgroup' program before the message is mailed to the news admin.

The 'newgroup' is started by relaynews, collects the articles which are
newer than the 'newgroup' control message, updates the 'history' file and
rebuilds the 'history.*' database.

During the collection, no 'expire' can be performed - both the modified
'newgroup' and 'expire' copy the updated history file to a new file and
rebuild the history database. 'newgroup' sets the 'LOCKexpire' lock. If
an 'expire' is in progress, the 'newgroup' waits until it is finished.

The modified 'newgroup' calls the 'collng' (COLLect NewGroup) program to
do the collection of the articles for the new group. This program reads
the history file and, if the article is newer than the 'newgroup' control
message, checks the '^Newsgroups:' line. If the new group is present,
a link is made into the directory of the new group. At exit the 'collng'
program returns the number of the last article, which is used for updating
the 'active' file.

Install the modified 'newgroup' and get rid of problems!

Long Haired Nick.

----CUT-HERE----CUT-HERE----
#!/bin/sh
# This is a shell archive (shar 3.32)
# made 02/22/1991 21:11 UTC by news@ideal
# Source directory /tank2/news/cnews
#
# existing files WILL be overwritten
#
# This shar contains:
# length  mode       name
# ------ ---------- ------------------------------------------
#   5184 -rwxr-xr-x relay/ctl/newgroup
#   4002 -rw-r--r-- relay/collng.c
#    594 -rwxr-xr-x misc/newsboot
#   3176 -rw-r--r-- relay/makefile.patch
#
if touch 2>&1 | fgrep 'amc' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
# ============= relay/ctl/newgroup ==============
if test ! -d 'relay'; then
    echo "x - creating directory relay"
    mkdir 'relay'
fi
if test ! -d 'relay/ctl'; then
    echo "x - creating directory relay/ctl"
    mkdir 'relay/ctl'
fi
if test -f ./relay/ctl/newgroup ; then
    echo "renaming newgroup to newgroup.orig"
    mv ./relay/ctl/newgroup ./relay/ctl/newgroup.orig
fi
echo "x - extracting relay/ctl/newgroup (Text)"
sed 's/^X//' << 'SHAR_EOF' > relay/ctl/newgroup &&
X#! /bin/sh
X# newgroup group flag - create group (4-field version: B-2.10.3+ compatible)
X#	subject to our sys file group pattern
X#
X# Modified by Nick Sandru (also known as Long Haired Nick)
X#  Feb 22, 1991
X#
X# The new group is no more created automtically, but submitted to the
X#  approval of the news administrator.
X#
X# Usage:
X#  All newgroup controls are mailed to the news adminstrator.
X#  If you want to run the newgroup, do the following:
X#   - save the newgroup posting into a file (with headers);
X#   - remove any lines inserted by the mailer before the Message-Id:;
X#   - check the Sender: line and put the $NEWSMASTER there if
X#     necessary;
X#   - feed the file into the news system by
X#
X#	inews -h <file>
X#
X#   - the new group will be created and all the articles in the spool
X#     containing the new group in the Newsgroups: line are linked into
X#     the new group. The active file is updated.
X#   - the collection is resumed after a crash by the newsboot script.
X#
X
X# =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()=
X. ${NEWSCONFIG-/news/lib/bin/config}
Xexport NEWSCTL NEWSBIN NEWSARTS
XPATH=$NEWSCTL/bin:$NEWSBIN/relay:$NEWSBIN/expire:$NEWSBIN:$NEWSPATH
XPATH=$NEWSBIN/ctl:$NEWSBIN/input:$NEWSBIN/inject:$PATH
Xexport PATH
Xumask $NEWSUMASK
X
Xhdr=/tmp/nc$$
Xcontrol="$NEWSCTL/NGcontrol"
Xinplock="$NEWSCTL/LOCKinput"
Xnglock="$NEWSCTL/LOCKnewgroup"
Xexplock="$NEWSCTL/LOCKexpire"
Xltemp="$NEWSCTL/L.$$"
Xecho $$ >$ltemp
Xtrap "rm -f $hdr ${hdr}.a ${hdr}.m $ltemp ; exit 0" 0 1 2 15
X
Xif [ -f $control -a $# = 0 ]
Xthen
X	NEWGROUP=`grep '^Control: ' $control | cut -f3 -d\  -`
X	FLAG=`grep '^Control: ' $control | cut -f4 -d\  -`
X	cp $control ${hdr}.a
X	rm -f $control
X	BGFLAG=bg
Xelse
X	if [ $# = 0 ] ; then
X		exit 0		# exit if no parameters
X	fi
X	NEWGROUP=$1
X	FLAG=$2
X	BGFLAG=$3
X	if [ x$BGFLAG = xbg ] ; then
X		cp $4 ${hdr}.a
X		rm -f $4
X	else
X		cat >${hdr}.a
X	fi
Xfi
X
Xcanonhdr <${hdr}.a >$hdr
X
X# prepare the modified article to be posted to the news administrator
Xsed 's/Path: />Path: /' $hdr | sed '/^Distribution: /d' | sed '/^Sender: /d' | sed 's/^Message-I/>Message-I/' > ${hdr}.m
Xecho "Distribution: local" >> ${hdr}.m
Xecho "Sender: $NEWSMASTER" >> ${hdr}.m
Xecho >> ${hdr}.m
Xsed '1,/^$/d' ${hdr}.a >> ${hdr}.m
X
X# unapproved ctl msg? then quit
Xgrep -s '^Approved:' $hdr >/dev/null || { rm -f $hdr; exit 0; }
X
XSENDER="`grep '^Sender:' $hdr | sed 's/^[^:]*: *//' | cut -f1 -d\( `"
Xcase "$SENDER" in
X"")	SENDER="`grep '^From:' $hdr | sed 's/^[^:]*: *//' | cut -f1 -d\( `" ;;
Xesac
XSENDER=`echo $SENDER`
X
Xgreppat="^`echo $NEWGROUP | sed 's/\./\\\\./g' ` "
Xif grep -s "$greppat" $NEWSCTL/active >/dev/null; then	# group exists?
X	export SENDER
X	if [ "$SENDER" = "$NEWSMASTER" ] ; then
X		chamod "$NEWGROUP" "$FLAG" 		# change moderated flag if needed
X		exit
X	else
X		mail $NEWSMASTER < ${hdr}.m
X		exit
X	fi
Xfi
X
Xme="`newshostname`"
Xgngppat=`awk -f $NEWSBIN/relay/canonsys.awk $NEWSCTL/sys |
X	egrep "^($me|ME):" |
X	awk -F: '
X{
X	fields = split($FLAG, field2, "/")	# split ngs/dists
X	print field2[1]			# print only ngs
X	exit
X}' `
X
Xif gngp -a "$gngppat" >/dev/null <<!
X$NEWGROUP
X!
Xthen			# no group in active, but sys file likes it: make it
X	if [ "$SENDER" = "$NEWSMASTER" ]
X	then
X		case "$FLAG" in
X		moderated)	flag=m ;;
X		*)		flag=y ;;
X		esac
X		# release the relaynews locks by starting 'newgroup'
X		#  in the background
X		if [ x$BGFLAG != xbg ]
X		then
X			cp ${hdr}.a $NEWSCTL/NG.$$
X			newgroup $1 $flag bg $NEWSCTL/NG.$$ &
X			exit 0
X		fi
X		rmlist="$hdr ${hdr}.a ${hdr}.m $ltemp"
X		trap "rm -f $rmlist ; exit 0" 0 1 2 15
X		# lock the database; wait first for running 'newgroup',
X		#  'expire' and 'newsrun' to terminate
X		for lock in $nglock $explock $inplock $NEWSCTL/LOCK
X		do
X			while [ `newslock $ltemp $lock ; echo $?` != 0 ]
X			do
X				sleep 30
X			done
X			rmlist="$rmlist $lock"
X			trap "rm -f $rmlist ; exit 0" 0 1 2 15
X		done
X		# make a control file for resume after crash
X		cp ${hdr}.a $control
X		# make the directory since rn will bitch if it's missing
X		mkpdir $NEWSARTS/`echo $NEWGROUP | tr . / `
X		# get the date of the newgroup message (do not collect
X		# articles older than that)
X		DATE=`grep '^Date: ' $hdr | sed 's/Date: //'`
X		DATE=`getdate "$DATE"`
X		# collect articles for the new group from 'junk' and
X		# from other groups
X		collng $NEWGROUP $NEWSARTS $NEWSCTL/history $NEWSCTL/history.n $DATE
X		exit_code=$?	# get the number of the last article
X		zeroes=000000000
X		nines=9
X		while [ 1 ]	# add leading zeroes to the number
X		do
X			if [ `expr $exit_code` -le $nines ]
X			then
X				break
X			else
X				zeroes=`echo $zeroes | cut -c2- -`
X				nines="${nines}9"
X			fi
X		done
X		echo "$NEWGROUP ${zeroes}${exit_code} 0000000001 $flag" >>$NEWSCTL/active
X		(echo "$NEWGROUP `getdate now` $SENDER" >>$NEWSCTL/active.times)  # rn hook
X		if [ $exit_code = 0 ]
X		then
X			# no changes in history, delete the new file
X			rm -f $NEWSCTL/history.n
X		else
X			mv $NEWSCTL/history $NEWSCTL/history.o
X			mv $NEWSCTL/history.n $NEWSCTL/history
X			mkdbm $NEWSCTL/history	# remake the history database
X		fi
X		rm -f $control		# remove the control file
X		echo "newsgroup $NEWGROUP was created by $SENDER." | mail $NEWSMASTER
X	else	# sender not the news adm - mail the article
X		mail $NEWSMASTER < ${hdr}.m
X	fi
Xfi
SHAR_EOF
$TOUCH -am 0222220991 relay/ctl/newgroup &&
chmod 0755 relay/ctl/newgroup ||
echo "restore of relay/ctl/newgroup failed"
set `wc -c relay/ctl/newgroup`;Wc_c=$1
if test "$Wc_c" != "5184"; then
	echo original size 5184, current size $Wc_c
fi
# ============= relay/collng.c ==============
echo "x - extracting relay/collng.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > relay/collng.c &&
X/*
X * Collng - collect articles for a new group
X *
X * written by Nick Sandru (also known as Long Haired Nick)
X * Feb 22, 1991
X *
X * Collng is executed from newgroup shell script in order to collect
X *  articles for a new group. It reads the Newsgroups: line from every
X *  article in the news spool, makes a link to the new group if necessary
X *  and produces a new history file.
X * Collng returns the number of the last article in the new group
X *  which is used by the newgroup script for updating the active file
X */
X#include<stdio.h>
X#include<string.h>
X#define TRUE -1
X#define FALSE 0
X/*
X * history file fields
X */
Xchar *mess_id;		/* message identifier */
Xchar *times;		/* time stamps */
Xchar *art_list;		/* list of articles */
X/*
X * buffers
X */
Xchar in_line[1024];	/* input buffer */
Xchar out_line[1024];	/* output buffer */
X/*
X * stuff related to articles
X */
Xchar *ng_art;		/* group and article number */
Xchar *ng_list;		/* Newsgroups: list */
Xchar *newsgroup;	/* element in the newsgroups list */
Xchar *newgroup;
XFILE *article;
XFILE *history;
XFILE *history_n;
Xchar *spool_dir;
Xchar art_line[1024];
Xchar art_name[1024];
Xchar new_art_name[1024];
Xint oldest_article;	/* don't collect articles older than that */
Xint i;
Xint file_flg;		/* file exists */
Xint ignore;		/* ignore article flag */
Xint art_nr;		/* article number */
Xint art_time;		/* article time stamp */
X
Xmake_name(buffer, art)	/* make a file name (incl. path) from group/article */
Xchar *buffer, *art;
X{
X  int i;
X
X  sprintf(buffer, "%s/%s", spool_dir, art);
X  for (i = strlen(spool_dir); i < strlen(buffer); i++)
X   if (buffer[i] == '.') buffer[i] = '/';
X}
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X  if ((history = fopen(argv[3],"r")) == NULL) exit(0);
X  if ((history_n = fopen(argv[4],"w")) == NULL) exit(0);
X  art_nr = 0;
X  newgroup = argv[1];
X  spool_dir = argv[2];
X  sscanf(argv[5], "%d", &oldest_article);
X  while(fgets(in_line, 1024, history) != NULL)
X  {
X   strtok(in_line, "\n");
X   file_flg = FALSE;
X   ignore = FALSE;
X   mess_id = strtok(in_line, "\t");	/* pointer to the message-id */
X   times = strtok(NULL, "\t");		/* pointer to time stamps */
X   sscanf(times, "%d", &art_time);
X   art_list = strtok(NULL, "\t");	/* pointer to the articles list */
X   sprintf(out_line, "%s\t%s", mess_id, times);	/* copy to output buffer */
X   ng_art = strtok(art_list, " ");	/* get the first article in list */
X   if (ng_art != NULL) strcat(out_line, "\t");
X   while(ng_art != NULL)
X   {
X    if (strncmp(ng_art, "control/", strlen("control/")) == 0) ignore = TRUE;
X    if (oldest_article > art_time) ignore = TRUE;
X    if ( ! ignore)
X    {
X     make_name(art_name, ng_art);
X     if ( ! file_flg)
X     {
X      if ((article = fopen(art_name, "r")) != NULL)
X       file_flg = TRUE;
X      if (file_flg)			/* read the Newsgroups: line */
X      {
X       while (fgets(art_line, 1024, article) != NULL)
X       {
X	if (strncmp(art_line, "Newsgroups: ", strlen("Newsgroups: ")) == 0)
X        {
X	 fclose(article);
X	 break;
X	}
X       }
X      }
X     }
X    }
X    strcat(out_line, ng_art);
X    ng_art = strtok(NULL, " ");
X    if (ng_art != NULL)
X     strcat (out_line, " ");
X   }
X   strtok(art_line, "\n");
X   ng_list = strtok(art_line, " ");
X   ng_list = strtok(NULL, " ");
X   newsgroup = strtok(ng_list, ",");
X   while (newsgroup != NULL)		/* look for the new group in the */
X   {					/*  Newsgroups: line		 */
X    if (strcmp(newgroup, newsgroup) == 0)
X    {
X     strcat(out_line, " ");		/* new group present in Newsgroups: */
X     art_nr++;				/*  put it in the history line and  */
X     sprintf(in_line, "%s/%d", newgroup, art_nr);
X     strcat(out_line, in_line);		/*  link it to the new directory    */
X     make_name(new_art_name, in_line);
X     i = link(art_name, new_art_name);
X     break;
X    }
X    newsgroup = strtok(NULL, ",");
X   }
X   fprintf(history_n, "%s\n", out_line); /* write the updated line in history */
X  }
X  fclose(history);
X  fclose(history_n);
X  exit(art_nr);		/* return the last article nr. for updating the active file */
X}
SHAR_EOF
$TOUCH -am 0222125791 relay/collng.c &&
chmod 0644 relay/collng.c ||
echo "restore of relay/collng.c failed"
set `wc -c relay/collng.c`;Wc_c=$1
if test "$Wc_c" != "4002"; then
	echo original size 4002, current size $Wc_c
fi
# ============= misc/newsboot ==============
if test ! -d 'misc'; then
    echo "x - creating directory misc"
    mkdir 'misc'
fi
if test -f ./misc/newsboot ; then
    echo "renaming newsboot to newsboot.orig"
    mv ./misc/newsboot ./misc/newsboot.orig
fi
echo "x - extracting misc/newsboot (Text)"
sed 's/^X//' << 'SHAR_EOF' > misc/newsboot &&
X#! /bin/sh
X# newsboot - clean up on reboot
X
X# =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()=
X. ${NEWSCONFIG-/news/lib/bin/config}
X
XPATH=$NEWSCTL/bin:$NEWSBIN:$NEWSPATH ; export PATH
Xumask $NEWSUMASK
X
Xcd $NEWSCTL
Xrm -f L.* LOCK*				# leftover locks
Xrm -f history.n*			# leftover expire work files
X
Xcd $NEWSARTS/in.coming
Xrm -f nspool.* nruntmp.*		# leftover temporaries
Xfor f in nntp.*				# find partial batches
Xdo
X	while test -f $f		# still there?
X	do
X		name=`getdate now`
X		if test ! -f $name
X		then
X			mv $f $name
X		else
X			sleep 2
X		fi
X	done
Xdone
X$NEWSBIN/ctl/newgroup	# resume new group collection
SHAR_EOF
$TOUCH -am 0220191091 misc/newsboot &&
chmod 0755 misc/newsboot ||
echo "restore of misc/newsboot failed"
set `wc -c misc/newsboot`;Wc_c=$1
if test "$Wc_c" != "594"; then
	echo original size 594, current size $Wc_c
fi
# ============= relay/makefile.patch ==============
echo "x - extracting relay/makefile.patch (Text)"
sed 's/^X//' << 'SHAR_EOF' > relay/makefile.patch &&
X*** ./relay/makefile.orig	Tue Nov  6 14:40:08 1990
X--- ./relay/makefile	Wed Feb 20 17:53:02 1991
X***************
X*** 47,53 ****
X  	active.h article.h caches.h mkdirs.h control.h fileart.h \
X  	hdrint.h headers.h history.h system.h transmit.h trbatch.h $(SRC)
X  
X! all: makefile relaynews
X  	chmod +x sh/[a-z]* aux/[a-z]* ctl/[a-z]*
X  
X  mkfile: makefile
X--- 47,53 ----
X  	active.h article.h caches.h mkdirs.h control.h fileart.h \
X  	hdrint.h headers.h history.h system.h transmit.h trbatch.h $(SRC)
X  
X! all: makefile relaynews ctl/collng
X  	chmod +x sh/[a-z]* aux/[a-z]* ctl/[a-z]*
X  
X  mkfile: makefile
X***************
X*** 55,60 ****
X--- 55,62 ----
X  
X  relaynews: $(OBJ) $(LIBOBJS)
X  	$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) $(PRE) $(LIBS) $(LIBOBJS) $(POST) -o $@
X+ ctl/collng: collng.c
X+ 	$(CC) $(COPTS) -o $@ collng.c
X  lint: $(SRC)
X  	$(LINT) $(LINTFLAGS) $(SRC) $(LLIBS) | $(LINTFILT)
X  lint-p: $(SRC)
X***************
X*** 66,72 ****
X  # bininstall: make directories, install programs
X  bininstall: install
X  install: $(NEWSBIN)/relay/relaynews
X! $(NEWSBIN)/relay/relaynews: relaynews
X  	-mkdir $(NEWSBIN)/relay $(NEWSBIN)/inject $(NEWSBIN)/ctl
X  	rm -f $(NEWSBIN)/relay/relaynews
X  	cp relaynews $(NEWSBIN)/relay
X--- 68,74 ----
X  # bininstall: make directories, install programs
X  bininstall: install
X  install: $(NEWSBIN)/relay/relaynews
X! $(NEWSBIN)/relay/relaynews: relaynews ctl/collng
X  	-mkdir $(NEWSBIN)/relay $(NEWSBIN)/inject $(NEWSBIN)/ctl
X  	rm -f $(NEWSBIN)/relay/relaynews
X  	cp relaynews $(NEWSBIN)/relay
X***************
X*** 77,83 ****
X  	rm -f $(BIN)/inews
X  	-ln $(NEWSBIN)/inject/inews $(BIN)/inews 2>/dev/null || cp sh/inews $(BIN)
X  
X! cmp:	relaynews
X  	cmp $(NEWSBIN)/relay/relaynews relaynews
X  	for f in `ls sh` ; do cmp $(NEWSBIN)/inject/$$f sh/$$f ; done
X  	for f in `ls ctl` ; do cmp $(NEWSBIN)/ctl/$$f ctl/$$f ; done
X--- 79,85 ----
X  	rm -f $(BIN)/inews
X  	-ln $(NEWSBIN)/inject/inews $(BIN)/inews 2>/dev/null || cp sh/inews $(BIN)
X  
X! cmp:	relaynews ctl/collng
X  	cmp $(NEWSBIN)/relay/relaynews relaynews
X  	for f in `ls sh` ; do cmp $(NEWSBIN)/inject/$$f sh/$$f ; done
X  	for f in `ls ctl` ; do cmp $(NEWSBIN)/ctl/$$f ctl/$$f ; done
X***************
X*** 85,91 ****
X  	cmp $(BIN)/inews sh/inews
X  	ls -lg $(NEWSBIN)/relay/relaynews | egrep -s '^-rwsrwsr-x  1 news     news'
X  
X! check:	relaynews
X  	cmp $(NEWSBIN)/relay/relaynews relaynews || true
X  	for f in `ls sh` ; do cmp $(NEWSBIN)/inject/$$f sh/$$f || true ; done
X  	for f in `ls ctl` ; do cmp $(NEWSBIN)/ctl/$$f ctl/$$f || true ; done
X--- 87,93 ----
X  	cmp $(BIN)/inews sh/inews
X  	ls -lg $(NEWSBIN)/relay/relaynews | egrep -s '^-rwsrwsr-x  1 news     news'
X  
X! check:	relaynews ctl/collng
X  	cmp $(NEWSBIN)/relay/relaynews relaynews || true
X  	for f in `ls sh` ; do cmp $(NEWSBIN)/inject/$$f sh/$$f || true ; done
X  	for f in `ls ctl` ; do cmp $(NEWSBIN)/ctl/$$f ctl/$$f || true ; done
X***************
X*** 106,112 ****
X  	pr $(PROPTS) $? | $P
X  	touch $@
X  clean:
X! 	rm -f core a.out relaynews *.o	
X  	rm -rf regress/tmp
X  
X  r:	relaynews
X--- 108,114 ----
X  	pr $(PROPTS) $? | $P
X  	touch $@
X  clean:
X! 	rm -f core a.out relaynews *.o ctl/collng
X  	rm -rf regress/tmp
X  
X  r:	relaynews
SHAR_EOF
$TOUCH -am 0222150791 relay/makefile.patch &&
chmod 0644 relay/makefile.patch ||
echo "restore of relay/makefile.patch failed"
set `wc -c relay/makefile.patch`;Wc_c=$1
if test "$Wc_c" != "3176"; then
	echo original size 3176, current size $Wc_c
fi
patch -p0 < ./relay/makefile.patch
exit 0
-- 
| Nick Sandru (alias Long Haired Nick)   | Backpacker's First Law:
| Hoje Topholm 37    | e-mail:           | "The thing you need lies either
| DK-3390 Hundested  |  ns@iddth.id.dk   |  in the bottom of your backpack,
| Denmark            |  ns@iddth2.id.dk  |  or in a closet at your home..."

exit 0 # Just in case...
-- 
Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
Sterling Software, IMD           UUCP:     uunet!sparky!kent
Phone:    (402) 291-8300         FAX:      (402) 291-4362
Please send comp.sources.misc-related mail to kent@uunet.uu.net.