[net.sources] tarscan -- Extract subject lines from news archives

paula@bcsaic.UUCP (Paul Allen) (01/10/87)

I have received several requests for this program, and it is small, so I
am posting it.  Tarscan is useful for packrats like myself who sometimes
find themselves rummaging around in the news archive tapes looking for
something that they didn't have the foresight to save the first time
around.  See the readme file for more details.

+------------------ Cut Here --------------------------------------+
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	readme
#	tarscan.c
# This archive created: Fri Jan  9 23:57:18 1987
export PATH; PATH=/bin:$PATH
if test -f 'readme'
then
	echo shar: will not over-write existing file "'readme'"
else
sed 's/^X//' << \SHAR_EOF > 'readme'
Xtarscan  --  a news archive tape scanner
X
XThis program reads a tar-format news archive tape and writes to 
Xstandard out a list of file names and Subject: lines.  It was written 
Xon a VAX running Ultrix.  I suspect (but do not know) that the format 
Xof tar tapes may differ on other varieties of Unix.  I wrote this 
Xprogram for my own use and have no excuse for any sloppy code you may 
Xfind herein.  You can do anything you like with this code.  If you 
Xsignificantly enhance it, or know of some faster/easier way to do the 
Xsame thing, drop me a note.
X
XTo build the program, just compile it.  There's no makefile.
X
XThe program takes no arguments.  The name of the tape device is
Xhard-coded.  An obvious enhancement would be to use argv[1] as the file
Xto open.  That's an exercise for the reader.  I usually pipe tarscan's
Xoutput into a file with a name that relates to the tape being scanned.
XThat way I can grep around in my tarscan listings and get a list telling
Xme the tape to mount, the files to load from the tape, and the subject
Xlines from the articles of interest.  It helps to scan new archive tapes
Xon a regular basis so you don't have to process a half dozen of them
Xbefore you can start looking for that particular article that's going to
Xsave your life.
X
XOne side note.  I have scanned about a year and a half of news tapes.
XThe resulting tables of contents occupy about 5Mb!  You better believe
Xit takes a while to grep through that much stuff.
X
XHave fun!
XPaul Allen
X
SHAR_EOF
fi # end of overwriting check
if test -f 'tarscan.c'
then
	echo shar: will not over-write existing file "'tarscan.c'"
else
sed 's/^X//' << \SHAR_EOF > 'tarscan.c'
X/*
X *	tarscan.c
X *
X *	News archive tape scanner.
X *
X *	Reads a tar news archive, extracts tape file names and
X *	associated subject lines, and writes same to stdout.
X *
X *	Written for Ultrix, but will probably work at most BSD sites.
X *
X *	Paul L. Allen
X *	July, 1986
X */
X
X#include <stdio.h>
X#include <sys/file.h>
X#include <strings.h>
X
Xmain () {
X
X#define TBLOCK	512
X#define NAMSIZ	100
X
Xunion hblock {
X	char dummy [TBLOCK];
X	struct header {
X		char name [NAMSIZ];
X		char mode [8];
X		char uid[8];
X		char gid [8];
X		char size [12];
X		char mtime [12];
X		char chksum [8];
X		char linkflag;
X		char linkname [NAMSIZ];
X	} dbuf;
X} *myblock;
X
Xint size;
Xint nblocks;
Xint mt;
Xchar *cptr, *tptr, filename[100];
Xint firstblock;
X
Xif ((mt=open("/dev/rmt0", O_RDONLY, 0)) == -1) {
X	perror ("tarscan: /dev/rmt0");
X	exit(0);
X	}
X
Xfirstblock = 0;
Xnblocks = 0;
Xwhile (myread(&myblock, TBLOCK, mt)) {
X	if (nblocks) {
X		nblocks--;
X		if (firstblock) {
X			firstblock = 0;
X			myblock->dbuf.name[TBLOCK-1] = 0;
X			cptr = myblock->dbuf.name;
X			while (tptr=index(cptr, '\n')) {
X				*tptr = 0;
X				cptr[7] = 0;
X				if (strcmp(cptr, "Subject") == 0) {
X				    printf ("%s   %s\n", filename, cptr+8);
X				    break;
X				    }
X				cptr = tptr+1;
X				}
X			}
X		}
X	else {
X		if (myblock->dbuf.name[0] == 0) {
X			exit (0);
X			}
X		if (myblock->dbuf.name[NAMSIZ-1]) {
X			printf ("name > 100 bytes! aborting...\n");
X			exit (1);
X			}
X		sscanf (myblock->dbuf.size, "%o", &size);
X		if (myblock->dbuf.linkflag == '1') size = 0;
X		nblocks = (size/TBLOCK) + ((size % TBLOCK) > 0);
X		strcpy (filename, myblock->dbuf.name);
X		firstblock = (nblocks > 0);
X		}
X	}
X}
X
X#define TAPEBLK 10240
Xchar tapebuff [TAPEBLK];
Xint buffpos = TAPEBLK;
X
Xmyread (buff, size, mt)
X
Xchar **buff;
Xint size;
Xint mt;
X{
X	if (buffpos == TAPEBLK) {
X		if (read (mt, tapebuff, TAPEBLK) == 0) {
X			perror("tarscan");
X			exit (1);
X			}
X		buffpos = 0;
X		}
X	*buff = &tapebuff[buffpos];
X	buffpos+=TBLOCK;
X	return (1);
X}
X
SHAR_EOF
fi # end of overwriting check
#	End of shell archive
exit 0
-- 
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Paul L. Allen                           | "Look out, men! He's armed!"
Boeing Advanced Technology Center       |        "I've got a cheese grater,
POB 24346 M/S 7L-44,                    |        and I'm not afraid to use it!"
Seattle, WA, USA 98124                  | "Don't make it any harder 
(206) 865-3207                          | on yourself, kid! Drop it!"
...!uw-beaver!ssc-vax!bcsaic!paula      |        "Eat mozzarella, copper!"