ahh@j.cc.purdue.edu (Brent L. Woods) (11/15/87)
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file
# 3. Execute the file with /bin/sh (not csh) to create the files:
#
# defdisk.c
#
#
if test -f 'defdisk.c'
then
echo shar: will not over-write existing file "'defdisk.c'"
else
echo extracting "'defdisk.c'"
sed 's/^X//' >defdisk.c <<'SHAR_EOF'
X/*
X * DEFDISK.C
X *
X * A program to make a specified disk/directory the default system disk.
X * It accomplishes this by resetting the DOS library structures to point
X * to the new path. To use this program you will need to compile it as
X * follows:
X * 1> cc defdisk
X * 1> ln defdisk.o -lc
X *
X * Real simple. I used AZTEC C v3.40a, but I think that 3.30c or later would
X * also work. It should be possible to compile & build it under LATTICE as
X * well, though I haven't tried. Once the program is built, put it on your
X * Workbench boot disk somewhere, load up your ram: disk or hard disk and
X *
X * 1> defdisk dh0:
X * or
X * 1> defdisk dh0:bin
X *
X * Woila! the standard workbench assignments are now pointed at the hard
X * disk. (SYS, C, L, DEVS, LIBS, FONTS) The advantage to me in using this
X * is that I don't have to load the Amiga DOS assign program 6 times to
X * point the system at the hard disk.
X *
X * Author: J. K. Levie
X *
X * Version 1.0 31-Mar-1987
X */
X
X#include <stdio.h>
X#include <functions.h>
X#include <exec/types.h>
X#include <exec/exec.h>
X#include <libraries/dos.h>
X#include <libraries/dosextens.h>
X
Xextern void BtoCSTR(); /* forward ... */
Xextern void CtoBSTR(); /* ... references */
X
Xstruct DevInfo
X{
X BPTR di_Next;
X LONG di_Type;
X APTR di_Task;
X BPTR di_Lock;
X BSTR di_Handler;
X LONG di_StackSize;
X LONG di_Priority;
X LONG di_Startup;
X BPTR di_SegList;
X BPTR di_GlobVec;
X BSTR di_Name;
X};
Xstruct DosLibrary *dosBase;
Xstruct RootNode *root;
Xstruct DosInfo *info;
Xstruct DevInfo *dev_head, *dev_ele;
Xstruct Lock *lock;
X
X/*
X * Define the logical to physical table.
X */
Xstruct ASSIGNS
X{
X char *log_name; /* logical name to look for */
X char *phy_name; /* physical name to assign */
X short success; /* result 0=> failure, 1=> success */
X};
Xstruct ASSIGNS assigns[]=
X{
X "SYS", NULL, 0,
X "C", "c", 0,
X "DEVS", "devs", 0,
X "LIBS", "libs", 0,
X "L", "l", 0,
X "S", "s", 0,
X "FONTS", "fonts", 0,
X NULL, NULL
X};
X
X
X
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X char *ptr, *path;
X register int len, n;
X
X /*
X * See if we can get a lock on the new C directory, if we can't
X * we won't even attempt to do the assigns.
X */
X path=argv[1];
X if(argc!=2 || *path=='?') /* correct arg cnt? useage? */
X {
X printf("Usage: defdisk dev:[dir.../dir]\n");
X exit(20);
X }
X /*
X * Now we are ready to fill in the logical name table. Handle the
X * Sys logical first since it will not have anything appended. Then
X * see if we will need to append a path separator to the user
X * specified path. We stop appending when we see the "T" logical.
X */
X assigns[0].phy_name=path; /* Sys is special case */
X len=1+strlen(path); /* find length of physical name */
X if(path[strlen(path)-1]!=':') /* path specify the root of volume? */
X {
X len++; /* room for path separator */
X ptr=AllocMem((long)(len+1), MEMF_PUBLIC);
X strcpy(ptr, path); /* put user specified path in ... */
X strcat(ptr, "/"); /* ... and path separator */
X path=ptr; /* point to new path */
X }
X /*
X * Now fill in the rest of the table. Allocate memory for the
X * complete physical name and the directory specified in the table
X * entry. Then concatenate the path and the directory and set up
X * the new pointer.
X */
X for(n=1; assigns[n].log_name[0]!=NULL; n++)
X {
X ptr=AllocMem((long)(len+strlen(assigns[n].log_name)), MEMF_PUBLIC);
X strcpy(ptr, path);
X strcat(ptr, assigns[n].phy_name);
X assigns[n].phy_name=ptr;
X }
X /*
X * Convert the logical names to B strings.
X */
X for(n=0; assigns[n].log_name!=NULL; n++) CtoBSTR(assigns[n].log_name);
X
X /*
X * Now for a little paranoia. I don't want to point the system
X * somewhere that doesn't contain a C directory.
X */
X lock=Lock(assigns[1].phy_name, SHARED_LOCK);
X if(lock==NULL) /* are we sane? */
X {
X /*
X * NO! Makes no sense to set the system volume to something that
X * doesn't contain a c directory.
X */
X printf("defdisk-F-%s does not contain a C directory\n",
X assigns[1].phy_name);
X exit(20);
X }
X UnLock(lock); /* Okay unlock the c directory */
X
X /*
X * Now open the resources we will need.
X */
X dosBase=(struct DosLibrary *)OpenLibrary(DOSNAME);
X root=(struct RootNode *)dosBase->dl_Root;
X info=(struct DosInfo *)BADDR(root->rn_Info);
X dev_head=(struct DevInfo *)BADDR(info->di_DevInfo);
X
X Forbid(); /* only us & nobody else */
X /*
X * Walk the DevInfo list looking for the locigal names to change. For
X * each entry in the list we can check each of the entries in the
X * logical name table. As we find them reset each logical to point
X * to the new system volume.
X */
X for(dev_ele=dev_head; dev_ele->di_Next;
X dev_ele=(struct DevInfo *)BADDR(dev_ele->di_Next))
X {
X /*
X * Check against each of the logical names in the table.
X */
X for(n=0; assigns[n].log_name!=NULL; n++)
X {
X /*
X * See if this one matches.
X */
X if(Bstrcmp(BADDR(dev_ele->di_Name), assigns[n].log_name))
X {
X /*
X * Name matches, is it the correct type?
X */
X if(dev_ele->di_Type!=DLT_DIRECTORY)
X {
X /*
X * No put logical name back to a C string and error out.
X */
X BtoCSTR(assigns[n].log_name);
X printf("defdisk-F-cannot reassign %s\n", assigns[n].log_name);
X goto done;
X }
X /*
X * Okay get a lock on the physical name for this logical.
X */
X lock=Lock(assigns[n].phy_name, SHARED_LOCK);
X if(!lock)
X {
X /*
X * Whoops, failed somehow, tell the world about it.
X */
X printf("defdisk-F-cannot get a lock on %s\n", assigns[n].phy_name);
X goto done;
X }
X /*
X * Time to clean up the old logical and point it to our
X * physical name.
X */
X UnLock(dev_ele->di_Lock);
X dev_ele->di_Lock=(BPTR)lock;
X dev_ele->di_Task=(APTR)(DeviceProc(assigns[n].phy_name));
X assigns[n].success=1; /* flag that we did this one */
X }
X }
X }
Xdone:
X Permit(); /* release the system */
X CloseLibrary(dosBase); /* clean up */
X
X /*
X * Now check to see that all of the assignments were made.
X */
X for(n=0; assigns[n].log_name!=NULL; n++)
X {
X if(assigns[n].success!=1) printf("defdisk-F-assignments failed\n");
X }
X}
X
X
X
X/*
X * Bstrcmp(a, b)
X *
X * Compare two btrings for equality, case insensitive.
X */
XBstrcmp(a, b)
Xchar *a, *b;
X{
X int len=(int)*a; /* first char of B string is length */
X
X for(len++; len!=0; len--) /* compare at most all */
X {
X if((*a&~0x20)!=(*b&~0x20)) return(0); /* quit if not equal */
X a++; /* point both ... */
X b++; /* ... at next character */
X }
X return(1); /* they matched */
X}
X
X
X
X/*
X * BtoCSTR(bstr)
X *
X * Convert (in place) a B string to a C string.
X */
Xvoid BtoCSTR(bstr)
Xchar *bstr;
X{
X register int i;
X register UBYTE *bptr, *cptr;
X
X cptr=(UBYTE *)bstr; /* point to input B string */
X bptr=cptr; /* output starts at B string len spot */
X for(i=*bptr++; i!=0; i--) *cptr++=*bptr++; /* left shift the string */
X *cptr='\0'; /* terminate it */
X}
X
X
X
X/*
X * CtoBSTR(cstr)
X *
X * Convert (in place) a C string to a B string.
X */
Xvoid CtoBSTR(cstr)
Xchar *cstr;
X{
X register int i, len;
X register UBYTE *cptr, *bptr;
X
X cptr=(UBYTE *)cstr; /* pointer to input */
X for(i=0; *cptr; i++, cptr++); /* count & push pointer to input */
X len=i; /* save count */
X bptr=cptr; /* point at end of input */
X cptr--; /* back up over null */
X while(i--) *bptr--=*cptr--; /* right the string */
X *bptr=(UBYTE)len; /* stuff in the string length */
X}
X
SHAR_EOF
if test 8046 -ne "`wc -c < 'defdisk.c'`"
then
echo shar: error transmitting "'defdisk.c'" '(should have been 8046 characters)'
fi
fi
#
# end of shell archive
#
exit 0
=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
Jim Levie REMTECH Inc Huntsville, Al
The opinions expressed above are just that.
Ph. (205) 536-8581 email: uunet!ingr!b11!jim