Path: utzoo!attcan!uunet!husc6!purdue!i.cc.purdue.edu!j.cc.purdue.edu!ain
From: ain@j.cc.purdue.edu (Patrick White)
Newsgroups: comp.sources.amiga
Subject: RunBack (sources 1 of 1)
Keywords: runback, uncompiled
Message-ID: <7374@j.cc.purdue.edu>
Date: 9 Jul 88 01:00:21 GMT
Organization: PUCC Land, USA
Lines: 470
Approved: ain@j.cc.purdue.edu	(Patrick White)

Submitted by:	barrett@crabcake.cs.JHU.EDU
Summary:	Runs a program in the background without attachments to the CLI.
Poster Boy:	Patrick White	(ain@j.cc.purdue.edu)
Archive Name:	sources/amiga/volume5/runback2.s.sh.Z
tested.
 
NOTES:
   I tried it, but didn't tru compiling it.
   Reshared it to separate sources, docs, and binaries.
   It worked perfectly except when I tried to runback the info.library.. but
that is a dumb thing to be doing anyway :-)  (did it cause older versions
died when you tried to run soemthign that was not there).
.
 
 
-- Pat White   (co-moderator comp.sources/binaries.amiga)
ARPA/UUCP: j.cc.purdue.edu!ain  BITNET: PATWHITE@PURCCVM  PHONE: (317) 743-8421
U.S.  Mail:  320 Brown St. apt. 406,    West Lafayette, IN 47906
[archives at: j.cc.purdue.edu.ARPA]
 
========================================
 
#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	Makefile
#	aztec.c
#	path.c
#	runback.c
# This archive created: Fri Jul  8 11:33:43 1988
# By:	Patrick White (PUCC Land, USA)
echo shar: extracting Makefile '(123 characters)'
cat << \SHAR_EOF > Makefile
CFLAGS=+L
OBJ=runback.o path.o aztec.o
PROG=RunBack

all:	$(OBJ)
	ln $(OBJ) -o $(PROG) -lc32

clean:
	delete \#?.o $(PROG)
SHAR_EOF
if test 123 -ne "`wc -c Makefile`"
then
echo shar: error transmitting Makefile '(should have been 123 characters)'
fi
echo shar: extracting aztec.c '(199 characters)'
cat << \SHAR_EOF > aztec.c
/* HasASpace(s):	Return 1 if there is a space in string s.
 *			Return 0 otherwise.
*/

HasASpace(s)
char *s;
{
	char *temp=s;
	while (*temp) {
		if (*(temp++) == ' ')
			return(1);
	}
	return(0);
}
SHAR_EOF
if test 199 -ne "`wc -c aztec.c`"
then
echo shar: error transmitting aztec.c '(should have been 199 characters)'
fi
echo shar: extracting path.c '(3991 characters)'
cat << \SHAR_EOF > path.c
/* This code is taken largely from Carolyn Scheppner's "which.c" program
 * from 11/87.  There were no copyright notices in the original file,
 * so to the best of my knowledge it is in the Public Domain.
*/

#include 
#include 
#include 
#include 

#define SBUFSZ 256
#define CBUFSZ 80

extern BOOL getPath();
extern struct Task *FindTask();		/* To scare away warning msgs */
extern VOID *AllocMem();
	
struct Path
   {
   BPTR  path_Next;
   LONG  path_Lock;
   };

