Received: from PURCCVM.BITNET by FINTUVM.UTU.FI (Mailer X1.25) with BSMTP id
 6845; Sat, 09 Jul 88 04:09:59 EET
Received: from PURCCVM by PURCCVM.BITNET (Mailer X1.25) with BSMTP id 3218;
 Fri, 08 Jul 88 20:02:26 EST
Received: from j.cc.purdue.edu by VM.CC.PURDUE.EDU ; Fri, 08 Jul 88 20:02:20 EST
Received: by j.cc.purdue.edu (5.54/1.14)
    id AA11798; Fri, 8 Jul 88 20:00:43 EST
Date: Fri, 8 Jul 88 20:00:43 EST
From: ain@j.cc.purdue.edu (Patrick White)
Message-Id: <8807090100.AA11798@j.cc.purdue.edu>
To: fys-ma@fintuvm.BITNET
Subject: comp.sources.amiga:   sources/amiga/volume5/runback2.s.sh
 
Newsgroups: comp.sources.amiga
Subject: RunBack (sources 1 of 1)
Keywords: runback, uncompiled
Approved: ain@j.cc.purdue.edu    (Patrick White)
 
Program Name:    RunBack  (sources)
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 something 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 <exec/types.h>
#include <exec/memory.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
 
#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; i<strlen(command); i++)
     {
     if(command[i] == ':')
        {
        FullPath = TRUE;
        break;
        }
     }
 
   /* Check current directory */
   if(Found = getPath(command,fib,sbuf))
      {
      if((!FullPath)&&(command[0]))  strcpy(sbuf,command);
      }
 
   /* Check paths */
   if((!Found)&&(!FullPath))
      {
      InitialCD = TRUE;
      /* Follow the BPTR path list */
      for(path = (struct Path *) BADDR(cli->cli_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 [ -<loaddelay>] <name> [<parm(s)>]\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: <NIL: " );
    strcat( &commandstring[0], filename);
 
    /* REMOVE THIS NEXT LINE IF YOU WANT TO INCLUDE REDIRECTION IN
     * THE COMMAND LINE FOR RUNBACKGROUND.   (The line was installed
     * to assure that something like "RUNBACKGROUND date ?" would
     * not crash the system.  "Date ?" is expecting to have an interactive
     * CLI, and unless it is specifically told to direct its output to nil:
     * it causes a crash.  If the next line is removed, and you are careful
     * about putting only NON-interactive commands in the command line,
     * everything should be ok.  Notice that if you do not specify a
     * non-interactive file handle (named_disk_file or NIL:) for your
     * program, it may still prevent the originating CLI from going away
     * until your program ends.  Also note that specifying two instances
     * of the same redirection (">somewhere" or "<somewhere") for a
     * background task crashes.
     */
 
    strcat( &commandstring[0], " >NIL: <NIL: ");
 
    argc--;
 
    while(--argc > 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: FILENAME >NIL: <NIL: PARAMETER(s)"
     *
     */
 
    if(success) {
    printf("Started %ls as a background task\n",filename);
 
    /* Execute, in this case, returns IMMEDIATELY.  The process
     * that is loading the code that is to be run as a background
     * process is working to get everything in and started.
     */
    }
    /* Now, to minimize thrashing between tasks, lets put this task to
     * sleep so that the each task actually gets a chance to load.
     */
    Delay(delaywillbe);
}
 
 
struct FileLock *FullPathOf(filename)
char *filename;
{
    struct FileLock *lock;
    char realname[256], *FindIt();
 
    strcpy(realname, FindIt(filename));
    lock = Lock(realname,ACCESS_READ);
    return(lock);
}
SHAR_EOF
if test 5865 -ne "`wc -c runback.c`"
then
echo shar: error transmitting runback.c '(should have been 5865 characters)'
fi
#    End of shell archive
exit 0
