[alt.sources] CNews Speedups

brendan@cs.widener.edu (Brendan Kehoe) (03/27/91)

   This package implements anne.jones, tear, and spacefor in C, to
  help speed up CNews a bit. They've been updated to include all of
  the changes/additions/whatever made with the March patches.

   Check out README and the top of the Makefile for instructions on
  how to build and install 'em.

   This set differs from the previous in three respects .. first, it
  doesn't include rnews, cuz it hasn't been rewritten yet; and second,
  you HAVE to have libcnews.a from your CNews build to make
  anne.jones. If you've already patched your version of CNews and
  didn't keep the stuff around, the README in here includes
  instructions on how far to go into doit.bin to get it without going
  through the entire build again.
   Also, anne.jones now contains the ability to be built to use
  'minimalist' Message-ID's. (aka 7-chars instead of 16+) It only uses
  characters that shouldn't cause problems with news software or odd
  shells (as has been discussed recently here).

   Please write me with any problems, etc.

Brendan

-- cut --
#! /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 <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  README FilePlaces Makefile anne.h anne.jones.c
#   anne.jones.sh anne.misc.c getline.c spacefor.h spacefor.c
#   spacefor.sh tear.c
# Wrapped by brendan@laverne on Tue Mar 26 18:23:30 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(2878 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
X
The CNews Extension Set
Revised: 03/26/91
X
X This is the latest edition of my programs to speed up the C-News
process a bit.  Note: it is NOT an official extension or part of C
News; it is simply my effort to jazz it up a bit more. It has not been
blessed by Henry or Geoff. (In fact, they object to it because it
takes away the configure-on-the-fly nature of using shell scripts.
This is if you don't think you'll ever be changing anne.jones,
spacefor [save changing the minimum requirements, in spacefor.h], or
tear very often.)
X Included are replacements for the anne.jones shell script &
defhdrs.awk awk program, to help speed up the parsing of headers; a C
version of spacefor, to keep the checks for disk space as fast as
possible (no parsing of the output of df anymore); and a new version of
tear, to replace the awk method of splitting an article's header &
body. The version of rnews that was previously released with this kit
won't be included until it's been updated to compensate for the
staleness facility with expires.
X Anne.jones (thanks to John Palkovic) now also includes the option of
having it do "minimalist" message ID's. They produce message ID
strings of (e.g.):
X	Message-ID: <9NM#2K-@cs.widener.edu>
rather than
X	Message-ID: <1991Mar06.191450.10734@cs.widener.edu>
X
X Note that all parts of this package are compatible with and are
currently running in the CNews system patched to 24-Mar-90 (all four
of the March patches). Also the changes in the December patches have
been fully incorporated. As far as I can tell, these should be drop-in
replacements.
X
X The set is currently available via anon. FTP from ftp.cs.widener.edu
X[192.55.239.132].
X
X Thanks to Geoff Collyer & Henry Spencer for writing really intuitive code.
X
X Check out the top of the Makefile for how to build all of this.
X
X	1. To install just anne.jones and none of the others, type:
X		make installaj
X	2. To install everything, type:
X		make install
X	3. If you want to replace only certain ones, or see what gets
X	   moved, check out the file
X	   'FilePlaces'.
X        4. Spacefor will let you say how much space you want by doing:
X		spacefor.stub 1 article 3500
X	   so you can tweak inews on the fly if need be.
X	5. To make them all work on your site, you'll want to check
X	   out anne.h, spacefor.h, & the Makefile and customize them
X	   as necessary.
X
X One new thing with this set is that you MUST have libcnews.a from
the CNews build. If you didn't save it, you'll have to go and re-run
doit.bin (or re-run build if you didn't save build.def) up to the
point where it's created. (It'll add a bunch, then do 'ranlib ../libcnews.a'
and 'touch ../ranlibed'. Then it'll go on to libstdio again, about to do
all of the compatability tests .. you can stop it there.)
X
X
Good luck! Any questions, comments, complaints, bug reports, etc. are welcome.
X
X		 Brendan Kehoe (brendan@cs.widener.edu)
X
END_OF_FILE
if test 2878 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'FilePlaces' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'FilePlaces'\"
else
echo shar: Extracting \"'FilePlaces'\" \(786 characters\)
sed "s/^X//" >'FilePlaces' <<'END_OF_FILE'
X Here's where everything goes, in case you just want to replace a few
of them.
X BINDIR is the newsbin directory (e.g. /usr/lib/newsbin) where all of this
stuff is located.
X
X For spacefor:
X	mkdir BINDIR/old if it's not already there
X	move BINDIR/spacefor	->		BINDIR/old/spacefor
X	move spacefor.sh	->		BINDIR/spacefor
X	move spacefor.stub	->		BINDIR/spacefor.stub
X
X For anne.jones: (you could also do 'make installaj')
X	mkdir BINDIR/inject/old if it's not already there
X	move BINDIR/inject/anne.jones	->	BINDIR/inject/old/anne.jones
X	move anne.jones.sh		->	BINDIR/inject/anne.jones
X	move anne.stub			->	BINDIR/inject/anne.stub
X
X For tear:
X	mkdir BINDIR/inject/old if it's not already there
X	move BINDIR/inject/tear	->		BINDIR/inject/old
X	move tear		->		BINDIR/inject/tear
X
X And that's it.
END_OF_FILE
if test 786 -ne `wc -c <'FilePlaces'`; then
    echo shar: \"'FilePlaces'\" unpacked with wrong size!
