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