Utilities 3 (Disk 38) (Mar 1987) : c / WBRun.c

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* |_o_o|\\ Copyright (c) 1986 The Software Distillery.  All Rights Reserved */
/* |. o.| || This program may not be distributed without the permission of   */
/* | .  | || the authors.                                                    */
/* | o  | ||    Dave Baker     Ed Burnette  Stan Chow    Jay Denebeim        */
/* |  . |//     Gordon Keener  Jack Rouse   John Toebes  Doug Walker         */
/* ======          BBS:(919)-471-6436      VOICE:(919)-469-4210              */ 
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#include <exec/types.h>
#include <exec/memory.h>
#include <workbench/workbench.h>
#include <workbench/icon.h>
#include <workbench/startup.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>

int setarg(struct WBArg *, char *, struct Lock *);
void msg(char *, char *);

struct IconBase *IconBase;
#define ICON_REV 0

void main(argc, argv)
register int argc;
char **argv;
{
register struct WBStartup *WBStartup;
register struct DiskObject *diskobj;
char *torun, nambuf[160];
register int stacksize, i;
struct Process *ourtask;
struct MsgPort *replyport;
register struct Lock *olddir, *lock;

/* initialize so our cleanup routine runs fine */
WBStartup = NULL;
IconBase  = NULL;
diskobj   = NULL;
replyport = NULL;
olddir    = NULL;

/* running this from workbench is ridiculous so just quit */
if (argc == 0) XCEXIT(-1);

/* issue the copyright notice - they can supress it by doing a WBRUN >NIL: */
msg(
"\x9B33mWBRun\x9B0m by John Toebes - Copyright © 1986 \x9B4mThe Software Distillery\x9B0m\n",
"235 Trillingham Ln, Cary NC 27511   BBS:(919)-471-6436");

/* not enough parameters? - give them the usage */
if (argc < 2)
   {
   msg(
"Usage: WBRun icon(s)\nWhere icon(s) is to run as if selected from Workbench\n",
"Note: Use WBRun >NIL: icon(s)   to hide copyright message");
   goto done;
   }

/* open the libraries we will need */
if ((IconBase = (struct IconBase *)OpenLibrary(ICONNAME, ICON_REV)) == NULL)
   goto done;

/* find ourselves - if this doesn't work it deserves to die a horrible */
/* death so I will not even look at our result */
ourtask = (struct Process *)FindTask(NULL);

/* allocate storage for all the arguments on the list */
if ((WBStartup = (struct WBStartup *)
                 AllocMem(sizeof(struct WBStartup), MEMF_CLEAR)) == NULL)
   goto done;

if ((WBStartup->sm_ArgList = (struct WBArg *)
                 AllocMem(sizeof(struct WBArg)*argc, MEMF_CLEAR)) == NULL)
   goto done;

if ((replyport = (struct MsgPort *)CreatePort("PhoneyWorkbench", 0)) == NULL)
   goto done;

/* initialize the remainder of the startup fields */
WBStartup->sm_Message.mn_ReplyPort = replyport;
WBStartup->sm_NumArgs = argc-1;

/* run through all the arguments getting locks and names for them */
for (i=1; i<argc; i++)
   if (setarg(&WBStartup->sm_ArgList[i-1], argv[i],
              (struct Lock *)ourtask->pr_CurrentDir))
         goto done;

/*-- Load the code that is desired ---*/
/* to do this, first find the program to be run */
olddir = (struct Lock *)CurrentDir( WBStartup->sm_ArgList[0].wa_Lock );

if ((diskobj = (struct DiskObject *)
               GetDiskObject( WBStartup->sm_ArgList[0].wa_Name )) == NULL)
   {
   msg("Can't get icon for ", WBStartup->sm_ArgList[0].wa_Name);
   goto done;
   }

torun = argv[1];

/* once we have the object, look at the tool type */
/* for TOOLS we run the program (argv[0] in our case) */
/* For projects it has the name of the default tool to run with it */
/* all others are to be blown away */
if (diskobj->do_Type == WBPROJECT)
   {
   /* for a project, we need to insert the tool icon as the first tool */
   /* move everything over one */
   movmem(&WBStartup->sm_ArgList[0],&WBStartup->sm_ArgList[1],
              (argc-1)*sizeof(struct WBArg));
   strcpy(nambuf, diskobj->do_DefaultTool);
   torun = nambuf;

   if (setarg(&WBStartup->sm_ArgList[0], torun, olddir))
      goto done;

   FreeDiskObject(diskobj);

   if ((diskobj = (struct DiskObject *)
                  GetDiskObject( WBStartup->sm_ArgList[0].wa_Name )) == NULL)
      {
      msg("Can't get icon for ", WBStartup->sm_ArgList[0].wa_Name);
      goto done;
      }

   WBStartup->sm_NumArgs++;
   }

/* at this point if it is not a TOOL we are scrod */
if (diskobj->do_Type != WBTOOL)
   {
   msg("Icon is not runnable for ", torun);
   goto done;
   }

if ((stacksize = diskobj->do_StackSize) < 4000)
   stacksize = 4000;

/* so lets load the segment for the program to run */
if ((WBStartup->sm_Segment = (BPTR)LoadSeg(torun)) == NULL)
   {
   msg("Can't open tool ", torun);
   goto done;
   }

/* also we will need to get it going as a process */
if ((WBStartup->sm_Process = (struct MsgPort *)
           CreateProc(torun, 0, WBStartup->sm_Segment, stacksize)) == NULL)
   {
   msg("Can't create process for ", torun);
   goto done;
   }

/* we are off and running, pass it the message to get running */
WBStartup->sm_ToolWindow = diskobj->do_ToolWindow;

PutMsg(WBStartup->sm_Process, WBStartup);

/* when he is done with what he needs, we can blow everything away */
WaitPort(replyport);

/* everything is now complete so clean up and go away */
done:
if (replyport != NULL) DeletePort(replyport);
replyport = NULL;

if (diskobj != NULL) FreeDiskObject(diskobj);
diskobj = NULL;

if (olddir != NULL) CurrentDir(olddir);

if (WBStartup != NULL)
   {
   if (WBStartup->sm_Segment != NULL)
      UnLoadSeg(WBStartup->sm_Segment);
   if (WBStartup->sm_ArgList != NULL)
      {
      /* run through and free any locks we may have */
      for (i=0; i<argc; i++)
         {
         lock = (struct Lock *)WBStartup->sm_ArgList[i].wa_Lock;
         if ((lock != NULL) && (lock != (struct Lock *)ourtask->pr_CurrentDir))
            UnLock(lock);
         }
      FreeMem(WBStartup->sm_ArgList,sizeof(struct WBArg)*argc);
      }
   FreeMem(WBStartup, sizeof(struct WBStartup));
   }
WBStartup = NULL;

if (IconBase != NULL) CloseLibrary(IconBase);
IconBase = NULL;

XCEXIT(0);
}