fi
# end of 'FilePlaces'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(2985 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X# The Cnews Extensions Package - Brendan Kehoe - brendan@cs.widener.edu
X#
X# This is available via anon FTP at 192.55.239.132 (ftp.cs.widener.edu)
X#
X# Last Updated: 03/26/91
X#
X# Step 1 - Edit anne.h, spacefor.h, and to customize them for your site.
X# Step 2 - Set up BINDIR, CC, CFLAGS, and CNEWSLIB for your configuration.
X# Step 3 - Do a make.
X# Step 4 - Do a 'make install' -- this will replace the current versions
X#	   of spacefor, tear, and anne.jones with the new ones.
X#[Step 5]- If you want to go back to what you had before, do 'make undo'..
X#	   it'll put the old versions back. (They're in $BINDIR/old)
X#
X# This is your NEWSBIN directory (if it's a sym link, that's ok)
BINDIR	= /usr/lib/newsbin
X#
X# CC:
X# If you don't have Gnu C, have 'cc' uncommented instead.
CC	= cc
X#CC	= gcc
X#
X# CFLAGS:
X# If you have Gnu C, work with the first line (with the -f's in it);
X#  otherwise, use the second. 
X# If you're a BSD system, use -DBSD
X# If you're running AIX 2.2.1 on an IBM RT use -DAIX
X# If you're on an Altos system, use -DALTOS (note only spacefor uses this)
X# Note for SunOS 4.1: I expressly didn't use -O2 or higher because of
X#  the many bugreports that are logged discounting their accuracy. (Most
X#  notable is -O2, generally accepted, even in the Gnu Project.)
X#
X#CFLAGS       = -O -traditional -finline-functions -fstrength-reduce -DBSD
CFLAGS		= -O -DBSD
X#
X# Where your libcnews.a is .. yup, you have to have it. If you don't
X# have it, go back into conf and run doit.bin again, Ctrl-C'ing after
X# it's run ranlib (or ar rux) on it.
X#
CNEWSLIB = /usr/local/work/cnews/libcnews.a # Make SURE you change THIS!
X#
X# And that's all she wrote. Change NOTHING else unless you know what
X# you're doing.
X  
all: anne.stub tear spacefor.stub $(CNEWSLIB)
X
anne.stub: getline.o anne.misc.o anne.h anne.jones.c
X	$(CC) $(CFLAGS) anne.jones.c -o anne.stub getline.o anne.misc.o $(LDFLAGS) $(CNEWSLIB)
X	strip $@
X
tear: getline.o tear.c
X	$(CC) $(CFLAGS) $@.c -o $@ getline.o $(LDFLAGS)
X	strip $@
X
spacefor.stub: spacefor.c
X	$(CC) $(CFLAGS) spacefor.c -o spacefor.stub $(LDFLAGS)
X	strip $@
X
install:
X	-mkdir $(BINDIR)/old
X	mv $(BINDIR)/spacefor $(BINDIR)/old
X	cp spacefor.sh $(BINDIR)/spacefor
X	cp spacefor.stub $(BINDIR)
X	-mkdir $(BINDIR)/inject/old
X	mv $(BINDIR)/inject/anne.jones $(BINDIR)/inject/old
X	mv $(BINDIR)/inject/tear $(BINDIR)/inject/old
X	cp anne.jones.sh $(BINDIR)/inject/anne.jones
X	cp anne.stub $(BINDIR)/inject
X	cp tear $(BINDIR)/inject
X
installaj:
X	-mkdir $(BINDIR)/old
X	mv $(BINDIR)/inject/anne.jones $(BINDIR)/inject/old
X	cp anne.jones.sh $(BINDIR)/inject/anne.jones
X	cp anne.stub $(BINDIR)/inject
X
undo:
X	rm -f $(BINDIR)/spacefor.stub $(BINDIR)/inject/anne.stub
X	-mv $(BINDIR)/old/* $(BINDIR)/
X	-mv $(BINDIR)/inject/old/* $(BINDIR)/inject
X	-rmdir $(BINDIR)/old $(BINDIR)/inject/old
X
shar:
X	shar -i list -o cnews.set.shar
X
clean:
X	rm -f anne.stub tear spacefor.stub getline.o anne.misc.o tear.o
X	rm -f core a.out spacefor.o anne.jones.o *.ln gmon.out cnews.set.shar
X
END_OF_FILE
if test 2985 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'anne.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'anne.h'\"
else
echo shar: Extracting \"'anne.h'\" \(2297 characters\)
sed "s/^X//" >'anne.h' <<'END_OF_FILE'
X/*
X * anne.h - for anne.jones.c
X */
X
X#undef MINIMALIST		/*
X				 * Use 'minimalist' Message ID's? (Pack
X				 * the info into 7 chars instead of 22 or
X				 * more .. credit for this whole thing goes
X				 * to palkovic@linac.fnal.gov (John Palkovic)
X				 */
X
X#define	HAVESTRSTR		/*
X				 * Have the strstr() function?
X				 * Test: nm /lib/libc.a | egrep strstr
X				 * Note: replace /lib/libc.a above with
X				 *  wherever your libc.a is
X				 */
X
X#define HAVEGETHOSTNAME		/*
X				 * Have the gethostname() function?
X				 * Test: nm /lib/libc.a | egrep gethostname
X				 */
X
X#undef	NOLINEBUF		/*
X				 * If fprintf() doesn't flush stdout()
X				 *  define this. This came from rn; I
X				 *  don't have a test for this .. suggestions
X				 *  (or part of a Configure script) are welcome
X				 */
X
X/* you're done .. no more playing */
X#define	MAXLINE		1000	/* maximum line length to be read in */
X#define	MAXHEAD		30	/* maximum length from ^ to : of header */
X#define	NUMHEADERS	50	/* max # of headers expected */
X#define	NAMESIZE	30	/* size of mailname */
X
X#define	ORDER		9	/* the range from 1-n that *HAVE* to be in */
X#define	NUMKNOWN	11	/* how many we already know */
X#define	KNOWSTART	1	/* # the below starts at */
X#define	MSGIDLEN	60	/* length of message id string, with <>'s */
X#define	DATELEN		30	/* length of date string */
X#define	ORGLEN		80	/* length of organization's name */
X
X#define	CTLNAMEPOS	1
X#define	NGNAMEPOS	2
X#define	PATHNAMEPOS	3
X#define	FROMPOS		4
X#define	SUBJECTPOS	5
X#define	MSGIDPOS	6
X#define	DATEPOS		7
X#define EXPIREPOS	8
X#define	ORGPOS		9
X#define	SENDERPOS	10
X#define	DISTPOS		11
X
X/* these aren't used yet */
X#define	CTLNAME		"Control:"
X#define	NGNAME		"Newsgroups:"
X#define	PATHNAME	"Path:"
X#define	FROMNAME	"From:"
X#define	SUBJECTHDR	"Subject:"
X#define	MSGIDNAME	"Message-ID:"
X#define	TYPONAME	"Message-Id:"
X#define	DATENAME	"Date:"
X#define EXPIRENAME	"Expires:"
X#define	ORGNAME		"Organization:"
X#define	SENDERNAME	"Sender:"
X#define	DISTRNAME	"Distribution:"
X
X/* don't play with this */
X#ifndef HAVESTRSTR
char *strstr();
X#endif /* !HAVESTRSTR */
X
X#define	NOTFOUND	-1
X#define	NOTKNOWN	-1
X
static char *allheads="\
Control:.....\
Newsgroups:..\
Path:........\
XFrom:........\
Subject:.....\
Message-ID:..\
Date:........\
XExpires:.....\
Organization:\
Sender:......\
Distribution:";
END_OF_FILE
if test 2297 -ne `wc -c <'anne.h'`; then
    echo shar: \"'anne.h'\" unpacked with wrong size!
