[comp.sources.amiga] v89i229: rcs - revision control system, Part14/14

page%swap@Sun.COM (Bob Page) (11/19/89)

Submitted-by: rsbx@cbmvax.commodore.com (Raymond S. Brand)
Posting-number: Volume 89, Issue 229
Archive-name: unix/rcs.14

# This is a shell archive.
# Remove anything above and including the cut line.
# Then run the rest of the file through 'sh'.
# Unpacked files will be owned by you and have default permissions.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: SHell ARchive
# Run the following text through 'sh' to create:
#	rcs/rcs.rcsfiles/ident.c,v
#	rcs/rcs.rcsfiles/merge.sh,v
#	rcs/rcs.rcsfiles/rcsmerge.c,v
#	rcs/rcs_link
#	readme
#	readme.extras
#	rsbx.lib/rsbx.lib.doc
#	rsbx.lib/xc.asm
#	rsbx.lib/emptymorgue.c
#	rsbx.lib/waitchild.c
#	rsbx.lib/childstatus.c
#	rsbx.lib/orphanchildren.c
#	rsbx.lib/escaping.c
#	rsbx.lib/makefile
#	rsbx.lib/orphanchild.c
#	rsbx.lib/readme
#	rsbx.lib/createfamily.c
#	rsbx.lib/popen.c
#	rsbx.lib/rsbx.lib.uu
#	rsbx.lib/uxmain.c
#	rsbx.lib/childtasking.h
#	rsbx.lib/launchc.obj.uu
#	rsbx.lib/ulseg.obj.uu
# This is archive 14 of a 14-part kit.
# This archive created: Sun Nov 19 01:12:14 1989
if `test ! -d rcs`
then
  mkdir rcs
  echo "mkdir rcs"
fi
if `test ! -d rcs/rcs.rcsfiles`
then
  mkdir rcs/rcs.rcsfiles
  echo "mkdir rcs/rcs.rcsfiles"