/***********************************************************/
/* given a null terminated name, fill in a WBArg structure */
/* with a lock and a name relative to that lock            */
/***********************************************************/
int setarg(WBArg, name, curdir)
register struct WBArg *WBArg;
char *name;
struct Lock *curdir;
{
register char *p, *lastc;
register unsigned char c;

if (name == NULL || !*name) return(1);  /* bad name to use */

/* first find the last colon or slash in the name */
lastc = NULL;
for (p = name; *p; p++)
   if (*p == ':' || *p == '/')
      lastc = p+1;

/* was there a path delimiter at all ? */
if (lastc == NULL)
   {
   /* no, use the default lock and full name */
   WBArg->wa_Lock = (BPTR)curdir;
   WBArg->wa_Name = name;
   }
else
   {
   /* must get a lock on the right directory and use part of the name */
   if (!*lastc) return(1); /* only a drawer specified */
   WBArg->wa_Name = lastc;

   /* when setting a directory, we need to include the delimiter */
   c = *lastc;
   *lastc = NULL;
   if ((WBArg->wa_Lock = (BPTR)Lock(name)) == NULL)
      {
      msg("Cannot open directory:", name);
      return(1);  /* couldn't find the director */
      }
   *lastc++ = c;
   }

/* it worked so let them continue on */
return(0);
}

void msg(str1, str2)
char *str1, *str2;
{
Write(Output(),str1,strlen(str1));
Write(Output(),str2,strlen(str2));
Write(Output(),"\n", 1);
}

void MemCleanup(){}