[comp.sources.amiga] defdisk--redefines the default system disk.

ahh@j.cc.purdue.edu (Brent L. Woods) (02/28/88)

Program Name:  defdisk
Submitted By:  Jim Levie   REMTECH Inc  Huntsville, Al 
Summary:  Redefines the default system disk.
Poster Boy:  Brent Woods  (ahh@j.cc.purdue.edu)
Tested.

NOTES:



Brent Woods, Co-Moderator, comp.{sources,binaries}.amiga

USENET:  ...!j.cc.purdue.edu!ahh     ARPANET:  ahh@j.cc.purdue.edu
BITNET:  PODUM@PURCCVM               PHONE:  +1 (317) 743-8421
USNAIL:  320 Brown St., #406  /  West Lafayette, IN  47906

================================================================

#	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:
#	author
#	defdisk.use
#	defdisk.c
# This archive created: Sun Feb 28 00:45:12 1988
# By:	Brent L. Woods (Co-Moderators Unlimited.)
cat << \SHAR_EOF > author

Anyway, here is 'defdisk', a program to redefine the default system
disk.  I have provided source, useage, and executable.

 =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
 Jim Levie   REMTECH Inc  Huntsville, Al 
 The opinions expressed above are just that.
 Ph.    (205) 536-8581               email: uunet!ingr!b11!jim

SHAR_EOF
cat << \SHAR_EOF > defdisk.use
  
   DEFDISK.C
  
   A program to make a specified disk/directory the default system disk.
   It accomplishes this by resetting the DOS library structures to point
   to the new path.  Put defdisk on your Workbench disk or hard disk somewhere,
   load up your ram: disk or hard disk and:
  
  		1> defdisk dh0:
  		      or
  		1> defdisk dh0:bin
  
   Woila! the standard workbench assignments are now pointed at the hard
   disk (SYS, C, L, S, DEVS, LIBS, FONTS).  The advantage to me in using this
   is that I don't have to load the AmigaDOS assign program 7 times to
   point the system at the hard disk.  I have the following two lines at the
   beginning of my startup-sequence for the Amiga 2090 disk controller:
  
                binddrivers
                dh0:system/defdisk dh0:
  
   One final note, be sure that there is a directory for each of the assigns
   on the target disk (C, L, S, DEVS, LIBS, FONTS).
  
   Author: J. K. Levie
 

SHAR_EOF
cat << \SHAR_EOF > defdisk.c
/*
 * DEFDISK.C
 *
 * A program to make a specified disk/directory the default system disk.
 * It accomplishes this by resetting the DOS library structures to point
 * to the new path. To use this program you will need to compile it as
 * follows:
 *		1> cc defdisk
 *		1> ln defdisk.o -lc
 *
 * Real simple.  I used AZTEC C v3.40a, but I think that 3.30c or later would
 * also work.  It should be possible to compile & build it under LATTICE as
 * well, though I haven't tried.  Once the program is built, put it on your
 * Workbench disk or hard disk somewhere, load up your ram: disk or hard disk
 * and:
 *		1> defdisk dh0:
 *		      or
 *		1> defdisk dh0:bin
 *
 * Woila! the standard workbench assignments are now pointed at the hard
 * disk (SYS, C, L, S, DEVS, LIBS, FONTS).  The advantage to me in using this
 * is that I don't have to load the AmigaDOS assign program 7 times to
 * point the system at the hard disk.  I have the following two lines at the
 * beginning of my startup-sequence for the Amiga 2090 disk controller:
 *
 *              binddrivers
 *              dh0:system/defdisk dh0:
 *
 * One final note, be sure that there is a directory for each of the assigns
 * on the target disk (C, L, S, DEVS, LIBS, FONTS).
 *
 * Author: J. K. Levie
 *
 * Version 1.1 24-Jan-1988 - minor corrections to documentation
 * Version 1.0 20-Mar-1986
 */

