home *** CD-ROM | disk | FTP | other *** search
- /* This program will reassign all the standard assigned names to be the proper
- usual directories on a new disk. The names are:
-
- C: DEVS: FONTS: L: LIBS: S: and SYS:
-
- This program will assign SYS: to the given volume and each of the other
- names to the directory of SYS: with that same name (C: = SYS:c etc).
-
- It's called MoveSys. Hard disk users can put it in their Startup-Sequence
- to ease the transition from the floppy boot disk (or RAD:) to the hard
- disk. Non-hard-disk users can use it to switch from one bootable
- application disk to another without getting "please insert volume
- Workbench 1.3" or the like all the time. For Aztec C. If you want
- flexibility, customize the source code. Usage:
-
- MoveSys name: ; where name is a volume name or drive name
-
- You can even MoveSys to a directory, if the appropriate subdirectories
- are present there. Like, MoveSys dh0:Workbench or something.
-
- By Paul Kienitz, 12/10/88. Public domain. For Aztec C only; do not
- compile with the +m flag. The result is "pure" and can be made resident.
-
- 1/17/89: Ooops! Had to add DosAllocate, because unassigning a node I
- created without that could cause bad craziness. I should put DosAllocate
- into AssignDev, though it's probably not needed if I fix the bug in
- detecting whether a node it's deleting is one it made, which I think
- somebody already did.
-
- 4/14/89: Stripped down internally (no stdio, for instance) to reduce size
- and make "pure". Added IoErr code return.
-
- ADD LATER: arguments after volume name to be exceptions or additions to
- the built-in list of assignments.
- ability to run from workbench, using workbench message and
- tooltypes.
- make it not reassign SYS: when locks fail on dirs?
- */
-
-
-
- #include <exec/types.h>
- #include <exec/nodes.h>
- #include <exec/lists.h>
- #include <exec/memory.h>
- #include <exec/ports.h>
- #include <exec/libraries.h>
- #include <exec/devices.h>
- #include <exec/io.h>
- #include <libraries/dosextens.h>
- #include <libraries/filehandler.h>
- #ifdef AZTEC_C
- #include <functions.h>
- #endif
- #include <Paul.h> /* defines null, adr, str, bool, bip, gbip, AllocXX ... */
-
-
- typedef struct DeviceNode den;
- typedef BPTR lock;
-
- #define HowMany 6
- char *dames[HowMany] = {"C", "DEVS", "FONTS", "L", "LIBS", "S"};
- char *dears[HowMany] = {"SYS:c", "SYS:devs", "SYS:fonts", "SYS:l",
- "SYS:libs", "SYS:s"};
- /* SYS: gets assigned to the volume named in the command line argument (or
- workbench message argument someday), and then each name in dames gets
- assigned to the corresponding directory name in dears. You can change
- dears to e.g. assign C: to RAM:C or whatever, or add more names to each,
- incrementing HowMany to match. */
-
-
- /* the only global variables are unchanging, e.g. library bases */
-
- extern struct DosLibrary *DOSBase;
- struct DosInfo *infoo; /* contains the root of the dev list */
-
-
-
- #undef put /* defined as fputs(stdout, S) in Paul.h */
-
- void put(s) str s;
- { long o = Output();
- if (o) Write(o, s, (long) strlen(s));
- }
-
-
-
- /* Allocate a block of memory the way the Dos does, with size (rounded up to
- the nearest multiple of four) in the longword below the address returned */
-
- adr DosAllocate(size) int size;
- {
- long longlen = (size + 7) & ~3L;
- long *dosalloc = AllocPZ(longlen);
- if (!dosalloc) return (null);
- *dosalloc = longlen;
- return (dosalloc + 1);
- }
-
-
-
- void DosFree(a) long *a;
- { FreeMem(a - 1, a[-1]);
- }
-
-
-
- den *MakeNewAssignNode(name) str name; /* do this within a Forbid */
- {
- den *foo = DosAllocate(sizeof(den));
- int len = strlen(name);
- str nom;
- if (!foo) return (null);
- if (!(nom = DosAllocate(len + 2))) { /* room for length byte AND */
- DosFree(foo); /* nul, like existing nodes */
- return (null);
- }
- foo->dn_Name = (long) nom >> 2;
- foo->dn_Type = 1L;
- nom[0] = len;
- strcpy(nom + 1, name); /* leave the nul on the end */
- foo->dn_Next = infoo->di_DevInfo; /* put new node at top of list */
- infoo->di_DevInfo = (long) foo >> 2;
- return (foo);
- }
-
-
-
- bool Match(s, b) str s; BSTR b;
- {
- str bee = bip(char, b);
- short len = strlen(s);
- short i;
- if (bee[0] != len) return (false);
- for (i = 0; i < len; i++)
- if (toupper(s[i]) != toupper(bee[i + 1]))
- return (false);
- return (true);
- }
-
-
-
- den *FindDNode(name) str name;
- {
- den *goob;
- for (goob = gbip(infoo->di_DevInfo); goob; goob = gbip(goob->dn_Next))
- if (goob->dn_Type == 1 && Match(name, goob->dn_Name))
- return (goob);
- return (null);
- }
-
-
-
- bool ReAssign(name, lok) str name; lock lok;
- {
- den *where;
- lock old;
- Forbid();
- where = FindDNode(name);
- if (!where) where = MakeNewAssignNode(name);
- if (!where) {
- Permit();
- put("Couldn't find or create device node for \"");
- put(name);
- put("\".\nOut of memory, I guess.\n");
- return (false);
- }
- old = where->dn_Lock;
- where->dn_Lock = lok;
- where->dn_Task = bip(struct FileLock, lok)->fl_Task;
- Permit();
- UnLock(old);
- return (true);
- }
-
-
-
-
- long _main(alen, aptr) long alen; str aptr;
- {
- lock syl, L;
- short f;
- long hair = 0, turn = 0;
- struct Process *me = (adr) FindTask(null);
-
- infoo = bip(struct DosInfo,
- ((struct RootNode *) DOSBase->dl_Root) ->rn_Info);
- while (alen && aptr[alen - 1] <= ' ') aptr[--alen] = 0;
- if (*aptr == '"') {
- if (aptr[alen - 1] == '"') aptr[--alen] = 0;
- aptr++;
- }
- if (alen && !(alen == 1 && *aptr == '?'))
- syl = (BPTR) RLock(aptr);
- else {
- put(
- "You must name a drive, volume, or directory to move SYS: to.\n");
- me->pr_Result2 = ERROR_LINE_TOO_LONG;
- return (10L);
- }
- if (!syl) {
- hair = me->pr_Result2; /* set by Lock */
- put("MoveSys couldn't find drive/volume \"");
- put(aptr);
- put("\".\n");
- me->pr_Result2 = hair;
- return (10L);
- }
- if (!ReAssign("SYS", syl)) {
- turn = 10;
- hair = ERROR_NO_FREE_STORE;
- } else for (f = 0; f < HowMany; f++) {
- L = (BPTR) RLock(dears[f]);
- if (!L) {
- turn = 5;
- hair = me->pr_Result2; /* set by Lock */
- put("MoveSys couldn't find directory \"");
- put(dears[f]);
- put("\" (SYS: = \"");
- put(aptr);
- put("\").\n");
- } else
- if (!ReAssign(dames[f], L)) {
- turn = 10;
- hair = ERROR_NO_FREE_STORE;
- break;
- }
- }
- me->pr_Result2 = hair;
- return (turn);
- }
-