[comp.sources.misc] v09i100: Trouble Report System 2

rjs@a.cs.okstate.edu (Roland Stolfa) (01/05/90)

Posting-number: Volume 9, Issue 100
Submitted-by: rjs@a.cs.okstate.edu (Roland Stolfa)
Archive-name: trs2_rs

Hello,

This is a set of Bourne shell scrips and C programs intended
to maintain a database of trouble reports.  The actions supported
in this package are open a trouble report (trouble), post a followup
on a trouble report (followup), remove a 'thread' of trouble reports
(rmthread), report all open trouble report ticket numbers (opentr),
and summarize a class of trouble reports (report).

Roland J. Stolfa
Department of Computing and Information Sciences
Oklahoma State University

Internet:       rjs@a.cs.okstate.edu

Disclaimer:	You have lost your MIND if you think ANYBODY speaks for
		this place!

echo x - README
sed '1,$s/^X//' <<\!FUNKY!STUFF! > README
XINTRODUCTION:
X
X	This is the Trouble Report System (TRS2) by
X
X	@(#) README 1.2 89/12/19
X
X	Roland J. Stolfa
X	Department of Computing and Information Sciences
X	Oklahoma State University
X
X	Internet:       rjs@a.cs.okstate.edu
X
X
XDISCLAIMER:
X
X	All code is public domain.  No guarentee, expressed nor implied,
X	covers this code.  I will NOT be responsible for it's use or
X	misuse in your application.  I just hope (Underline that in red)
X	that it may prove useful to you.  If something doesn't compile,
X	I hope that the comments that surround the troble line will be
X	sufficient to fix the problem.
X
X
XDESCRIPTION:
X
X	This is a set of Bourne shell scrips and C programs intended
X	to maintain a database of trouble reports.  The actions supported
X	in this package are open a trouble report (trouble), post a followup
X	on a trouble report (followup), remove a 'thread' of trouble reports
X	(rmthread), report all open trouble report ticket numbers (opentr),
X	and summarize a class of trouble reports (report).
X
X	As the second release of this package, several things have been
X	attempted to clean up the operation.  First off, the links (using
X	"ln(2)") have been done away with.  This has been replaced by using
X	the trouble ticket id number stored in a soundex index file.  Second,
X	some race conditions have been handled better using the "P" and "V"
X	shell commands, contained herein.
X
X
XINSTALLATION PROCEDURES:
X
X1.	Make a directory and put this shar in it.  Then say "sh <fn>".
X
X2.	Edit the file "Localize" to point the "ROOT", "BIN" and
X	shell script escape sequences at the localally correct
X	values.  Then type "sh Localize" to install these values
X	on all files in this directory.  Then edit the Makefile
X	and change the -DSYS5 to either -DSYS5 or -DULTRIX.
X
X3.	Say "make install".  This makes the various directories &
X	sets the permissions to allow the next procedure to function.
X
X4.	Say "make all".
X
X5.	Done.
X
X
XDIRECTORY STRUCTURE:
X
X			  /usr/local/lib/Trs
X				|
X		+---------------+---------------+
X    		|		|		|
X	      Entry	       Seq	      Xref
X		|				|
X	    +---+-----+			+-------+-------+
X	    |   ...   |			|		|
X   <Timestamp1> ... <Timestamp1>     <Soundex> ... <Soundex>
X
XEach TRS record is first built in a temporary.  It is then copied into the
X.../Trs/Entry/<Timestamp>" file.  Then it is referenced in a file in the
X.../Trs/Xref subdirectory for each SOUNDEX encoded keyword given during
Xdata entry.
X
X
XNOTES:
X
X1.	If the average TRS record size is small and the default
X	block size on the storage device is large, you loose...
X
X2.	Each user can override the default "ROOT" setting by having
X	an environment variable "TRSROOT" set to some directory
X	that has the same structure as the one above.
X
X
XFILES:
X
X	Localize
X
X		This shell script patches all the files in this system to
X		work with the locally chosen directories.
X
X	Makefile
X
X		Used to create all the executables for each program.
X
X	README
X
X		This file.
X
X	followup.sh
X
X		This program is used to enter a follow up report onto
X		the end of a TRS thread.  It walks the thread, from anywhere
X		on the thread, to then end and then doubly links the end
X		of the current thread to the new report.
X
X	opentr.sh
X
X		This shell script lists the initial trouble report ticket
X		number for all active trouble reports.
X
X	print.c
X
X		This simple program is used to print all the command line
X		arguments on a line by itself without a carriage return
X		on the end.
X
X	report.sh
X
X		This shell script attempts to extract data from the TRS
X		database given any combination of keys.
X
X	rmthread.sh
X
X		This shell script removes an entire linked list of trouble
X		reports, given a report anywhere in the list.
X
X	soundex.c
X
X		This C program implements a "SOUNDEX" algorithm and is used
X		in the TRS to encode keywords within the database to ease
X		searching.
X
X	trouble.sh
X
X		This shell script does the actual data entry for the TRS system.
X		It attempts to prompt for all the relavant data, generates
X		some stuff by default, and then builds all the linked files
X		that constitue the database.
X
X	P.c, V.c, lockp.c
X
X		These two programs provide a method of binary semaphores from
X		the shell using "link(2)" to be the final arbitrator.
X
X	*.1
X
X		Manual pages for all of the directly executable programs above.
!FUNKY!STUFF!
echo x - Localize
sed '1,$s/^X//' <<\!FUNKY!STUFF! > Localize
X#
X# Localizing script for the (T)rouble (R)eport (S)ystem
X#
X#	@(#) Localize 1.2 89/12/19
X#
X
Xfor i in Makefile *.sh
Xdo
X
X	#
X	# Attach the "ROOT" to some clean point like /usr/local/lib/trs
X	# as this will need to be a publically writable directory that
X	# will hold all trouble reports.
X	#
X	# Attach the "BIN" to some global point like /usr/lbin for all
X	# the executables
X	#
Xed - $i <<'EOF'
Xg;^ROOT;s;=.*$;=/u/rjs/lib/Trs;
Xg;^BIN;s;=.*$;=/u/rjs/bin;
Xw
Xq
XEOF
X
Xdone
X
Xfor i in *.sh
Xdo
X
X	#
X	# The ":" in the ed script below is the first line of all shell
X	# scripts for SYS5.  For ULTRIX, it should be "#!/bin/sh".
X	#
Xed - $i <<'EOF'
X1 s;^.*$;:;
Xw
Xq
XEOF
X
Xdone
!FUNKY!STUFF!
echo x - Makefile
sed '1,$s/^X//' <<\!FUNKY!STUFF! > Makefile
X#
X# Package	: TRS
X# Module	: (Makefile)
X# Programmer	: R. Stolfa
X# SCCS id	: @(#) Makefile 1.2 89/12/19
X#
X# Purpose :	To maintain a Trouble Report System for an
X#		university environment
X#
X# Modification History:
X#   04/11/88	Created
X#   10/25/88	Updated for distribution outside of OSU
X#
X#   10/16/89	Rewrote for release 2
X#
XROOT =		/u/rjs/lib/Trs
XBIN =		/u/rjs/bin
XCFLAGS =	-O -DSYS5		# For System 5 Un*x
X#CFLAGS =	-O -DULTRIX		# For VAX Ultr*x
XMANDIR =	/u/rjs/lib/man/l_man/man1
XMANPAGES =	followup.1 opentr.1 report.1 rmthread.1 trouble.1 P.1 V.1
X
XDuMb:
X	@echo Make what?
X
Xfollowup:	$(BIN)/followup
X$(BIN)/followup:	followup.sh
X	cp followup.sh $(BIN)/followup
X	chmod 755 $(BIN)/followup
X
Xopentr:	$(BIN)/opentr
X$(BIN)/opentr:	opentr.sh
X	cp opentr.sh $(BIN)/opentr
X	chmod 755 $(BIN)/opentr
X
Xprint:	$(BIN)/print
X$(BIN)/print:	print.c
X	cc print.c -o $(BIN)/print
X	chmod 755 $(BIN)/print
X
Xreport:	$(BIN)/report
X$(BIN)/report:	report.sh
X	cp report.sh $(BIN)/report
X	chmod 755 $(BIN)/report
X
Xrmthread:	$(BIN)/rmthread
X$(BIN)/rmthread:	rmthread.sh
X	cp rmthread.sh $(BIN)/rmthread
X	chmod 755 $(BIN)/rmthread
X
Xsoundex:	$(BIN)/soundex
X$(BIN)/soundex:	soundex.c
X	cc soundex.c -o $(BIN)/soundex
X	chmod 755 $(BIN)/soundex
X
Xtrouble:	$(BIN)/trouble
X$(BIN)/trouble:	trouble.sh
X	cp trouble.sh $(BIN)/trouble
X	chmod 755 $(BIN)/trouble
X
XP:	$(BIN)/P
X$(BIN)/P:	P.c lockp.c
X	cc P.c lockp.c -o $(BIN)/P
X	chmod 755 $(BIN)/P
X
XV:	$(BIN)/V
X$(BIN)/V:	V.c lockp.c
X	cc V.c lockp.c -o $(BIN)/V
X	chmod 755 $(BIN)/V
X
X#
X# Housekeeping
X#
X
Xall:	followup opentr print report rmthread soundex trouble P V
X	@echo "Don't forget 'make install' to setup sequence file"
X
Xbackout:	clean
X	rm -rf $(ROOT)
X	rm -if $(BIN)/followup $(BIN)/opentr $(BIN)/report $(BIN)/rmthread \
X		$(BIN)/trouble $(BIN)/print $(BIN)/soundex $(BIN)/P $(BIN)/V
X	cd $(MANDIR) ; rm -f $(MANPAGES)
X
Xclean:
X	rm -f *.o a.out core
X
Xinstall:
X	-mkdir $(ROOT) $(ROOT)/Entry $(ROOT)/Xref
X	chmod 777 $(ROOT) $(ROOT)/Entry $(ROOT)/Xref
X	echo "0" > $(ROOT)/sequence
X	cp $(MANPAGES) $(MANDIR)
X
Xrub:
X	rm -f $(ROOT)/Entry/* $(ROOT)/Xref/*
X	echo "0" > $(ROOT)/sequence
X
Xshar:
X	shar README Localize Makefile [PVa-z]* > Trs.shar
!FUNKY!STUFF!
echo x - P.1
sed '1,$s/^X//' <<\!FUNKY!STUFF! > P.1
X'\" @(#) P.1 1.2 89/10/30
X.TH P 1 L
X.SH NAME
XP - Performs binary semaphore operations using lock files.
X.sp 1
X.SH SYNTAX
XP [ -w ] [[ -e ] / [ -f <fixed> ]] -l <lockfile>
X.sp 1
X.SH DESCRIPTION
X.I P
XAttempts to generate the named
X.I <lockfile>
Xusing the
X.I lockp(3L)
Xprocedure.  This attempts to provide a binary semaphore operation
Xfrom the shell.  One of the parameters
X.I -e
Xor
X.I "-f <fixed>"
Xmust be specified.  If the user specifies the
X.I -w
Xoption, then a warning message appears on stderr for every attempt to get the
Xlock file installed.  If the user specifies the
X.I -e
Xoption, an exponential decay is applyed to the time waited between
Xattempts to get the semaphore file in place.  If the user specifies the
X.I "-f <fixed>"
Xoption, then the fixed period of time
X.I <fixed>
Xis waited between each attempt to get the semaphore file in place.
XThe option
X.I "-l <lockfile>"
Xmust be present and implies that the named
X.I <lockfile>
Xis the name of the binary semaphore to be used.
X.sp 1
X.SH "INTERNALS"
XThis program uses the
X.I lockp(3L)
Xcode to generate the semaphore file.  It is fairly fool proof, but may be
Xgoofed up upon systems with more than one processor accessing the disk
Xdrive system at once.
X.sp 1
X.SH RETURN VALUE
XIf there is an error in the command line arguments, a
X.I -1
Xis returned.  Otherwise, the exit status is
X.I 0
Xand the 
X.I "<lockfile>"
XPID is returned on stdout.
X.SH SEE ALSO
XV(1L), lockp(3L), unlockp(3L)
X.sp 1
X.SH VERSION
X1.2
X.sp 1
X.SH AUTHOR
XRoland J. Stolfa
X.br
XDepartment of Computing and Information Sciences
X.br
XOklahoma State University
X.br
Xrjs@a.cs.okstate.edu
!FUNKY!STUFF!
echo x - P.c
sed '1,$s/^X//' <<\!FUNKY!STUFF! > P.c
X/*
X * Program	: LIBRARY (lockp)
X * Module	: T_P.c
X * Functions	: main, usage
X * Programmer	: R. Stolfa (rjs@a.cs.okstate.edu)
X * SCCSid	: @(#) P.c 1.2 89/10/30
X *
X * Purpose :	To provide a process locking facility to the shell.
X *
X * Modification History:
X *   05/11/89	Created
X *   08/31/89	Modified to work with "T_V.c" by outputing the PID of
X *		the process that made the lockfile (this one) on stdout
X *		for later use by "T_V.c" in removing that lock.
X */
X
X/**
X***	Copyright (c) 1989, Roland J. Stolfa,  Right to copy is
X***	granted so long as it is not for monetary gain and this
X***	message and all headers in all files remain in tact.
X***
X***	THE AUTHOR DOES NOT MAKE ANY WARRANTIES, EITHER EXPRESS
X***	OR IMPLIED, AS TO ANY MATTER WHATSOEVER, INCLUDING WITHOUT
X***	LIMITATION, THE CONDITION OF THIS DISTRIBUTION, ITS
X***	MERCHANTABILITY OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
X**/
X
Xstatic char	*sccsid = "@(#) P.c 1.2 89/10/30";
X
X#include	<stdio.h>
X
X#define		FALSE		0
X#define		TRUE		1
X
Xmain (argc, argv)
X	int	argc;
X	char	*argv[];
X{
X	extern int	optind;
X	extern char	*optarg;
X	int		c;
X
X	int	exponential,
X		fixed,
X		delay,
X		warn;
X	char	*fnptr;
X
X	/*
X	 * Parse those command line arguments.
X	 */
X	exponential = fixed = FALSE;
X	fnptr = NULL;
X	warn = FALSE;
X	while ((c = getopt (argc, argv, "ef:l:w")) != EOF) {
X		switch (c) {
X		case 'e':
X			exponential = TRUE;
X			delay = 1;
X#ifdef DEBUG
X			printf ("exponential delay set to %d\n", delay);
X#endif
X			break;
X		case 'f':
X			fixed = atoi (optarg);
X			if (fixed > 101)
X				fixed = 101;
X			delay = fixed;
X#ifdef DEBUG
X			printf ("fixed delay set to %d\n", delay);
X#endif
X			break;
X		case 'l':
X			fnptr = optarg;
X#ifdef DEBUG
X			printf ("got >%s< as lock file name\n", fnptr);
X#endif
X			break;
X		case 'w':
X			warn = TRUE;
X			break;
X		default:
X			usage();
X			/*NOTREACHED*/
X		}
X	}
X	if ((exponential == fixed) || (fnptr == NULL))
X		usage();
X		/*NOTREACHED*/
X
X	while (lockp (fnptr) < 0) {
X		if (warn == TRUE)
X			fprintf (stderr,
X				"Waiting on lock file >%s<...\n", fnptr);
X		sleep (delay);
X		if (exponential == TRUE) {
X			if (delay != 100)
X				delay = delay * 10;
X#ifdef DEBUG
X			printf ("Adjusting exponential delay to %d\n", delay);
X#endif
X		}
X	}
X#ifdef DEBUG
X	printf ("P: exiting\n");
X#endif
X	printf ("%d\n", getpid());
X}
X
Xusage ()
X{
X	fprintf (stderr, "Usage: P { -e / -f<fixed> } [-w] -l <fn>\n");
X	exit (-1);
X}
!FUNKY!STUFF!
echo x - V.1
sed '1,$s/^X//' <<\!FUNKY!STUFF! > V.1
X'\" @(#) V.1 1.2 89/10/30
X.TH V 1 L
X.SH NAME
XV - Performs binary semaphore operations using lock files.
X.sp 1
X.SH SYNTAX
XV -i <pid> -l <lockfile>
X.sp 1
X.SH DESCRIPTION
X.I V
Xattempts to remove the named
X.I <lockfile>
Xusing the
X.I unlockp(3L)
Xprocedure.  This attempts to provide a binary semaphore operation
Xfrom the shell.  The user must specify both the
X.I "-i <pid>"
Xand the
X.I "-l <lockfile>"
Xparameters.
XThe
X.I "-i <pid>"
Xparameter is what is looked for in the named lock file.  This is the
XPID returned by
X.I "P(1L)"
Xon stdout that it put in the named
X.I "<lockfile>"
Xupon creation.
X.I "-l <lockfile>"
Xmust be present and implies that the named
X.I <lockfile>
Xis the name of the binary semaphore to be used.
X.sp 1
X.SH "INTERNALS"
XThis program uses the
X.I unlockp(3L)
Xcode to generate the semaphore file.  It is fairly fool proof, but may be
Xgoofed up upon systems with more than one processor accessing the disk
Xdrive system at once.
X.sp 1
X.SH RETURN VALUE
XIf there is an error in the command line arguments or the named
X.I "<lockfile>"
Xdoes not contain the named
X.I "<pid>"
X, a
X.I -1
Xis returned.  Otherwise, 
X.I 0
Xis returned.
X.SH SEE ALSO
XP(1L), unlockp(3L), lockp(3L)
X.sp 1
X.SH VERSION
X1.2
X.sp 1
X.SH AUTHOR
XRoland J. Stolfa
X.br
XDepartment of Computing and Information Sciences
X.br
XOklahoma State University
X.br
Xrjs@a.cs.okstate.edu
!FUNKY!STUFF!
echo x - V.c
sed '1,$s/^X//' <<\!FUNKY!STUFF! > V.c
X/*
X * Package	: LIBRARY (lockp)
X * Module	: T_V.c
X * Functions	: main, usage
X * Programmer	: R. Stolfa (rjs@a.cs.okstate.edu)
X * SCCSid	: @(#) V.c 1.2 89/10/30
X *
X * Purpose :	This program remove a lock file as generated in
X *		"T_P.c" if the associated PID matches
X *
X * Modification History:
X *   08/31/89	Created
X *   10/30/89	Changed to reflect changes in "unlockp(3L)" code.
X */
X
X/**
X***	Copyright (c) 1989, Roland J. Stolfa,  Right to copy is
X***	granted so long as it is not for monetary gain and this
X***	message and all headers in all files remain in tact.
X***
X***	THE AUTHOR DOES NOT MAKE ANY WARRANTIES, EITHER EXPRESS
X***	OR IMPLIED, AS TO ANY MATTER WHATSOEVER, INCLUDING WITHOUT
X***	LIMITATION, THE CONDITION OF THIS DISTRIBUTION, ITS
X***	MERCHANTABILITY OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
X**/
X
Xstatic char	*sccsid = "@(#) V.c 1.2 89/10/30";
X
X#include	<stdio.h>
X
X#include	"lockp.h"
X
X#define		BUFSZ		80
X
Xmain (argc, argv)
X	int	argc;
X	char	*argv[];
X{
X	extern int	optind;
X	extern char	*optarg;
X	int		c;
X
X	char	*lockfn;	/* The name of the lockfile */
X	int	pid;		/* Pid of original parent */
X
X	/*
X	 * Parse those comand line parameters.
X	 */
X	if (argc < 5)
X		usage ();
X		/*NOTREACHED*/
X	pid = 0;
X	lockfn = NULL;
X	while ((c = getopt (argc, argv, "i:l:")) != EOF)
X		switch (c) {
X		case 'i':	pid = atoi(optarg);	break;
X		case 'l':	lockfn = optarg;	break;
X		default:	usage(); /*NOTREACHED*/	break;
X		}
X	if ((pid == 0) || (lockfn == NULL))
X		usage();
X		/*NOTREACHED*/
X
X	/*
X	 * Call "unlockp(3L)" to check on sanity and do all the right
X	 * things about getting rid of the lock file.  If it returns
X	 * an error condition, bitch about it.
X	 */
X	switch (unlockpp(lockfn,pid)) {
X	case LOCKP_BADF:
X		fprintf (stderr, "V: bad lock file name\n");
X		exit (-1);
X		/*NOTREACHED*/
X	break;
X
X	case LOCKP_EMPTY:
X		fprintf (stderr, "V: lock file is empty\n");
X		exit (-1);
X		/*NOTREACHED*/
X	break;
X
X	case LOCKP_BADPID:
X		fprintf (stderr, "V: lock file is not owned by given pid\n");
X		exit (-1);
X		/*NOTREACHED*/
X	break;
X
X	default:
X		exit (0);
X		/*NOTREACHED*/
X	break;
X	}
X}
X
Xusage ()
X{
X	fprintf (stderr,
X		"Usage: V -i <pid> -l <fn>\n");
X	exit (-1);
X}
!FUNKY!STUFF!
echo x - followup.1
sed '1,$s/^X//' <<\!FUNKY!STUFF! > followup.1
X'\" @(#) followup.1 1.2 89/12/19
X.TH FOLLOWUP L
X.SH NAME
Xfollowup - post a followup trouble report
X.SH SYNOPSIS
X.B followup [ ticket number ]
X.br
X.SH DESCRIPTION
X.I followup
Xis intended to be the method of posting a new report in a "thread" of
Xreports associated with a reported problem in hardware/software.
X.PP
XIf 
X.I followup
Xis invoked without a ticket number, it prompts for one.  Then an entire
Xnew trouble report is attached to a thread of reports associated together.
XThis list of reports is doubly linked in the trouble report file and then
Xadded to all soundex encoded search files relating to the keywords specified.
X.PP
XAll of the files and directories contained in the system are all plain
Xtext files, with an easy format that can be used to your advantage.
X.sp 1
X.SH "INTERNALS"
X.I followup
Xuses a tree structured file data-base to store all trouble reports.  Each
Xreport occupies one file in the "../Trs/Entry" directory with the name
Xbeing equal to that of the date (in YYMMDD format) and a sequence number
Xappended (i.e. 881025.1).  This file is then referenced in
X"../Trs/Xref/<soundex>" for each keyword specified in the
X.I followup
Xkeyword prompt.  Each keyword is encoded via the
X.I soundex
Xalgorithm to be the "link" directory.  This allows fast searches of
Xrecurring problems (see "report(L)").
X.SH "FILES"
X"/usr/local/lib/trs/...."	- Root directory for help
X.br
X"/usr/local/lib/trs/Entry/..."	- Directory where ALL trouble reports reside
X.br
X"/usr/local/lib/trs/Xref/..."   - Directory of soundex encoded cross references
X.br
X"/usr/local/lib/trs/sequence"	- Sequence file
X.PP
X.SH DIAGNOSTICS
XThere are no real diagnostics.
X.SH AUTHOR
XRoland J. Stolfa
X.br
XDepartment of Computing and Information Sciences
X.br
XOklahoma State University
X.br
Xrjs@a.cs.okstate.edu
!FUNKY!STUFF!
echo x - followup.sh
sed '1,$s/^X//' <<\!FUNKY!STUFF! > followup.sh
X:
X#
X# Package	: (Trs2)
X# Module	: followup.sh
X# Programmer	: R. Stolfa (rjs@a.cs.okstate.edu)
X# SCCSid	: @(#) followup.sh 1.2 89/12/19
X#
X# Purpose :	To 'needle & thread' TRS records together.
X#
X# Modification History:
X#   04/12/88	Created
X#   10/25/88	Added user configurable "ROOT" to allow more than
X#		one TRS to exist on a particular system.
X#
X#   10/16/89	Release 2 started.
X#
X
X###
X###	Copyright (c) 1989, Roland J. Stolfa,  Right to copy is
X###	granted so long as it is not for monetary gain and this
X###	message and all headers in all files remain in tact.
X###
X###	THE AUTHOR DOES NOT MAKE ANY WARRANTIES, EITHER EXPRESS
X###	OR IMPLIED, AS TO ANY MATTER WHATSOEVER, INCLUDING WITHOUT
X###	LIMITATION, THE CONDITION OF THIS DISTRIBUTION, ITS
X###	MERCHANTABILITY OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
X###
X
X#
X# Get configured.
X#
Xif [ "${TRSROOT}" != "" ]
Xthen
X	ROOT = ${TRSROOT}
Xelse
XROOT=/u/rjs/lib/Trs
Xfi
XEntry=${ROOT}/Entry
X
XBIN=/u/rjs/bin
XPATH=${BIN}:/bin:/usr/bin
Xexport PATH
Xumask 022
XPager=${PAGER:-pg}
X
X#
X# Ok.  Get the 'trouble ticket' number.
X#
Xnum="$*"
Xif test ! -s ${Entry}/${num}
Xthen
X	echo "Invalid trouble ticket number.  Try again."
X	num=""
Xfi
Xwhile [ "${num}" = "" ]
Xdo
X	${BIN}/print "Enter trouble ticket number? "
X	read num
X
X	if test ! -s ${Entry}/${num}
X	then
X		echo "Invalid trouble ticket number.  Try again."
X		num=""
X	fi
Xdone
X
X#
X# Follow it's threads until you reach the last one.
X#
Xthread="+"
Xwhile [ "${thread}" != "" ]
Xdo
X	thread="`grep '^thread=' ${Entry}/${num} | awk -F= '{print $2}'`"
X	if [ "${thread}" != "" ]
X	then
X		num="${thread}"
X	fi
Xdone
X
X#
X# Display last entry.
X#
Xecho "Last entry as follows:"
Xecho ""
Xecho "ticket=${num}"
Xecho "reporter=`ls -l ${Entry}/${num} | awk '{print $3}'`"
X${Pager} ${Entry}/${num}
Xecho ""
Xyesno=""
Xwhile [ "${yesno}" = "" ]
Xdo
X	${BIN}/print "Is this the correct one? (Y/N) "
X	read yesno
Xdone
X
X#
X# If incorrect, try again.
X#
Xif [ "${yesno}" = "N" -o "${yesno}" = "n" ]
Xthen
X	exec ${BIN}/followup
Xfi
X
X#
X# Ok.  Generate a new trouble report and then fix the threading.
X# Do this by 'including' the trouble ticket generator.
X#
Xnumber=${num}
X. ${BIN}/trouble
Xecho "thread=${NTN}" >> ${Entry}/${number}
Xecho "needle=${num}" >> ${Entry}/${NTN}
!FUNKY!STUFF!
echo x - lockp.c
sed '1,$s/^X//' <<\!FUNKY!STUFF! > lockp.c
X/*
X * Package	: LIBRARY (lockp)
X * Module	: lockp.c
X * Functions	: lockp, unlockp
X * Programmer	: R. Stolfa (rjs@a.cs.okstate.edu)
X * SCCSid	: @(#) lockp.c 1.3 89/10/30
X *
X * Purpose :	To provide a system portable way of binary semaphores
X *		(via linked files in the file system) for Un*x.
X *
X * Modification History:
X *   05/08/89	Created
X *   10/03/89	Ported to ULTRIX
X *   10/30/89	Optimized generation of temporary file name.
X *      -	Rewrote "unlockp" to do more of the job.
X */
X
X/**
X***	Copyright (c) 1989, Roland J. Stolfa,  Right to copy is
X***	granted so long as it is not for monetary gain and this
X***	message and all headers in all files remain in tact.
X***
X***	THE AUTHOR DOES NOT MAKE ANY WARRANTIES, EITHER EXPRESS
X***	OR IMPLIED, AS TO ANY MATTER WHATSOEVER, INCLUDING WITHOUT
X***	LIMITATION, THE CONDITION OF THIS DISTRIBUTION, ITS
X***	MERCHANTABILITY OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
X**/
X
Xstatic char	*sccsid = "@(#) lockp.c 1.3 89/10/30";
X
X#include	<stdio.h>
X#ifdef ULTRIX
X#include	<sys/file.h>
X#else
X#include	<fcntl.h>
X#endif
X
Xextern char	*strrchr();
X
X#include	"lockp.h"
X
X/* #define		DEBUG /* */
X
X#define		BIGBUFSZ	512
X#define		SMLBUFSZ	80
X
Xint lockp (final)
X	char	*final;
X{
X	int	len,
X		pidlen,
X		fd;
X	char	*ptr,
X		fn[BIGBUFSZ],
X		pidbuf[SMLBUFSZ];
X
X	/*
X	 * Generate the temporary file name.
X	 */
X	fn[0] = '\0';
X	if ((ptr = strrchr (final, '/')) != NULL) {
X		len = ptr - final + 1;
X		strncpy (fn, final, len);
X		fn[len] = '\0';
X	}
X	strcat (fn, "LCK.XXXXXX");
X#ifdef DEBUG
X	fprintf (stderr, "lockp:  generated >%s< as lock fn pattern\n", fn);
X#endif
X	mktemp (fn);
X#ifdef DEBUG
X	fprintf (stderr, "lockp:  generated >%s< as lock fn\n", fn);
X#endif
X
X	/*
X	 * Attempt to create the lock temporary file.  If anything
X	 * goes wrong, return -1.
X	 */
X	sprintf (pidbuf, "%d\n", getpid());
X	pidlen = strlen (pidbuf) + 1;
X	if ((fd = open (fn, O_WRONLY | O_CREAT | O_TRUNC, 0644)) < 0) {
X#ifdef DEBUG
X		fprintf (stderr, "lockp:  open(2) failed on >%s<\n", fn);
X		perror (fn);
X#endif
X		return (-1);
X	}
X	if (write (fd, pidbuf, pidlen) != pidlen) {
X#ifdef DEBUG
X		fprintf (stderr, "lockp:  write(2) failed\n");
X#endif
X		close (fd);
X		unlink (fn);
X		return (-1);
X	}
X	close (fd);
X
X	/*
X	 * Now comes the real locking.  If the "link(2)" function fails,
X	 * someone else already has the lock.  Else we have it.
X	 */
X	if (link (fn, final) < 0) {
X#ifdef DEBUG
X		fprintf (stderr, "lockp:  link(2) failed\n");
X#endif
X		unlink (fn);
X		return (-1);
X	}
X
X	/*
X	 * Now let's clean up the directory by removing the temp file.
X	 */
X	unlink (fn);
X	return (0);
X}
X
Xint unlockpp (final, pid)
X	char	*final;
X	int	pid;
X{
X	FILE	*fp;		/* File pointer for lockfile */
X	char	buff[SMLBUFSZ];
X
X	/*
X	 * Get the lock file open and read it's id.
X	 */
X	if ((fp = fopen (final, "r")) == NULL) {
X#ifdef DEBUG
X		fprintf (stderr, "unlockp:  fopen(3) failed\n");
X		perror (lockfn);
X#endif
X		return (LOCKP_BADF);
X	}
X	if (fgets (buff, SMLBUFSZ, fp) == NULL) {
X#ifdef DEBUG
X		fprintf (stderr, "unlockp:  lock file empty\n");
X#endif
X		fclose (fp);
X		return (LOCKP_EMPTY);
X	}
X	fclose (fp);
X	if (atoi (buff) != pid) {
X#ifdef DEBUG
X		fprintf (stderr,
X			"unlockp:  lock file not owned by this process\n");
X#endif
X		return (LOCKP_BADPID);
X	}
X
X	/*
X	 * If we get to here, we have found the correct lock that we
X	 * are looking for, it has the stated PID in it, so we may
X	 * unlock it.
X	 *
X	 * NOTE:  This assumes that the lock file is owned by us.  If
X	 *	  this is not the case, chaos may reign...
X	 */
X	unlink (final);
X	return (0);
X}
!FUNKY!STUFF!
echo x - lockp.h
sed '1,$s/^X//' <<\!FUNKY!STUFF! > lockp.h
X/*
X * Package	: LIBRARY (lockp)
X * Module	: lockp.h
X * Programmer	: R. Stolfa (rjs@a.cs.okstate.edu)
X * SCCSid	: @(#) lockp.h 1.1 89/10/30
X *
X * Modification History:
X *   10/30/89	Created
X */
X
X/**
X***	Copyright (c) 1989, Roland J. Stolfa,  Right to copy is
X***	granted so long as it is not for monetary gain and this
X***	message and all headers in all files remain in tact.
X***
X***	THE AUTHOR DOES NOT MAKE ANY WARRANTIES, EITHER EXPRESS
X***	OR IMPLIED, AS TO ANY MATTER WHATSOEVER, INCLUDING WITHOUT
X***	LIMITATION, THE CONDITION OF THIS DISTRIBUTION, ITS
X***	MERCHANTABILITY OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
X**/
X
X#define		LOCKP_BADF	-1
X#define		LOCKP_EMPTY	-2
X#define		LOCKP_BADPID	-3
X
X#define		unlockp(fn)	unlockpp((fn),getpid())
!FUNKY!STUFF!
echo x - opentr.1
sed '1,$s/^X//' <<\!FUNKY!STUFF! > opentr.1
X'\" @(#) opentr.1 1.2 89/12/19
X.TH OPENTR L
X.SH NAME
Xopentr - report all open trouble reports
X.SH SYNOPSIS
X.B opentr
X.br
X.SH DESCRIPTION
X.I opentr
Xis intended to be used to find all open trouble reports to give
Xthe trouble manager something to do in their spare time :-).
X.SH AUTHOR
XRoland J. Stolfa
X.br
XDepartment of Computing and Information Sciences
X.br
XOklahoma State University
X.br
Xrjs@a.cs.okstate.edu
!FUNKY!STUFF!
echo x - opentr.sh
sed '1,$s/^X//' <<\!FUNKY!STUFF! > opentr.sh
X:
X#
X# Package	: (Trs2)
X# Module	: opentr
X# Programmer	: R. Stolfa (rjs@a.cs.okstate.edu)
X# SCCSid	: @(#) opentr.sh 1.2 89/12/19
X#
X# Purpose :	To list all open trouble report ticket numbers
X#		in the TRS database.
X#
X# Modification History:
X#   04/15/88	Created
X#   10/25/88	Added a user configurable "ROOT" to allow more than
X#		one TRS on a system.
X#
X#   10/16/89	Release 2 started.
X#
X
X###
X###	Copyright (c) 1989, Roland J. Stolfa,  Right to copy is
X###	granted so long as it is not for monetary gain and this
X###	message and all headers in all files remain in tact.
X###
X###	THE AUTHOR DOES NOT MAKE ANY WARRANTIES, EITHER EXPRESS
X###	OR IMPLIED, AS TO ANY MATTER WHATSOEVER, INCLUDING WITHOUT
X###	LIMITATION, THE CONDITION OF THIS DISTRIBUTION, ITS
X###	MERCHANTABILITY OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
X###
X
X#
X# Get configured.
X#
Xif [ "${TRSROOT}" != "" ]
Xthen
X	ROOT = ${TRSROOT}
Xelse
XROOT=/u/rjs/lib/Trs
Xfi
XEntry=${ROOT}/Entry
X
XBIN=/u/rjs/bin
XPATH=${BIN}:/bin:/usr/bin
Xexport PATH
Xumask 022
X
Xif [ `ls ${Entry} | wc -l` -gt 0 ]
Xthen
X	for i in ${Entry}/*
X	do
X		if [ `grep "^needle=" $i | wc -l` -eq 0 ]
X		then
X			echo `basename $i`
X		fi
X	done
Xfi
!FUNKY!STUFF!
echo x - print.c
sed '1,$s/^X//' <<\!FUNKY!STUFF! > print.c
X/*
X * Package	: (Trs2)
X * Module	: print.c
X * Functions	: main
X * Programmer	: R. Stolfa (rjs@a.cs.okstate.edu)
X * SCCSid	: @(#) print.c 1.2 89/12/19
X *
X * Purpose :	To provide a portable way of printing a string
X *		of text on stdout without having a newline at the
X *		end.
X *
X * Modification History:
X *   04/01/88	Created
X *
X *   10/16/89	Rewrote for release 2
X *		Added check to make sure no newlines ever get out.
X */
X
X/**
X***	Copyright (c) 1989, Roland J. Stolfa,  Right to copy is
X***	granted so long as it is not for monetary gain and this
X***	message and all headers in all files remain in tact.
X***
X***	THE AUTHOR DOES NOT MAKE ANY WARRANTIES, EITHER EXPRESS
X***	OR IMPLIED, AS TO ANY MATTER WHATSOEVER, INCLUDING WITHOUT
X***	LIMITATION, THE CONDITION OF THIS DISTRIBUTION, ITS
X***	MERCHANTABILITY OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
X**/
X
Xstatic char	*sccsid = "@(#) print.c 1.2 89/12/19";
X
X#include	<stdio.h>
X
Xmain (argc, argv)
Xint	argc;
Xchar	*argv[];
X{
X	int	i;
X
X	if (argc > 1) {
X		for (i = 1; i < argc - 1 ; i ++) {
X			p (argv[i]);
X			p (' ');
X		}
X
X		p (argv[argc-1]);
X	}
X}
X
Xp (s)
X	char	*s;
X{
X	while ((*s != '\n') && (*s != '\0')) {
X		putchar (*s);
X		s ++;
X	}
X}
!FUNKY!STUFF!
echo x - report.1
sed '1,$s/^X//' <<\!FUNKY!STUFF! > report.1
X'\" @(#) report.1 1.2 89/12/19
X.TH REPORT L
X.SH NAME
Xreport - extract all requested trouble reports by selection criteria
X.SH SYNOPSIS
X.B report [ t=<thread> ] [ k=<keyword> ] [ d=<date> ] [ r=<reporter> ] [ e=<equipment> ]
X.br
X.SH DESCRIPTION
X.I report
Xis intended to extract the utmost information from the (T)rouble (R)eport
X(S)ystem.  With this shell script, you can extract an entire thread
Xusing the
X.B [ t=<thread id> ]
Xoption, or you may select all reports with a particular keyword
Xusing the
X.B [ k=<keyword> ]
Xoption.  In addition, you may select all reports on a particular day
Xusing the
X.B [ d=<date> ]
Xoption.  If that isn't enough, you can select a particular reporter (read that
Xas UN*X user login id) by using the
X.B [ r=<reporter> ]
Xoption.  Lastly, you can use the
X.B [ e=<equipment id string> ]
Xoption to extract all info about a particular piece of equipment and or a class
Xof equipment, depending on what you use for the
X.B <equipment id string>.
X.PP
XIn addition, you can use the different options of 
X.I report
Xadditively.  Several examples follow.
X.PP
Xreport t=881025.1 e="terminal"
X.br
Xextracts all trouble report entries in the thread associated with the head
Xof the thread pointed to by 881025.1 that deal with the "terminal" class
Xof devices.
X.PP
Xreport d=881025 r=joe e="terminal"
X.br
Xextracts all trouble reports on 10/25/88 by user "joe" involving a
X"terminal".
X.PP
Xreport k=broken e="terminal"
X.br
Xextracts all trouble reports about "broken" "terminal"s.
X.sp 1
X.SH "INTERNALS"
X.I report
Xuses a single pass over the arguments above
X.B IN THE LISTED ORDER
Xto refine the eventual list of trouble report tickets to be printed
Xas the "report".  Note that any misordering of the arguments will be
Xhandled by re-ordering them as listed above BEFORE selection occurs.
X.sp 1
X.SH DIAGNOSTICS
XThere are no real diagnostics.  You are expected to be able to fathom the
Xdeep-dark recesses of shell programming to do ANY debugging of this system.
X.sp 1
X.SH AUTHOR
XRoland J. Stolfa
X.br
XDepartment of Computing and Information Sciences
X.br
XOklahoma State University
X.br
Xrjs@a.cs.okstate.edu
!FUNKY!STUFF!
echo x - report.sh
sed '1,$s/^X//' <<\!FUNKY!STUFF! > report.sh
X:
X#
X# Package	: (Trs2)
X# Module	: report.sh
X# Programmer	: R. Stolfa (rjs@a.cs.okstate.edu)
X# SCCSid	: @(#) report.sh 1.2 89/12/19
X#
X# Purpose :	To scan the TRS database and extract "reasonable"
X#		information.  This information will be presented
X#		on the screen in a format suitable for printing
X#
X# Command line syntax:
X#		report <flags>
X#		where <flags> are some set of the following
X#
X#		t=<thread id>
X#		k=<keyword to search on>
X#		d=<date in YYMMDD format>
X#		r=<reporter (userid)>
X#		e=<equipment id string (inventory number?)>
X#
X# Modification History:
X#   04/12/88	Created
X#   10/25/88	Added a user configurable "ROOT" to allow more than
X#		one TRS on a system
X#
X#   10/16/89	Release 2 started.
X#
X
X###
X###	Copyright (c) 1989, Roland J. Stolfa,  Right to copy is
X###	granted so long as it is not for monetary gain and this
X###	message and all headers in all files remain in tact.
X###
X###	THE AUTHOR DOES NOT MAKE ANY WARRANTIES, EITHER EXPRESS
X###	OR IMPLIED, AS TO ANY MATTER WHATSOEVER, INCLUDING WITHOUT
X###	LIMITATION, THE CONDITION OF THIS DISTRIBUTION, ITS
X###	MERCHANTABILITY OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
X###
X
X#
X# Get configured.
X#
Xif [ "${TRSROOT}" != "" ]
Xthen
X	ROOT = ${TRSROOT}
Xelse
XROOT=/u/rjs/lib/Trs
Xfi
XEntry=${ROOT}/Entry
XXref=${ROOT}/Xref
X
XBIN=/u/rjs/bin
XPATH=${BIN}:/bin:/usr/bin
Xexport PATH
Xumask 022
XPager=${PAGER:-pg}
X
XAwkprog=/tmp/trs1.$$
XTemp=/tmp/trs2.$$
XTemp2=/tmp/trs3.$$
Xtrap "rm -f /tmp/trs*$$ ; exit 1" 1 2 15
X
X#
X# Parse the command line
X#
Xthread=""
Xkey=""
Xdate=""
Xreporter=""
Xequip=""
Xcat > ${Awkprog} << 'EOF'
XBEGIN	{ FS = "="; }
X{
X	if (NF == 2) {
X		char = substr ($1, 0, 1);
X		if ((char == "t") || (char == "T"))
X			printf "T\n";
X		else if ((char == "k") || (char == "K"))
X			printf "K\n";
X		else if ((char == "d") || (char == "D"))
X			printf "D\n";
X		else if ((char == "r") || (char == "R"))
X			printf "R\n";
X		else if ((char == "e") || (char == "E"))
X			printf "E\n";
X	}
X}
XEOF
Xfor i in $*
Xdo
X	case `echo $i | awk -f ${Awkprog}` in
X	T)
X		thread="`echo $i | awk -F= '{print $2}'`"
X		continue;;
X	K)
X		item=`echo $i | awk -F= '{print $2}'`
X		key=`soundex ${item}`
X		continue;;
X	D)
X		date="`echo $i | awk -F= '{print $2}'`"
X		continue;;
X	R)
X		reporter="`echo $i | awk -F= '{print $2}'`"
X		continue;;
X	E)
X		equip="`echo $i | awk -F= '{print $2}'`"
X		continue;;
X	esac
Xdone
Xrm -f ${Awkprog}
X
X#
X# Separate out a thread (if required).
X#
Xif [ "${thread}" != "" ]
Xthen
X	#
X	# Ok.  Let's generate a thread list.
X	#
X	if test ! -s ${Entry}/${thread}
X	then
X		echo "Invalid thread id.  Try again."
X		exit
X	fi
X	rm -f ${Temp}
X	#
X	# Find head of thread
X	#
X	needle=${thread}
X	while [ "${needle}" != "" ]
X	do
X		thread=${needle}
X		needle="`grep '^needle=' ${Entry}/${needle} | awk -F= '{print $2}'`"
X	done
X	#
X	# List the members of the thread
X	#
X	while [ "${thread}" != "" ]
X	do
X		echo "${thread}" >> ${Temp}
X		thread="`grep '^thread=' ${Entry}/${thread} | awk -F= '{print $2}'`"
X	done
Xelse
X	#
X	# Get all trouble tickets, system wide
X	#
X	cat ${Xref}/Entry > ${Temp}
Xfi
Xsort -u ${Temp} > ${Temp2}
Xmv ${Temp2} ${Temp}
X
X#
X# Now lets get the key field taken care of.
X#
Xif [ "${key}" != "" ]
Xthen
X	if test -s ${Xref}/${key}
X	then
X		comm -12 ${Temp} ${Xref}/${key} | sort -u > ${Temp2}
X		mv ${Temp2} ${Temp}
X	else
X		echo "Key >${key}< doesn't exist.  Continuing..."
X	fi
Xfi
X
X#
X# Ok.  Now let's generate the subset of the list that has occured on
X# the date in question.
X#
Xif [ "${date}" != "" ]
Xthen
X	grep "${date}" < ${Temp} | sort -u > ${Temp2}
X	mv ${Temp2} ${Temp}
Xfi
X
X#
X# Do the awking for a particular reporter (if necessary).
X#
Xif [ "${reporter}" != "" ]
Xthen
X
X	cat > ${Awkprog} << 'EOF'
X{
X	if (NR == 1) {
X		reporter = $1;
X	} else if (substr($3, 0, length(reporter)) == reporter) {
X		printf "%s\n", $NF;
X	}
X}
XEOF
X
X	echo "${reporter}" > ${Temp2}
X	ls -l `cat ${Temp}` >> ${Temp2}
X	awk -f ${Awkprog} < ${Temp2} > ${Temp}
X	rm -f ${Temp2} ${Awkprog}
Xfi
X
X#
X# Do the greping for a particular piece of equipment (if necessary).
X#
Xif [ "${equip}" != "" ]
Xthen
X	cat ${Temp} | while read x
X	do
X		grep -l "^equipment=${equip}*" $x > ${Temp2}
X	done
X	sort -u ${Temp2} > ${Temp}
Xfi
X
X#
X# Ok.  More the junk to the screen...
X#
Xfor i in `cat ${Temp}`
Xdo
X	fn=${Entry}/$i
X	if test -s ${fn}
X	then
X		echo "ticket=$i"
X		echo "reporter=`ls -l ${fn} | awk '{print $3}'`"
X		cat ${fn}
X		echo ""
X	fi
Xdone | ${Pager}
X
X#
X# Now clean up and exit.
X#
Xrm -f ${Temp} ${Temp2}
!FUNKY!STUFF!
echo x - rmthread.1
sed '1,$s/^X//' <<\!FUNKY!STUFF! > rmthread.1
X'\" @(#) rmthread.1 1.2 89/12/19
X.TH RMTHREAD L
X.SH NAME
Xrmthread - remove a trouble report system thread from anywhere on the thread
X.SH SYNOPSIS
X.B rmthread [threadid]
X.br
X.SH DESCRIPTION
X.I rmthread
Xis to be used when an entire thread of trouble reports have been dealt with
Xand the amassed information is no longer of any use.  This program finds
Xthe head of the list of trouble reports (on the thread given) and then builds
Xa list of thread files to remove.  It then displays the entire thread and
Xasks you if you really want to remove it.  If so, it then gets rid of all
Xoccurrences of the associated thread from the trouble report system.
X.sp 1
X.SH "INTERNALS"
X.I rmthread
Xuses an text line in the thread file to provide both a forward link to the
Xnext trouble report and another text line to provide the backward link to
Xthe previous trouble report.  This is why it is so slow at times.
X.sp 1
X.SH AUTHOR
XRoland J. Stolfa
X.br
XDepartment of Computing and Information Sciences
X.br
XOklahoma State University
X.br
Xrjs@a.cs.okstate.edu
!FUNKY!STUFF!
echo x - rmthread.sh
sed '1,$s/^X//' <<\!FUNKY!STUFF! > rmthread.sh
X:
X#
X# Package	: (Trs2)
X# Module	: rmthread.sh
X# Programmer	: R. Stolfa (rjs@a.cs.okstate.edu)
X# SCCSid	: @(#) rmthread.sh 1.2 89/12/19
X#
X# Purpose :	To delete a thread of trouble reports in the TRS
X#		database system.
X#
X# Modification History:
X#   04/12/88	Created
X#   10/25/88	Added a user configurable "ROOT" to allow more than
X#		one TRS on a system
X#
X#   10/16/89	Release 2 started.
X#   12/19/89	Fixed minor bug in invocation of "V"
X#
X
X###
X###	Copyright (c) 1989, Roland J. Stolfa,  Right to copy is
X###	granted so long as it is not for monetary gain and this
X###	message and all headers in all files remain in tact.
X###
X###	THE AUTHOR DOES NOT MAKE ANY WARRANTIES, EITHER EXPRESS
X###	OR IMPLIED, AS TO ANY MATTER WHATSOEVER, INCLUDING WITHOUT
X###	LIMITATION, THE CONDITION OF THIS DISTRIBUTION, ITS
X###	MERCHANTABILITY OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
X###
X
X#
X# Get configured.
X#
Xif [ "${TRSROOT}" != "" ]
Xthen
X	ROOT = ${TRSROOT}
Xelse
XROOT=/u/rjs/lib/Trs
Xfi
XEntry=${ROOT}/Entry
XXref=${ROOT}/Xref
XPlock=${ROOT}/LCK.TRS
X
XBIN=/u/rjs/bin
XPATH=${BIN}:/bin:/usr/bin
Xexport PATH
Xumask 022
XPager=${PAGER:-pg}
X
XTemp=/tmp/trs1.$$
XTemp2=/tmp/trs2.$$
Xtrap "rm -f /tmp/trs*$$ ; exit 1" 1 2 15
X
X#
X# Get the tread to delete.
X#
Xthread="$*"
Xwhile [ "${thread}" = "" ]
Xdo
X	${BIN}/print "Enter thread to delete? "
X	read thread
X
X	if test \! -s ${Entry}/${thread}
X	then
X		echo "Invalid thread.  Try again"
X		thread=""
X	fi
Xdone
X
X#
X# Search backwards (if possible) for head of thread.
X#
Xneedle="+"
Xwhile [ "${needle}" != "" ]
Xdo
X	needle="`grep '^needle=' ${Entry}/${thread} | awk -F= '{print $2}'`"
X	if [ "${needle}" != "" ]
X	then
X		thread="${needle}"
X	fi
Xdone
X
X#
X# ASSERT:
X#	At this point, thread is the original trouble report ticket
X#	number.  Now let's keep that number safe and display the thread
X#	to assure that it is the one that needs to be removed.
X#
X
Xptr="${thread}"
Xecho "The following is the listing of this thread."
Xecho ""
Xwhile [ "${ptr}" != "" ]
Xdo
X	echo "ticket=${ptr}"
X	echo "reporter=`ls -l ${Entry}/${ptr} | awk '{print $3}'`"
X	cat ${Entry}/${ptr}
X	echo ""
X	ptr="`grep '^thread=' ${Entry}/${ptr} | awk -F= '{print $2}'`"
Xdone | ${Pager}
X
X#
X# Prompt for removal.
X#
Xyesno=""
Xwhile [ "${yesno}" = "" ]
Xdo
X	${BIN}/print "Is this the thread you want to delete? (Y/N) "
X	read yesno
Xdone
X
Xif [ "${yesno}" = "n" -o "${yesno}" = "N" ]
Xthen
X	exit
Xfi
X
X#
X# Ok.  We have permission.  Just remove the whole stupid thing...
X#
Xrm -f ${Temp}
Xptr=${thread}
Xwhile [ "${ptr}" != "" ]
Xdo
X	echo "Removing ticket ${ptr}"
X	echo ${ptr} >> ${Temp}
X	thread="`grep '^thread=' ${Entry}/${ptr} | awk -F= '{print $2}'`"
X	rm -f ${Entry}/${ptr}
X	ptr="${thread}"
Xdone
Xsort -u ${Temp} > ${Temp2}
Xpid=`P -wel ${Plock}`
Xfor i in ${Xref}/*
Xdo
X	comm -23 $i ${Temp2} | sort -u > ${Temp}
X	cp ${Temp} $i
Xdone
XV -i ${pid} -l ${Plock}
X
Xrm -f ${Temp} ${Temp2}
!FUNKY!STUFF!
echo x - soundex.c
sed '1,$s/^X//' <<\!FUNKY!STUFF! > soundex.c
X/*
X * Package	: (Trs2)
X * Module	: soundex.c
X * Functions	: main, soundex
X * Programmer	: R. Stolfa (rjs@a.cs.okstate.edu)
X * SCCSid	: @(#) soundex.c 1.2 89/12/19
X *
X * Purpose :	This program implements the SOUNDEX procedure as
X *		outlined on page 655 of "Database Design" by
X *		Gio Wiederhold.  This procedure was originally
X *		introduced by Odell & Russel (1918) and was
X *		described by McEwen (1974).
X *
X * Usage :	soundex <string1> <string2> ... <stringN>
X *
X * Modification History:
X *   00/00/00	Created
X */
X
X/**
X***	Copyright (c) 1989, Roland J. Stolfa,  Right to copy is
X***	granted so long as it is not for monetary gain and this
X***	message and all headers in all files remain in tact.
X***
X***	THE AUTHOR DOES NOT MAKE ANY WARRANTIES, EITHER EXPRESS
X***	OR IMPLIED, AS TO ANY MATTER WHATSOEVER, INCLUDING WITHOUT
X***	LIMITATION, THE CONDITION OF THIS DISTRIBUTION, ITS
X***	MERCHANTABILITY OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
X**/
X
Xstatic char	*sccsid = "@(#) soundex.c 1.2 89/12/19";
X
X#include	<stdio.h>
X
X#define		BS		200
X
Xmain (argc, argv)
Xint	argc;
Xchar	*argv[];
X{
X	char	sound[BS];
X	int	i;
X
X	if (argc == 1) {
X		fprintf (stderr,
X			"Usage: soundex <string1> <string2> ... <stringN>\n");
X		exit (-1);
X	}
X
X	for (i = 1; i < argc; i ++) {
X		soundex (argv[i], sound);
X		printf ("%s\n", sound);
X	}
X}
X
Xsoundex (word, sound)
Xchar	word[],		/* String to convert to SOUNDEX */
X	sound[];	/* Output SOUNDEX */
X{
X	int	outpos,		/* Current output position in SOUNDEX */
X		j;		/* Index into word */
X
X	/* Initialize return word */
X	outpos = 0;
X	sound[outpos] = '\0';
X
X	/* If the word is null, then the output should be null */
X	if (strlen(word) == 0)
X		return;
X
X	/* Copy first character of word to SOUNDEX */
X	sound[outpos] = toupper (word[0]);
X
X	for (j = 1; j < strlen (word); j ++) {
X
X		/* Convert each character to uppercase */
X		word[j] = toupper(word[j]);
X
X		switch (word[j]) {
X
X		/* Replace Labials with "1" */
X		case 'B':
X		case 'F':
X		case 'P':
X		case 'V':
X			if (sound[outpos] != '1') {
X				outpos ++;
X				sound[outpos] = '1';
X			}
X			break;
X
X		/* Replace Gutterals & sibilants with "2" */
X		case 'C':
X		case 'G':
X		case 'J':
X		case 'K':
X		case 'Q':
X		case 'S':
X		case 'X':
X		case 'Z':
X			if (sound[outpos] != '2') {
X				outpos ++;
X				sound[outpos] = '2';
X			}
X			break;
X
X		/* Replace Dentals with "3" */
X		case 'D':
X		case 'T':
X			if (sound[outpos] != '3') {
X				outpos ++;
X				sound[outpos] = '3';
X			}
X			break;
X
X		/* Replace Longliquids with "4" */
X		case 'L':
X			if (sound[outpos] != '4') {
X				outpos ++;
X				sound[outpos] = '4';
X			}
X			break;
X
X		/* Replace Nasals with "5" */
X		case 'M':
X		case 'N':
X			if (sound[outpos] != '5') {
X				outpos ++;
X				sound[outpos] = '5';
X			}
X			break;
X
X		/* Replace Shortliquids with "6" */
X		case 'R':
X			if (sound[outpos] != '6') {
X				outpos ++;
X				sound[outpos] = '6';
X			}
X			break;
X		}
X	}
X
X	/* Terminate the soundex string */
X	outpos ++;
X	sound[outpos] = '\0';
X
X	/* Forcably trunicate soundex to 4 characters */
X	sound[4] = '\0';
X}
!FUNKY!STUFF!
echo x - trouble.1
sed '1,$s/^X//' <<\!FUNKY!STUFF! > trouble.1
X'\" @(#) trouble.1 1.2 89/12/19
X.TH TROUBLE L
X.SH NAME
Xtrouble - enter an initial trouble report
X.SH SYNOPSIS
X.B trouble
X.br
X.SH DESCRIPTION
X.I trouble
Xenters the initial trouble report in the trouble report system.  It is
Xused also by
X.I followup
Xto enter all followup trouble reports in the current thread.
X.PP
XThis program is self prompting and fairly self explanatory.
X.sp 1
X.SH AUTHOR
XRoland J. Stolfa
X.br
XDepartment of Computing and Information Sciences
X.br
XOklahoma State University
X.br
Xrjs@a.cs.okstate.edu
!FUNKY!STUFF!
echo x - trouble.sh
sed '1,$s/^X//' <<\!FUNKY!STUFF! > trouble.sh
X:
X#
X# Package	: (Trs2)
X# Module	: trouble.sh
X# Programmer	: R. Stolfa (rjs@a.cs.okstate.edu)
X# SCCSid	: @(#) trouble.sh 1.2 89/12/19
X#
X# Purpose :	To enter trouble reports into the TRS database system.
X#
X# Modification History:
X#   04/11/88	Created
X#   04/12/88	Added hooks for recording the new trouble number in the
X#		environment variable NTN for use in "followup"
X#   10/25/88	Added user configurable "ROOT" to allow more than
X#		one TRS on a system
X#
X#   10/16/89	Release 2 started.
X#
X
X###
X###	Copyright (c) 1989, Roland J. Stolfa,  Right to copy is
X###	granted so long as it is not for monetary gain and this
X###	message and all headers in all files remain in tact.
X###
X###	THE AUTHOR DOES NOT MAKE ANY WARRANTIES, EITHER EXPRESS
X###	OR IMPLIED, AS TO ANY MATTER WHATSOEVER, INCLUDING WITHOUT
X###	LIMITATION, THE CONDITION OF THIS DISTRIBUTION, ITS
X###	MERCHANTABILITY OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
X###
X
X#
X# Get configured.
X#
Xif [ "${TRSROOT}" != "" ]
Xthen
X	ROOT = ${TRSROOT}
Xelse
XROOT=/u/rjs/lib/Trs
Xfi
XEntry_dir=${ROOT}/Entry
XSeq=${ROOT}/sequence
XXref=${ROOT}/Xref
XPlock=${ROOT}/LCK.TRS
X
XBIN=/u/rjs/bin
XPATH=${BIN}:/bin:/usr/bin
Xexport PATH
Xumask 000
XPager=${PAGER:-pg}
X
XTemp=/tmp/trs.$$
Xtrap "rm -f /tmp/trs*$$ ; exit 1" 1 2 15
Xrm -f ${Temp}
X
X#
X# Prompt for what piece of equipment is down.
X#
Xequipment=""
Xwhile [ "${equipment}" = "" ]
Xdo
X	${BIN}/print "Enter equipment ID string? "
X	read equipment
Xdone
Xecho "equipment=${equipment}" >> ${Temp}
X
X#
X# Get the keywords to link the file in "Entry" to in each
X# of their respective "SOUNDEX" equivalents files.
X#
Xecho "Enter the keywords that are to be associated with this"
Xecho "report one per line, ending with a blank line."
X${BIN}/print "keywords=" >> ${Temp}
Xkeywords=""
Xdummy="+"
Xwhile [ "${dummy}" != "" ]
Xdo
X	read dummy
X	if [ "${dummy}" != "" ]
X	then
X		${BIN}/print "${dummy} " >> ${Temp}
X		keywords="${keywords}`soundex ${dummy}` "
X	fi
Xdone
Xecho "" >> ${Temp}
X
X#
X# Enter the report.
X#
Xecho "Enter report, ending with a blank line"
Xdummy="+"
Xwhile [ "${dummy}" != "" ]
Xdo
X	read dummy
X	if [ "${dummy}" != "" ]
X	then
X		echo "desc=${dummy}" >> ${Temp}
X	fi
Xdone
X
X#
X# Handle the process locking on the Entry spool to allow us to copy
X# into that area safe from race conditions.
X#
Xpid=`P -ewl ${Plock}`
Xseqence=`cat ${Seq}`
Xentry="`date '+%y%m%d'`.${seqence}"
Xexpr ${seqence} + 1 > ${Seq}
Xmv ${Temp} ${Entry_dir}/${entry}
XV -i ${pid} -l ${Plock}
X
X#
X# Report the "trouble ticket" number for future 'threading'.
X#
Xecho " "
Xecho "Your trouble ticket number is ${entry}"
Xecho "save this number for future reference."
X
X#
X# Record the new trouble number in the environment variable NTN.
X#
XNTN=${entry}
X
X#
X# Now enter the "Entry" into a file for each of the "SOUNDEX"'ed
X# keywords.  This is an attempt to make the system easier to search.
X#
Xecho ${entry} >> ${Xref}/Entry
Xfor i in ${keywords}
Xdo
X	echo ${entry} >> ${Xref}/$i
Xdone
X
X#
X# Ok.  Let's be clean...
X#
Xrm -f ${Temp}
!FUNKY!STUFF!