fi
# end of 'anne.h'
fi
if test -f 'anne.jones.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'anne.jones.c'\"
else
echo shar: Extracting \"'anne.jones.c'\" \(10146 characters\)
sed "s/^X//" >'anne.jones.c' <<'END_OF_FILE'
X/*
X * anne.jones - anne.jones.c - 03/26/91 - Brendan Kehoe
X * An implementation of Cnews' anne.jones program to parse down articles
X */
X
X#include <stdio.h>
X#include <string.h>
X#include <pwd.h>
X#include <time.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <sys/utsname.h>
X#include "anne.h"
X#include <signal.h>
X
struct passwd *getpwuid(); /* Not included in pwd.h -- a3@rivm.nl */
X
X#ifdef	DEBUG
XFILE *debug = stderr;
X#endif
X
extern char *get_a_line(), *safemalloc(), *saferealloc(),
X     *fix_expire(), *fix_date(), *legaldate();
X
int
main(argc, argv)
X     int argc;
X     char **argv;
X/*ARGSUSED*/
X{
X  char *user, *name, *home, *newsctl, *mailname, *colon, *org, *line,
X#ifdef MINIMALIST
X       wildstrng[20],
X#endif /* MINIMALIST */
X       **header, from[100], head[MAXHEAD], path[200], fullname[50];
X  extern char *mon[12];
X  int tmp, i, headcnt = 0, *found, *pme, status = 0;
X  FILE *fp;
X  time_t t;
X  struct stat statbuf;
X  struct tm *tm;
X  struct utsname ut;
X  struct passwd *pent;
X
X  extern char *getenv();
X  char *squeeze(), *getmname(), **buildbook();
X  FILE *trypath();
X  void termin(), squeeze2();
X#ifdef MINIMALIST
X  void rand_id();
X#endif /* MINIMALIST */
X  
X  signal(SIGSEGV, termin);
X  signal(SIGINT, termin);
X  signal(SIGQUIT, termin);
X  signal(SIGHUP, termin);
X  signal(SIGBUS, termin);
X
X  if ((newsctl = getenv("NEWSCTL")) == (char *) NULL) {
X    perror("NEWSCTL");
X    exit(1);
X  }
X  found = (int *) calloc(NUMKNOWN + KNOWSTART, sizeof(int));
X  for (i = KNOWSTART; i < NUMKNOWN + KNOWSTART; i++)
X    found[i] = NOTFOUND;
X  header = (char **) buildbook(NUMHEADERS);
X  
X  /* mailname & host set */
X  mailname = safemalloc(301);
X  if ((fp = trypath(newsctl, "mailname")) != (FILE *) NULL) {
X    mailname = squeeze(getmname(fp));
X  } else if ((fp = trypath(newsctl, "whoami")) != (FILE *) NULL) {
X    mailname = getmname(fp);
X#ifdef HAVEGETHOSTNAME
X  } else if ((gethostname(mailname, 100)) < 0) {
X    perror("ghostname");
X    exit(1);
X#endif /* HAVEGETHOSTNAME */
X  } else if ((fp = fopen("/etc/whoami", "r")) != (FILE *) NULL) {
X    mailname = getmname(fp);
X    /* skipped the uuname -l one, since it does gethostname(2) */
X  } else if (uname(&ut) >= 0) {
X    strcpy(mailname, ut.sysname);
X  } else {
X    strcpy(mailname, "the_unknown_host");
X  }
X  
X  /* if it doesn't have a ., it's probably a uucp host */
X  if (strchr(mailname, '.') == (char *) NULL)
X    strcat(mailname, ".uucp");
X  
X  /* user's name set */
X  pent = getpwuid(geteuid());	/* make it so su'ing someone works */
X  if ((user = getenv("LOGNAME")) == NULL)
X    user = pent->pw_name;
X  
X  /* name set & cleaned up */
X  if (((name = getenv("NAME")) == NULL) &&
X      ((home = getenv("HOME")) != (char *) NULL)) {
X    strcpy(path, home);
X    strcat(path, "/.name");
X    stat(path, &statbuf);
X    if (statbuf.st_size > 0) {
X      if ((fp = fopen(path, "r")) != (FILE *) NULL) {
X	name = safemalloc(101);
X	if ((get_a_line(name, 100, fp)) == (char *) NULL) {
X	  perror("get_a_line .name");
X	  exit(1);
X	}
X	if (*(colon = (name + strlen(name) - 1)) == '\n')
X	  *colon = '\0';
X	fclose(fp);
X      }
X    } else {
X      
X      /*
X	if gecos has '&', use capitalized login name
X	*/
X      if ((strchr(pent->pw_gecos, '&') != (char *) NULL)) {
X	name = safemalloc(strlen(pent->pw_name) + 1);
X	strcpy(name, pent->pw_name);
X	*name = toupper(*name);
X      } else {
X	name = pent->pw_gecos;
X      }
X    }
X  }
X
X  /* fullname test */
X  if (name != NULL) {	/* if no real name, leave it off */
X    strtok(name, ",");  /* preserve only the name field -- ns@iddth.id.dk */
X    sprintf(fullname, " (%s)", name);
X  }
X
X  /* setup the from field */
X  sprintf(from, "%s@%s", user, mailname);
X  if (name != NULL)
X    strcat(from, fullname);
X  
X  /* set up the date */
X  time(&t);
X  tm = gmtime(&t);
X  
X  /* set up the org */
X  if ((org = getenv("ORGANIZATION")) == (char *) NULL) {
X    if (((fp = trypath(newsctl, "organization")) == (FILE *) NULL) &&
X	((fp = trypath(newsctl, "organisation")) == (FILE *) NULL)) {
X      org = (char *)NULL;
X    } else {
X      org = safemalloc(ORGLEN + 1);
X      get_a_line(org, ORGLEN, fp);
X      if (*(colon = (org + strlen(org) - 1)) == '\n')
X	*(org + strlen(org) - 1) = '\0';
X      fclose(fp);
X    }
X  }
X
X  /* now pump out a nice clean header */
X  line = safemalloc(MAXLINE + 1);
X  
X  while (get_a_line(line, MAXLINE, stdin) != (char *) NULL) {
X    /* squeeze out (tr) the bad chars */
X#ifdef	DEBUG
X    fprintf(debug, "getline got ->%s<-\n", line);
X#endif
X    if (*line != '\n') {
X      if (*(colon = (line + strlen(line) - 1)) == '\n')
X	*colon = '\0';
X      /* clean out the garbage */
X      squeeze2(line);
X
X      /*
X       * replace :tab with :spc and :[^spc] with :spc followed  by
X       * what was there
X       */
X      if (colon = strchr(line, ':'))
X	{
X	  if (*(colon + 1) == '\t')
X	    *(colon + 1) = ' ';
X	  else if (*(colon + 1) != ' ')
X	    {
X	      char *_insert = safemalloc(strlen(line) + 1);
X	      strncpy(_insert, line, colon - line);
X	      *(_insert + (colon - line + 1)) = ' ';
X	      *(_insert + (colon - line + 2)) = '\0';
X	      strcat(_insert, colon + 1);
X	      free(line);
X	      line = _insert;
X	    }
X	}
X    }
X    header[headcnt] = safemalloc(strlen(line) + 1);
X    strcpy(header[headcnt++], line);
X#ifdef	DEBUG
X    fprintf(debug, "getline put ->%s<-\n", line);
X#endif
X  }
X  
X  /* thus begins the defheaders.awk hack */
X  
X  /* nullify all headers with empty contents */
X  for (i = 0; i < headcnt; i++) {
X    if ((header[i][0]) && (colon = strchr(header[i], ':'))) {
X      colon++;	/* move to the chr past the colon */
X      
X      /*
X	strspn -> the last position (the NULL) if there was
X	nothing but tabs & spaces .. in that case, it's an
X	empty header and discard it
X	*/
X      if (strspn(colon, " \011") == strlen(colon)) {
X	header[i][0] = '\0';
X	continue;
X      }
X      strncpy(head, header[i], colon - header[i]);
X      *(head + (colon - header[i])) = '\0';
X      
X      /* fix Message-Id to read Message-ID */
X      if (strcmp(head, TYPONAME) == 0)
X	header[i][9] = 'D';
X      
X      /* mark off the ones we're expecting */
X      if ((tmp = know_head(head)) != NOTKNOWN)
X	found[tmp] = i;
X    }
X  }
X  
X  for (i = KNOWSTART; i < (NUMKNOWN + KNOWSTART); i++) {
X    
X    /*
X      If no header was given for something, then fill it in with
X      what we've come up with above
X      */
X    if (found[i] == NOTFOUND) {
X      switch (i) {
X	case PATHNAMEPOS:
X	  header[headcnt] = safemalloc(strlen(user) + 8);
X	  sprintf(header[headcnt], "Path: %s", user);
X	  found[i] = headcnt++;
X	  break;
X	case MSGIDPOS:
X	  header[headcnt] = safemalloc(MSGIDLEN + 13);
X#ifdef MINIMALIST
X	  rand_id(wildstrng);
X#endif /* MINIMALIST */
X	  sprintf(header[headcnt],
X#ifdef MINIMALIST
X		  "Message-ID: <%s@%s>", wildstrng,
X#else /* !MINIMALIST */
X	          "Message-ID: <19%02d%s%02d.%02d%02d%02d.%i@%s>",
X	          tm->tm_year, *(mon + tm->tm_mon),
X		  tm->tm_mday, tm->tm_hour,
X		  tm->tm_min, tm->tm_sec, getpid(),
X#endif /* MINIMALIST */
X		  mailname);
X      found[i] = headcnt++;
X	break;
X      case DATEPOS:
X	
X	/*
X	 * put it in the form Day, DD Mon Yr hh:mm:ss GMT
X	 */
X	header[headcnt] = safemalloc(DATELEN + 5);
X	header[headcnt] = legaldate(tm, header[headcnt], "Date:");
X	found[i] = headcnt++;
X	break;
X      case ORGPOS:
X	  if (org)
X	    {
X	      header[headcnt] = safemalloc(strlen(org) + 16);
X	      sprintf(header[headcnt], "Organization: %s",
X		      org);
X	      found[i] = headcnt++;
X	    }
X	  break;
X      case FROMPOS:
X	header[headcnt] = safemalloc(strlen(from) + 8);
X	sprintf(header[headcnt], "From: %s", from);
X	found[i] = headcnt++;
X	break;
X      }
X    } else {
X      switch (i)
X	{
X	  case DATEPOS:
X	    header[found[DATEPOS]] = fix_date(header[found[DATEPOS]]);
X	    break;
X	  case EXPIREPOS:
X	    header[found[EXPIREPOS]] = fix_expire(header[found[EXPIREPOS]]);
X	    break;
X	}
X    }
X  }  
X
X  /* kill the dist header if it's to 'world' */
X  if (found[DISTPOS] != NOTFOUND)
X    if (strcmp("Distribution: world", header[found[DISTPOS]]) == 0) {
X      header[found[DISTPOS]][0] = '\0';
X      found[DISTPOS] = NOTFOUND;
X    }
X  
X  /*
X   * if chars 1-14 of Subject header is 'Subject: cmsg ', then create
X   * the Control line to read 'Control: 15th_on'
X   * 
X   * if newsgroup line contains '.ctl', build Control: line so it reads
X   * 'Control: 8th_on'
X   */
X  if ((found[SUBJECTPOS] != NOTFOUND) && (found[CTLNAMEPOS] == NOTFOUND) &&
X      (strncmp(header[found[SUBJECTPOS]], "Subject: cmsg ", 14) == 0)) {
X      /*
X       * get 'Control: ' (10) plus rest of Subject (-14)
X       */
X      header[headcnt] = safemalloc(strlen(header[found[SUBJECTPOS]]) - 3);
X      sprintf(header[headcnt], "Control: %s", header[found[SUBJECTPOS]] + 14);
X      found[CTLNAMEPOS] = headcnt;
X      headcnt++;
X    } else if ((found[NGNAMEPOS] != NOTFOUND) &&
X	       (strstr(header[found[NGNAMEPOS]], ".ctl") != (char *) NULL)) {
X      /*
X       * get 'Control: ' (10) plus rest of Subject (-9)
X       */
X      header[headcnt] = safemalloc(strlen(header[found[SUBJECTPOS]]) + 3);
X      sprintf(header[headcnt], "Control: %s", header[found[SUBJECTPOS]] + 9);
X      found[CTLNAMEPOS] = headcnt;
X      headcnt++;
X    }
X
X  /* warn if there's no subject */
X  if (found[SUBJECTPOS] == NOTFOUND)
X    {
X      fputs("defhdrs.awk: no Subject: header!", stderr);
X      status = 1;
X    }
X
X  /* warn to if there are no newsgroups listed */
X  if (found[NGNAMEPOS] == NOTFOUND)
X    {
X      fputs("defhdrs.awk: no newsgroups header!\n", stderr);
X      status = 1;
X    }
X  else
X    {
X      /* warn if there's white space anywhere after the :spc */
X      colon = strchr(header[found[NGNAMEPOS]], ' ');
X      if (colon = strpbrk(colon + 1, " \t"))
X	{
X	  fputs("defhdrs.awk: whitespace in Newsgroups: header", stderr);
X	  status = 1;
X	}
X    }
X
X  /* reorder & emit headers */
X  pme = (int *) calloc(headcnt, sizeof(int));
X  
X  for (i = KNOWSTART; i < ORDER + 1; i++) {
X    if ((found[i] != NOTFOUND) && (header[found[i]][0])) {
X      fprintf(stdout, "%s\n", header[found[i]]);
X      pme[found[i]] = 1;
X    }
X  }
X  
X  for (i = 0; i < headcnt; i++) {
X    if ((pme[i] != 1) && (header[i][0]))
X      fprintf(stdout, "%s\n", header[i]);
X  }
X  fflush(stdout);
X  exit(status);
X}
END_OF_FILE
if test 10146 -ne `wc -c <'anne.jones.c'`; then
    echo shar: \"'anne.jones.c'\" unpacked with wrong size!
fi
# end of 'anne.jones.c'
fi
if test -f 'anne.jones.sh' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'anne.jones.sh'\"
else
echo shar: Extracting \"'anne.jones.sh'\" \(587 characters\)
sed "s/^X//" >'anne.jones.sh' <<'END_OF_FILE'
X#! /bin/sh
X# anne.jones [file...] - censor headers: munge locally-generated headers in
X#  files, enforce feeble attempts at Usenet security, generate lots of silly
X#  headers.
X# Last changed: 03/26/91
X# (named after the notorious ring-leader of the Ontario Film and Video
X# Review Board (nee Ontario Board of Censors), Ontario's very own Mrs.
X# Mary Whitehouse.) 
X# =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()=
X. ${NEWSCONFIG-/usr/lib/news/bin/config}
export NEWSCTL NEWSBIN NEWSARTS
PATH=$NEWSCTL/bin:$NEWSBIN/inject:$NEWSBIN:$NEWSPATH ; export PATH
umask $NEWSUMASK
X
cat $* | exec anne.stub
END_OF_FILE
if test 587 -ne `wc -c <'anne.jones.sh'`; then
    echo shar: \"'anne.jones.sh'\" unpacked with wrong size!
fi
chmod +x 'anne.jones.sh'
# end of 'anne.jones.sh'
fi
if test -f 'anne.misc.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'anne.misc.c'\"
else
echo shar: Extracting \"'anne.misc.c'\" \(5188 characters\)
sed "s/^X//" >'anne.misc.c' <<'END_OF_FILE'
X/*
X * anne.jones - anne.misc.c - 03/26/91
X *
X * Miscellaneous routines used by anne.jones
X */
X
X#include <stdio.h>
X#include <string.h>
X#ifndef AIX		/* AIX doesn't have malloc.h.  Oh well. */
X#include <malloc.h>
X#endif
X#include <sys/types.h>
X#include <time.h>
X#include <sys/timeb.h>
X#include "anne.h"
X
char *legaldate(), *fixgmt(), *fix_date(), *fix_expire();  
extern char	*safemalloc(), *saferealloc(), *get_a_line();
X
XFILE *
trypath(route, name)
X     register char *route, *name;
X{
X  register char *s;
X  
X  if ((s = safemalloc(strlen(route) + strlen(name) + 2)) == (char *) NULL) {
X    perror("trypath safemalloc");
X    exit(1);
X  }
X  strcpy(s, route);
X  strcat(s, "/");
X  strcat(s, name);
X  
X  return (fopen(s, "r"));
X}
X
char *
squeeze(str)
X     char *str;
X{
X  register char *s, *t, *u;
X
X#ifdef	DEBUG
X  fprintf(debug, "squeeze got ->%s<-\n", str);
X#endif
X  s = str;
X  
X  /*
X    worst case it'll be as long as s .. never longer
X    */
X  t = u = safemalloc(strlen(s) + 1);
X
X  /*
X    fixed by fk@u222.rci.dk (Flemming Kraglund); it stored one too many
X    \0's, which can become a problem if the length of the string is a
X    multiple of the memory allocation size
X   */
X  for (; *s; ++s) if (*s != ' ' && *s != '\t') *t++ = *s;
X  
X  *t = '\0';
X#ifdef	DEBUG
X  fprintf(debug, "squeeze gave back ->%s<-\n", u);
X#endif
X  return (u);
X}
X
void
squeeze2(s)
X     register char *s;
X{
X  register char *t, *u, *orig;
X
X  t = u = safemalloc(strlen(s) + 8);
X#ifdef	DEBUG
X  fprintf(debug, "squeeze2 got ->%s<-\n", s);
X#endif
X  orig = s;
X  do {
X    if (!((*s < '\040') &&
X	  ((*s >= '\015') || (*s == '\013') || (*s < '\010'))
X	  )) {
X      *(t++) = *s;
X    }
X  } while (*(++s));
X  *t = '\0';
X  
X  strcpy(orig, u);
X#ifdef	DEBUG
X  fprintf(debug, "squeeze2 put ->%s<-\n", orig);
X#endif
X  free(u);
X}
X
char *
getmname(f)
X     FILE *f;
X{
X  char *s, *t;
X  s = safemalloc(NAMESIZE + 1);
X  if ((get_a_line(s, NAMESIZE, f)) == (char *) NULL) {
X    perror("getmname");
X    exit(1);
X  }
X  fclose(f);
X  if (*(t = (s + strlen(s) - 1)) == '\n')
X    *t = '\0';
X  return (s);
X}
X
int
know_head(s)
X     char *s;
X{
X  register char *t;
X  
X  if ((t = strstr(allheads, s)) != (char *) NULL)
X    return (((t - allheads) / 13) + 1);
X  else
X    return (NOTKNOWN);
X}
X
char **
buildbook(dim)
X     int dim;
X{
X  register int i;
X  register char *pages, **book;
X  
X  pages = safemalloc(dim * dim);
X  if (pages == (char *)NULL) {
X    fprintf(stderr, "No heap space for header book items!\n");
X    exit(1);
X  }
X  book = (char **) calloc(dim, sizeof(char *));
X  if (book == (char **)NULL) {
X    fprintf(stderr, "No heap space for header book!\n");
X    exit(1);
X  }
X  for (i = 0; i < dim; i++) {
X    *(book + i) = pages;
X    pages += dim;
X  }
X  return (book);
X}
X
void
termin()
X{
X  creat("/tmp/termin", 0644);
X  exit(0);
X}
X
X/* This was ripped from rn 4.3 */
X
X#ifndef	HAVESTRSTR
X/* return ptr to little string in big string, NULL if not found */
char *
strstr(big, little)
X     char *big, *little;
X{
X  register char *t, *s, *x;
X  
X  for (t = big; *t; t++) {
X    for (x = t, s = little; *s; x++, s++) {
X      if (!*x)
X	return ((char *) NULL);
X      if (*s != *x)
X	break;
X    }
X    if (!*s)
X      return (t);
X  }
X  return ((char *) NULL);
X}
X#endif	/* HAVESTRSTR */
X
X#ifdef MINIMALIST
X  /*
X   * The following is based on a program apparently written by Jon Zeeff
X   * (zeeff@b-tech.ann-arbor.mi.us). Palkovic@linac.fnal.gov, 3/22/91.
X   *
X   * A string of some valid message id characters
X   */
X
void
rand_id(s)
char *s;
X{
X   static char string[] = "!#._+-=ABCDFGHJKLMNPQRSTVWXYZ1234567890";
X   register int size = sizeof(string) - 1;
X   long num;
X
X   num = (time((long *)0) - 658216800) / 60;
X   do {
X	*s++ = string[num % size];
X	num /= size;
X   } while (num);
X
X   num = (long) getpid();
X   do {
X	*s++ = string[num % size];
X	num /= size;
X   } while (num);
X   *s = '\0';
X}
X#endif /* MINIMALIST */
X
static struct timeb epoch;
X
char *
fix_date(s)
X     char *s;
X{
X  time_t absdate;
X  
X  ftime(&epoch);
X  if ((absdate = getabsdate(s, &epoch)) < 0)
X    drop("Date:");
X  else
X      return(fixgmt(absdate, s, "Date:"));
X}
X
X/*
X * in anne.jones, there's a note that this will use getreldate instead
X *  at some point in the future
X */
char *
fix_expire(s)
X     char *s;
X{
X  time_t absdate;
X
X  ftime(&epoch);
X  if ((absdate = getdate(s, &epoch)) < (time_t)0)
X    drop("Expires:");
X  else
X      return(fixgmt(absdate, s, "Expires:"));
X}
X
drop(s)
X     char *s;
X{
X  fprintf(stderr, "anne.jones: bad %s header\n", s);
X  exit(1);
X}
X
char *
fixgmt(t, s, head)
X     time_t t;
X     char *s;
X     char *head;
X{
X  register struct tm *prstime = gmtime(&t);
X  return (legaldate(prstime, s, head));
X}
X
char *mon[12] = {
X  "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
X  "Aug", "Sep", "Oct", "Nov", "Dec",
X};
X
char *
legaldate(tm, s, head)
X     struct tm *tm;
X     char *s;
X     char *head;
X{
X  static char *dayname[8] = {  "Sun", "Mon", "Tue", "Wed", "Thu", "Fri",
X			       "Sat", "Sun",
X			    };
X  char *_tmp = safemalloc(29 + strlen(head));
X
X  sprintf(_tmp,
X	  "%s %s, %02d %s %02d %02d:%02d:%02d GMT",
X	  head,
X	  *(dayname + tm->tm_wday), tm->tm_mday,
X	  *(mon + tm->tm_mon), tm->tm_year,
X	  tm->tm_hour, tm->tm_min, tm->tm_sec);
X  free(s);
X  return(_tmp);
X}
END_OF_FILE
if test 5188 -ne `wc -c <'anne.misc.c'`; then
    echo shar: \"'anne.misc.c'\" unpacked with wrong size!