fi
echo "extracting rcs/rcs.rcsfiles/ident.c,v"
sed 's/^X//' << \SHAR_EOF > rcs/rcs.rcsfiles/ident.c,v
Xhead     4.5;
Xbranch   4.5.2;
Xaccess   ;
Xsymbols  amiga_rcs:4.5.2 cbmvax_source:4.5.1 uunet_june89_dist:4.5;
Xlocks    ; strict;
Xcomment  @ * @;
X
X
X4.5
Xdate     89.05.01.15.11.54;  author narten;  state Exp;
Xbranches 4.5.1.1 4.5.2.1;
Xnext     ;
X
X4.5.1.1
Xdate     89.08.11.01.41.49;  author rsbx;  state Exp;
Xbranches ;
Xnext     ;
X
X4.5.2.1
Xdate     89.10.13.19.17.33;  author rsbx;  state Exp;
Xbranches ;
Xnext     4.5.2.2;
X
X4.5.2.2
Xdate     89.10.15.15.43.19;  author rsbx;  state Exp;
Xbranches ;
Xnext     ;
X
X
Xdesc
X@RCS identification operation.
X@
X
X
X
X4.5
Xlog
X@checked in with -k by rsbx at 89.08.10.16.01.57.
X@
Xtext
X@/* Copyright (C) 1982, 1988, 1989 Walter Tichy
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by Walter Tichy.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X *
X * Report all problems and direct all questions to:
X *   rcs-bugs@@cs.purdue.edu
X * 
X
X
X
X
X
X
X
X*/
X
X/*
X *                     RCS identification operation
X */
X#ifndef lint
Xstatic char rcsid[]=
X"$Header: /usr/src/local/bin/rcs/src/RCS/ident.c,v 4.5 89/05/01 15:11:54 narten Exp $Purdue CS";
X#endif
X
X/* $Log:	ident.c,v $
X * Revision 4.5  89/05/01  15:11:54  narten
X * changed copyright header to reflect current distribution rules
X * 
X * Revision 4.4  87/10/23  17:09:57  narten
X * added exit(0) so exit return code would be non random
X * 
X * Revision 4.3  87/10/18  10:23:55  narten
X * Updating version numbers. Changes relative to 1.1 are actually relative
X * to 4.1
X * 
X * Revision 1.3  87/07/09  09:20:52  trinkle
X * Added check to make sure there is at least one arg before comparing argv[1]
X * with "-q".  This necessary on machines that don't allow dereferncing null
X * pointers (i.e. Suns).
X * 
X * Revision 1.2  87/03/27  14:21:47  jenkins
X * Port to suns
X * 
X * Revision 1.1  84/01/23  14:50:03  kcs
X * Initial revision
X * 
X * Revision 4.1  83/05/10  16:31:02  wft
X * Added option -q and input from reading stdin.
X * Marker matching is now done with trymatch() (independent of keywords).
X * 
X * Revision 3.4  83/02/18  17:37:49  wft
X * removed printing of new line after last file.
X *
X * Revision 3.3  82/12/04  12:48:55  wft
X * Added LOCKER.
X *
X * Revision 3.2  82/11/28  18:24:17  wft
X * removed Suffix; added ungetc to avoid skipping over trailing KDELIM.
X *
X * Revision 3.1  82/10/13  15:58:51  wft
X * fixed type of variables receiving from getc() (char-->int).
X*/
X
X#include  "rcsbase.h"
X#define fflsbuf _flsbuf
X/* redefinition of _flsbuf in putc not needed */
X#ifndef lint
Xstatic char rcsbaseid[] = RCSBASE;
X#endif
X
Xextern enum markers trymatch();
X
Xint quietflag;
X
Xmain(argc, argv)
Xint  argc; char  *argv[];
X/*  Ident searches the named files for all occurrences
X *  of the pattern $keyword:...$, where the keywords are
X *  Author, Date, Header, Id, Log, RCSfile, Revision, Source, and State.
X */
X
X{
X   FILE *fp, *fopen();
X
X   quietflag = false;
X   if (argc > 1 && strcmp("-q",argv[1])==0) {
X        quietflag = true;
X        argc--; argv++;
X   }
X
X   if (argc<2) {
X	 if ((scanfile(stdin) == 0) && !quietflag)
X	    VOID fprintf(stderr, "ident warning: no id keywords in input\n");
X	exit(0);
X   }
X
X   while ( --argc > 0 ) {
X      if ( (fp = fopen(*++argv, "r") ) == NULL ) {
X         VOID fprintf(stderr,  "ident error: can't open %s\n", *argv);
X         continue;
X      } else {
X         VOID printf( "%s:\n", *argv);   /*  print file name  */
X	 if ((scanfile(fp) == 0) && !quietflag)
X	    VOID fprintf(stderr, "ident warning: no id keywords in %s\n", *argv);
X	 if (argc>1) putchar('\n');
X	 VOID fclose(fp);
X      }
X   }
X   exit(0);
X}
X
X
Xint scanfile(file)
XFILE * file;
X/* Function: scan an open file with descriptor file for keywords.
X * Returns the number of matches.
X */
X{
X   register int matchcount;
X   register int c;
X
X
X   matchcount = 0;
X   while( (c=getc(file)) != EOF) {
X      if ( (char)c==KDELIM)
X	 matchcount += match(file);
X   }
X   return matchcount;
X}
X
X
X
Xmatch(fp)   /* group substring between two KDELIM's; then do pattern match */
XFILE *fp;
X{
X   char line[keyvallength];
X   register int c;
X   register char * tp;
X
X   tp = line;
X   while( (c = getc(fp)) != KDELIM ) {
X      *tp++ = c;
X      if ( c==EOF || c=='\n' || tp>= line+keyvallength-2)
X         return(0);
X   }
X   *tp++ = c;     /*append trailing KDELIM*/
X   *tp   = '\0';
X   if (trymatch(line,true)!=Nomatch) {
X        VOID fprintf(stdout,"     $%s\n",line);
X        return(1);
X   } else {
X      /* no match; put trailing KDELIM back into input */
X      VOID ungetc(c,fp );
X      return(0);
X   }
X}
X@
X
X
X4.5.2.1
Xlog
X@Start of Amiga RCS port branch.
X@
Xtext
X@d31 1
Xa31 5
X<<<<<<< ident.c
X"$Header: /u/softeng/rsbx/rcs/amiga/RCS.cbmvax/ident.c,v 4.5.1.1 89/08/11 01:41:49 rsbx Exp Locker: rsbx $Purdue CS";
X=======
X"$Header: /u/softeng/rsbx/rcs/amiga/RCS/ident.c,v 1.2 89/09/17 13:34:20 rick Exp $Purdue CS";
X>>>>>>> 1.2
Xa34 4
X<<<<<<< ident.c
X * Revision 4.5.1.1  89/08/11  01:41:49  rsbx
X * Start of cbmvax RCS source branch.
X * 
Xa35 3
X * checked in with -k by rsbx at 89.08.10.16.01.57.
X * 
X * Revision 4.5  89/05/01  15:11:54  narten
Xa36 9
X=======
X * Revision 1.2  89/09/17  13:34:20  rick
X * Port to AmigaDos done by Rick Schaeffer (ricks@@iscuva.iscs.com)
X * All changes done with conditional compile (#ifdef AMIGA).  This version
X * compiles correctly with Lattice C version 5.02 or later.
X * 
X * Revision 1.2  88/09/03  15:07:58  rick
X * Port to AmigaDos.  All done with conditional compiles
X>>>>>>> 1.2
X@
X
X
X4.5.2.2
Xlog
X@Finished the integration of Rick Schaeffer's RCS Amiga port with the RCS
Xsources I have here (and are later than the ones Rick used).
X@
Xtext
X@d31 5
Xa35 1
X"$Header: /u/softeng/rsbx/rcs/amiga/RCS/ident.c,v 4.5.2.1 89/10/13 19:17:33 rsbx Exp Locker: rsbx $Purdue CS";
Xd39 1
Xa39 3
X * Revision 4.5.2.1  89/10/13  19:17:33  rsbx
X * Start of Amiga RCS port branch.
X * 
Xd48 9
X@
X
X
X4.5.1.1
Xlog
X@Start of cbmvax RCS source branch.
X@
Xtext
X@d31 1
Xa31 1
X"$Header: /u/softeng/rsbx/rcs/rcs.uunet/src/RCS/ident.c,v 4.5 89/05/01 15:11:54 narten Exp $Purdue CS";
Xa34 3
X * Revision 4.5  89/05/01  15:11:54  narten
X * checked in with -k by rsbx at 89.08.10.16.01.57.
X * 
X@
SHAR_EOF
echo "extracting rcs/rcs.rcsfiles/merge.sh,v"
sed 's/^X//' << \SHAR_EOF > rcs/rcs.rcsfiles/merge.sh,v
Xhead     1.3;
Xbranch   1.3.2;
Xaccess   ;
Xsymbols  amiga_rcs:1.3.2 cbmvax_source:1.3.1 uunet_june89_dist:1.3;
Xlocks    ; strict;
Xcomment  @# @;
X
X
X1.3
Xdate     88.11.08.12.06.42;  author narten;  state Exp;
Xbranches 1.3.1.1 1.3.2.1;
Xnext     ;
X
X1.3.1.1
Xdate     89.08.11.01.41.55;  author rsbx;  state Exp;
Xbranches ;
Xnext     ;
X
X1.3.2.1
Xdate     89.10.13.19.19.40;  author rsbx;  state Exp;
Xbranches ;
Xnext     ;
X
X
Xdesc
X@Three-way file merge operation.
X@
X
X
X
X1.3
Xlog
X@checked in with -k by rsbx at 89.08.10.16.05.37.
X@
Xtext
X@
X#	$Id: merge.sh,v 1.3 88/11/08 12:06:42 narten Exp $
X
XPATH=/bin:/usr/bin
XDIFF=/bin/diff
XDIFF3=/usr/local/lib/rdiff3
Xp=w
Xcase $1 in
X-p)
X	p='1,$p'
X	shift
Xesac
X
Xcase $# in
X0|1|2)
X	echo >&2 "merge: usage: merge [-p] file1 file2 file3"
X	exit 1
Xesac
X
Xcase $p in
Xw)
X	if test ! -w $1
X	then
X		echo >&2 "$1 not writeable"
X		exit 1
X	fi
Xesac
X
Xtrap 's=$?; rm -f /tmp/d3a$$ /tmp/d3b$$; exit $s' 0
Xtrap exit 1 2 3 13 15
Xumask 077
X
X$DIFF $1 $3 >/tmp/d3a$$
Xcase $? in
X0|1) ;;
X*) exit
Xesac
X
X$DIFF $2 $3 >/tmp/d3b$$
Xcase $? in
X0|1) ;;
X*) exit
Xesac
X
X{
X	$DIFF3 -E /tmp/d3a$$ /tmp/d3b$$ $1 $2 $3 $4 $5
X	case $? in
X	0) ;;
X	1) echo >&2 merge: warning: 1 overlap during merge.;;
X	*) echo >&2 merge: warning: $? overlaps during merge.
X	esac
X	echo $p
X} | ed - $1
X@
X
X
X1.3.2.1
Xlog
X@Start of Amiga RCS port branch.
X@
Xtext
X@d2 1
Xa2 1
X#	$Id: merge.sh,v 1.3.1.1 89/08/11 01:41:55 rsbx Exp Locker: rsbx $
X@
X
X
X1.3.1.1
Xlog
X@Start of cbmvax RCS source branch.
X@
Xtext
X@@
SHAR_EOF
echo "extracting rcs/rcs.rcsfiles/rcsmerge.c,v"
sed 's/^X//' << \SHAR_EOF > rcs/rcs.rcsfiles/rcsmerge.c,v
Xhead     4.5;
Xbranch   4.5.2;
Xaccess   ;
Xsymbols  amiga_rcs:4.5.2 cbmvax_source:4.5.1 uunet_june89_dist:4.5;
Xlocks    ; strict;
Xcomment  @ * @;
X
X
X4.5
Xdate     89.05.01.15.13.16;  author narten;  state Exp;
Xbranches 4.5.1.1 4.5.2.1;
Xnext     ;
X
X4.5.1.1
Xdate     89.08.11.01.42.57;  author rsbx;  state Exp;
Xbranches ;
Xnext     ;
X
X4.5.2.1
Xdate     89.10.13.19.19.04;  author rsbx;  state Exp;
Xbranches ;
Xnext     4.5.2.2;
X
X4.5.2.2
Xdate     89.10.15.15.44.55;  author rsbx;  state Exp;
Xbranches ;
Xnext     ;
X
X
Xdesc
X@rcsmerge operation.
X@
X
X
X
X4.5
Xlog
X@checked in with -k by rsbx at 89.08.10.16.22.33.
X@
Xtext
X@/*
X *                       rcsmerge operation
X */
X#ifndef lint
Xstatic char rcsid[]=
X"$Header: /usr/src/local/bin/rcs/src/RCS/rcsmerge.c,v 4.5 89/05/01 15:13:16 narten Exp $ Purdue CS";
X#endif
X/*****************************************************************************
X *                       join 2 revisions with respect to a third
X *****************************************************************************
X */
X
X/* Copyright (C) 1982, 1988, 1989 Walter Tichy
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by Walter Tichy.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X *
X * Report all problems and direct all questions to:
X *   rcs-bugs@@cs.purdue.edu
X * 
X
X
X
X
X
X
X
X*/
X
X
X
X/* $Log:	rcsmerge.c,v $
X * Revision 4.5  89/05/01  15:13:16  narten
X * changed copyright header to reflect current distribution rules
X * 
X * Revision 4.4  88/11/08  12:00:47  narten
X * changes from  eggert@@sm.unisys.com (Paul Eggert)
X * 
X * Revision 4.4  88/08/09  19:13:13  eggert
X * Beware merging into a readonly file.
X * Beware merging a revision to itself (no change).
X * Use execv(), not system(); yield exit status like diff(1)'s.
X * 
X * Revision 4.3  87/10/18  10:38:02  narten
X * Updating version numbers. Changes relative to version 1.1 
X * actually relative to 4.1
X * 
X * Revision 1.3  87/09/24  14:00:31  narten
X * Sources now pass through lint (if you ignore printf/sprintf/fprintf 
X * warnings)
X * 
X * Revision 1.2  87/03/27  14:22:36  jenkins
X * Port to suns
X * 
X * Revision 1.1  84/01/23  14:50:36  kcs
X * Initial revision
X * 
X * Revision 4.1  83/03/28  11:14:57  wft
X * Added handling of default branch.
X * 
X * Revision 3.3  82/12/24  15:29:00  wft
X * Added call to catchsig().
X *
X * Revision 3.2  82/12/10  21:32:02  wft
X * Replaced getdelta() with gettree(); improved error messages.
X *
X * Revision 3.1  82/11/28  19:27:44  wft
X * Initial revision.
X *
X */
X#include "rcsbase.h"
X#ifndef lint
Xstatic char rcsbaseid[] = RCSBASE;
X#endif
Xstatic char co[] = CO;
Xstatic char merge[] = MERGE;
X
Xextern int  cleanup();              /* cleanup after signals                */
Xextern char * mktempfile();         /*temporary file name generator         */
Xextern struct hshentry * genrevs(); /*generate delta numbers                */
Xextern int  nerror;                 /*counter for errors                    */
X
Xchar *RCSfilename;
Xchar *workfilename;
Xchar * temp1file, * temp2file;
X
Xmain (argc, argv)
Xint argc; char **argv;
X{
X        char * cmdusage;
X        int  revnums; /* counter for revision numbers given */
X        int tostdout;
X	int nochange;
X        char * rev1, * rev2; /*revision numbers*/
X	char commarg[revlength+3];
X        char numericrev[revlength];   /* holds expanded revision number     */
X        struct hshentry * gendeltas[hshsize];/*stores deltas to be generated*/
X        struct hshentry * target;
X
X        catchints();
X        cmdid = "rcsmerge";
X        cmdusage = "command format:\n    rcsmerge -p -rrev1 -rrev2 file\n    rcsmerge -p -rrev1 file";
X	revnums=0;tostdout=false;nochange=false;
X
X        while (--argc,++argv, argc>=1 && ((*argv)[0] == '-')) {
X                switch ((*argv)[1]) {
X                case 'p':
X                        tostdout=true;
X                        /* falls into -r */
X                case 'r':
X                        if ((*argv)[2]!='\0') {
X                            if (revnums==0) {
X                                    rev1= *argv+2; revnums=1;
X                            } elif (revnums==1) {
X                                    rev2= *argv+2; revnums=2;
X                            } else {
X                                    faterror("too many revision numbers");
X                            }
X                        } /* do nothing for empty -r or -p */
X                        break;
X
X                default:
X                        faterror("unknown option: %s\n%s", *argv,cmdusage);
X                };
X        } /* end of option processing */
X
X        if (argc<1) faterror("No input file\n%s",cmdusage);
X        if (revnums<1) faterror("no base revision number given");
X
X        /* now handle all filenames */
X
X        if (pairfilenames(argc,argv,true,false)==1) {
X
X                if (argc>2 || (argc==2&&argv[1]!=nil))
X                        warn("too many arguments");
X                diagnose("RCS file: %s",RCSfilename);
X		if (!(access(workfilename,tostdout?4:6)==0))
X			nowork();
X
X                if (!trysema(RCSfilename,false)) goto end; /* give up */
X
X                gettree();  /* reads in the delta tree */
X
X                if (Head==nil) faterror("no revisions present");
X
X
X                if (!expandsym(rev1,numericrev)) goto end;
X                if (!(target=genrevs(numericrev, (char *)nil, (char *)nil, (char *)nil,gendeltas))) goto end;
X                rev1=target->num;
X                if (revnums==1)  /*get default for rev2 */
X                        rev2=Dbranch!=nil?Dbranch->num:Head->num;
X                if (!expandsym(rev2,numericrev)) goto end;
X                if (!(target=genrevs(numericrev, (char *)nil, (char *)nil, (char *)nil,gendeltas))) goto end;
X                rev2=target->num;
X
X		if (strcmp(rev1,rev2) == 0) {
X			diagnose("Merging revision %s to itself (no change)",
X				rev1
X			);
X			nochange = true;
X			if (tostdout) {
X				FILE *w = fopen(workfilename,"r");
X				if (w==NULL)
X					nowork();
X				fastcopy(w,stdout);
X			}
X			goto end;
X		}
X
X                temp1file=mktempfile("/tmp/",TMPFILE1);
X                temp2file=mktempfile("/tmp/",TMPFILE2);
X
X                diagnose("retrieving revision %s",rev1);
X                VOID sprintf(commarg,"-p%s",rev1);
X                if (run((char*)nil,temp1file, co,"-q",commarg,RCSfilename,(char*)nil)){
X                        faterror("co failed");
X                }
X                diagnose("retrieving revision %s",rev2);
X                VOID sprintf(commarg,"-p%s",rev2);
X                if (run((char*)nil,temp2file, co,"-q",commarg,RCSfilename,(char*)nil)){
X                        faterror("co failed");
X                }
X                diagnose("Merging differences between %s and %s into %s%s",
X                         rev1, rev2, workfilename,
X                         tostdout?"; result to stdout":"");
X
X                if (
X		      tostdout
X		    ? run((char*)nil,(char*)nil,merge,"-p",workfilename,temp1file,temp2file,workfilename,rev2,(char*)nil)
X		    : run((char*)nil,(char*)nil,merge,     workfilename,temp1file,temp2file,workfilename,rev2,(char*)nil)) {
X                        faterror("merge failed");
X                }
X        }
X
Xend:
X        VOID cleanup();
X	exit(2*(nerror!=0) + nochange);
X
X}
X
X
Xnowork()
X{
X	faterror("Can't open %s",workfilename);
X}
X@
X
X
X4.5.2.1
Xlog
X@Start of Amiga RCS port branch.
X@
Xtext
X@d6 1
Xa6 5
X<<<<<<< rcsmerge.c
X"$Header: /u/softeng/rsbx/rcs/amiga/RCS.cbmvax/rcsmerge.c,v 4.5.1.1 89/08/11 01:42:57 rsbx Exp Locker: rsbx $ Purdue CS";
X=======
X"$Header: /u/softeng/rsbx/rcs/amiga/RCS/rcsmerge.c,v 1.2 89/09/17 13:36:20 rick Exp $ Purdue CS";
X>>>>>>> 1.2
Xa40 11
X<<<<<<< rcsmerge.c
X * Revision 4.5.1.1  89/08/11  01:42:57  rsbx
X * Start of cbmvax RCS source branch.
X=======
X * Revision 1.2  89/09/17  13:36:20  rick
X * Port to AmigaDos done by Rick Schaeffer (ricks@@iscuva.iscs.com)
X * All changes done with conditional compile (#ifdef AMIGA).  This version
X * compiles correctly with Lattice C version 5.02 or later.
X>>>>>>> 1.2
X * 
X<<<<<<< rcsmerge.c
Xa41 3
X * checked in with -k by rsbx at 89.08.10.16.22.33.
X * 
X * Revision 4.5  89/05/01  15:13:16  narten
Xa51 11
X=======
X * Revision 1.4  89/09/10  09:27:46  rick
X * Moved TARGETDIR to rcs:
X * 
X * Revision 1.3  89/09/09  17:35:44  rick
X * Amiga changes
X * 
X * Revision 1.2  88/09/03  15:12:06  rick
X * Port to AmigaDos.  All done with conditional compiles
X * 
X>>>>>>> 1.2
Xa85 6
X#ifdef AMIGA
X#define DTMPFILE1    ",RDFt1XXXXXX"
X#define DTMPFILE2    ",RDFt2XXXXXX"
X#define DTMPFILE3    ",RDFt3XXXXXX"
X#endif
X
Xa163 1
X<<<<<<< rcsmerge.c
Xa178 7
X=======
X#ifdef AMIGA
X                temp1file=mktempfile("t:",DTMPFILE1);
X                temp2file=mktempfile("t:",DTMPFILE2);
X#else
X				temp1file=mktempfile("/tmp/",TMPFILE1);
X>>>>>>> 1.2
Xd180 1
Xa180 1
X#endif
Xa181 1
X<<<<<<< rcsmerge.c
Xa183 5
X=======
X                VOID sprintf(command,"%sco -q -p%s %s >%s\n",
X                        TARGETDIR,rev1,RCSfilename,temp1file);
X                if (system(command)){
X>>>>>>> 1.2
Xa186 1
X<<<<<<< rcsmerge.c
Xa188 5
X=======
X                VOID sprintf(command,"%sco -q -p%s %s >%s\n",
X                         TARGETDIR,rev2,RCSfilename,temp2file);
X                if (system(command)){
X>>>>>>> 1.2
X@
X
X
X4.5.2.2
Xlog
X@Finished the integration of Rick Schaeffer's RCS Amiga port with the RCS
Xsources I have here (and are later than the ones Rick used).
X@
Xtext
X@d6 5
Xa10 1
X"$Header: /u/softeng/rsbx/rcs/amiga/RCS/rcsmerge.c,v 4.5.2.1 89/10/13 19:19:04 rsbx Exp Locker: rsbx $ Purdue CS";
Xd45 1
Xa45 3
X * Revision 4.5.2.1  89/10/13  19:19:04  rsbx
X * Start of Amiga RCS port branch.
X * 
Xd48 6
Xd55 1
Xd70 11
Xd199 1
Xd214 2
Xd220 2
Xa221 1
X                temp1file=mktempfile("/tmp/",TMPFILE1);
Xd225 1
Xd228 5
Xd236 1
Xd239 5
X@
X
X
X4.5.1.1
Xlog
X@Start of cbmvax RCS source branch.
X@
Xtext
X@d6 1
Xa6 1
X"$Header: /u/softeng/rsbx/rcs/rcs.uunet/src/RCS/rcsmerge.c,v 4.5 89/05/01 15:13:16 narten Exp $ Purdue CS";
Xa40 3
X * Revision 4.5  89/05/01  15:13:16  narten
X * checked in with -k by rsbx at 89.08.10.16.22.33.
X * 
X@
SHAR_EOF
echo "extracting rcs/rcs_link"
sed 's/^X//' << \SHAR_EOF > rcs/rcs_link
XRCS.RCSfiles/
SHAR_EOF
echo "extracting readme"
sed 's/^X//' << \SHAR_EOF > readme
XThese 2 disks contain the sources and executable to a port of RCS to the
XAmiga from Unix. The port was done by Raymond S. Brand and Rick Schaeffer.
X
XInstallation:
X	Create a directory for the RCS executables and in your startup-
Xsequence, assign RCS: to that directory. You may also want to add RCS: to
Xyour path. Copy the files from the bin directory on disk 1 to the RCS
Xdirectory. Add 'SetEnv USERNAME xxxx' to your startup-sequence, where xxxx
Xis replaced by what you want RCS to think your user id is. Your user id
Xmay not contain any of the following characters; " ", "$", ",", ".", ":",
X";", "@".
X	Read the documentation in the doc directory of disk 1.
X
XRCS_link:
X	If the file "RCS_link" exists in the current directory, then
Xthe RCS tools  will look in this file for the path name of the RCS
Xdirectory.  So, if your RCS files are in foo:local/src/foobar/RCS and
Xyou are in your local directory of hd6:joker/foobar then the RCS_link
Xfile in your current directory should contain:
X
X	"foo:local/src/foobar/RCS/\n"
X
XThe RCS_link may either an absolute or a relative path but must end with
Xa ":" or a "/" followed by a linefeed. The RCS_link feature is a rather
Xlate addition to the code and therefor has had rather limited testing.
X
XWarning:
X	The business of RCS is the manipulation of source files. We believe
Xthat the software has no serious bugs but you should make plenty of backups
Xof your files (at least) until you are sure this software works for you.
X
XTodo:
X	Port the rcsfreeze and rcsclean scripts to the Amiga. Cleanup the
Xcode sections labeled TODO.
X
XBugs:
X	If you find any, please send a descriptive note Ray and/or Rick at
Xthe addresses below.
X
XRaymond S. Brand		Rick Schaeffer
XCommodore-Amiga Engineering	E. 13611 26th Ave.
X1200 Wilson Drive		Spokane, Wa.   99216
XWest Chester PA 19380		ricks@isc-br.isc-br.com
Xrsbx@cbmvax.commodore.com       ...!uunet!isc-br!ricks
X...!uunet!cbmvax!rsbx
SHAR_EOF
echo "extracting readme.extras"
sed 's/^X//' << \SHAR_EOF > readme.extras
XThere are some stand-alone utilities in this distribution that are
Xuseful.  They must be located in the "RCS:" directory in order for
Xthe RCS programs to find them, but assuming that "RCS:" is in your
Xsearch path, they are available for other purposes.
X
XFirst, there is "diff" and "diff3".  These are ports from GNU and are much
Xfaster and more flexible than anything similar available for the Amiga.
XFor instance, the version of diff provided here supports directory and
Xsub-directory diff listings.  Diff3 is probably of limited use except
Xinside RCS...however, it does use true pipes and, in conjunction with
Xthe source for popen.c (in the "rsbx.lib" directory) may prove useful
Xas a coding example. [Another good popen() example is merge.c in the source
Xdirectory for RCS. rsbx]  At any rate, peruse the README file that is
Xpresent in the "diff" directory for details.
X
XSecond there is "ked".  This is an Amiga version of the famous (infamous?)
XUnix "ed" program.  It is named "ked" here because the name "ed" was
Xalready taken on the Amiga.  It is, as far as I know, completely compatible
Xwith the Unix version of ed...including the ability to read scripts from
Xstdin.  It is used by the "merge" program in RCS to process the piped
Xoutput from diff3 but does work stand-alone.
X
X
X					Rick
SHAR_EOF
if `test ! -d rsbx.lib`
then
  mkdir rsbx.lib
  echo "mkdir rsbx.lib"
fi
echo "extracting rsbx.lib/rsbx.lib.doc"
sed 's/^X//' << \SHAR_EOF > rsbx.lib/rsbx.lib.doc
X
X
XTABLE OF CONTENTS
X
Xrsbx.lib/ChildStatus()
Xrsbx.lib/CreateFamily()
Xrsbx.lib/EmptyMorgue()
Xrsbx.lib/EscapeAdditions()
Xrsbx.lib/EscapeString()
Xrsbx.lib/LaunchChildl()
Xrsbx.lib/LaunchChildv()
Xrsbx.lib/OrphanChild()
Xrsbx.lib/OrphanChildren()
Xrsbx.lib/pclose()
Xrsbx.lib/popenl()
Xrsbx.lib/popenv()
Xrsbx.lib/WaitChild()
X
X
Xrsbx.lib/ChildStatus()                                   rsbx.lib/ChildStatus()
X
X   NAME
X	ChildStatus -- Check completion status of child process.
X
X   SYNOPSIS
X	completion = ChildStatus(child, status)
X
X	struct ChildNode *ChildStatus(struct ChildNode *, long *);
X
X   FUNCTION
X	Checks if a child process has completed and sets status to the return
X	    code from the child process if it has.
X
X   INPUTS
X	child         - Child process identifier returned from LaunchChildX();
X	status        - Pointer to a long to place the return code from the
X	                child process in.
X
X   RESULT
X	completion    - Child process identifier if child is a child process
X	                of this process and has completed. If child is a child
X	                process of this process and has not completed, then
X			completion is 0 and status is set to 0. If child is
X	                not a child procewss of this process, then completion
X	                is 0 and status will be non-zero.
X
X   NOTES
X
X   SEE ALSO
X	CreateFamily(), EmptyMorgue(), LaunchChildl(), LaunchChildv(),
X	OrphanChild(), OrphanChildren(), WaitChild().
X
X   BUGS
X	None known.
X
X
Xrsbx.lib/CreateFamily()                                 rsbx.lib/CreateFamily()
X
X   NAME
X	CreateFamily -- 
X
X   SYNOPSIS
X	success = CreateFamily()
X
X	int CreateFamily( void );
X
X   FUNCTION
X	This function initializes the structures used to keep track of child
X	    processes of this process.
X
X   INPUTS
X
X   RESULT
X	success       - Zero if unable to allocate and initialize needed
X	                structures.
X
X   NOTES
X
X   SEE ALSO
X	ChildStatus(), EmptyMorgue(), LaunchChildl(), LaunchChildv(),
X	OrphanChild(), OrphanChildren(), WaitChild().
X
X   BUGS
X	None Known.
X
X
Xrsbx.lib/EmptyMorgue()                                   rsbx.lib/EmptyMorgue()
X
X   NAME
X	EmptyMorgue -- Process child termination messages.
X
X   SYNOPSIS
X	EmptyMorgue()
X
X	void EmptyMorgue( void );
X
X   FUNCTION
X	This function processes any termination messages from child processes
X	    of this process.
X
X   INPUTS
X
X   RESULT
X
X   NOTES
X
X   SEE ALSO
X	ChildStatus(), CreateFamily(), LaunchChildl(), LaunchChildv(),
X	OrphanChild(), OrphanChildren(), WaitChild().
X
X   BUGS
X	None Known.
X
X
Xrsbx.lib/EscapeAdditions()                           rsbx.lib/EscapeAdditions()
X
X   NAME
X	EscapeAdditions -- Return number of characters to escape an argument.
X
X   SYNOPSIS
X	escapes = EscapeAdditions(argv)
X
X	int EscapeAdditions(char *);
X
X   FUNCTION
X	Determines the number of extra characters that are needed to escape
X	    a command argument for AmigaDos command parsing.
X
X   INPUTS
X	argv          - Argument to check.
X
X   RESULT
X	escapes       - The number of characters that need to be added to the
X	                argument to escape the characters special to AmigaDos.
X
X   NOTES
X	Characters special to AmigaDos are " [0x22], * [0x2a], ESC [0x1b],
X	    LF [0x0a], SP [0x20].
X
X   SEE ALSO
X	EscapeAdditions(), EscapeString().
X
X   BUGS
X	Thinks spaces need an AmigaDos escape character preceeding them.
X
X
Xrsbx.lib/EscapeString()                                 rsbx.lib/EscapeString()
X
X   NAME
X	EscapeString -- Copy argument to buffer escaping as needed.
X
X   SYNOPSIS
X	dest = EscapeString(buffer, argv)
X
X	char *EscapeAdditions(char *, char *);
X
X   FUNCTION
X	Copies a string containing a single argument to a buffer, escaping
X	    characters special to AmigaDos.
X
X   INPUTS
X	buffer        - Buffer for escaped argument string.
X	argv          - Argument string to escape.
X
X   RESULT
X	dest          - The same as buffer.
X
X   NOTES
X	Characters special to AmigaDos are " [0x22], * [0x2a], ESC [0x1b],
X	    LF [0x0a], SP [0x20].
X
X   SEE ALSO
X	EscapeAdditions(), EscapeString().
X
X   BUGS
X	Thinks spaces need an AmigaDos escape character preceeding them.
X
X
Xrsbx.lib/LaunchChildl()                                 rsbx.lib/LaunchChildl()
X
X   NAME
X	LaunchChildl -- Launch a child process with argument list.
X
X   SYNOPSIS
X	cpid = LaunchChildl(envp, name, arg0, ..., argn, NULL)
X
X	struct ChildNode *LaunchChildl(struct LAUNCHENV *, char *, char *, ...);
X
X   FUNCTION
X	This function behaves like a combination of the Unix 'fork' and 'execl'
X	    functions. That is, a new process is created, as with 'fork', and
X	    executes a load module, as with 'execl'.
X
X   INPUTS
X	envp          - Pointer to a LAUNCHENV structure that has been
X	                initialized with apropriate values prior to calling
X	                this function. The LAUNCHENV structure only need exist
X	                during the execution of this function.
X	name          - Name of the file to execute.
X	arg0          - Same as name, by Unix convention.
X       ...           - Other command line arguments needed by the file to be
X	                executed.
X	NULL          - Zero.
X
X   RESULT
X	cpid          - Pointer to a ChildNode structure, used to identify the
X	                child process.
X
X   NOTES
X	struct LAUNCHENV
X	        {
X	        long priority;   priority for child process
X	        ULONG stack;     stack size for child process.
X	                          If zero, stack size of calling
X	                          process will be used.
X	        BPTR std_in;     AmigaDos filehandle for child's
X	                          Input() stream. If zero, Input()
X	                          stream of calling process used.
X	        BPTR std_out;    AmigaDos filehandle for child's
X	                          Output() stream. If zero, Output()
X	                          stream of calling process used.
X	        BPTR console;    console window handler port for
X	                          child.
X	        BPTR le_fh1;     AmigaDos filehandle for child to
X	                          close at exit.
X	        BPTR le_fh2;     AmigaDos filehandle for child to
X	                          close at exit.
X	        };
X
X   SEE ALSO
X	ChildStatus(), CreateFamily(), EmptyMorgue(), LaunchChildv(),
X	OrphanChild(), OrphanChildren(), WaitChild().
X
X   BUGS
X	This function does not create a complete CLI enviroment for the child
X	    process. Use of this function with a command that expects a BCPL
X	    environment will crash the system.
X
X
Xrsbx.lib/LaunchChildv()                                 rsbx.lib/LaunchChildv()
X
X   NAME
X	LaunchChildv -- Launch a child process with argument list.
X
X   SYNOPSIS
X	cpid = LaunchChildv(envp, name, argv)
X
X	struct ChildNode *LaunchChildv(struct LAUNCHENV *, char **);
X
X   FUNCTION
X	This function behaves like a combination of the Unix 'fork' and 'execv'
X	    functions. That is, a new process is created, as with 'fork', and
X	    executes a load module, as with 'execv'.
X
X   INPUTS
X	envp          - Pointer to a LAUNCHENV structure that has been
X	                initialized with apropriate values prior to calling
X	                this function. The LAUNCHENV structure only need exist
X	                during the execution of this function.
X	name          - Name of the file to execute.
X	argv          - An array of pointers to the argument strings for the
X	                command. The last argument pointer must be followed
X	                by a 0 pointer. The first pointer, argv[0], is the
X	                same as name, by unix convention.
X
X   RESULT
X	cpid          - Pointer to a ChildNode structure, used to identify the
X	                child process.
X
X   NOTES
X	struct LAUNCHENV
X	        {
X	        long priority;   priority for child process
X	        ULONG stack;     stack size for child process.
X	                          If zero, stack size of calling
X	                          process will be used.
X	        BPTR std_in;     AmigaDos filehandle for child's
X	                          Input() stream. If zero, Input()
X	                          stream of calling process used.
X	        BPTR std_out;    AmigaDos filehandle for child's
X	                          Output() stream. If zero, Output()
X	                          stream of calling process used.
X	        BPTR console;    console window handler port for
X	                          child.
X	        BPTR le_fh1;     AmigaDos filehandle for child to
X	                          close at exit.
X	        BPTR le_fh2;     AmigaDos filehandle for child to
X	                          close at exit.
X	        };
X
X   SEE ALSO
X	ChildStatus(), CreateFamily(), EmptyMorgue(), LaunchChildl(),
X	OrphanChild(), OrphanChildren(), WaitChild().
X
X   BUGS
X	This function does not create a complete CLI enviroment for the child
X	    process. Use of this function with a command that expects a BCPL
X	    environment will crash the system.
X
X
Xrsbx.lib/OrphanChild()                                   rsbx.lib/OrphanChild()
X
X   NAME
X	OrphanChild -- Dis-associate a child process from this process.
X
X   SYNOPSIS
X	success = OrphanChild(child)
X
X	int OrphanChild(struct ChildNode * );
X
X   FUNCTION
X	This function will dis-associate a child process from this process and
X	    free the structures used to track the child process.
X
X   INPUTS
X	child         - Child identifier returned by LaunchChildl() or by
X	                LaunchChildv().
X
X   RESULT
X	success       - Zero if invalid child identifier.
X
X   NOTES
X
X   SEE ALSO
X	ChildStatus(), CreateFamily(), EmptyMorgue(), LaunchChildl(),
X	LaunchChildv(), OrphanChildren(), WaitChild().
X
X   BUGS
X	None Known.
X
X
Xrsbx.lib/OrphanChildren()                             rsbx.lib/OrphanChildren()
X
X   NAME
X	OrphanChildren -- Orphan all child processes of this process.
X
X   SYNOPSIS
X	OrphanChildren()
X
X	void OrphanChildren( void );
X
X   FUNCTION
X	This function orphans all child processes of this process and frees
X	    the memory used to keep track of the children.
X
X   INPUTS
X
X   RESULT
X
X   NOTES
X
X   SEE ALSO
X	ChildStatus(), CreateFamily(), EmptyMorgue(), LaunchChildl(),
X	LaunchChildv(), OrphanChild(), WaitChild().
X
X   BUGS
X	None Known.
X
X
Xrsbx.lib/pclose()                                             rsbx.lib/pclose()
X
X   NAME
X	pclose -- Closes pipe opened by popenl() or by popenv().
X
X   SYNOPSIS
X	status = pclose(pipe)
X
X	int pclose(FILE *);
X
X   FUNCTION
X	Waits for the command associated with the pipe to exit, closes the
X	    stream, and returns the return code from the command.
X
X   INPUTS
X	pipe          - Stream pointer returned by a call to popenl() or to
X	                popenv().
X
X   RESULT
X	status        - The return code from the command executed, or -1 if
X	                pipe wasn't opened by popenl() or by popenv().
X
X   NOTES
X
X   SEE ALSO
X	popenl(), popenv().
X
X   BUGS
X	None known.
X
X
Xrsbx.lib/popenl()                                             rsbx.lib/popenl()
X
X   NAME
X	popenl -- Initiate I/O to or from a command.
X
X   SYNOPSIS
X	pipe = popenl(arg0, ..., argn, NULL, mode)
X
X	FILE *popenl(char *, char *, ...);
X
X   FUNCTION
X	Creates a stream between the calling process and the stdin or stdout
X	    streams of the command it executes. Mode should be "r" to read
X	    the stdout stream of the command, or "w" to write to the stdin
X	    stream of the command. 
X
X   INPUTS
X	arg0          - Name of file to execute.
X       ...           - Other command line arguments needed by the file to be
X	                executed.
X	NULL          - Zero.
X	mode          _ I/O mode string.
X
X   RESULT
X	pipe          - File pointer to use to read or write to the command
X	                with.
X
X   NOTES
X	A stream opened by popenl() should be closed by pclose().
X
X   SEE ALSO
X	popenv(), pclose().
X
X   BUGS
X	This function does not create a complete CLI enviroment for the child
X	    process. Use of this function with a command that expects a BCPL
X	    environment will crash the system. The Unix function 'popen' takes
X	    as arguments a command string which it passes to the shell, and a
X	    mode string.
X
X
Xrsbx.lib/popenv()                                             rsbx.lib/popenv()
X
X   NAME
X	popenv -- Initiate I/O to or from a command.
X
X   SYNOPSIS
X	pipe = popenv(argv, mode)
X
X	FILE *popenv(char **, char *);
X
X   FUNCTION
X	Creates a stream between the calling process and the stdin or stdout
X	    streams of the command it executes. Mode should be "r" to read
X	    the stdout stream of the command, or "w" to write to the stdin
X	    stream of the command. 
X
X   INPUTS
X	argv          - An array of pointer to the argument strings for the
X	                command. The last pointer must be followed by a 0
X	                pointer. The first pointer, argv[0], is the name of
X	                file to execute.
X	mode          _ I/O mode string.
X
X   RESULT
X	pipe          - File pointer to use to read or write to the command
X	                with.
X
X   NOTES
X	A stream opened by popenv() should be closed by pclose().
X
X   SEE ALSO
X	popenl(), pclose().
X
X   BUGS
X	This function does not create a complete CLI enviroment for the child
X	    process. Use of this function with a command that expects a BCPL
X	    environment will crash the system. The Unix function 'popen' takes
X	    as arguments a command string which it passes to the shell, and a
X	    mode string.
X
X
Xrsbx.lib/WaitChild()                                       rsbx.lib/WaitChild()
X
X   NAME
X	WaitChild -- Wait for child process to terminate.
X
X   SYNOPSIS
X	term = WaitChild(child, status)
X
X	struct ChildNode *WaitChild(struct ChildNode *, long * );
X
X   FUNCTION
X	This function waits for a child process to terminate, and places the
X	    child's return val in the long pointed to by status. If the child
X	    identifier provided doen't belong to a child of this process, then
X	    0 is returned. If the child identifier is zero, returns the child
X	    identifier of a child that has terminated and sets the long status
X	    points to to its return val. If the child identifier is zero and
X	    no child has yet terminated, wait for any child to terminate and
X	    return its identifier and set the long status points to to its
X	    return val. If the child identifier is zero and there are no child
X	    processes of this process, return zero.
X
X   INPUTS
X	child         - Child identifier as returned by LaunchChildl() or by
X	                LaunchChildv().
X	status        - Pointer to a long to store the return val of the child
X	                in.
X
X   RESULT
X	term          - Child identifier of the child process whos return val
X	                was stored in the long pointed to by status, or zero
X	                if there was an error.
X
X   NOTES
X
X   SEE ALSO
X	ChildStatus(), CreateFamily(), EmptyMorgue(), LaunchChildl(),
X	LaunchChildv(), OrphanChild(), OrphanChildren().
X
X   BUGS
X	None Known.
X
X
SHAR_EOF
echo "extracting rsbx.lib/xc.asm"
sed 's/^X//' << \SHAR_EOF > rsbx.lib/xc.asm
X*
X* This is a copy of c.a, distributed with the Lattice 5.04 compiler, that has
X*	been hacked to support my LaunchChild calls. There is no WorkBench
X*	support in this startup.
X*
X*					Ray
X*
X*
X* C initial startup procedure under AmigaDOS
X* 
X* Use the following command line to make c.o
X* asm -u -iINCLUDE: c.a
X*
X* Use the following command line to make cres.o
X* asm -u -dRESIDENT -iINCLUDE: -ocres.o c.a
X*
X	INCLUDE	"exec/types.i"
X	INCLUDE	"exec/alerts.i"
X	INCLUDE	"exec/nodes.i"
X	INCLUDE	"exec/lists.i"
X	INCLUDE	"exec/ports.i"
X	INCLUDE	"exec/libraries.i"
X	INCLUDE	"exec/tasks.i"
X	INCLUDE	"exec/memory.i"
X	INCLUDE	"exec/execbase.i"
X	INCLUDE	"libraries/dos.i"
X	INCLUDE	"libraries/dosextens.i"
X	INCLUDE	"exec/funcdef.i"
X	INCLUDE	"exec/exec_lib.i"
X	INCLUDE	"libraries/dos_lib.i"
X
XMEMFLAGS	EQU	MEMF_CLEAR+MEMF_PUBLIC
XAbsExecBase	EQU	4
X
X; some usefull macros:
X
Xcallsys macro
X	CALLLIB _LVO\1
X	endm
X	
X	xdef	_XCEXIT		* exit(code) is standard way to leave C.
X	xdef	_@XCEXIT
X	
X	xref	_LinkerDB	* linker defined base value
X	xref	__BSSBAS	* linker defined base of BSS
X	xref	__BSSLEN	* linker defined length of BSS
X	IFD	RESIDENT
X	xref	_RESLEN
X	xref	_RESBASE
X	xref	_NEWDATAL
X	xref	__stack
X	ENDC
X	
X*	library references
X
X	section text,code
X
X	xref	__xmain			* Name of C program to start with.
X	xref	_MemCleanup		* Free all allocated memory
X	xref	___fpinit		* initialize floating point
X	xref	___fpterm		* terminate floating point
X	
Xstart:
X	movem.l d1-d6/a0-a6,-(a7)
X
X	move.l	a0,a2			* save command pointer
X	move.l	d0,d2			* and command length
X	lea	_LinkerDB,a4		* load base register
X	move.l	AbsExecBase.W,a6
X
X*------ are we running as a son of Workbench?
X	move.l	ThisTask(a6),A3
X	tst.l	pr_CLI(A3)
X	bne.s	fromCLI
X	
X*=======================================================================
X*====== Workbench Startup Code =========================================
X*=======================================================================
X
XfromWorkbench:
X
X	lea	pr_MsgPort(A3),a0	* our process base
X	callsys WaitPort
X	lea	pr_MsgPort(A3),a0	* our process base
X	callsys GetMsg
X	move.l	d0,a2
X
X*$* should put recoverable alert here
X
X*------	return the startup message to our parent
X*	we forbid so workbench can't UnLoadSeg() us
X*	before we are done:
X	callsys	Forbid
X	move.l	a2,a1
X	callsys	ReplyMsg
X
X	moveq.l	#-1,D0
X	
X	movem.l (a7)+,d1-d6/a0-a6
X	rts
X	
X*=======================================================================
X*====== CLI Startup Code ===============================================
X*=======================================================================
X
XfromCLI:
X	IFND	RESIDENT
X		lea	__BSSBAS,a3		* get base of BSS
X		moveq	#0,d1
X		move.l	#__BSSLEN,d0		* get length of BSS in longwords
X		bra.s	clr_lp			* and clear for length given
Xclr_bss		move.l	d1,(a3)+
Xclr_lp		dbf	d0,clr_bss
X		move.l	a7,__StackPtr(A4)	* Save stack ptr
X		move.l	a6,_SysBase(A4)
X	ENDC
X	
X
X	IFD	RESIDENT
X		movem.l	d2,-(a7)
X		movem.l a0-a2,-(a7)
X
X*------		get the size of the stack, if CLI use cli_DefaultStack
X
X		move.l	ThisTask(a6),A3
X		move.l	pr_CLI(A3),d1
X		lsl.l	#2,d1
X		move.l	d1,a0
X		move.l	cli_DefaultStack(a0),d1
X		lsl.l	#2,d1			* # longwords -> # bytes
X
Xdostack:
X		moveq	#0,d2			* use d2 as flag for newstack or not
X		move.l	#RESLEN,d0
X		cmp.l	__stack(a4),d1		* This a4 is in the original 
X						* set of data
X		bcc.s	nochange	
X		move.l	__stack(a4),d1
X		add.l	d1,d0			* increase size of mem for new stack
X		moveq	#1,d2			* set flag
X		
Xnochange:
X		move.l	d1,a3			* save stacksize to set up stack checking
X		move.l	#MEMFLAGS,d1
X		callsys AllocMem
X		tst.l	d0
X		bne.s	ok1
X		movem.l	(a7)+,d2/a0-a2
X*$* ACK!!!
X*$*		rts
X*$* ACK!!!
X
Xok1:		move.l	d0,a0
X		move.l	d0,a2
X
X	;a2 now has difference
X		move.l	d0,a1
X		move.l	#NEWDATAL,d0
X		sub.l	#RESBASE,a4
X	;copy data over
Xcpy:		move.l	(a4)+,(a0)+
X		subq.l	#1,d0
X		bne.s	cpy
X	;a4 now points at number of relocs
X		move.l	(a4)+,d0
Xreloc:		beq.s	nreloc
X		move.l	a1,a0
X		add.l	(a4)+,a0		* a0 now has add of reloc
X		add.l	(a0),a2
X		move.l	a2,(a0) 
X		move.l	a1,a2			* restore offset
X		subq.l	#1,d0
X		bra.s	reloc
X
Xnreloc:		move.l	a1,a4			* set up new base register
X		add.l	#RESBASE,a4
X
X		move.l	#RESLEN,realdatasize(a4)
X		movem.l (a7)+,a0-a2
X
X		move.l	a6,_SysBase(A4)
X		tst.b	d2
X		movem.l	(a7)+,d2		* restore d2 
X		movem.l a7,__StackPtr(A4)	* Save stack ptr (movem doesn't
X						* change flags
X		beq.s	nochg2
X
X*------		set up new stack
X		move.l	a4,d0
X		sub.l	#RESBASE,d0
X		add.l	#RESLEN,d0
X		add.l	__stack(a4),d0		* here a4 will be pointing at the
X						* new data, but _stack will be the
X						* same if all goes well
X
X		sub.l	#128,d0			* 128 down for good measure
X		move.l	d0,a7
X		move.l	__stack(a4),d0
X		move.l	d0,4(a7)		* fill in size of new stack	
X		add.l	d0,_realdatasize(a4) 	* need to know how much to free later
X
Xnochg2:
X*------		Set _base for stack checking
X		move.l	a7,d1
X		sub.l	a3,d1			* get top of stack
X		add.l	#128,D1			* allow for parms overflow
X		move.l	D1,__base(A4)		* save for stack checking
X
X	ENDC
X
Xclrwb:
X	clr.l	_WBenchMsg(A4)
X
X*-----	clear any pending signals
X	moveq	#0,d0
X	move.l	#$00003000,d1
X	callsys	SetSignal
X	
X
X*------ attempt to open DOS library:
X	lea	DOSName(PC),A1
X	moveq.l #0,D0
X	callsys OpenLibrary
X	move.l	D0,_DOSBase(A4)
X	bne.s	ok2
X	moveq.l #100,d0
X	bra.w	exit2
X
Xok2:
X*=======================================================================
X*
X* Entry: D2 = command length
X*	A2 = Command pointer
X
X	ifnd	RESIDENT		* we need to set _base if not resident
X		move.l	a7,D0		* get top of stack
X		sub.l	4(a7),D0	* compute bottom 
X		add.l	#128,D0		* allow for parms overflow
X		move.l	D0,__base(A4)	* save for stack checking
X	endc
X	
X*------ find command name:
X	move.l	ThisTask(a6),A3
X	move.l	pr_CLI(a3),a0
X	add.l	a0,a0		* bcpl pointer conversion
X	add.l	a0,a0
X	move.l	cli_CommandName(a0),a1
X	add.l	a1,a1		* bcpl pointer conversion
X	add.l	a1,a1
X
X*------ collect parameters:
X	move.b	(a1)+,d0
X	move.l	a1,__ProgramName(A4)
X
X
X	move.l	d2,-(A7)		* push command line length
X	move.l	a2,-(A7)		* push command line address
X
X*=============================================
X*------ common code --------
X*=============================================
X
Xmain	jsr	___fpinit(PC)		* Initialize floating point
X	jsr	__xmain(PC)		* call C entrypoint
X	moveq.l	#0,d0			* set successful status
X	bra.s	exit2
X*
X
X_XCEXIT:
X	move.l	4(SP),d0		* extract return code
X_@XCEXIT:
Xexit2:
X	move.l	d0,-(a7)
X	move.l	__ONEXIT(A4),d0		* exit trap function?
X	beq.s	 exit3
X	move.l	d0,a0
X	jsr	(a0)
Xexit3	move.l	__Children(a4),d0	* if we have any children
X	beq.s	exit4			*	orphan them
X	move.l	d0,a0
X	move.l	(a0),a0
X	jsr	(a0)
Xexit4	jsr	_MemCleanup(PC)		* cleanup leftover memory alloc.
X	move.l	AbsExecBase.W,a6
X	move.l	_DOSBase(A4),a1
X	callsys CloseLibrary		* close Dos library
X
X	jsr	___fpterm(PC)		* clean up any floating point
X
X*------ this rts sends us back to DOS:
XexitToDOS:
X	IFD	RESIDENT
X		move.l	realdatasize(a4),d0
X		move.l	a4,a1
X		sub.l	#RESBASE,a1
X		move.l	AbsExecBase.W,a6
X		move.l	(A7)+,d6
X		movea.l	__StackPtr(a4),a5
X		callsys	FreeMem
X		move.l	d6,d0
X		movea.l	a5,sp
X	ELSE
X		move.l	(A7)+,D0
X		movea.l	__StackPtr(a4),SP	* restore stack ptr
X	ENDC
X	
X	movem.l (a7)+,d1-d6/a0-a6
X	rts
X
X
XDOSName	 dc.b	'dos.library',0
X
X	section __MERGED,BSS
X*
X	xref	_DOSBase
X
X	xdef	_NULL,_SysBase,_WBenchMsg
X	xdef	_curdir,__mbase,__mnext,__msize,__tsize
X	xdef	__oserr,__OSERR,__FPERR,__SIGFPE,__ONERR,__ONEXIT,__ONBREAK
X	xdef	__SIGINT
X	xdef	__ProgramName,__StackPtr,__base
X	xdef	__Children
X
X*
X	ifd	RESIDENT
Xrealdatasize	ds.l	1	* size of memory allocated for data +
X				* possible stack
X	endc
X	
X_NULL		ds.l	1	*
X__base		ds.l	1	* base of stack
X__mbase		ds.l	1	* base of memory pool
X__mnext		ds.l	1	* next available memory location
X__msize		ds.l	1	* size of memory pool
X__tsize		ds.l	1	* total size?
X__oserr		equ	*
X__OSERR		ds.l	1
X__FPERR		ds.l	1
X__SIGFPE	ds.l	1
X__SIGINT	ds.l	1
X__ONERR		ds.l	1
X__ONEXIT	ds.l	1
X__ONBREAK	ds.l	1
X_curdir	 	ds.l	1
X_SysBase	ds.l	1
X_WBenchMsg	ds.l	1
X__StackPtr	ds.l	1
Xstdin		ds.l	1
X__ProgramName	ds.l	1
X__Children	ds.l	1
X		END
SHAR_EOF
echo "extracting rsbx.lib/emptymorgue.c"
sed 's/^X//' << \SHAR_EOF > rsbx.lib/emptymorgue.c
X/****** rsbx.lib/EmptyMorgue() ***********************************************
X*
X*   NAME
X*	EmptyMorgue -- Process child termination messages.
X*
X*   SYNOPSIS
X*	EmptyMorgue()
X*
X*	void EmptyMorgue( void );
X*
X*   FUNCTION
X*	This function processes any termination messages from child processes
X*	    of this process.
X*
X*   INPUTS
X*
X*   RESULT
X*
X*   NOTES
X*
X*   SEE ALSO
X*	ChildStatus(), CreateFamily(), LaunchChildl(), LaunchChildv(),
X*	OrphanChild(), OrphanChildren(), WaitChild().
X*
X*   BUGS
X*	None Known.
X*
X******************************************************************************
X*
X*/
X
X#include <rsbx/childtasking.h>
X
Xvoid EmptyMorgue( void )
X	{
X	struct DeathNotice *msg;
X	struct ChildNode *node;
X
X	while (msg = (struct DeathNotice *)GetMsg(_Children->Morgue))
X		{
X		for (node = (struct ChildNode *)_Children->ChildList.mlh_Head;
X			node->node.mln_Succ;
X			node = (struct ChildNode *)node->node.mln_Succ)
X			{
X			if (&node->notice == msg)
X				{
X				msg->noticeptr = NULL;
X				break;
X				}
X			}
X
X		if (!node->node.mln_Succ)
X			{
X			ReplyMsg((struct Message *)msg);
X			}
X		}
X	}
SHAR_EOF
echo "extracting rsbx.lib/waitchild.c"
sed 's/^X//' << \SHAR_EOF > rsbx.lib/waitchild.c
X/****** rsbx.lib/WaitChild() *************************************************
X*
X*   NAME
X*	WaitChild -- Wait for child process to terminate.
X*
X*   SYNOPSIS
X*	term = WaitChild(child, status)
X*
X*	struct ChildNode *WaitChild(struct ChildNode *, long * );
X*
X*   FUNCTION
X*	This function waits for a child process to terminate, and places the
X*	    child's return val in the long pointed to by status. If the child
X*	    identifier provided doen't belong to a child of this process, then
X*	    0 is returned. If the child identifier is zero, returns the child
X*	    identifier of a child that has terminated and sets the long status
X*	    points to to its return val. If the child identifier is zero and
X*	    no child has yet terminated, wait for any child to terminate and
X*	    return its identifier and set the long status points to to its
X*	    return val. If the child identifier is zero and there are no child
X*	    processes of this process, return zero.
X*
X*   INPUTS
X*	child         - Child identifier as returned by LaunchChildl() or by
X*	                LaunchChildv().
X*	status        - Pointer to a long to store the return val of the child
X*	                in.
X*
X*   RESULT
X*	term          - Child identifier of the child process whos return val
X*	                was stored in the long pointed to by status, or zero
X*	                if there was an error.
X*
X*   NOTES
X*
X*   SEE ALSO
X*	ChildStatus(), CreateFamily(), EmptyMorgue(), LaunchChildl(),
X*	LaunchChildv(), OrphanChild(), OrphanChildren().
X*
X*   BUGS
X*	None Known.
X*
X******************************************************************************
X*
X*/
X
X#include <proto/exec.h>
X#include <rsbx/ChildTasking.h>
X
X
Xstruct ChildNode *WaitChild(struct ChildNode *child, long *status)
X	{
X	struct ChildNode *node;
X
X	while (1)
X		{
X		EmptyMorgue();
X
X		if (child)
X			{
X			for (node = (struct ChildNode *)_Children->ChildList.mlh_Head;
X				node->node.mln_Succ;
X				node = (struct ChildNode *)node->node.mln_Succ)
X				{
X				if (node == child)
X					{
X					if (!child->notice.noticeptr)
X						{
X						*status = child->notice.ret;
X						return child;
X						}
X					break;
X					}
X				}
X			if (!node->node.mln_Succ)
X				{
X				return 0;
X				}
X			}
X		else
X			{
X			for (node = (struct ChildNode *)_Children->ChildList.mlh_Head;
X				node->node.mln_Succ;
X				node = (struct ChildNode *)node->node.mln_Succ)
X				{
X				if (!node->notice.noticeptr)
X					{
X					*status = node->notice.ret;
X					return node;
X					}
X				}
X
X			}
X
X		WaitPort(_Children->Morgue);
X		}
X	}
SHAR_EOF
echo "extracting rsbx.lib/childstatus.c"
sed 's/^X//' << \SHAR_EOF > rsbx.lib/childstatus.c
X/****** rsbx.lib/ChildStatus() ***********************************************
X*
X*   NAME
X*	ChildStatus -- Check completion status of child process.
X*
X*   SYNOPSIS
X*	completion = ChildStatus(child, status)
X*
X*	struct ChildNode *ChildStatus(struct ChildNode *, long *);
X*
X*   FUNCTION
X*	Checks if a child process has completed and sets status to the return
X*	    code from the child process if it has.
X*
X*   INPUTS
X*	child         - Child process identifier returned from LaunchChildX();
X*	status        - Pointer to a long to place the return code from the
X*	                child process in.
X*
X*   RESULT
X*	completion    - Child process identifier if child is a child process
X*	                of this process and has completed. If child is a child
X*	                process of this process and has not completed, then
X*			completion is 0 and status is set to 0. If child is
X*	                not a child procewss of this process, then completion
X*	                is 0 and status will be non-zero.
X*
X*   NOTES
X*
X*   SEE ALSO
X*	CreateFamily(), EmptyMorgue(), LaunchChildl(), LaunchChildv(),
X*	OrphanChild(), OrphanChildren(), WaitChild().
X*
X*   BUGS
X*	None known.
X*
X******************************************************************************
X*
X*/
X
X#include <rsbx/childtasking.h>
X
Xstruct ChildNode *ChildStatus(struct ChildNode *child, long *status)
X	{
X	struct ChildNode *node;
X
X	EmptyMorgue();
X
X	for (node = (struct ChildNode *)_Children->ChildList.mlh_Head;
X		node->node.mln_Succ;
X		node = (struct ChildNode *)node->node.mln_Succ)
X		{
X		if (node == child)
X			{
X			if (!child->notice.noticeptr)
X				{
X				*status = child->notice.ret;
X				return child;
X				}
X			else
X				{
X				*status = 0;
X				return 0;
X				}
X			}
X		}
X
X	*status = -1;
X	return 0;
X	}
SHAR_EOF
echo "extracting rsbx.lib/orphanchildren.c"
sed 's/^X//' << \SHAR_EOF > rsbx.lib/orphanchildren.c
X/****** rsbx.lib/OrphanChildren() ********************************************
X*
X*   NAME
X*	OrphanChildren -- Orphan all child processes of this process.
X*
X*   SYNOPSIS
X*	OrphanChildren()
X*
X*	void OrphanChildren( void );
X*
X*   FUNCTION
X*	This function orphans all child processes of this process and frees
X*	    the memory used to keep track of the children.
X*
X*   INPUTS
X*
X*   RESULT
X*
X*   NOTES
X*
X*   SEE ALSO
X*	ChildStatus(), CreateFamily(), EmptyMorgue(), LaunchChildl(),
X*	LaunchChildv(), OrphanChild(), WaitChild().
X*
X*   BUGS
X*	None Known.
X*
X******************************************************************************
X*
X*/
X
X#include <rsbx/childtasking.h>
X
Xvoid OrphanChildren( void )
X	{
X	struct ChildNode *node;
X
X	Forbid();
X	EmptyMorgue();
X	DeletePort(_Children->Morgue);
X
X	while ((node = (struct ChildNode *)_Children->ChildList.mlh_Head) &&
X		node->node.mln_Succ)
X		{
X		if (node->notice.noticeptr)
X			{
X			*node->notice.noticeptr = NULL;
X			}
X		Remove((struct Node *)node);
X		FreeMem(node, sizeof(struct ChildNode));
X		}
X
X	FreeMem(_Children, sizeof(*_Children));
X	_Children = NULL;
X	
X	Permit();
X	}
SHAR_EOF
echo "extracting rsbx.lib/escaping.c"
sed 's/^X//' << \SHAR_EOF > rsbx.lib/escaping.c
X/****** rsbx.lib/EscapeAdditions() *******************************************
X*
X*   NAME
X*	EscapeAdditions -- Return number of characters to escape an argument.
X*
X*   SYNOPSIS
X*	escapes = EscapeAdditions(argv)
X*
X*	int EscapeAdditions(char *);
X*
X*   FUNCTION
X*	Determines the number of extra characters that are needed to escape
X*	    a command argument for AmigaDos command parsing.
X*
X*   INPUTS
X*	argv          - Argument to check.
X*
X*   RESULT
X*	escapes       - The number of characters that need to be added to the
X*	                argument to escape the characters special to AmigaDos.
X*
X*   NOTES
X*	Characters special to AmigaDos are " [0x22], * [0x2a], ESC [0x1b],
X*	    LF [0x0a], SP [0x20].
X*
X*   SEE ALSO
X*	EscapeAdditions(), EscapeString().
X*
X*   BUGS
X*	Thinks spaces need an AmigaDos escape character preceeding them.
X*
X******************************************************************************
X*
X*/
X
X#include <stdio.h>
X#include <string.h>
X
X
X#define QUOTE '\"'
X#define ESCAPE '*'
X#define ESC '\033'
X#define NL '\n'
X#define SPACE ' '
X
X#define SPECIAL "\"*\033\n "
X
X
Xint EscapeAdditions(char *argv);
Xchar *EscapeString(char *buff, char *argv);
X
X
Xint EscapeAdditions(char *argv)
X	{
X	int count = 0;
X	char *pos = argv;
X
X	while (pos = strpbrk(pos, SPECIAL))
X		{
X		count++;
X		pos++;
X		}
X
X	if (count)
X		{
X		count += 2;
X		}
X
X	return count;
X	}
X
X
X/****** rsbx.lib/EscapeString() **********************************************
X*
X*   NAME
X*	EscapeString -- Copy argument to buffer escaping as needed.
X*
X*   SYNOPSIS
X*	dest = EscapeString(buffer, argv)
X*
X*	char *EscapeAdditions(char *, char *);
X*
X*   FUNCTION
X*	Copies a string containing a single argument to a buffer, escaping
X*	    characters special to AmigaDos.
X*
X*   INPUTS
X*	buffer        - Buffer for escaped argument string.
X*	argv          - Argument string to escape.
X*
X*   RESULT
X*	dest          - The same as buffer.
X*
X*   NOTES
X*	Characters special to AmigaDos are " [0x22], * [0x2a], ESC [0x1b],
X*	    LF [0x0a], SP [0x20].
X*
X*   SEE ALSO
X*	EscapeAdditions(), EscapeString().
X*
X*   BUGS
X*	Thinks spaces need an AmigaDos escape character preceeding them.
X*
X******************************************************************************
X*
X*/
X
Xchar *EscapeString(char *buff, char *argv)
X	{
X	char *pos;
X
X	pos = buff;
X	*pos++ = '\"';
X	while (*argv)
X		{
X		switch (*argv)
X			{
X			case ESC:
X				*pos++ = ESCAPE;
X				*pos++ = 'E';
X				break;
X			case NL:
X				*pos++ = ESCAPE;
X				*pos++ = 'N';
X				break;
X			case QUOTE:
X			case SPACE:
X			case ESCAPE:
X				*pos++ = ESCAPE;
X			default:
X				*pos++ = *argv;
X			}
X		argv++;
X		}
X	*pos++ = '\"';
X	*pos = '\0';
X
X	return buff;
X	}
SHAR_EOF
echo "extracting rsbx.lib/makefile"
sed 's/^X//' << \SHAR_EOF > rsbx.lib/makefile
X#$Header$
X#
X# Compiler level:
X#	Lattice 5.04.01
X#
X# Compiler and linker options:
X#	This Makefile is distributed with the -d3 option turned on and the optimizer
X#	option turned off because it yields working executables. Other combinations
X#	may also yield working executables, but removing "-d3" and turing on the
X#	optimizer didn't.
X#
X#
X.SILENT:
X#
X#
XCC1 = LC:lc1
XCC2 = LC:go
XCC3 = LC:lc2
XC1FLAGS	= -d3
XC2FLAGS	=
XC3FLAGS	=
X#
XASM = LC:asm
XASMFLAGS = -iinclude:
X#
X#
X#.c.o:
X#	$(CC1) -. $(C1FLAGS) $(CFLAGS) -oQUAD: $*
X#	$(CC2) -. $(C2FLAGS) QUAD:$*.q
X#	$(CC3) -. $(C3FLAGS) -o$*.o QUAD:$*.q
X#
X.c.o:
X	$(CC1) -. $(C1FLAGS) $(CFLAGS) -oQUAD: $*
X	$(CC3) -. $(C3FLAGS) -o$*.o QUAD:$*.q
X	rename $*.o $*.z
X	-lc:blink prelink nodebug from $*.z to $*.o
X	delete $*.z
X#
X#
X.asm.o:
X	$(ASM) -. $(ASMFLAGS) $*.asm
X#
X#
X
XCDEFINES =
XCFLAGS	 = $(CDEFINES)
X
X
XTARGETS = rsbx.lib xc.o
X
X
Xall:	$(TARGETS)
X
X
Xinstall:
X	copy rsbx.lib LIB:
X	copy xc.o LIB:
X
X
Xclean:
X	-delete \#?.o
X	-delete $(TARGETS)
X
X
XRSBXOBJ = childstatus.o createfamily.o emptymorgue.o escaping.o launchc.o orphanchild.o orphanchildren.o popen.o ulseg.o uxmain.o waitchild.o
Xrsbx.lib:	$(RSBXOBJ)
X	oml $@ r $?
X
X
X#SOURCE = childstatus.c createfamily.c emptymorgue.c escaping.c launchc.c orphanchild.c orphanchildren.c popen.c ulseg.asm uxmain.c waitchild.c xc.asm
X#
X#HFILES = INCLUDE:rsbx/childtasking.h
X#
X#depend:	${SOURCE} ${HFILES}
X#	(sed '/^# DO NOT DELETE THIS LINE/q' Makefile && \
X#	 cc -Em ${CFLAGS} ${SOURCE} | sed 's/\.\///; /\//d' \
X#	) >Makefile.new
X#	cp Makefile Makefile.bak
X#	cp Makefile.new Makefile
X#	rm -f Makefile.new
X
X
X# DO NOT DELETE THIS LINE - 
Xchildstatus.c: INCLUDE:rsbx/childtasking.h
Xchildstatus.o: childstatus.c
Xcreatefamily.c: INCLUDE:rsbx/childtasking.h
Xcreatefamily.o: createfamily.c
Xemptymorgue.c: INCLUDE:rsbx/childtasking.h
Xemptymorgue.o: emptymorgue.c
Xescaping.o: escaping.c
Xlaunchc.c: INCLUDE:rsbx/childtasking.h
Xlaunchc.o: launchc.c
Xorphanchild.c: INCLUDE:rsbx/childtasking.h
Xorphanchild.o: orphanchild.c
Xorphanchildren.c: INCLUDE:rsbx/childtasking.h
Xorphanchildren.o: orphanchildren.c
Xpopen.c: INCLUDE:rsbx/childtasking.h
Xpopen.o: popen.c
Xulseg.o: ulseg.asm
Xuxmain.o: uxmain.c
Xwaitchild.c: INCLUDE:rsbx/childtasking.h
Xwaitchild.o: waitchild.c
Xxc.o: xc.asm
SHAR_EOF
echo "extracting rsbx.lib/orphanchild.c"
sed 's/^X//' << \SHAR_EOF > rsbx.lib/orphanchild.c
X/****** rsbx.lib/OrphanChild() ***********************************************
X*
X*   NAME
X*	OrphanChild -- Dis-associate a child process from this process.
X*
X*   SYNOPSIS
X*	success = OrphanChild(child)
X*
X*	int OrphanChild(struct ChildNode * );
X*
X*   FUNCTION
X*	This function will dis-associate a child process from this process and
X*	    free the structures used to track the child process.
X*
X*   INPUTS
X*	child         - Child identifier returned by LaunchChildl() or by
X*	                LaunchChildv().
X*
X*   RESULT
X*	success       - Zero if invalid child identifier.
X*
X*   NOTES
X*
X*   SEE ALSO
X*	ChildStatus(), CreateFamily(), EmptyMorgue(), LaunchChildl(),
X*	LaunchChildv(), OrphanChildren(), WaitChild().
X*
X*   BUGS
X*	None Known.
X*
X******************************************************************************
X*
X*/
X
X#include <rsbx/childtasking.h>
X
X/*
X * name		OrphanChild --
X *
X * synopsis	error = OrphanChild(child);
X *
X *		int error;                 error if 0
X *		struct ChildNode *child;   child identifier
X *
X * description	This function removes all records of a child process.
X *		Returns 0 if child unknown.
X */
X
Xint OrphanChild(struct ChildNode *child)
X	{
X	struct ChildNode *node;
X
X	Forbid();
X	EmptyMorgue();
X
X	for (node = (struct ChildNode *)_Children->ChildList.mlh_Head;
X		node->node.mln_Succ;
X		node = (struct ChildNode *)node->node.mln_Succ)
X		{
X		if (node == child)
X			{
X			if (child->notice.noticeptr)
X				{
X				*child->notice.noticeptr = 0;
X				}
X			Remove((struct Node*)child);
X			FreeMem(child, sizeof(*child));
X			return -1;
X			}
X		}
X
X	return 0;
X	}
SHAR_EOF
echo "extracting rsbx.lib/readme"
sed 's/^X//' << \SHAR_EOF > rsbx.lib/readme
XThis is the source directory for a scanned library neede to recreate the RCS
Xexecutables. Documentation, in AutoDoc format, for the library is in file
Xrsbx.lib.doc.
X
XTo make the library, place childtasking.h in directory INCLUDE:rsbx/ and type
X"lmk -f Makefile".
X
XTwo source files needed to build the library from scratch, launchc.c and
Xulseg.asm, are not included in the distribution because the original sources
Xthey were based on belong to Lattice. However, the object modules needed to to
Xmake the library are included.
X
X
X						Ray
SHAR_EOF
echo "extracting rsbx.lib/createfamily.c"
sed 's/^X//' << \SHAR_EOF > rsbx.lib/createfamily.c
X/****** rsbx.lib/CreateFamily() **********************************************
X*
X*   NAME
X*	CreateFamily -- 
X*
X*   SYNOPSIS
X*	success = CreateFamily()
X*
X*	int CreateFamily( void );
X*
X*   FUNCTION
X*	This function initializes the structures used to keep track of child
X*	    processes of this process.
X*
X*   INPUTS
X*
X*   RESULT
X*	success       - Zero if unable to allocate and initialize needed
X*	                structures.
X*
X*   NOTES
X*
X*   SEE ALSO
X*	ChildStatus(), EmptyMorgue(), LaunchChildl(), LaunchChildv(),
X*	OrphanChild(), OrphanChildren(), WaitChild().
X*
X*   BUGS
X*	None Known.
X*
X******************************************************************************
X*
X*/
X
X#include <proto/exec.h>
X#include <rsbx/childtasking.h>
X
Xint CreateFamily( void )
X	{
X	if (!_Children)
X		{
X		if (!(_Children = AllocMem(sizeof(*_Children), 0)))
X			{
X			return NULL;
X			}
X		NewList((struct List *)&_Children->ChildList);
X		_Children->Orphan = OrphanChildren;
X		if (!(_Children->Morgue = CreatePort(0, 0)))
X			{
X			FreeMem(_Children, sizeof(*_Children));
X			return NULL;
X			}
X		}
X
X
X	return -1;
X	}
SHAR_EOF
echo "extracting rsbx.lib/popen.c"
sed 's/^X//' << \SHAR_EOF > rsbx.lib/popen.c
X#include <stdio.h>
X#include <string.h>
X#include <ctype.h>
X#include <dos.h>
X#include <ios1.h>
X#include <fcntl.h>
X#include <libraries/dosextens.h>
X#include <exec/lists.h>
X#include <exec/nodes.h>
X#include <rsbx/ChildTasking.h>
X
X
Xstruct pstruct {
X	struct MinNode node;
X	FILE	*fptr1;
X	struct ChildNode *child;
X	};
X
Xstatic struct MinList PList = { 0 };
X
X
XFILE *popenl(char *args, ...);
XFILE *popenv(char **args, char *mode);
Xint pclose(FILE *fptr);
Xstatic char *mktemp(char *template);
X
X
X
X/****** rsbx.lib/popenl() ****************************************************
X*
X*   NAME
X*	popenl -- Initiate I/O to or from a command.
X*
X*   SYNOPSIS
X*	pipe = popenl(arg0, ..., argn, NULL, mode)
X*
X*	FILE *popenl(char *, char *, ...);
X*
X*   FUNCTION
X*	Creates a stream between the calling process and the stdin or stdout
X*	    streams of the command it executes. Mode should be "r" to read
X*	    the stdout stream of the command, or "w" to write to the stdin
X*	    stream of the command. 
X*
X*   INPUTS
X*	arg0          - Name of file to execute.
X*       ...           - Other command line arguments needed by the file to be
X*	                executed.
X*	NULL          - Zero.
X*	mode          _ I/O mode string.
X*
X*   RESULT
X*	pipe          - File pointer to use to read or write to the command
X*	                with.
X*
X*   NOTES
X*	A stream opened by popenl() should be closed by pclose().
X*
X*   SEE ALSO
X*	popenv(), pclose().
X*
X*   BUGS
X*	This function does not create a complete CLI enviroment for the child
X*	    process. Use of this function with a command that expects a BCPL
X*	    environment will crash the system. The Unix function 'popen' takes
X*	    as arguments a command string which it passes to the shell, and a
X*	    mode string.
X*
X******************************************************************************
X*
X*/
X
XFILE *popenl(char *args, ...)
X	{
X	char **nullarg;
X
X	for(nullarg = (char **)(&args); *nullarg != 0; nullarg++);
X
X	return(popenv(&args, *(nullarg+1)));
X	}
X
X
X/****** rsbx.lib/popenv() ****************************************************
X*
X*   NAME
X*	popenv -- Initiate I/O to or from a command.
X*
X*   SYNOPSIS
X*	pipe = popenv(argv, mode)
X*
X*	FILE *popenv(char **, char *);
X*
X*   FUNCTION
X*	Creates a stream between the calling process and the stdin or stdout
X*	    streams of the command it executes. Mode should be "r" to read
X*	    the stdout stream of the command, or "w" to write to the stdin
X*	    stream of the command. 
X*
X*   INPUTS
X*	argv          - An array of pointer to the argument strings for the
X*	                command. The last pointer must be followed by a 0
X*	                pointer. The first pointer, argv[0], is the name of
X*	                file to execute.
X*	mode          _ I/O mode string.
X*
X*   RESULT
X*	pipe          - File pointer to use to read or write to the command
X*	                with.
X*
X*   NOTES
X*	A stream opened by popenv() should be closed by pclose().
X*
X*   SEE ALSO
X*	popenl(), pclose().
X*
X*   BUGS
X*	This function does not create a complete CLI enviroment for the child
X*	    process. Use of this function with a command that expects a BCPL
X*	    environment will crash the system. The Unix function 'popen' takes
X*	    as arguments a command string which it passes to the shell, and a
X*	    mode string.
X*
X******************************************************************************
X*
X*/
X
XFILE *popenv(char **args, char *mode)
X	{
X	struct LAUNCHENV env = { 0,0,0,0,0,0,0 };
X	static char tempname[] = "pipe:popen.XXXX.XXXXXXXX";
X	char *pname;
X	char redir[64];
X	struct pstruct *poptr;
X	char *mode1;
X	int mode2;
X	int f2;
X
X	if (!PList.mlh_Head)
X		{
X		NewList(&PList);
X		}
X
X	if ((strcmp(mode,"r") != 0) && (strcmp(mode,"w") != 0))
X		{
X		fprintf(stderr,"popen: bad mode!\n");
X		return(NULL);
X		}
X
X	if (*mode == 'r')
X		{
X		mode1 = "r";
X		mode2 = MODE_NEWFILE;
X		}
X	else
X		{
X		mode1 = "w";
X		mode2 = MODE_OLDFILE;
X		}
X
X	strcpy(redir,tempname);
X
X	if (!(poptr = (struct pstruct *)malloc(sizeof(struct pstruct))))
X		{
X		fprintf(stderr,"popen: Out of memory!\n");
X		return(NULL);
X		}
X
X	if (!(pname = mktemp(redir)))
X		{
X		fprintf(stderr,"popen: Unable to find an available pipe.\n");
X		free(poptr);
X		return(NULL);
X		}
X
X	if (!(poptr->fptr1 = fopen(pname, mode1)))
X		{
X		fprintf(stderr,"popen: Unable to open pipe end 1 file %s mode %s\n", pname, mode);
X		free(poptr);
X		return(NULL);
X		}
X
X	if (!(f2 = Open(pname, mode2)))
X		{
X		fprintf(stderr,"popen: Unable to open pipe end 2 file %s mode %s\n", pname, mode);
X		fclose(poptr->fptr1);
X		free(poptr);
X		return(NULL);
X		}
X
X	env.priority = ((struct Task *)FindTask(NULL))->tc_Node.ln_Pri;
X	if (*mode == 'r')
X		{
X		env.std_out = f2;
X		}
X	else
X		{
X		env.std_in = f2;
X		}
X	env.le_fh1 = f2;
X
X	if (!(poptr->child = LaunchChildv(&env, *args, args)))
X		{
X		fprintf(stderr,"popen: Fork failed\n");
X		Close(f2);
X		fclose(poptr->fptr1);
X		free(poptr);
X		return(NULL);
X		}
X
X	AddTail(&PList, poptr);
X
X	return(poptr->fptr1);
X	}
X
X
X/****** rsbx.lib/pclose() ****************************************************
X*
X*   NAME
X*	pclose -- Closes pipe opened by popenl() or by popenv().
X*
X*   SYNOPSIS
X*	status = pclose(pipe)
X*
X*	int pclose(FILE *);
X*
X*   FUNCTION
X*	Waits for the command associated with the pipe to exit, closes the
X*	    stream, and returns the return code from the command.
X*
X*   INPUTS
X*	pipe          - Stream pointer returned by a call to popenl() or to
X*	                popenv().
X*
X*   RESULT
X*	status        - The return code from the command executed, or -1 if
X*	                pipe wasn't opened by popenl() or by popenv().
X*
X*   NOTES
X*
X*   SEE ALSO
X*	popenl(), popenv().
X*
X*   BUGS
X*	None known.
X*
X******************************************************************************
X*
X*/
X
Xint pclose(FILE *fptr)
X	{
X	long status;
X	struct pstruct *poptr;
X
X	for (poptr = (struct pstruct *)PList.mlh_Head;
X		poptr->node.mln_Succ;
X		poptr = (struct pstruct *)poptr->node.mln_Succ)
X		{
X		if (poptr->fptr1 == fptr)
X			{
X			Remove(poptr);
X			fclose(poptr->fptr1);
X			if (!WaitChild(poptr->child, &status))
X				{
X				status = -1;
X				}
X			free(poptr);
X			return(status);
X			}
X		}
X
X	return -1;
X	}
X
Xstatic unsigned short Generation = 0;
X
Xstatic char *hex = "0123456789abcdef";
X
Xstatic char *mktemp(char *template)
X	{
X	char *cp;
X	unsigned long val;
X
X	cp = template;
X	cp += strlen(template);
X
X	val = (unsigned long) FindTask(0L);
X	while (*--cp == 'X')
X		{
X		*cp = hex[val%16];
X		val /= 16;
X		}
X
X	val = Generation++;
X	while (*--cp == 'X')
X		{
X		*cp = hex[val%16];
X		val /= 16;
X		}
X
X	return template;
X	}
SHAR_EOF
echo "extracting rsbx.lib/rsbx.lib.uu"
sed 's/^X//' << \SHAR_EOF > rsbx.lib/rsbx.lib.uu
X
Xbegin 640 rsbx.lib
XM```#^@``""8```/I````+$Y5__R_[```90```$CG`#(F;0`()&T`#$ZZ```@R
XM"V<^(&P``"MH``3__"!M__Q*D&<@(&W__+'+9@Y*JP`<9A(DJP`@(`M@7B!M=
XM__PK4/_\8-@@;?_\2I!F.'``8$@@;```*V@`!/_\(&W__$J09R(@;?_\2J@`$
XM'&8.(&W__"2H`"`@+?_\8!X@;?_\*U#__&#6(&P``"!H`!`L>``$3J[^@&``D
XM_W1,WTP`3EU.=0`````#[X8```-?7T-H:6QD<F5N```````#````E````&``Q
XM```B@P```U]%;7!T>4UO<F=U90````$````:@P```E]?>&-O=F8``````0``*
XM``J&```"7U]B87-E```````!````!@````````/R```#Z0```+1.5?_XO^P`,
XM`&4```!(YR,2)FT`""XM``PL;```3J[_RBE```0L;```3J[_Q"E```Q![```.
XM(@@D/````^TL;```3J[_XBE``!0`K```@!$```"L``"`$@`(`*P``(`#`!!P>
XM`"E``!QP`2E``#YP`BE``&!*K```9P1P`&`&(#P``(``+``@!@!```$I0``8_
XM(`8`0``"*4``.B`&`$``@"E``%Q!^@``*4@``"!L```0*/__2(!(P-"'5(`O.
XM`$ZZ``!83RM`__Q*@&8*2'@``4ZZ``!83R`L`!CE@%*L`!A![``<(:W__`@`X
XM(&P``!`H__](@$C`+P`O""\M__Q.N@``3^\`#"!L```0*/__2(`@;?_\T,`KN
XM2/_\(&W__$(8*TC__`RL```!```8;``!0A`3<B"P`6<,<@FP`6<&<@JP`68*B
XM2H=G!E*+4X=@XDJ'9P`!'B`L`!CE@%*L`!A![``<(:W__`@`<"*P$V8``,!24
XMBU.'2H=G;!`3<B*P`6=D<"JP$V904HM3AV8,+RP`'&$``/I83V#<$!-(@`1`<
XM`$5G"`1```EG$&`<(&W__!#\`!<K2/_\8!@@;?_\$/P`"BM(__Q@"B!M__P03
XMTRM(__Q3AU*+8)X@;?_\$-LK2/_\4X=@D$J'9@HO+``<80``GEA/4HM3AR!M#
XM__Q"&"M(__Q*AV<`_R`0$W(@L`%G`/\6<@FP`6<`_PYR"K`!9P#_!B\L`!QA-
XM``!F6$]@`/[X2H=G(A`3<B"P`6<:<@FP`6<4<@JP`6<.(&W__!#;*TC__%.'H
XM8-I*AV8*<``@;?_\$(!@#B!M__Q"&"M(__Q@`/ZV2&P`'"\L`!A.N@``0I=.'
XMN@``3.U(Q/_D3EU.=4Y5``"_[```90```"\+)FT`"$AL`$1(;``"3KH``$AL"
XM`$0O"TZZ``!(;`!$2'@`"DZZ``!(>`!D3KH``"9M__Q.74YU``````/X````S
XM#@````$```)T```"<````B````'H```!C````5X```%:```!5````2@```#@G
XM````W````-8```*B````,@````````/O@P```E]F<'5T8P```````0```KR#"
XM```"7V9P=71S```````"```"L````J:#```"7V5X:70````````"```"Q```5
XM`GZ#```"7VUA:6X````````!```">(,```)?<W1R;F-P>0````$```#^@P``]
XM`E]?97AI=````````0```-"#```"7VUA;&QO8P`````!````OH8```1?7U!RP
XM;V=R86U.86UE`````````P```08```#J````K(8```-?7T].0E)%04L``````
XM```!````J(,```)?0UA"4DL```````$```"DA@```E]?9FUO9&4``````0``^
XM`'2&```"7U]I;V(````````)```"M````JH```*>````H````)8```",````!
XM<````&H```!DA@```E]?=69B<P``````!@```%X```!6````3@```$8````NP
XM````(H8```)?1$]30F%S90````,````^````)@```!J#```"7U]X8V]V9@``4
XM```"```"E`````J&```"7U]B87-E```````"```"D`````8````````#\@``2
XM`^H```$'*@!);G9A;&ED(&%R9W5M96YT('1O(```````````````````````,
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM`````````````````````````````````````````````````````````````
XM``````````````````````````````````/R```#Z@```%````%``````&`4G
XM``````````````````````````!(YW_^+'@`!)/)3J[^VBA`0>P`7$ZN_H!!P
XM[`!<3J[^C")`1?K_R"5I`"@`#"5I`"P`$"5I`"``!"5I`!P``"5I`"0`"$'J#
XM``@D4"5(`!0@:0`4("D`&$CG@(!.KOZ&(FP`@%:)T\G3R2*Z_WQ#^O]T("D`?
XM!.6(6(`B0$S?`0$B+``Z)`\$@@```!24@2\L`+!(YP`*+P(I3P"P3I%8CTS?0
XM4``I7P"P+P!%^O]"(CK_."\.+&H``$ZN_V0L7R(L`)@O#BQJ``!.KO^F+%\B.
XM*@`,9PPO#BQJ``!.KO_<+%\B*@`09PPO#BQJ``!.KO_<+%\B:@``3J[^8DZN&
XM_WP@*@`(9QHB0"-?`!A"J0`40JD`#B!J``0B:@`(3J[^DDS??_Y.=0```_(`0
XM``/I````($Y5__R_[```90```$ZZ``!.N@``(&P``"\H`!!.N@``6$\B;```Z
XM(&D`!"M(__P@"&<V(&W__$J09RX@;?_\2J@`'&<*(FW__"!I`!Q"D"\M__Q.D
XMN@``2'@`)"\M__Q.N@``3^\`#&"Z2'@`%"\L``!.N@``0JP``$ZZ``!.74YU\
XM```#[X,```)?4&5R;6ET``````$```!Z@P```E]&<F5E365M`````@```'(`[
XM``!@@P```E]296UO=F4``````0```%2#```#7T1E;&5T95!O<G0``````0``E
XM`!Z&```#7U]#:&EL9')E;@``````!````'8```!N````)````!:#```#7T5M'
XM<'1Y36]R9W5E`````0```!*#```"7T9O<F)I9``````!````#H,```)?7WAC&
XM;W9F``````$````*A@```E]?8F%S90```````0````8````````#\@```^D`?
XM```:3E7__+_L``!E````+PLF;0`(3KH``$ZZ```@;```*V@`!/_\(&W__$J0M
XM9S(@;?_\L<MF($JK`!QG!B!K`!Q"D"\+3KH``$AX`"0O"TZZ``!P_V`,(&W_I
XM_"M0__Q@QG``)FW_^$Y=3G4```/O@P```E]&<F5E365M`````0```$Z#```"+
XM7U)E;6]V90`````!````1(8```-?7T-H:6QD<F5N```````!````'(,```-?$
XM16UP='E-;W)G=64````!````&(,```)?1F]R8FED``````$````4@P```E]?I
XM>&-O=F8``````0````J&```"7U]B87-E```````!````!@````````/R```#1
XMZ0```5M.50``O^P``&4```!(YP`P)FT`""1M``Q(;0`0+PHO"V$```Q,[0P`Y
XM__A.74YU3E7_L+_L``!E````2.<_,B9M``@D;0`,3KH``$J`9@9P`&``!1`OQ
XM"DZZ``!83RM`_^!2@&<`!/P@"V8$1^P``)/)+'@`!$ZN_MHK0/_`2JL`!&80U
XM(&W_P"`H`#Z0J``Z)T``!`RK```@```$9`H@/```(``G0``$("L`!%:``D#_%
XM_"=```1^`7P`(`?E@"!M`!!*L`@`9SH@!^6`(&T`$"!P"`!*&&;\4X@B;0`0M
XMD?$(`"`'Y8`O,0@`+T@`*$ZZ``!83R(O`"32@%*!W(%2AV"X2H97P$0`2(!(O
XMP%*&2H!G`E*&.7P`!``V<``I0``X*48`/"E\``$``0!`<$`I0`!$0JP`2")M7
XM`!`@44H89OQ3B)'1(`A4@"E``$Q"K`!0*6P```!40>P`*"QX``1.KO\B*T#_>
XMN"`M_[@(```?9Q`B+?_@+&P``$ZN_Z9@``/D(&W_N"MH`!#__"!M_[@K:``89
XM_[0B;?^X(&D`("M(_]@@;?^X*V@`*/_L("W_V"(`Y($@;?^T(4$`$"!M_]A2I
XMK?_8+&T`$")62AEF_%.)D]8@"1"`(FT`$"!1(FW_V!+89OQ^`7P`(`?E@"!M^
XM`!!*L`@`9P``@B`'Y8`@;0`0+S`(`$ZZ``!83RH`2H5G'"!M__S1QB`'Y8`B#
XM;0`0+S$(`"\(3KH``%!/8!8@;?_\T<8@!^6`(FT`$")Q"``0V6;\(`?E@"!M"
XM`!`@<`@`2AAF_%.((FT`$)'Q"``@"-"%W(`@1E*&(FW__"`($[P`(`@`4H=@I
XM`/]R2H9G`E.&($92AB)M__P@"!.\``H(`"!M__Q",&@`(BW_X"QL``!.KO^"Y
XM*T#_X"(`3J[_H"M`_]PB"BQL``!.KO]J*T#_Y"(M_^`L;```3J[_@B(`3J[_D
XMIDJM_^1G``)V("P``$'L```B;?_L8`(2V%.`9/H@;?_L*TC_Z%BM_^@@;?_H!
XM(*W_Y"`M_^CD@"M`_^A(>``P3KH``%A/*T#_S$J`9P`")"!M_\PQ?``<`!)"[
XMIT*G3KH``%!/(&W_S"%```YG``'Z(&W_S"%M__P`%"!M_\PA1@`80^P`''``G
XM+'@`!$ZN_=@@;?_,(4``'&<``<!P)'(`+'@`!$ZN_SHK0/_42H!G``&:(&W_O
XMU%"((FW_S"-(`"0@+?_H(@HF`"03*"L`!"QL``!.KO]V*T#_T$J`9P`!7B!M)
XM_]`K:``0_[P@;?^\2J@`2F80(&W_O-#\`$HO"$ZZ``!83R!M_[S0_`!*(FW_7
XMN"QX``1.KO\*(&W_O"%M_]P`F"!M_\`B;?^\(V@`J`"H("W_M.2`(&W_O"%`L
XM`*Q*JP`09QH@*P`0Y8`K0/_$(&W_Q")M_[PC:``(`*1@#B!M_\`B;?^\(V@``
XMI`"D2JL`"&<,(&W_O"%K``@`G&`.(&W_P")M_[PC:`"<`)Q*JP`,9PP@;?^\S
XM(6L`#`"@8`X@;?_`(FW_O"-H`*``H"!M_\PA:P`4`"@@;?_,(6L`&``L(&P`;
XM`")M_\PC:``0`"`@;```6(@B;?_4+'@`!$ZN_PH@;?_0(FW_S"QX``1.KOZ2Z
XM(&W_S"!H``XL>``$3J[^@"M`_\BPK?_,9Q@@;?_,(&@`#BQX``1.KOZ,(D!.U
XMKOZ&8,X@;?_,+R@`#DZZ```NK?_,3KH``"`M_]1@7")M_]1P)"QX``1.KO\NV
XM(FW_S")I`!PL>``$3J[^8B!M_\PO*``.3KH``%A/+RW_S$ZZ``!83R(M_^0LE
XM;```3J[_9"(M_]PL;```3J[_IB!M_[@L>``$3J[_''``3.U,_/^,3EU.=0``;
XM`_@````,`````0```58```%2```!3````4@```$R```!+@```2@```$@```!U
XM'````18```-.````;`````````/O@P```E]F<F5E`````````@``!3@```3^I
XM@P```U]$96QE=&50;W)T``````(```4N```$]H8```-?7T-H:6QD<F5N````\
XM```"```$F@``!(R#```"7TYE=TQI<W0````!```#RH,```-?0W)E871E4&]R2
XM=``````!```#*H,```)?;6%L;&]C``````$```,,@P``!%]%<V-A<&53=')IG
XM;F<````````!```"(H8```)?1$]30F%S90````<```5.```%0@```YH```+`"
XM```"L````I@```%TA@```U]?;'-E9VUE;G0```````,```+:```"U@```5"#R
XM```$7T5S8V%P94%D9&ET:6]N<P````(```("````[H,```-?9FEN9'!A=&@`Z
XM```````!````6(,```1?0W)E871E1F%M:6QY`````````0```$B#```"7U]XY
XM8V]V9@`````"````.`````J&```"7U]B87-E```````"````-`````8`````/
XM```#\@```^H````6`````````````````````````````````````&1O<RYL8
XM:6)R87)Y````````````````````````````````````````````````````)
XM`````````````````_(```/I````/TY5__B_[```90```$CG`1`F;0`(?@`K.
XM2__X2&P``"\M__A.N@``4$\K0/_X9PA2AU*M__A@Y$J'9P)4AR`'3-\(@$Y=N
XM3G5.5?_\O^P``&4```!(YP`P)FT`""1M``P@2RM(__P@;?_\$/P`(BM(__Q*/
XM$F=L$!)(@`1```IG+@1``!%G#EM`9SY50&<Z44!G-F!`(&W__!#\`"HK2/_\L
XM(&W__!#\`$4K2/_\8#`@;?_\$/P`*BM(__P@;?_\$/P`3BM(__Q@%B!M__P0A
XM_``J*TC__"!M__P0TBM(__Q2BF"0(&W__!#\`"(K2/_\(&W__$(0(`M,WPP`8
XM3EU.=0```_@````!`````0```!P````````#[X,```)?<W1R<&)R:P````$`F
XM```D@P```E]?>&-O=F8``````@```%`````*A@```E]?8F%S90```````@``,
XM`$P````&`````````_(```/J`````B(J&PH@```````#\@```^D````;3E7_E
XM^+_L``!E````(&P``"\H`!!.N@``6$\K0/_\9T8@;```*V@`!/_X(&W_^$J0U
XM9R`@;?_X4(BQ[?_\9@H@;?_\0J@`%&`*(&W_^"M0__A@V"!M__A*D&:R+RW_;
XM_$ZZ``!83V"F3EU.=0`````#[X,```-?4F5P;'E-<V<````````!````8(,`-
XM``)?1V5T37-G``````$````6A@```U]?0VAI;&1R96X```````(````B````3
XM#H,```)?7WAC;W9F``````$````*A@```E]?8F%S90```````0````8`````J
XM```#\@```^D````<3E7__+_L``!E````+PY*K```9E1P%'(`+'@`!$ZN_SHI4
XM0```2H!F!'``8#X@;```6(@O"$ZZ``!!^@``(FP``"*(0I="ITZZ``!03R!L5
XM```A0``09A(B;```<!0L>``$3J[_+G``8`)P_RQ?3EU.=0```^^#```#7T-R2
XM96%T95!O<G0``````0```$B#```$7T]R<&AA;D-H:6QD<F5N``````$````Z_
XM@P```E].97=,:7-T`````0```#:&```#7U]#:&EL9')E;@``````!@```%@`O
XM``!.````/@```"X````B````$(,```)?7WAC;W9F``````$````*A@```E]?F
XM8F%S90```````0````8````````#\@```^D````93E7__+_L``!E````2.<`Y
XM,"9M``@D;0`,3KH``"!L```K:``$__P@;?_\2I!G)B!M__RQRV842JL`'&8(Z
XM)*L`("`+8!9"DG``8!`@;?_\*U#__&#2</\D@'``3-\,`$Y=3G4``````^^&4
XM```#7U]#:&EL9')E;@```````0```!Z#```#7T5M<'1Y36]R9W5E`````0``M
XM`!J#```"7U]X8V]V9@`````!````"H8```)?7V)A<V4```````$````&````V
XM`````_(```/I````SDY5__R_[```90```$'M``@K2/_\(&W__$J09P98K?_\0
XM8/(@;?_\+R@`!$AM``AA```&3EU.=4Y5_Y"_[```90```$CG`S`F;0`()&T`7
XM#$'Y`````$/M_^1P!B+84<C__$JL``!F"DAL``!.N@``6$\@2D/L`"80&+`96
XM9@9*`&;V9R0@2D/L`"@0&+`99@9*`&;V9Q)(;``J2&P`1$ZZ``!P`&```7IPS
XM<K`29A!![``\*TC_F"X\```#[F`.0>P`/BM(_Y@N/````^U![``,0^W_H!+8G
XM9OQ(>``03KH``%A/*T#_G$J`9A)(;`!`2&P`1$ZZ``!P`&```29(;?^@80`!*
XMJ%A/*T#_X$J`9AI(;`!82&P`1$ZZ```NK?^<3KH``'``8```^B\M_Y@O+?_@E
XM3KH``%!/(&W_G"%```AF("\*+RW_X$AL`()(;`!$3KH``"ZM_YQ.N@``<`!@V
XM``#"+P<O+?_@3KH``%!/+`!*AF8L+PHO+?_@2&P`M$AL`$1.N@``(&W_G"ZH"
XM``A.N@``+JW_G$ZZ``!P`&```(1"ITZZ``!83R!`$B@`"4B!2,$K0?_D<'*P0
XM$F8&*T;_\&`$*T;_["M&__@O"R\32&W_Y$ZZ``!/[P`,(&W_G"%```QF*DAL%
XM`.9(;`!$3KH``"Z&3KH``"!M_YPNJ``(3KH``"ZM_YQ.N@``<`!@%"\M_YQ(1
XM;```3KH``"!M_YP@*``(3.T,P/^`3EU.=4Y5__B_[```90```"\+)FT`""MLT
XM``#_^"!M__A*D&=6(FW_^"!I``BQRV9`+RW_^$ZZ```@;?_X+J@`"$ZZ``!(8
XM;?_\(&W_^"\H``Q.N@``3^\`#$J`9@9P_RM`__PO+?_X3KH``"`M__Q@#"!M(
XM__@K4/_X8*)P_R9M__1.74YU3E7_^+_L``!E````2.<!$"9M``@K2__\($M*Y
XM&&;\4XB1RR`(T:W__$*G3KH``%A/+@!3K?_\<%@@;?_\L!!F%B`'<@_`@2!L4
XM`0XB;?_\$K`(`.B/8-PP+`#Z4FP`^GX`/@!3K?_\<%@@;?_\L!!F%B`'<@_`/
XM@2!L`0XB;?_\$K`(`.B/8-P@"TS?"(!.74YU```#^````!,````!```#(```A
XM`P0```,````"\````CP```(0```!X@```7@```%&```!#@```.H```#,````T
XMO@```*X```"6````A@```'0```!H````8@````````/L`````0````(```!0(
XM`````````^^#```#7U=A:71#:&EL9````````0```G:#```"7U)E;6]V90``;
XM```!```"6H,```)?061D5&%I;`````$```(4@P```E]#;&]S90```````0``&
XM`?"#```$7TQA=6YC:$-H:6QD=@````````$```'0@P```U]&:6YD5&%S:P``7
XM``````(```+4```!H(,```)?9F-L;W-E``````,```)F```!_````8R#```"3
XM7T]P96X````````!```!9H,```)?9F]P96X```````$```$P@P```E]F<F5E-
XM````````!0```HP```($```!E````58```$>@P```E]M86QL;V,``````0``!
XM`-R#```"7V9P<FEN=&8````&```!Z@```8````%.```!%@```/(```">A@``G
XM`E]?:6]B````````!@```>8```%\```!2@```1(```#N````FH,```)?3F5W8
XM3&ES=`````$```!L@P```E]?>&-O=F8`````!````K(```(R````0`````J&N
XM```"7U]B87-E```````$```"K@```BX````\````!@````````/R```#Z@``C
XM`$4```````````````!P:7!E.G!O<&5N+EA86%@N6%A86%A86%@``'(`=P!PD
XM;W!E;CH@8F%D(&UO9&4A"@!R`'<`<&]P96XZ($]U="!O9B!M96UO<GDA"@``9
XM<&]P96XZ(%5N86)L92!T;R!F:6YD(&%N(&%V86EL86)L92!P:7!E+@H`<&]P<
XM96XZ(%5N86)L92!T;R!O<&5N('!I<&4@96YD(#$@9FEL92`E<R!M;V1E("5S$
XM"@!P;W!E;CH@56YA8FQE('1O(&]P96X@<&EP92!E;F0@,B!F:6QE("5S(&UO=
XM9&4@)7,*`'!O<&5N.B!&;W)K(&9A:6QE9`H````P,3(S-#4V-S@Y86)C9&5F*
XM``````#\``````/L`````0````$```$.`````````_(```/J````!P``````E
XM``````````````````````````````````/R```#^P```18"<`!W86ET8VAIE
XM;&0N;P!?7V)A<V4`7U]X8V]V9@!?16UP='E-;W)G=64`7U]#:&EL9')E;@!?-
XM5V%I=$-H:6QD`'5X;6%I;BYO`%]$3U-"87-E`%]?=69B<P!?7VEO8@!?7V9M?
XM;V1E`%]#6$)22P!?7T].0E)%04L`7U]0<F]G<F%M3F%M90!?;6%L;&]C`%]?]
XM97AI=`!?<W1R;F-P>0!?;6%I;@!?97AI=`!?9G!U=',`7V9P=71C`%]?>&UA?
XM:6X`7U]-15)'140`=6QS96<`7U]L<V5G;65N=`!O<G!H86YC:&EL9')E;BYOT
XM`%]&;W)B:60`7T1E;&5T95!O<G0`7U)E;6]V90!?1G)E94UE;0!?4&5R;6ETI
XM`%]/<G!H86Y#:&EL9')E;@!O<G!H86YC:&EL9"YO`%]/<G!H86Y#:&EL9`!LP
XM875N8VAC+F\`7T-R96%T949A;6EL>0!?9FEN9'!A=&@`7T5S8V%P94%D9&ETG
XM:6]N<P!?17-C87!E4W1R:6YG`%]#<F5A=&50;W)T`%].97=,:7-T`%]F<F5E>
XM`%],875N8VA#:&EL9'8`7TQA=6YC:$-H:6QD;`!E<V-A<&EN9RYO`%]S=')PM
XM8G)K`&5M<'1Y;6]R9W5E+F\`7T=E=$US9P!?4F5P;'E-<V<`8W)E871E9F%MZ
XM:6QY+F\`8VAI;&1S=&%T=7,N;P!?0VAI;&13=&%T=7,`<&]P96XN;P!?9G!R=
XM:6YT9@!?9F]P96X`7T]P96X`7V9C;&]S90!?1FEN9%1A<VL`7T-L;W-E`%]!<
XM9&1486EL`%]P;W!E;G8`7W!O<&5N;`!?<&-L;W-E```!`````0```"P#Z0`$Y
XM``P`$P`;`"@``0`T`````0`_`$D``@```+0#Z0`0``P`$P!'`%``5P!=`&4`A
XM;`!V`(0`C`"3`)P`H@"H`*\``0"W`````0"_`0<#Z@``````R`*&``$`OP!0G
XM`^H````!`,X````!`-D"V0`!````(`/I``D`#``3`.D`&P`H`/$`_0$%`0X`5
XM`0$7`````0$G`S(``0```!H#Z0`'``P`$P#I`!L`*`#]`04``0$U`````0%".
XM`W8``@```5L#Z0`.``P`$P%+`5D!8P#-`$<!=`"$`8(!C@`H`/$!EP`"`9X`K
XM+@`!`:P````!`+\`%@/J``````&Z!5X``@```#\#Z0`#``P`$P'$``(!9```X
XM``$!=0!&``$`OP`"`^H``````<X%O0`!````&P/I``4`#``3`"@!VP'C``$`2
XM'`````$![@7Y``$````<`^D`!@`,`!,`*`&.`18!@@`!`4P````!`?T&00`!>
XM````&0/I``0`#``3`!L`*``!`@L````!`A@&=0`#````S@/I`!``#``3`8X`*
XM5P(?`(0!EP(H`B\"-0(]`9T"1P).`/T`,P`#`E@`-@`!`F`````!`F@"*``!8
X6`+\`10/J``````````<#Z@```````/T`B
X``
Xend
Xsize 9472
SHAR_EOF
echo "extracting rsbx.lib/uxmain.c"
sed 's/^X//' << \SHAR_EOF > rsbx.lib/uxmain.c
X#include <stdio.h>
X#include <fcntl.h>
X#include <ios1.h>
X#include <string.h>
X#include <stdlib.h>
X#include <libraries/dos.h>
X#include <libraries/dosextens.h>
X#include <proto/dos.h>
X#include <proto/exec.h>
X
X#define MAXARG 256	/* maximum command line arguments */
X#define QUOTE  '"'
X#define ESCAPE '*'
X#define ESC '\027'
X#define NL '\n'
X
X#define isspace(c) ((c == ' ')||(c == '\t') || (c == '\n'))
X
X#ifndef TINY
Xextern int _fmode,_iomode;
Xextern int (*_ONBREAK)();
Xextern int CXBRK();
X#endif
X
Xextern void main(int argc, char **argv);
X
Xextern char *_ProgramName;
Xextern struct UFB _ufbs[];
Xstatic int argc;		/* arg count */
Xstatic char *argv[MAXARG];	/* arg pointers */
Xstatic void badarg(char *program);
X
X#define MAXWINDOW 40
X
X/*
X * name		_xmain - process command line, open files, and call "main"
X *
X * synopsis	_xmain(line, length);
X *		char *line;	argument string to command
X *		int  length	length of argument string
X *
X * description	This function performs the standard pre-processing for
X *		the main module of a C program. It accepts a command
X *		line of the form
X *
X *			arg1 arg2 ...
X *
X *		and builds a list of pointers to each argument. The first
X *		pointer is to the program name. For some environments, the
X *		standard I/O files are also opened, using file names that
X *		were set up by the OS interface module XCMAIN.
X */
X
X/*
X * This is a modified umain.c, supplied with the Lattice 5.04 compiler,
X *	that correctly handles AmigaDos escapes.
X *
X *					Ray
X */
X
Xvoid _xmain(char *line, int length)
X	{
X	char *argbuf;
X	int x;
X
X	/*
X	 *
X	 * Open standard files
X	 *
X	 */
X#ifndef TINY
X
X	_ufbs[0].ufbfh = Input();
X	_ufbs[1].ufbfh = Output();
X	_ufbs[2].ufbfh = Open("*", MODE_OLDFILE);
X
X	_ufbs[0].ufbflg |= UFB_RA | O_RAW | UFB_NC;
X	_ufbs[1].ufbflg |= UFB_WA | O_RAW | UFB_NC;
X	_ufbs[2].ufbflg |= UFB_RA | O_RAW | UFB_WA;
X
X	stdin->_file  = 0;
X	stdout->_file = 1;
X	stderr->_file = 2;
X
X	x = (_fmode) ? 0 : _IOXLAT;
X	stdin->_flag  = _IOREAD | x;
X	stdout->_flag = _IOWRT  | x;
X	stderr->_flag = _IORW   | x;
X
X	/* establish control-c handler */
X
X	_ONBREAK = CXBRK;
X
X#endif
X
X	if (!(argbuf = malloc(_ProgramName[-1] + length + 2)))
X		{
X		_exit(1);
X		}
X
X	argv[argc++] = argbuf;
X	strncpy(argbuf, _ProgramName, _ProgramName[-1]);
X	argbuf += _ProgramName[-1];
X	*argbuf++ = '\0';
X
X	/*
X	 *
X	 * Build argument pointer list
X	 *
X	 */
X	while (argc < MAXARG)
X		{
X		while (isspace(*line) && length)
X			{
X			line++;
X			length--;
X			}
X		if (!length)
X			{
X			break;
X			}
X		argv[argc++] = argbuf;
X		if (*line == QUOTE)
X			{
X			line++;
X			length--;
X			while (length && (*line != QUOTE))
X				{
X				if (*line == ESCAPE)
X					{
X					line++;
X					length--;
X					if (!length)
X						{
X						badarg(*argv);
X						}
X					else
X						{
X						switch (*line)
X							{
X							case 'E':
X								*argbuf++ = ESC;
X								break;
X							case 'N':
X								*argbuf++ = NL;
X								break;
X							default:
X								*argbuf++ = *line;
X							}
X						length--;
X						line++;
X						}
X					}
X				else
X					{
X					*argbuf++ = *line++;
X					length--;
X					}
X				}
X
X			if (!length)
X				{
X				badarg(*argv);
X				}
X
X			line++;
X			length--;
X			*argbuf++ = '\0';	/* terminate arg */
X
X			if (length && !isspace(*line))
X				{
X				badarg(*argv);
X				}
X			}
X		else  /* non-quoted arg */
X			{
X			while (length && (!isspace(*line)))
X				{
X				*argbuf++ = *line++;
X				length--;
X				}
X			if (!length)
X				{
X				*argbuf = '\0';
X				break;
X				}
X			else
X				{
X				*argbuf++ = '\0';	/* terminate arg */
X				}
X			}
X		}  /* while */
X
X	/*
X	 *
X	 * Call user's main program
X	 *
X	 */
X
X	main(argc, argv);	/* call main function */
X#ifndef TINY
X	exit(0);
X#else
X	_exit(0);
X#endif
X	}
X
X
Xstatic void badarg(char *program)
X	{
X	fputs("Invalid argument to ", stderr);
X	fputs(program, stderr);
X	fputc('\n', stderr);
X	exit(100);
X	}
SHAR_EOF
echo "extracting rsbx.lib/childtasking.h"
sed 's/^X//' << \SHAR_EOF > rsbx.lib/childtasking.h
X/*
X * ChildTasking.h
X */
X
X#include <exec/types.h>
X#include <exec/lists.h>
X#include <exec/ports.h>
X#include <libraries/dos.h>
X
X
Xstruct ProcessTreeNode
X	{
X	void (*Orphan)( void );
X	struct MinList ChildList;
X	struct MsgPort *Morgue;
X	};
X
Xstruct DeathNotice			/* termination message from child */
X	{
X	struct Message msg;
X	struct DeathNotice **noticeptr;	/* process ID of sending task    */
X	long ret;			/* return value                  */
X	};
X
Xstruct ChildNode
X	{
X	struct MinNode node;
X	struct DeathNotice notice;
X	};
X
Xstruct StartMsg				/* startup message sent to child */
X	{
X	struct Message msg;
X	char *command;			/* command line                  */
X	ULONG cmdlen;			/* command line length           */
X	struct Library *DOSBase;	/* DOS lib pointer               */
X	struct MsgPort *morgue;		/* message port for parent       */
X	struct DeathNotice *termmsg;	/* child's termination message   */
X	BPTR st_fh1;			/* filehandle for child to close */
X	BPTR st_fh2;			/* filehandle for child to close */
X	};
X
Xstruct LAUNCHENV
X	{
X	long priority;	/* priority for child process          */
X	ULONG stack;	/* stack size for child process.       */
X			/*  If zero, stack size of calling     */
X			/*  process will be used.              */
X	BPTR std_in;	/* AmigaDos filehandle for child's     */
X			/*  Input() stream. If zero, Input()   */
X			/*  stream of calling process used.    */
X	BPTR std_out;	/* AmigaDos filehandle for child's     */
X			/*  Output() stream. If zero, Output() */
X			/*  stream of calling process used.    */
X	BPTR console;	/* console window handler port for     */
X			/*  child.                             */
X	BPTR le_fh1;	/* AmigaDos filehandle for child to    */
X			/*  close at exit.                     */
X	BPTR le_fh2;	/* AmigaDos filehandle for child to    */
X			/*  close at exit.                     */
X	};
X
X
Xextern struct ProcessTreeNode *_Children;
X
Xstruct ChildNode *LaunchChildl(struct LAUNCHENV *envp, char *name, char *args, ...);
Xstruct ChildNode *LaunchChildv(struct LAUNCHENV *envp, char *name, char **argv);
Xvoid EmptyMorgue( void );
Xstruct ChildNode *WaitChild(struct ChildNode *child, long *status);
Xstruct ChildNode *ChildStatus(struct ChildNode *child, long *status);
Xint OrphanChild(struct ChildNode *child);
Xvoid OrphanChildren( void );
Xint CreateFamily( void );
SHAR_EOF
echo "extracting rsbx.lib/launchc.obj.uu"
sed 's/^X//' << \SHAR_EOF > rsbx.lib/launchc.obj.uu
X
Xbegin 640 launchc.obj
XM```#YP````-L875N8VAC+F\```````/H`````````^D```%;3E4``+_L``!E.
XM````2.<`,"9M``@D;0`,2&T`$"\*+PMA```,3.T,`/_X3EU.=4Y5_["_[```C
XM90```$CG/S(F;0`()&T`#$ZZ``!*@&8&<`!@``40+PI.N@``6$\K0/_@4H!G+
XM``3\(`MF!$?L``"3R2QX``1.KO[:*T#_P$JK``1F$"!M_\`@*``^D*@`.B=`D
XM``0,JP``(```!&0*(#P``"``)T``!"`K``16@`)`__PG0``$?@%\`"`'Y8`@H
XM;0`02K`(`&<Z(`?E@"!M`!`@<`@`2AAF_%.((FT`$)'Q"``@!^6`+S$(`"](4
XM`"A.N@``6$\B+P`DTH!2@=R!4H=@N$J&5\!$`$B`2,!2ADJ`9P)2ACE\``0`6
XM-G``*4``."E&`#PI?``!``$`0'!`*4``1$*L`$@B;0`0(%%*&&;\4XB1T2`(E
XM5(`I0`!,0JP`4"EL````5$'L`"@L>``$3J[_(BM`_[@@+?^X"```'V<0(BW_<
XMX"QL``!.KO^F8``#Y"!M_[@K:``0__P@;?^X*V@`&/^T(FW_N"!I`"`K2/_8=
XM(&W_N"MH`"C_["`M_]@B`.2!(&W_M"%!`!`@;?_84JW_V"QM`!`B5DH99OQ3Z
XMB9/6(`D0@")M`!`@42)M_]@2V&;\?@%\`"`'Y8`@;0`02K`(`&<``((@!^6`(
XM(&T`$"\P"`!.N@``6$\J`$J%9QP@;?_\T<8@!^6`(FT`$"\Q"``O"$ZZ``!0P
XM3V`6(&W__-'&(`?E@")M`!`B<0@`$-EF_"`'Y8`@;0`0('`(`$H89OQ3B")MD
XM`!"1\0@`(`C0A=R`($92AB)M__P@"!.\`"`(`%*'8`#_<DJ&9P)3AB!&4H8BV
XM;?_\(`@3O``*"``@;?_\0C!H`"(M_^`L;```3J[_@BM`_^`B`$ZN_Z`K0/_<C
XM(@HL;```3J[_:BM`_^0B+?_@+&P``$ZN_X(B`$ZN_Z9*K?_D9P`"=B`L``!!#
XM[```(FW_[&`"$MA3@&3Z(&W_["M(_^A8K?_H(&W_Z""M_^0@+?_HY(`K0/_HO
XM2'@`,$ZZ``!83RM`_\Q*@&<``B0@;?_,,7P`'``20J="ITZZ``!03R!M_\PA1
XM0``.9P`!^B!M_\PA;?_\`!0@;?_,(48`&$/L`!QP`"QX``1.KOW8(&W_S"%`I
XM`!QG``'`<"1R`"QX``1.KO\Z*T#_U$J`9P`!FB!M_]10B")M_\PC2``D("W_>
XMZ"(*)@`D$R@K``0L;```3J[_=BM`_]!*@&<``5X@;?_0*V@`$/^\(&W_O$JH/
XM`$IF$"!M_[S0_`!*+PA.N@``6$\@;?^\T/P`2B)M_[@L>``$3J[_"B!M_[PA^
XM;?_<`)@@;?_`(FW_O"-H`*@`J"`M_[3D@"!M_[PA0`"L2JL`$&<:("L`$.6`0
XM*T#_Q"!M_\0B;?^\(V@`"`"D8`X@;?_`(FW_O"-H`*0`I$JK``AG#"!M_[PAO
XM:P`(`)Q@#B!M_\`B;?^\(V@`G`"<2JL`#&<,(&W_O"%K``P`H&`.(&W_P")M3
XM_[PC:`"@`*`@;?_,(6L`%``H(&W_S"%K`!@`+"!L```B;?_,(V@`$``@(&P`[
XM`%B((FW_U"QX``1.KO\*(&W_T")M_\PL>``$3J[^DB!M_\P@:``.+'@`!$ZNK
XM_H`K0/_(L*W_S&<8(&W_S"!H``XL>``$3J[^C")`3J[^AF#.(&W_S"\H``Y..
XMN@``+JW_S$ZZ```@+?_48%PB;?_4<"0L>``$3J[_+B)M_\PB:0`<+'@`!$ZNP
XM_F(@;?_,+R@`#DZZ``!83R\M_\Q.N@``6$\B+?_D+&P``$ZN_V0B+?_<+&P`-
XM`$ZN_Z8@;?^X+'@`!$ZN_QQP`$SM3/S_C$Y=3G4```/X````#`````$```%6M
XM```!4@```4P```%(```!,@```2X```$H```!(````1P```$6```#3@```&P`&
XM```````#[P$```1?3&%U;F-H0VAI;&1L``````````$```1?3&%U;F-H0VAI4
XM;&1V````````+H,```)?9G)E90````````(```4X```$_H,```-?1&5L971ES
XM4&]R=``````"```%+@``!/:&```#7U]#:&EL9')E;@```````@``!)H```2,T
XM@P```E].97=,:7-T`````0```\J#```#7T-R96%T95!O<G0``````0```RJ#'
XM```"7VUA;&QO8P`````!```##(,```1?17-C87!E4W1R:6YG`````````0``8
XM`B*&```"7T1/4T)A<V4````'```%3@``!4(```.:```"P````K````*8```!Y
XM=(8```-?7VQS96=M96YT```````#```"V@```M8```%0@P``!%]%<V-A<&5!:
XM9&1I=&EO;G,````"```"`@```.Z#```#7V9I;F1P871H`````````0```%B#A
XM```$7T-R96%T949A;6EL>0````````$```!(@P```E]?>&-O=F8``````@``-
XM`#@````*A@```E]?8F%S90```````@```#0````&`````````_(```/H````_
XM`E]?34521T5$```#Z@```!8`````````````````````````````````````W
XM9&]S+FQI8G)A<GD`````````````````````````````````````````````I
X3```````````````````````#\@``U
X``
Xend
Xsize 2044
SHAR_EOF
echo "extracting rsbx.lib/ulseg.obj.uu"
sed 's/^X//' << \SHAR_EOF > rsbx.lib/ulseg.obj.uu
X
Xbegin 640 ulseg.obj
XM```#YP````)U;'-E9P```````^@````"7U]-15)'140```/J````4````4``I
XM````8!0``````````````````````````$CG?_XL>``$D\E.KO[:*$!![`!<I
XM3J[^@$'L`%Q.KOZ,(D!%^O_()6D`*``,)6D`+``0)6D`(``$)6D`'```)6D`G
XM)``(0>H`""10)4@`%"!I`!0@*0`82.>`@$ZN_H8B;`"`5HG3R=/)(KK_?$/ZZ
XM_W0@*0`$Y8A8@")`3-\!`2(L`#HD#P2"````%)2!+RP`L$CG``HO`BE/`+!.I
XMD5B/3-]0`"E?`+`O`$7Z_T(B.O\X+PXL:@``3J[_9"Q?(BP`F"\.+&H``$ZN?
XM_Z8L7R(J``QG#"\.+&H``$ZN_]PL7R(J`!!G#"\.+&H``$ZN_]PL7R)J``!..
XMKOYB3J[_?"`J``AG&B)`(U\`&$*I`!1"J0`.(&H`!")J``A.KOZ23-]__DYUE
X@```#[P$```-?7VQS96=M96YT`````````````````_)JR
X``
Xend
Xsize 392
SHAR_EOF
echo "End of archive 14 (of 14)"
# if you want to concatenate archives, remove anything after this line
exit