char *FindIt(command)
char *command;
{
   struct Process *proc;
   struct CommandLineInterface *cli;
   struct Path *path;
   struct FileInfoBlock *fib;
   APTR oldWindowPtr;
   LONG lock, startcd;
   BOOL Found, InitialCD, FullPath;
   int  i;
   char sbuf[SBUFSZ], cbuf[CBUFSZ];

   /* Fail if not CLI process */
   proc = (struct Process *)FindTask(NULL);
   cli = (struct CommandLineInterface *)(proc->pr_CLI << 2);
   if(!cli)  exit(RETURN_ERROR);

   /* Allocate a FileInfoBlock - must be longword aligned */
   if(!(fib=(struct FileInfoBlock *)
     AllocMem(sizeof(struct FileInfoBlock),MEMF_PUBLIC|MEMF_CLEAR)))
      printf("Not enough memory\n"), exit(RETURN_FAIL);

   /* Save old WindowPtr, and disable volume requesters */
   oldWindowPtr = proc->pr_WindowPtr;
   proc->pr_WindowPtr = (APTR)-1L;

   /* Were we given full path in command name ? */
   for(FullPath = FALSE, i=0; icli_CommandDir);
          (path) && (!Found);
            path = (struct Path *) BADDR(path->path_Next))
         {
         /* CD to each path */
         lock = CurrentDir(path->path_Lock);
         if(InitialCD)  startcd = lock, InitialCD = FALSE;

         /* See if command is there */
         Found = getPath(command,fib,sbuf);
         }
      /* If we CD'd anywhere, restore initial CD */
      if(! InitialCD)  CurrentDir(startcd);
      }

   /* Check C: */
   if((!Found)&&(!FullPath))
      {
      strcpy(cbuf,"C:");
      strcpy(&cbuf[2],command);
      if(Found = getPath(cbuf,fib,sbuf))  strcpy(sbuf,cbuf);
      }

   /* Re-enable volume requesters */
   proc->pr_WindowPtr = oldWindowPtr;

   /* Free fib */
   if (fib)
	FreeMem(fib, sizeof(struct FileInfoBlock));

   if(Found)
	return(sbuf);
   else
	return(NULL);
}


BOOL
getPath(command,fib,buf)
char *command;
struct FileInfoBlock *fib;
char *buf;
   {
   LONG lock;
   BOOL Success = FALSE;

   if(lock = Lock(command,ACCESS_READ))
      {
      if(Examine(lock,fib))
         {
         Success = TRUE;
         buildPath(lock,fib,buf);
         }
      UnLock(lock);
      }
   return(Success);
   }


buildPath(inlock,fib,buf)
LONG inlock;
struct FileInfoBlock *fib;
char *buf;
   {
   int i;
   LONG lock,oldlock;
   BOOL MyOldLock = FALSE;

   buf[0] = NULL;
   lock = inlock;

   while(lock)
      {
      if(Examine(lock,fib))
         {
         if(fib->fib_FileName[0] > ' ')
            {
            if(buf[0]) insert(buf,"/");
            insert(buf,fib->fib_FileName);
            }
         }
      oldlock = lock;
      lock = ParentDir(lock);
      if(MyOldLock)  UnLock(oldlock);
      else           MyOldLock = TRUE;
      }

   if(fib->fib_FileName[0] > ' ')
      {
      for(i=0; i<(strlen(buf)); i++)
         {
         if(buf[i] == '/')
            {
            buf[i] = ':';
            break;
            }
         }
      }
   else  insert(buf,"RAM:");

   return(strlen(buf));
   }

insert(buf,s)
char *buf,*s;
   {
   char tmp[SBUFSZ];

   strcpy(tmp,buf);
   strcpy(buf,s);
   strcpy(&buf[strlen(s)],tmp);
   }

SHAR_EOF
if test 3991 -ne "`wc -c path.c`"
then
echo shar: error transmitting path.c '(should have been 3991 characters)'
fi
echo shar: extracting runback.c '(5865 characters)'
cat << \SHAR_EOF > runback.c
/* runbackground.c */
/* Author:  Rob Peck.  5/9/86 */

/* Modified 5/21/88 by Dan Barrett to include PATH searching; added
 * the functions FullPathOf() and FindIt(), largely taken from C.
 * Scheppner's "which.c" program.
 *
 * Also, a few "#ifdef AZTEC_C" lines had to be added.  It seems that
 * Aztec C parses the command line differently from the way Lattice
 * does with respect to arguments in quotes.  When I compiled this
 * program with Aztec, all the quotes in quoted arguments were 
 * disappearing.  I re-insert them around any argument that has a
 * space character (' ') in it.
*/

/*#define DEBUG*/ 	/* Uncomment this line for debugging. */

#define EQUAL(a,b)	!strcmp(a,b)
	