fi
# end of 'anne.misc.c'
fi
if test -f 'getline.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'getline.c'\"
else
echo shar: Extracting \"'getline.c'\" \(1997 characters\)
sed "s/^X//" >'getline.c' <<'END_OF_FILE'
X/*
X * this was mercilessly stolen from rn
X */
X
X#include <stdio.h>
X#ifndef AIX		/* AIX doesn't have malloc.h.  Oh well... */
X#include <malloc.h>
X#endif
X
typedef unsigned int	MEM_SIZE;
X#ifdef NOLINEBUF
X#define FLUSH ,fflush(stdout)
X#else
X#define FLUSH
X#endif
X
X/* just like fgets but will make bigger buffer as necessary */
X
char *
get_a_line(original_buffer, buffer_length, fp)
X     char *original_buffer;
X     register int buffer_length;
X     FILE *fp;
X{
X  register int bufix = 0;
X  register int nextch;
X  register char *some_buffer_or_other = original_buffer;
X  char *safemalloc(), *saferealloc();
X  
X  do {
X    if (bufix >= buffer_length) {
X      buffer_length *= 2;
X      if (some_buffer_or_other == original_buffer) {
X	/* currently static? */
X	some_buffer_or_other = safemalloc((MEM_SIZE) buffer_length + 1);
X	strncpy(some_buffer_or_other, original_buffer, buffer_length / 2);
X	/* so we must copy it */
X      } else {	/* just grow in place, if possible */
X	some_buffer_or_other = saferealloc(some_buffer_or_other,
X					   (MEM_SIZE) buffer_length + 1);
X      }
X    }
X    if ((nextch = getc(fp)) == EOF)
X      return ((char *) NULL);
X    some_buffer_or_other[bufix++] = (char) nextch;
X  } while (nextch && nextch != '\n');
X  some_buffer_or_other[bufix] = '\0';
X  return some_buffer_or_other;
X}
X
static char nomem[] = "annejones: out of memory!\n";
X
X/* paranoid version of safemalloc */
X
char *
safemalloc(size)
X     MEM_SIZE size;
X{
X  char *ptr;
X  extern char *malloc();
X  
X  ptr = malloc(size ? size : 1);	/* safemalloc(0) is NASTY on our
X					   system */
X  if (ptr != (char *) NULL)
X    return ptr;
X  else {
X    fputs(nomem, stdout) FLUSH;
X    exit(0);
X  }
X  /* NOTREACHED */
X}
X
X/* paranoid version of realloc */
char *
saferealloc(where, size)
X     char *where;
X     MEM_SIZE size;
X{
X  char *ptr;
X  extern char *realloc();
X  
X  ptr = realloc(where, size ? size : 1);
X
X  if (ptr != (char *) NULL)
X    return ptr;
X  else {
X    fputs(nomem, stdout) FLUSH;
X    exit(0);
X  }
X  /* NOTREACHED */
X}
END_OF_FILE
if test 1997 -ne `wc -c <'getline.c'`; then
    echo shar: \"'getline.c'\" unpacked with wrong size!
fi
# end of 'getline.c'
fi
if test -f 'spacefor.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'spacefor.h'\"
else
echo shar: Extracting \"'spacefor.h'\" \(744 characters\)
sed "s/^X//" >'spacefor.h' <<'END_OF_FILE'
X/*
X * spacefor.h - for spacefor.c
X */
X
X#define	UUCP_DIR	"/usr/spool/uucp"   /* Your uucp spool directory */
X/*
X * #undef HAVESTATFS for Ultrix; it's got one, but not what we want to use
X */
X#define HAVESTATFS			    /* have the statfs() call? */
X
X/*
X * If you're a Berkeley-based system & have 1024-byte blocks, or non-Berkeley
X * with 512-byte blocks, you don't have to do anything. If you've got a
X * special case, go below and do as directed.
X */
X#ifdef BSD
X#define BLK_SIZE        1024
X#else /* !BSD */
X#define BLK_SIZE        512
X#endif /* !BSD */
X/*
X * Uncomment these and replace custom with whatever value you need, if it
X * isn't 1024 on a Berkeley system or 512 on other types.
X */
X/*#undef BLKSIZE
X/*#define BLKSIZE         custom */
END_OF_FILE
if test 744 -ne `wc -c <'spacefor.h'`; then
    echo shar: \"'spacefor.h'\" unpacked with wrong size!
fi
# end of 'spacefor.h'
fi
if test -f 'spacefor.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'spacefor.c'\"
else
echo shar: Extracting \"'spacefor.c'\" \(3664 characters\)
sed "s/^X//" >'spacefor.c' <<'END_OF_FILE'
X/*
X * spacefor - spacefor.c - 10/5/90 - Brendan Kehoe
X *
X * a replacement for the spacefor shell script
X *
X * call with (e.g.):   spacefor.stub 1 articles [size]
X * you can specify the minimum amount of space you want left with the
X *  optional size argument (without a size argument, it uses the defaults
X *  that were in the old anne.jones
X *
X * NEWSCTL and NEWSARTS have to be exported into the environment before
X *  this is called for it to work
X */
X
X#include <stdio.h>
X#include <ctype.h>
X#include <sys/types.h>
X#ifdef HAVE_STATFS
X#include <stdlib.h> /* note: ALTOS needs this */
X#ifdef ALTOS
X#include <sys/statfs.h>
X#else /* !ALTOS */
X#include <sys/vfs.h>
X#endif
X#else /* !HAVE_STATFS */
X#include <sys/stat.h>
X#include <ustat.h>
X#endif /* HAVE_STATFS */
X#include "spacefor.h"
X
int
main(argc, argv)
X     int argc;
X     char **argv;
X{
X#ifdef HAVE_STATFS
X  struct statfs b;
X#else /* !HAVESTATFS */
X  struct stat b;
X  struct ustat device;
X#endif /* HAVESTATFS */
X  int nb, desire = 0, num_items;
X  char *arg, path_buf[100], *news_arts, *news_ctl;
X  extern char *getenv();
X  
X  if (argc < 3)
X    exit(1);
X  if ((argc == 4) && (isdigit(**(argv + 3)))) {
X    desire = atoi(*(argv + 3));
X  }
X  
X  if ((news_ctl = getenv("NEWSCTL")) == (char *)NULL) {
X    perror("newsctl");
X    puts("0");
X    exit(1);
X  }
X
X  if ((news_arts = getenv("NEWSARTS")) == (char *)NULL) {
X    perror("newsarts");
X    puts("0");
X    exit(1);
X  }
X  
X  if ((num_items = atoi(*(argv+1))) == 0) {
X    puts("10000");
X    exit(0);
X  }
X  
X  switch (*(*(argv+2))) {
X  case 'i':
X    arg = path_buf;
X    (void) strcpy(arg, news_arts);
X    (void) strcat(arg,"/in.coming");
X    desire = (desire) ? desire : 5000;
X    break;
X  case 'c': arg = news_ctl;
X    desire = (desire) ? desire : 3000;
X    break;
X  case 'o': arg = UUCP_DIR;
X    desire = (desire) ? desire : 10000;
X    break;
X  case 'a':
X    switch (*(*(argv+2)+2)) {
X    case 't': arg = news_arts;
X      desire = (desire) ? desire : 5000;
X      break;
X    case 'c': arg = news_arts;
X      desire = (desire) ? desire : 1;
X      break;
X    default: (void) fprintf(stderr, "%s: bad type argument `%s'!!\n",
X			    *argv, *(argv+2));
X      puts("0");
X      exit(2);
X    }
X    break;
X  default: (void) fprintf(stderr, "%s: bad type argument `%s'!!\n",
X			  *argv, *(argv+2));
X    puts("0");
X    exit(2);
X  }
X
X/*
X * Beware: with all of the dependancies included, this is MESSY as HELL
X */
X#ifdef HAVE_STATFS
X# ifdef ALTOS /* this is for an Altos 2000/386 */
X  if (statfs(arg, &b, sizeof(struct statfs), 0) < 0) {
X# else /* !ALTOS */
X  if (statfs(arg, &b) < 0) {
X# endif /* ALTOS */
X    nb = 0;
X    fprintf(stderr, "%s: Can't statfs() `%s'\n", *argv, arg);
X  } else
X    nb = ((int)b.f_bavail - desire) * BLK_SIZE / num_items;
X#ifdef DEBUG
X  printf("nb = (b.f_bavail - desire) * BLK_SIZE / num_items;\n");
X  printf("%d = (%ld - %d) * %d / %d;\n", nb, b.f_bavail, desire, BLK_SIZE, 
X	 num_items);
X#endif /* DEBUG */
X#else /* !HAVESTATFS */
X  if (stat(arg,&b)) {
X    nb = 0;         /* can't stat arg */
X    fprintf(stderr, "%s: Can't stat() `%s'\n", *argv, arg);
X  } else
X    if (ustat(b.st_dev, &device)) {
X      nb = 0;         /* can't stat the device */
X      fprintf(stderr, "%s: Can't ustat() `%s'\n", *argv, b.st_dev);
X    } else
X      nb = (device.f_tfree - desire) * BLK_SIZE / num_items;
X#ifdef DEBUG
X  printf("nb = (device.f_tfree - desire) * BLK_SIZE / num_items;\n");
X  printf("%d = (%d - %d) * %d / %d;\n", nb, device.f_tfree, desire, BLK_SIZE,
X	 num_items);
X#endif /* DEBUG */
X#endif /* HAVESTATFS */
X  
X  if (nb > 10000)
X    nb = 10000;
X  if (nb <= 0)
X    puts("0");
X  else
X    (void) printf("%d\n", nb);
X  return(0);	/* shut UP lint! */
X}
END_OF_FILE
if test 3664 -ne `wc -c <'spacefor.c'`; then
    echo shar: \"'spacefor.c'\" unpacked with wrong size!
fi
# end of 'spacefor.c'
fi
if test -f 'spacefor.sh' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'spacefor.sh'\"
else
echo shar: Extracting \"'spacefor.sh'\" \(1250 characters\)
sed "s/^X//" >'spacefor.sh' <<'END_OF_FILE'
X#! /bin/sh
X# spacefor - determine available disk space
X# About how many things of $1 bytes will fit in the available space for
X# stuff of type $2 ("incoming", "articles", "control", "outbound $3",
X# or "archive") without cramping things too badly?
X#
X# Last changed: 10/5/90
X#
X# Note that right now the new spacefor does NOT work on systems that aren't able
X# to do a df on a directory to see through to its mount point (e.g. can
X# do it on /usr/lib to see /usr's filesystem).
X# Edit spacefor.h to adjust your block size & uucp directory if necessary.
X#
X# Thanks to ns@iddth.id.dk for the $* and $NEWSBIN/inject stuff.
X# =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()=
X. ${NEWSCONFIG-/usr/lib/news/bin/config}
export NEWSARTS NEWSCTL NEWSBIN
PATH=$NEWSCTL/bin:$NEWSBIN:$NEWSBIN/inject:$NEWSPATH ; export PATH
umask $NEWSUMASK
X
X# punt to server if necessary
if test -r $NEWSCTL/server
then
X	server="`cat $NEWSCTL/server`"
X	me="`hostname`"
X	if test " $server" != " $me"
X	then
X		exec rsh $server -n /bin/sh -c "'PATH=$PATH `basename $0` $*'"
X		# does not return
X	fi
fi
X#
X# now speed up inews a bit by doing this in a C program instead of using awk
X# $1 = # of items, $2 = type of item, and $3, how many blocks should be left
X#  free, is optional
spacefor.stub $*
END_OF_FILE
if test 1250 -ne `wc -c <'spacefor.sh'`; then
    echo shar: \"'spacefor.sh'\" unpacked with wrong size!
fi
chmod +x 'spacefor.sh'
# end of 'spacefor.sh'
fi
if test -f 'tear.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tear.c'\"
else
echo shar: Extracting \"'tear.c'\" \(1423 characters\)
sed "s/^X//" >'tear.c' <<'END_OF_FILE'
X/*
X * tear - tear.c - 03/26/91 - Brendan Kehoe
X *
X * a replacement for the tear shell script & awk procedure
X */
X
X#include <stdio.h>
X#include <string.h>
X
extern char	*safemalloc(), *get_a_line();
X
main(argc, argv)
X	int argc;
X	char **argv;
X{
X	register char *lp;
X	register int curline;
X	extern char *safemalloc(), *get_a_line();
X	char *line, *hdr, *body;
X	short doit;
X	FILE *fin, *fout;
X
X	line = safemalloc(1001);
X	hdr = safemalloc(100);
X	body = safemalloc(100);
X
X	if (argc < 2)
X		exit(1);
X
X	if (argc == 2)
X		fin = stdin;
X	else if ((fin = fopen(*(argv+2),"r"))==(FILE *)NULL)
X		exit(1);
X
X	strcpy(hdr,*(argv+1));
X	strcpy(body,*(argv+1));
X	strcat(hdr,"hdr");
X	strcat(body,"body");
X	fout = fopen(hdr,"w");
X
X	lp = line;
X	doit = curline = 0;
X	while (get_a_line(line,1000,fin))
X	  {
X	    curline++;
X	    if (doit == 0)
X	      {
X		/* ($0 ~ /^[^ \t]*:/ || ($0 ~ /^[ \t]/ && NR > 1)) */
X		
X		if ((*lp != ' ') && (*lp != '\t'))
X		  {
X		    /* if the first is non-ws, but it doesn't have
X		       a : in it, then it's bad */
X		    
X		    if (!strchr(lp, ':'))
X		      doit = 1;
X		  }
X		else
X		  {
X		    /* if it starts with a space or a tab, and we've
X		       not gone past the first header, it's bad */
X		    
X		    if (curline <= 1)
X		      doit = 1;
X		  }
X
X		if (doit)
X		  {
X		    fclose(fout);
X		    fout = fopen(body,"w");
X		  }
X	      }
X	    fputs(line,fout);
X	  }
X
X	fclose(fout);
X	fclose(fin);
X	return(0);	/* shut UP lint! */
X}
END_OF_FILE
if test 1423 -ne `wc -c <'tear.c'`; then
    echo shar: \"'tear.c'\" unpacked with wrong size!
fi
# end of 'tear.c'
fi
echo shar: End of shell archive.
exit 0
-- cut --
-- 
     Brendan Kehoe - Widener Sun Network Manager - brendan@cs.widener.edu
  Widener University in Chester, PA                A Bloody Sun-Dec War Zone
 Now that we know he has ID, we could give him an account. finger bush@cs....