[comp.sys.amiga] How can I get to the command search path?

mills-c@pike.cis.ohio-state.edu (Chris Mills) (11/12/87)

[ I'm new to this so bear with me ]

I'm trying to write a program which, among other things, will do command and
filename completion on the Amiga.  What I need to know is how do I get at
the search path (given by the PATH command)?  I need to be able to search
all the directories from the current dir down to C:.

			Thanks in advance,
			Chris.

bryce@hoser.berkeley.edu (Bryce Nesbitt) (11/15/87)

In article <1538@tut.cis.ohio-state.edu> mills-c@pike.cis.ohio-state.edu (Chris Mills) writes:
>
>I'm trying to write a program which, among other things, will do command and
>filename completion on the Amiga.  What I need to know is how do I get at
>the search path (given by the PATH command)?  I need to be able to search
>all the directories from the current dir down to C:.

Here's a public wish that C= would provide the technical information
in Amiga Mail in electronic form, perhaphs after a delay to give
subscribers "first jump".  Good technical information that *everyone*
can have helps the machine.


"The path list is held as a BPTR in the CommandDir member of the
CommandLineInterface structure.  Although currrently documented as
the lock on the command directory, this is either zero or a BPTR
to a list of path elements, each consisting of:
	BPTR	NextPath	(BPTR to next in list)
	BPTR	PathLock	(BPTR to a lock on the directory)"

The lock on the currrent directory is *NOT* in the list, nor is
the C: lock.  I feel this is unfortunate, as there are real
reasons for wanting to play with the order of those two as well.

|\ /|  . Ack! (NAK, SOH, EOT)
{o O} . bryce@hoser.berkeley.EDU -or- ucbvax!hoser!bryce
 (")
  U

dillon@CORY.BERKELEY.EDU (Matt Dillon) (11/15/87)

>I'm trying to write a program which, among other things, will do command and
>filename completion on the Amiga.  What I need to know is how do I get at
>the search path (given by the PATH command)?  I need to be able to search
>all the directories from the current dir down to C:.

	I thought about doing something like this, but found that it simply
takes too long to sequentially search floppy directories.  The Amiga is much
better finding specific names (and partial names are no good because you
still have to scan the directory).   The IBM sequentially searches its
directories, and if you have a big directories that HD really gets busy 
trying to find the program!  I like the 'find a specific name fast'
approach... it means I can search C: on 2 floppy drives, VD0:, and RAM:
in the blink of an eye.

	What?  Oh yah.  The PATH is stored in the CLI structure's 
cli_CommandDir entry as a linked list of FileLock's.  That is:

  	 (Note, construction is from memory.. untested)

#include <exec/types.h>
#include <dos.h>
#include <dosextens.h>

#define BTOC(bptr) ((long)(bptr) << 2)

typedef struct Task TASK;
typedef struct Process PROC;
typedef struct CommandLineInterface CLI;
typedef struct FileLock LOCK;

extern TASK *FindTask();

blah()
{
    CLI *cli;
    BPTR lock;

    /* assume we are a process */

    cli = (CLI *)BTOC(((PROC *)FindTask(NULL))->pr_CLI);
    for (lock = cli->cli_CommandDir;lock;lock=((LOCK *)BTOC(lock))->fl_Link) {
	/* Search directory referenced by 'lock' */
    }
}

	Something like that, anyway.

				-Matt

carolyn@cbmvax.UUCP (Carolyn Scheppner CATS) (11/18/87)

In article <21790@ucbvax.BERKELEY.EDU> bryce@hoser.berkeley.edu (Bryce Nesbitt) writes:
>
>Here's a public wish that C= would provide the technical information
>in Amiga Mail in electronic form, perhaphs after a delay to give
>subscribers "first jump".  Good technical information that *everyone*
>can have helps the machine.
>
>
>"The path list is held as a BPTR in the CommandDir member of the...
>[]

We already upload much of what we put in Amigamail, both here and on BIX.

Prior to that AmigaMail, I personally put that PATH list information:

   - on usenet in "Some AmigaDOS Info from Tim King"
   - on usenet and BIX in almost exact form as article
   - on the 1.2 ReadMe disk (Native Developer Update)

Andy, Phil (while he was here), and I almost always post our AmigaMail
programs to usenet and BIX.  We could probably post more of our article
type stuff, but on the other hand, we (especially Lauren) work very
hard to make AmigaMail and anyone can get a subscription:

 $20 US / year, + $2.50 Canada, + $5.00 foreign
 Check made out to Commodore Business Machines

    CATS - AmigaMail
    Lauren Brown - Software Admin.
    CBM
    1200 Wilson Drive
    West Chester, PA.  19380


    
    
-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Carolyn Scheppner -- CATS   >>Commodore Amiga Technical Support<<
                     UUCP  ...{allegra,ihnp4,rutgers}!cbmvax!carolyn 
                     PHONE 215-431-9180
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

carolyn@cbmvax.UUCP (Carolyn Scheppner CATS) (11/18/87)

In article <1538@tut.cis.ohio-state.edu> mills-c@pike.cis.ohio-state.edu (Chris Mills) writes:
>
>I'm trying to write a program which, among other things, will do command and
>filename completion on the Amiga.  What I need to know is how do I get at
>the search path (given by the PATH command)?  I need to be able to search
>all the directories from the current dir down to C:.

   I have lots of paths set up on my A2000, and recently got annoyed because
I forgot where I had put a command I needed to update.  So I wrote this.
It contains code to search paths and to build full path names.

-------

/*
 *  which.c  ---  C. Scheppner  CBM  11/87
 *
 *     Usage:  which commandname
 *     Tells you the path to that command
 */

#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();

struct Path
   {
   BPTR  path_Next;
   LONG  path_Lock;
   };

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

   /* Fail from WB, give usage from CLI if command name not passed */
   if(argc == 0)  exit(RETURN_ERROR);
   if((argc != 2)||(*argv[1]=='?'))
      printf("Usage: which commandname\n"), exit(RETURN_OK);
   command = argv[1];

   /* 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);
      }

   if(Found)  printf("%s\n",sbuf);
   else  printf("%s Not Found\n",command);

   /* Re-enable volume requesters */
   proc->pr_WindowPtr = oldWindowPtr;
   /* We wouldn't have got here if we hadn't allocated this */
   FreeMem(fib, sizeof(struct FileInfoBlock));

   /* Return warning if not found */
   exit(Found ? RETURN_OK : RETURN_WARN);
   }


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);
   }

strlen(s)
char *s;
   {
   int i = 0;
   while(*s++) i++;
   return(i);
   }


strcpy(to,from)
char *to, *from;
   {
   do
      {
      *to++ = *from;
      }
   while(*from++);
   }

/* end */
-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Carolyn Scheppner -- CATS   >>Commodore Amiga Technical Support<<
                     UUCP  ...{allegra,ihnp4,rutgers}!cbmvax!carolyn 
                     PHONE 215-431-9180
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=