#include "exec/types.h"
#include "exec/memory.h"
#include "libraries/dosextens.h"

extern struct FileHandle *Open();
extern struct FileLock *Lock();
extern VOID *AllocMem();
	
main(argc, argv)
int argc;
char *argv[];
{	
    LONG success, delaywillbe;
    UBYTE commandstring[255];
    char *test, *filename;
    LONG fromparm;
    struct FileInfoBlock *fib;
    struct FileHandle *nilfh;	/* NOTE: will hang around until next reset */
    struct FileLock *lock, *FullPathOf();
#ifdef AZTEC_C
    int hasSpace=0;		/* Does an string have a space in it. */
#endif
    
    fib = NULL;			/* No file info block so far. */
    delaywillbe = 1;

    if(argc < 2 || EQUAL(argv[1],"?")) {
usage:
	printf("Usage: RUNBACKGROUND [ -]  []\n");
	printf("          where optional loaddelay is 0-9,\n");
	printf("          specified in seconds for the CLI\n");
	printf("          to sleep, waiting for task to load\n");
	printf("          (minimizes inter-task disk-thrashing)\n");
	if(fib)
		FreeMem(fib, sizeof(struct FileInfoBlock));
	exit(0);
    }

    /* See if there is a delay parameter present */

    test = argv[1];

    if(*test++ == '-') {
	filename = argv[2];	/* argv[1] is delay so argv[2] is file  */
	fromparm = 3;		/* Copy parms from 3 to end  		*/

	if(*test >= '0' && *test <= '9')
	    delaywillbe = 1 + (50 * (*test - '0')); 

	if (argc < 3)
		goto usage; /* Only a delay, and no filename!! */

	argc--;		/* one less parm to copy */
    }
    else {
	filename = argv[1];
	fromparm = 2;		/* Copy parms from 2 to end 		*/
    }

    /* Now see if the file exists!  If not, it can crash the background
     * CLI and take the system along with it.
     */

    lock = FullPathOf(filename);
    if(!lock) {
	printf("%ls: Command not found\n",filename);
	goto usage;
    }
    else {
	/* If file exists, it better be a file and not a directory */

/*DJB*/	/* With my (Dan's) changes, a file that is not found at all
	 * is falsely identified as a directory.  Irritating, but not
	 * fatal.
	 */

	/* Unfortunately, it is difficult to tell if it is an executable
	 * file.  If not executable, we'll still get blown out of the
	 * water, but that is up to the user to do it right!
	 */

	fib =  (struct FileInfoBlock *)
        	AllocMem(sizeof(struct FileInfoBlock),MEMF_CLEAR);
	if(!fib) {
	    UnLock(lock);
	    printf("Ran out of memory!\n");
	    exit(0);
	}
	else {
	    success = Examine(lock,fib);
	    if(fib->fib_DirEntryType > 0) {
/*		printf("%ls is a directory, not a file!\n",filename); */
/*DJB*/		printf("Cannot open %ls... maybe a directory?\n",filename);
		goto usage;
	    }
	}
   	FreeMem(fib, sizeof(struct FileInfoBlock));
	UnLock(lock);
    }
 
    nilfh = Open("NIL:",MODE_NEWFILE); /* will always succeed */

    strcpy( &commandstring[0], "RUN >NIL: somewhere" or "NIL:  0) {     /* Rebuild parameter string for passing it on */
	strcat( &commandstring[0], " ");	/* add a blank */

#ifdef AZTEC_C
	hasSpace = HasASpace(argv[fromparm]);	/* Quoted argument?     */
	if (hasSpace)				/* Then quote it again! */
		strcat( &commandstring[0], "\"");
#endif

	strcat( &commandstring[0], argv[fromparm++]);

#ifdef AZTEC_C
	if (hasSpace)
		strcat( &commandstring[0], "\"");
#endif

    }

#ifdef DEBUG
    printf("Execute %s\n", &commandstring[0]);
#else
    success = Execute( &commandstring[0] , nilfh, nilfh);
#endif

    /* The full command passed to Execute now looks like this:
     *
     *	"RUN >NIL: NIL: