[net.sources] rmgroups for old rec groups have been posted

hansen@pegasus.UUCP (12/21/86)

< I got all the rmgroups.  Unfortunately, I found out the hard way
< that rmgroup still doesn't lock the active file while doing its
< work, so if news is coming in while you're rmgroup'ing, you'll
< corrupt your active file.

Here is a locknews (and unlocknews) program which uses the same locking
scheme as the rest of 2.11 news. I've only tested it on System V machines,
but the code is there for other systems and it should work unless I've made
some silly mistake in the coding. Feel free to post fixes as they are found.

The following shar contains the code for locknews/unlocknews, plus patches
for Makefile.dst and rmgroup.sh to build and use the new process.  I put the
same copyright comment at the top of the code which is found on top of all
of the rest of the 2.11 code.  On System V machines, only epathinit.o needs
to be linked in, but this may not be true for other systems. 

This pair of processes can also be used whenever you're doing some work on
the news system. Simply run locknews, do your work, and then run unlocknews.

The code is being mailed to Rick as well as being posted.

					Tony Hansen
					ihnp4!pegasus!hansen

#!/bin/sh
# This is a shar archive.
# The rest of this file is a shell script which will extract:
#
# locknews.c Make.patch rmgroup.patch
#
# To extract the files from this shell archive file simply
# create a directory for this file, move the archive file
# to it and enter the command
#
#	sh filename
# 
# The files will be extracted automatically.
# Note: Do not use csh.
#
# Archive created: Sat Dec 20 23:05:48 EST 1986
#
echo x - locknews.c
sed 's/^X//' > locknews.c << '~FUNKY STUFF~'
/*
 * This software is Copyright (c) 1986 by Rick Adams.
 *
 * Permission is hereby granted to copy, reproduce, redistribute or
 * otherwise use this software as long as: there is no monetary
 * profit gained specifically from the use or reproduction or this
 * software, it is not sold, rented, traded or otherwise marketed, and
 * this copyright notice is included prominently in any copy
 * made.
 *
 * The author make no claims as to the fitness or correctness of
 * this software for any use whatsoever, and it is provided as is.
 * Any use of this software is at the user's own risk.
 *
 * lock.news/unlock.news - locks and unlocks news system
 */

#ifdef SCCSID
static char	*SccsId = "@(#)locknews.c	1.1	12/19/86";
#endif /* SCCSID */

#include "params.h"
#include "defs.h"
#include <errno.h>

#ifdef LOCKF
#include <unistd.h>
#endif /* LOCKF */

char *Progname;				/* name of program */
char bfr[LBUFLEN];			/* general-use scratch area */

#if defined(BSD4_2) || defined(LOCKF)
static int LockFd = -1;			/* file descriptor opened */
#endif

#if defined(BSD4_2) || defined(LOCKF)
catchunlock()
{
    /* don't do anything */
}
#endif /* BSD4_2 || LOCKF */

dolock()
{
#if defined(BSD4_2) || defined(LOCKF)
    if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
	signal(SIGHUP, catchunlock);
    if (signal(SIGINT, SIG_IGN) != SIG_IGN)
        signal(SIGINT, catchunlock);
    if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
        signal(SIGTERM, catchunlock);

    /* set up exclusive locking so inews does not run while expire does */
    LockFd = open(ACTIVE, 2);
# ifdef    LOCKF
    (void) lockf(LockFd, F_LOCK, 0);
# else    /* BSD4_2 */
    (void) flock(LockFd, LOCK_EX);
# endif    /* BSd4_2 */
    
    /* save a reference to this process so */
    /* that unlocknews can find it */
    sprintf(bfr, "%s.lock", ACTIVE);
    lockfp = fopen(bfr, "w");
    if (!lockfp)
	xerror("Cannot open lock file\n");

    if (fork())
        {
        sleep(2); /* give the child a chance to write its pid */
        xxit(0);
	}
    else
        {
        (void) fprintf (lockfp, "%d", getpid());
        fclose(lockfp);
        pause();	/* now wait for signal from unlocknews */
	}
#else    /* !BSD4_2 && !LOCKF */
    int i = 0;
    sprintf(bfr, "%s.lock", ACTIVE);
    while (LINK(ACTIVE, bfr) < 0 && errno == EEXIST)
        {
        if (i++ > 5)
	    xerror("Can't get lock for locknews\n");
        sleep(i*2);
	}
#endif    /* !BSD4_2  && !LOCKF */
}

rmlock()
{
#if defined(BSD4_2) || defined(LOCKF)
    sprintf(bfr, "%s.lock", ACTIVE);
    lockfp = fopen(bfr, "r");
    if (!lockfp)
	xerror("Cannot open lock file\n");

    if (!fgets(bfr, sizeof(bfr), lockfp))
        xerror("Cannot cannot read locking process id\n");
    (void) UNLINK(bfr);
    (void) kill(atoi(bfr), SIGTERM);
#else
    sprintf(bfr, "%s.lock", ACTIVE);
    (void) UNLINK(bfr);
#endif    /* !BSD4_2 */
}

main(argc, argv)
int argc;
char **argv;
{
    char *name = rindex(argv[0], '/');
    if (name++ == NULL)
        name = argv[0];
    Progname = argv[0];
    pathinit();
    (void) umask(N_UMASK);

    if (strncmp(name, "lock", 4) == 0)
        dolock();
    else
        rmlock();
    xxit(0);
    /* NOTREACHED */
}

xxit(i)
{
    exit(i);
}

/* VARARGS1 */
xerror(message, arg1, arg2, arg3)
char *message;
long arg1, arg2, arg3;
{
	char buffer[LBUFLEN];

	fflush(stdout);
	(void) fprintf (stderr, "%s: ", Progname);
	(void) fprintf (stderr, message, arg1, arg2, arg3);
	xxit(1);
}
~FUNKY STUFF~
ls -l locknews.c
echo x - Make.patch
sed 's/^X//' > Make.patch << '~FUNKY STUFF~'
*** OMakefile	Sat Dec 20 22:23:21 1986
--- Makefile	Sat Dec 20 22:21:01 1986
***************
*** 59,64
  	$(OBJECTS) visual.o virtterm.o
  EXPOBJS = expire.o header.o funcs.o getdate.o iextern.o epathinit.o \
  	funcs2.o ndir.o $(MISC)
  
  SRCS = funcs.c funcs2.c header.c
  ISRCS = inews.c ifuncs.c iextern.c control.c fullname.c  $(SRCS)

--- 59,65 -----
  	$(OBJECTS) visual.o virtterm.o
  EXPOBJS = expire.o header.o funcs.o getdate.o iextern.o epathinit.o \
  	funcs2.o ndir.o $(MISC)
+ LOBJS = locknews.o epathinit.o
  
  SRCS = funcs.c funcs2.c header.c
  ISRCS = inews.c ifuncs.c iextern.c control.c fullname.c  $(SRCS)
***************
*** 71,76
  	funcs2.c
  OSRCS = uurec.c recnews.c sendnews.c batch.c unbatch.c caesar.c \
  	recmail.c compress.c
  
  UTILS = inews uurec recnews sendnews expire batch unbatch caesar recmail \
  	encode decode $(COMPRESS)

--- 72,78 -----
  	funcs2.c
  OSRCS = uurec.c recnews.c sendnews.c batch.c unbatch.c caesar.c \
  	recmail.c compress.c
+ LSRCS = locknews.c
  
  UTILS = inews uurec recnews sendnews expire batch unbatch caesar recmail \
  	encode decode $(COMPRESS) locknews
***************
*** 73,79
  	recmail.c compress.c
  
  UTILS = inews uurec recnews sendnews expire batch unbatch caesar recmail \
! 	encode decode $(COMPRESS)
  SCRIPTS = sendbatch rmgroup checkgroups
  OTHERS = $(UTILS) $(SCRIPTS)
  COMMANDS = readnews checknews postnews vnews

--- 75,81 -----
  LSRCS = locknews.c
  
  UTILS = inews uurec recnews sendnews expire batch unbatch caesar recmail \
! 	encode decode $(COMPRESS) locknews
  SCRIPTS = sendbatch rmgroup checkgroups
  OTHERS = $(UTILS) $(SCRIPTS)
  COMMANDS = readnews checknews postnews vnews
***************
*** 219,224
  
  checknews.o:  checknews.c defs.h header.h Makefile params.h
  	$(CC) $(CFLAGS) -c checknews.c
  
  vnews:	$(VOBJECTS)
  	$(CC) $(LFLAGS) $(VOBJECTS) $(TERMLIB) $(LIBS) -o $@

--- 221,232 -----
  
  checknews.o:  checknews.c defs.h header.h Makefile params.h
  	$(CC) $(CFLAGS) -c checknews.c
+ 
+ locknews.o: locknews.c defs.h params.h
+ 	$(CC) $(CFLAGS) -c locknews.c
+ 
+ locknews: $(LOBJS)
+ 	$(CC) $(LFLAGS) $(LOBJS) $(LIBS) -o $@
  
  vnews:	$(VOBJECTS)
  	$(CC) $(LFLAGS) $(VOBJECTS) $(TERMLIB) $(LIBS) -o $@
~FUNKY STUFF~
ls -l Make.patch
echo x - rmgroup.patch
sed 's/^X//' > rmgroup.patch << '~FUNKY STUFF~'
*** Ormgroup.sh	Sat Dec 20 23:03:04 1986
--- rmgroup.sh	Sat Dec 20 23:03:50 1986
***************
*** 1,4
  : '@(#)rmgroup.sh	1.6	9/19/86'
  for group
  do
  	echo "Removing newsgroup $group"

--- 1,5 -----
  : '@(#)rmgroup.sh	1.6	9/19/86'
+ locknews &&
  for group
  do
  	echo "Removing newsgroup $group"
***************
*** 24,29
  	else
  		echo "$0: $group: no such newsgroup" 2>&1
  	fi
! done
! rm -f /tmp/$$
  exit 0

--- 25,31 -----
  	else
  		echo "$0: $group: no such newsgroup" 2>&1
  	fi
! done &&
! rm -f /tmp/$$ &&
! unlocknews
  exit 0
~FUNKY STUFF~
ls -l rmgroup.patch
# The following exit is to ensure that extra garbage 
# after the end of the shar file will be ignored.
exit 0