#include <stdio.h>
#include <functions.h>
#include <exec/types.h>
#include <exec/exec.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>

extern void BtoCSTR();			/* forward ... */
extern void CtoBSTR();			/* ... references */

struct DevInfo
{
   BPTR di_Next;
   LONG di_Type;
   APTR di_Task;
   BPTR di_Lock;
   BSTR di_Handler;
   LONG di_StackSize;
   LONG di_Priority;
   LONG di_Startup;
   BPTR di_SegList;
   BPTR di_GlobVec;
   BSTR di_Name;
};
struct DosLibrary *dosBase;
struct RootNode *root;
struct DosInfo *info;
struct DevInfo *dev_head, *dev_ele;
struct Lock *lock;

/*
 * Define the logical to physical table.
 */
struct ASSIGNS
{
   char *log_name;			/* logical name to look for */
   char *phy_name;			/* physical name to assign */
   short success;			/* result 0=> failure, 1=> success */
};
struct ASSIGNS assigns[]=
{
   "SYS",   NULL,    0,
   "C",     "c",     0,
   "DEVS",  "devs",  0,
   "LIBS",  "libs",  0,
   "L",     "l",     0,
   "S",     "s",     0,
   "FONTS", "fonts", 0,
   NULL,    NULL
};




main(argc, argv)
int argc;
char *argv[];
{
   char *ptr, *path;
   register int len, n;

   /*
    * See if we can get a lock on the new C directory, if we can't
    * we won't even attempt to do the assigns.
    */
   path=argv[1];
   if(argc!=2 || *path=='?')		/* correct arg cnt?  useage? */
   {
      printf("Usage: defdisk dev:[dir.../dir]\n");
      exit(20);
   }
   /*
    * Now we are ready to fill in the logical name table.  Handle the 
    * Sys logical first since it will not have anything appended.  Then
    * see if we will need to append a path separator to the user
    * specified path.  We stop appending when we see the "T" logical.
    */
   assigns[0].phy_name=path;		/* Sys is special case */
   len=1+strlen(path);			/* find length of physical name */
   if(path[strlen(path)-1]!=':')	/* path specify the root of volume? */
   {
      len++;				/* room for path separator */
      ptr=AllocMem((long)(len+1), MEMF_PUBLIC);
      strcpy(ptr, path);		/* put user specified path in ... */
      strcat(ptr, "/");			/* ... and path separator */
      path=ptr;				/* point to new path */
   }
   /*
    * Now fill in the rest of the table.  Allocate memory for the
    * complete physical name and the directory specified in the table
    * entry.  Then concatenate the path and the directory and set up
    * the new pointer.
    */
   for(n=1; assigns[n].log_name[0]!=NULL; n++)
   {
      ptr=AllocMem((long)(len+strlen(assigns[n].log_name)), MEMF_PUBLIC);
      strcpy(ptr, path);
      strcat(ptr, assigns[n].phy_name);
      assigns[n].phy_name=ptr;
   }
   /*
    * Convert the logical names to B strings.
    */
   for(n=0; assigns[n].log_name!=NULL; n++) CtoBSTR(assigns[n].log_name);

   /*
    * Now for a little paranoia.  I don't want to point the system
    * somewhere that doesn't contain a C directory.
    */
   lock=Lock(assigns[1].phy_name, SHARED_LOCK);
   if(lock==NULL)			/* are we sane? */
   {
      /*
       * NO!  Makes no sense to set the system volume to something that
       * doesn't contain a c directory.
       */
      printf("defdisk-F-%s does not contain a C directory\n",
              assigns[1].phy_name);
      exit(20);
   }
   UnLock(lock);			/* Okay unlock the c directory */

   /*
    * Now open the resources we will need.
    */
   dosBase=(struct DosLibrary *)OpenLibrary(DOSNAME);
   root=(struct RootNode *)dosBase->dl_Root;
   info=(struct DosInfo *)BADDR(root->rn_Info);
   dev_head=(struct DevInfo *)BADDR(info->di_DevInfo);

   Forbid();				/* only us & nobody else */
   /*
    * Walk the DevInfo list looking for the locigal names to change.  For
    * each entry in the list we can check each of the entries in the
    * logical name table.  As we find them reset each logical to point
    * to the new system volume.
    */
   for(dev_ele=dev_head; dev_ele->di_Next;
       dev_ele=(struct DevInfo *)BADDR(dev_ele->di_Next))
   {
      /*
       * Check against each of the logical names in the table.
       */
      for(n=0; assigns[n].log_name!=NULL; n++)
      {
         /*
          * See if this one matches.
          */
         if(Bstrcmp(BADDR(dev_ele->di_Name), assigns[n].log_name))
         {
            /*
             * Name matches, is it the correct type?
             */
            if(dev_ele->di_Type!=DLT_DIRECTORY)
            {
               /*
                * No put logical name back to a C string and error out.
                */
               BtoCSTR(assigns[n].log_name);
               printf("defdisk-F-cannot reassign %s\n", assigns[n].log_name);
               goto done;
            }
            /*
             * Okay get a lock on the physical name for this logical.
             */
            lock=Lock(assigns[n].phy_name, SHARED_LOCK);
            if(!lock)
            {
               /*
                * Whoops, failed somehow, tell the world about it.
                */
               printf("defdisk-F-cannot get a lock on %s\n", assigns[n].phy_name);
               goto done;
            }
            /*
             * Time to clean up the old logical and point it to our
             * physical name.
             */
            UnLock(dev_ele->di_Lock);
            dev_ele->di_Lock=(BPTR)lock;
            dev_ele->di_Task=(APTR)(DeviceProc(assigns[n].phy_name));
            assigns[n].success=1;	/* flag that we did this one */
         }
      }
   }
done:
   Permit();				/* release the system */
   CloseLibrary(dosBase);		/* clean up */
   
   /*
    * Now check to see that all of the assignments were made.
    */
   for(n=0; assigns[n].log_name!=NULL; n++)
   {
      if(assigns[n].success!=1) printf("defdisk-F-assignments failed\n");
   }
}



