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#__(&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```QX@;?_\$-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#__</\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