/*
 * Bstrcmp(a, b)
 *
 * Compare two btrings for equality, case insensitive.
 */
Bstrcmp(a, b)
char *a, *b;
{
   int len=(int)*a;			/* first char of B string is length */

   for(len++; len!=0; len--)		/* compare at most all */
   {
      if((*a&~0x20)!=(*b&~0x20)) return(0); /* quit if not equal */
      a++;				/* point both ... */
      b++;				/* ... at next character */
   }
   return(1);				/* they matched */
}



/*
 * BtoCSTR(bstr)
 *
 * Convert (in place) a B string to a C string.
 */
void BtoCSTR(bstr)
char *bstr;
{
   register int i;
   register UBYTE *bptr, *cptr;

   cptr=(UBYTE *)bstr;			/* point to input B string */
   bptr=cptr;				/* output starts at B string len spot */
   for(i=*bptr++; i!=0; i--) *cptr++=*bptr++; /* left shift the string */
   *cptr='\0';				/* terminate it */
}



/*
 * CtoBSTR(cstr)
 *
 * Convert (in place) a C string to a B string.
 */
void CtoBSTR(cstr)
char *cstr;
{
   register int i, len;
   register UBYTE *cptr, *bptr;

   cptr=(UBYTE *)cstr;			/* pointer to input */
   for(i=0; *cptr; i++, cptr++);	/* count & push pointer to input */
   len=i;				/* save count */
   bptr=cptr;				/* point at end of input */
   cptr--;				/* back up over null */
   while(i--) *bptr--=*cptr--;		/* right the string */
   *bptr=(UBYTE)len;			/* stuff in the string length */
}

SHAR_EOF
#	End of shell archive
exit 0