[comp.sources.amiga] v89i079: bindnames - intelligent logical name assignment

page@swan.ulowell.edu (Bob Page) (03/17/89)

Submitted-by: cbmvax!daveh (Dave Haynie)
Posting-number: Volume 89, Issue 79
Archive-name: dos/bindnames.1

Here's a program I whipped up to more intelligently handle logical
name assignments in a Startup-Sequence.  It reads all the files from
the "SYS:Names" directory, each of which has one or more lines logical
to physical assignments.  It sorts them according to dependencies,
then makes all the name assignments.  This managed to get every single
"Assign" command out of my Startup-Sequence, and it makes adding new
names a simple matter of dropping a new "names" file into SYS:Names.
This compiles under Lattice C V5.02 (binary included), and is fully
public domain.

[uuencoded executable included.  ..Bob]

#	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:
#	BindNames.c
#	BindNames.uu
#	Makefile
#	ReadMe
# This archive created: Thu Mar 16 15:43:50 1989
cat << \SHAR_EOF > BindNames.c
/* ====================================================================== */

/*	BindNames.c by Dave Haynie

	This is a simple utility to remove some of the drudgery of program
	installation.  Instead of having to edit a Startup-Sequence for
	every logical name that must be used by a new program, this lets
	names be block-allocated.  The BindNames program looks for files
	in the SYS:Names directory.  Each of these files contains any number
	of lines of the form:
	
		Name:	Path
	
	Where "Name" is the logical name we're assigning, "Path" is the
	path name we're making equivalent.  
*/

#include <exec/types.h>
#include <exec/memory.h>	
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <proto/all.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>

/* ====================================================================== */

/* Macros */

#define CADDR(x)	((BPTR)(((ULONG)x)>>2))
#define NAMEDIR		"SYS:Names"
#define CopyStr(s)	strcpy(malloc(strlen(s)+1),s)
#define FreeStr(s)	free(s)

/* The "-rr" option doesn't like NewList, bit it's real simple.  WHEN can
   we have inline functions.... */

#define NewList(l)	{ (l)->lh_Head     = (struct Node *)&(l)->lh_Tail; \
			  (l)->lh_TailPred = (struct Node *)&(l)->lh_Head; \
			  (l)->lh_Tail     = NULL;	    \
			}

/* ====================================================================== */

/* Global variables */

extern struct DosLibrary *DosBase = NULL;
struct DosInfo *info = NULL;
struct DeviceList *lastdev;
BPTR namelock = NULL;
BOOL verbose = FALSE;
BOOL test = FALSE;
struct FileInfoBlock *fileinfo = NULL;

/* ====================================================================== */

/* This function makes a BCPL string into a C style string. */

char *b2cstr(char *cstr, BPTR bptr) {
   char *ptr = (char *)BADDR(bptr);
   strncpy(cstr,ptr+1,*ptr);
   cstr[*ptr] = '\0';
   return cstr;   	
}

/* This function allocates things in a DOS friendly way. */

void *DOSAlloc(LONG size) {
   LONG *ptr = AllocMem(size+4,MEMF_PUBLIC|MEMF_CLEAR);
   *ptr = size+4;
   return ptr+1;
}

/* This function frees memory in a DOS friendly way. */

void DOSFree(void *mem) {
   LONG *ptr = (LONG *)mem;
   FreeMem(ptr-1,*(ptr-1));
}

/* ====================================================================== */

/* Here we manage name trees.  Name nodes are built from the device list
   first.  All primary nodes based on the device list have NULL paths,
   indicating that they are primary and thus, don't need to be recreated.
   Subsequent nodes are added to the node that they depend on.  If a node 
   is encountered that doesn't have a parent listed yet, it will be place
   on a temporary node list. */

struct NameNode {
   struct Node node;
   struct NameNode *parent;
   struct List children;
   char *path;
};

struct List Names;
struct NameNode *lostnodes;

/* This function creates a name node, allocating whatever memory is 
   needed. */

struct NameNode *MakeNode(char *name, char *path) {
   struct NameNode *nn;
   
   if (!(nn = calloc(1,sizeof(struct NameNode)))) return NULL;
   if (name) nn->node.ln_Name = CopyStr(name);
   NewList(&nn->children);
   if (path) nn->path = CopyStr(path);
   return nn;
}

/* This function finds a particular name in the Names data base, via a 
   depth-first search.  If it finds the name, it returns that node, 
   otherwise, it returns NULL. */

struct NameNode *FindNode(struct List *lst,char *name) {
   struct Node *n;
   struct NameNode *nn;
   
   for (n = lst->lh_Head; n->ln_Succ; n = n->ln_Succ) {
      if (!(stricmp(name,n->ln_Name))) return (struct NameNode *)n;
      if (nn = FindNode(&((struct NameNode *)n)->children,name)) return nn;
   }
   return NULL;
}

/* This is the node assignment routine.  It accepts a node name and a path
   for assignment.  It handles all the proper node creations to add that
   information to the node data base. */
   
void DefNode(char *name, char *path) {
   struct NameNode *nn, *parent;
   char pardev[64];
   int i;
   
   for (i = 0; path[i] != ':' && i < 63; ++i) pardev[i] = path[i];
   pardev[i] = '\0';
   if (!(parent = FindNode(&Names,pardev))) {
      AddHead(&lostnodes->children,(struct Node *)(parent=MakeNode(pardev,NULL)));
      parent->parent = lostnodes;
   }
   
   if (!(nn = FindNode(&Names,name)))
      nn = MakeNode(name,path);
   else {
      Remove((struct Node *)nn);
      if (nn->path) FreeStr(nn->path);
      nn->path = CopyStr(path);
   }

   AddHead(&parent->children,(struct Node *)nn);
}  

/* This function reads in the individual file's data and builds entries
   in the name list based on that data. */
   
void AddFIB(struct FileInfoBlock *fib,char *name) {  
   BPTR file;
   char *buf,*com,*path;
      
   if (buf = AllocMem(fib->fib_Size+1,0L)) {
      if (file = Open(name,MODE_OLDFILE)) {
         Read(file,buf,fib->fib_Size);
         buf[fib->fib_Size] = '\0';
         com = strtok(strupr(buf)," :\t\n");
         path = strtok(NULL," \t\n");
         while (com && path) {
            DefNode(com,path);
            com = strtok(NULL," :\t\n");
            path = strtok(NULL," \t\n");
         }
         Close(file);
      }
      FreeMem(buf,fib->fib_Size+1);
   }
}

/* ====================================================================== */

/* This function opens up the stuff we need. */
   	
BOOL DoInits(void) {
   if (!(DosBase = (struct DosLibrary *)OpenLibrary("dos.library",33L)))
      return FALSE;
   if (!(info = (struct DosInfo *)BADDR(((struct RootNode *)DosBase->dl_Root)->rn_Info)))
      return FALSE;
   if (!(fileinfo = AllocMem(sizeof(struct FileInfoBlock),MEMF_PUBLIC)))
      return FALSE;
	      
   return TRUE;
}

/* This function cleans up after DoInits. */

void CloseUp(int code, char *str) {
   if (str) printf("Error: %s\n",str);
   if (fileinfo) FreeMem(fileinfo,sizeof(struct FileInfoBlock));
   if (namelock) UnLock(namelock);
   if (DosBase) CloseLibrary((struct Library *)DosBase);
   exit(code);   
}

/* ====================================================================== */

/* This function finds a directory node.  It has the side effect of
   setting "lastdev" to the last device in the global device list. */

struct DeviceList *AllocDirNode(char *name) {
   struct DeviceList *dev, *newdev;
   char *str,old[64];

  /* Let's see if the assignment has already been made... */
   for (dev = (struct DeviceList *)BADDR(info->di_DevInfo); dev != NULL; 
        dev = (struct DeviceList *)BADDR(dev->dl_Next)) {
      lastdev = dev;
      if (dev->dl_Type != DLT_DIRECTORY) continue;
      b2cstr(old,dev->dl_Name);
      if (!stricmp(old,name)) return dev;
   }

  /* Create the new name structure */
   if (!(newdev=DOSAlloc(sizeof(struct DeviceList))) || !(str=DOSAlloc(32L))) {
      if (newdev) DOSFree(newdev);
      return NULL;
   }
   newdev->dl_Type = DLT_DIRECTORY;
   strcpy(str+1,name);
   str[0] = strlen(name);
   newdev->dl_Name = CADDR(str);
   return newdev;
}

/* This function does the "Assign" operation. */

BOOL Assign(char *name, char *path) {
   BPTR block;
   struct DeviceList *newdev;

  /* Let's verify that the path object is really there.  If not, try to make
     the thing. */
   if (!(block = Lock(path,SHARED_LOCK))) {
      if (!(block = CreateDir(path))) return FALSE;
      UnLock(block);
      if (!(block = Lock(path,SHARED_LOCK))) return FALSE;
   }

  /* Get a node for this assignment. */
   Forbid();
   newdev = AllocDirNode(name);

  /* Make the assignment */
   if (newdev->dl_Lock) {
      Permit();
      UnLock(newdev->dl_Lock);
      newdev->dl_Lock = block;
      newdev->dl_Task = ((struct FileLock *)BADDR(block))->fl_Task;
      return TRUE;
   }
   newdev->dl_Lock = block;
   newdev->dl_Task = ((struct FileLock *)BADDR(block))->fl_Task;

   /* Now link it into the device list. */
   newdev->dl_Next = lastdev->dl_Next;
   lastdev->dl_Next = CADDR(newdev);
   Permit();
   return TRUE;
}

/* This list takes in a node list, and performs assignments for all non-primary
   nodes in the list, as long as "inhibit" is FALSE. */

void AssignList(struct List *lst, int level, BOOL inhibit) {
   struct Node *n;
   struct NameNode *nn;
   
   for (n = lst->lh_Head; n->ln_Succ; n = n->ln_Succ) {
      nn = (struct NameNode *)n;
      if (nn->path) {
         if (!inhibit) Assign(nn->node.ln_Name,nn->path);
         if (verbose || inhibit)
	 printf("%*s%-15s%*s%s\2330m\n",level+1,"\23333m",nn->node.ln_Name,
                                       14-level,"\23332m",nn->path);
      }
      if (nn->children.lh_Head->ln_Succ) 
         AssignList(&nn->children,level+2,inhibit);
   }
}

/* ====================================================================== */

void main(int argc, char *argv[]) {
   char path[256];
   long i;
   struct NameNode *nn;
   struct DeviceList *dev;

   if (!DoInits()) CloseUp(5,NULL);

  /* Check the command line. */
   for (i = 1; i < argc; ++i)
      switch (toupper(argv[i][0])) {
         case 'S':
            Assign("SYS",argv[++i]);
            break;
         case 'V':
            verbose = TRUE;
            break;
         case 'T':
            test = TRUE;
            verbose = TRUE;
            break;
         case '?':
            printf("\2337mBindNames V1.0 by Dave Haynie\2330m\n\n");
            printf("Usage: %s [VERBOSE] [TEST] [SYSTEM drive]\n",argv[0]);
            CloseUp(0,NULL);
      }
      if (verbose) printf("\2337mBindNames V1.0 by Dave Haynie\2330m\n\n");
      
  /* Let's build the internal device list.  We know this list is going to be
     a flat list; everything is primary, and thus hung from the root list. */
   NewList(&Names);
   Forbid();
   for (dev = (struct DeviceList *)BADDR(info->di_DevInfo); dev != NULL; 
        dev = (struct DeviceList *)BADDR(dev->dl_Next)) {
      if (!(nn = MakeNode(strupr(b2cstr(path,dev->dl_Name)),NULL))) continue;
      AddHead(&Names,(struct Node *)nn);
   }
   Permit();
   
  /* I need to build the "lostnodes" node.  In order to avoid name collisions,
     I make the name of this node '\0'.  We never need to search for it by
     name... */

   AddTail(&Names,(struct Node *)(lostnodes = MakeNode("\0",NULL)));
    
  /* Here I build the list of required assignments by walking through the
     SYS:Names directory, and reading each file. */
  
    if ((namelock = Lock(NAMEDIR,SHARED_LOCK))) {
      Examine(namelock,fileinfo);
      while (ExNext(namelock,fileinfo) || IoErr() != ERROR_NO_MORE_ENTRIES) {
         if (fileinfo->fib_DirEntryType > 0) continue;
         strcat(strcat(strcpy(path,NAMEDIR),"/"),fileinfo->fib_FileName);
         AddFIB(fileinfo,path);
      }
   }

  /* Now I've got everything; let's see what's actually here. */
  
   Remove((struct Node *)lostnodes);

   if (verbose) printf("Assigned Names:\n");
   AssignList(&Names,1,test);
   if (lostnodes->children.lh_Head->ln_Succ) {
      if (verbose) printf("\n");
      printf("Warning: Can't Resolve Names:\n");
      AssignList(&lostnodes->children,1,TRUE);
   }
   CloseUp(0,NULL);
}
SHAR_EOF
cat << \SHAR_EOF > BindNames.uu

begin 644 BindNames
M```#\P`````````#``````````(```@@`````````64```/I```(("1()`!)V
M^0````!'^0```PAR`"`\````HV`")L%1R/_\+'@`!"E.`T`I3P-(0JP#1"9N`
M`11P`"(\```P`$ZN_LXI:P"8`SQ*JP"L9P``<"`/D*\`!`:`````@"E``PQA/
M``$N(&L`K-'(T<@B:``0T\G3R2`"<@`2&2E)`U#0@5*`0F=2@`)`__Z?P%6`_
M0G<(`"`"4X#4@1^R```@`%."4<C_]A^\`"`@`%."'[$@`"``4<K_^")/+PE@Z
M``!X*6L`.@,,<']2@-&L`PQA``#"0>L`7$ZN_H!!ZP!<3J[^C"E``T0O`"1`8
M("H`)&<2+&P%A"!`(B@``"E!`SQ.KO^"(BH`(&<:)#P```/M3J[_XBE``TQG1
M"N6(($`G:``(`*0@;`-$+PA(;`,((&@`)"EH``0#4$ZZ"(1.NAX@<`!@!"`OL
M``0O`"`L`S1G!"!`3I!.NAX`+'@`!")L!81.KOYB3KH(6DJL`T1G&B(L`TQG,
M!$ZN_]PL>``$3J[_?")L`T1.KOZ&(!\N;`-(3G5P9&"T0_H`$'``3J[]V"E`5
M!81G[$YU9&]S+FQI8G)A<GD`3E7_]"\**T#_^.6`(D!%Z0`!$A%(@4C!+T``3
M!"M(__P@`2)*3KH3LB!O``00$$B`(&W__$(P```@""1?3EU.=4Y5__@O#BM`<
M__Q8@"]```0B/``!``$L>``$3J[_.B!`(*\`!$/H``0@"2Q?3EU.=4Y5__PO4
M#B)(68DK2/_\("C__"QX``1.KO\N+%].74YU3E7_^$CG`#`F2"M)__AP`7(DN
M3KH<J"1`(`IF!'``8&(@"V<@($M*&&;\4XB1RR`(4H!.NA;P($LB0!+89OP@/
M0"5(``I!Z@`6)4@`$D'J`!(E2``:0JH`%B9M__@@"V<@($M*&&;\4XB1RR`('
M4H!.NA:T($LB0!+89OP@0"5(`"`@"DS?#`!.74YU2.<`,"9()$DF4V`@($HBX
M:P`*3KH3%DJ`9@0@"V`40>L`$B)*8=I*@&8()E-*DV;<<`!,WPP`3G5.5?^LF
M2.<!,B9)*TC_L'X`8`84LW@`4H=![?^TT<<D2'`ZL#-X`&<&<#^^@&WD0A)!9
M[`-80^W_M&&.)$`@"F8L(&P#9M#\`!(O2``00>W_M)/)80#^ZB1`(&\`$")*(
M+'@`!$ZN_Q`E;`-F``XK2O_T0>P#6")M_[!A`/].)$`@"F8.(&W_L")+80#^A
MM"1`8#@B2BQX``1.KO\$2JH`(&<((&H`($ZZ%QP@2TH89OQ3B)'+(`A2@$ZZ3
M%:H@2R)`$MAF_"!`)4@`("!M__30_``2(DHL>``$3J[_$$S?3(!.74YU3E7_)
MZ$CG,3(D2"`J`'Q2@"M(_^PK2?_P<@`L>``$3J[_.B9`($LO2``8(`MG``"::
M(BW_\"0\```#[2QL!81.KO_B+@!*AV=H(@<D"R8J`'Q.KO_6(&H`?"`(0C,(Z
M`"!+3KH0@B!`0^P`%$ZZ$+@F0)'(0^P`&DZZ$*PD0&`@($LB2F$`_IJ1R$/L`
M`!Y.NA"6)D"1R$/L`"1.NA"*)$`@"V<$(`IFV"('+&P%A$ZN_]PD;?_L)F\`4
M&"`J`'Q2@")++'@`!$ZN_RY,WTR,3EU.=2\.0^P`*'`A+'@`!$ZN_=@I0```F
M2H!F!'``8"X@;```(&@`(B`H`!CE@"E```1F!'``8!9P0>6(<@%.KO\Z*4``9
M$&8$<`!@`G`!+%].=4Y5__Q(YP`2)D@K0/_\(@MG#"\+2&P`-$ZZ!6103TJL&
M`!!G$")L`!!P0>6(+'@`!$ZN_RY*K``(9PPB+``(+&P%A$ZN_Z9*K```9PPBH
M;```+'@`!$ZN_F(@+?_\3KH5B$S?2`!.74YU3E7_M$CG`#`K2/^T(&P`!"`HQ
M``3E@"9`8#(I2P-4<`&PJP`$9B`@*P`H0>W_N&$`_!9![?^X(FW_M$ZZ$$Y*D
M@&8$(`M@7B`3Y8`F0"`+9LIP+&$`_#(F0"`+9PQP(&$`_"8D0"`*9@X@"V<&(
M($MA`/Q&<`!@+G`!)T``!$'J``$B;?^T$-EF_"!M_[1*&&;\4XB1[?^T(`@4M
M@"`*Y(@G0``H(`M,WPP`3EU.=4CG(3(F2"1)(@IT_BQL!81.KO^L+@!*AV8H%
M(@I.KO^(+@!*AV8$<`!@>"('3J[_IB(*=/Y.KO^L+@!*AV8$<`!@8"QX``1.^
MKO]\($MA`/\&)$`@!^6`)D!*J@`,9R0L>``$3J[_=B(J``PL;`6$3J[_IB5'Z
M``P@:P`,)4@`"'`!8"`E1P`,)6L`#``((&P#5"20(`KDB""`+'@`!$ZN_W9P[
M`4S?3(1.=4Y5__Q(YP$0)D@N`"M!__PF4V!F2JL`(&=&2FW__F8,(&L`"B)KI
M`"!A`/\N2FP`#&8&2FW__F<H(`=2@'(.DH<O*P`@2&P`6"\!+RL`"DAL`%(O`
M`$AL`$!.NA(:3^\`'"!K`!)*D&<00>L`$B`'5(`R+?_^2,%AB"932I-FEDS?T
M"(!.74YU3E7^Y$CG(S(N`"M(_NQA`/U@2D!F"'`%D<AA`/VB?`$D;?[L6(HF.
M;?[L4(M@``"H)E(0$TB`2,!![`(!"#```0@`9PP0$TB`2,!R()"!8`80$TB`P
M2,`F;?[P<B`$00`(:VZPNQ`(9O1.^Q`&````/V```#X```!48```*@```%9@N
M```:````4V````)2AD'L`%XB6V$`_CQ8BF`T.7P``0`,8"QP`3E```XY0``,+
M8"!(;`!B3KH"'B!M_NPND$AL`(A.N@)X<`"1R&$`_/)03U*&6(I8BRM+_O"\E
MAVT`_U)*;``,9PI(;`"T3KH!Z%A/0>P#7"E(`UA![`-8*4@#8)'(*4@#7"QXY
M``1.KO]\(&P`!"`H``3E@"9`8#0@*P`H0>W^]&$`^48@0$ZZ#%@@0)/)80#Y+
MR"1`(`IG#D'L`U@B2BQX``1.KO\0(!/E@"9`(`MFR"QX``1.KO]V0>P`VI/)%
M80#YF"E``V9![`-8(D`L>``$3J[_"D'L`-PB"'3^+&P%A$ZN_ZPI0``(9W0BV
M`"0L`!!.KO^:8$@@;``0("@`!$J`;CQ#[`#F3>W^]"S9+-D\D4/M_O0@24/L+
M`/!.N@TD(&P`$%"(+T@`'"!`(F\`'$ZZ#1`@;``00^W^]&$`^L`B+``()"P`A
M$"QL!81.KO^42H!FI$ZN_WQR=-*!L(%FF")L`V8L>``$3J[_!$IL``QG"DALX
M`/).N@"Z6$\P+``.2,!R`4'L`UC!06$`_4P@;`-F(&@`$DJ09RI*;``,9PI(I
M;`$$3KH`C%A/2&P!!DZZ`((@;`-FT/P`$G`!(@!A`/T86$]P`)'(80#[4DS?6
M3,1.74YU``!.=4YU2.<',"X`)D@L`2`'3KH4GB1`(`IF!'#_8#`(*@`#``-GJ
M#DAX``(@!W(`3KH/Q%A/("H`!"(&($M.NA$Z*@!*K`,@9P1P_V`"(`5,WPS@:
M3G4```````!P84CG`Q`F;P`0($M*&&;\4XB1RRP(?@`>&TJ'9S!3K`%N;18@%
M;`%F0^@``2E)`68@!Q"`<@`2`&#<(`=R`!(`(`%![`%B3KH'\B(`8,AP_T'L2
M`6).N@?D(`9,WPC`3G4``````````'!A3E7_W$CG#S`F;P!$?`!![0`,*TC_P
M\AX;2@=G``$`<"6^`&8``,8>&W``$`=R&%U!:P``AK![$`AF]$[[$`0`9&``Z
M`%``>&```!H`<&```!0`<V````(@;?_R)%@K2/_R8$@@;?_R*!@K2/_R1>W_4
M['H'2H5K%B`$<@_`@4'Z`++1P!204XKHA%.%8.9"+?_M8!@@;?_R*!@K2/_RA
M(`1![?_E3KH+9$7M_^4O"DZZ_NI83]R`8`#_8%*&4ZP!;FT8(&P!9D/H``$I!
M20%F(`<0@'(`$@!@`/]`<``0!T'L`6).N@;N(@!@`/\N4H93K`%N;1@@;`%F*
M0^@``2E)`68@!Q"`<@`2`&``_PYP`!`'0>P!8DZZ!KPB`&``_OQP_T'L`6).7
MN@:L(`9,WPSP3EU.=3`Q,C,T-38W.#E!0T1%1@!.5?_$2.<G,"9()$E^`'P`(
M>@!P`!M\`"#_^W(`*T'_]G3_*T+_\D'M_]`;0/_Q&T#__"M!_^0K0?_H*TC_Q
MS$H39T)P`!`3<AA=06LXL'L0"&;V3OL0!``C8```(``@8```%@`K8```#``MI
M8````GX!8`Y\`6`*>@%@!AM\``'__%*+8+H0$W(PL`%F!E*+&T'_^W`JL!-FY
M$"!20^@`!"2)*U#_]E*+8`P@2T/M__9.N@KXU\`0$W(NL`%F)%*+<"JP$V80V
M(%)#Z``$)(DK4/_R4HM@#"!+0^W_\DZZ"LS7P!`3<FRP`68*&WP``?_Q4HM@K
M"')HL`%F`E*+$!MR`!(`&T#_\'`P74!K``)(LGL`"&;T3OL`!`!C8``"'@!SU
M8``!W`!88``!>`!X8``!<@!P8``!6`!O8``!"@!U8```X`!D8````DHM__%G%
M#"!20^@`!"2)(!!@"B!20^@`!"2)(!`K0/_L;`IR`42M_^PK0?_H2JW_Z&<$I
M<"U@"DH&9P1P*V`"<"`;0/_0<``0!B(M_^B"@'``$`6"@&<(4JW_S%*M_^0@Y
M+?_L(&W_S$ZZ",HK0/_(("W_\DJ`:@9R`2M!__(@+?_((BW_\I*`2.T``O_$D
M;RX@;?_,(DC3P6`"$MA3@&3Z<``0+?_[(BW_Q"!M_\Q@`A#`4X%D^B`M__(K.
M0/_(T:W_Y$'M_]`K2/_,2@=G``%$&WP`(/_[8``!.DHM__%G#"!20^@`!"2)4
M(!!@"B!20^@`!"2)(!`K0/_L8`#_9$HM__%G#"!20^@`!"2)(!!@"B!20^@`0
M!"2)(!`K0/_L2BW__&<2(&W_S!#\`#!R`2M!_^0K2/_,(&W_S$ZZ""`K0/_(P
M8`#_+!M\`##_^R`M__)*@&H&<`@K0/_R2BW_\6<,(%)#Z``$)(D@$&`*(%)#/
MZ``$)(D@$"M`_^Q*+?_\9Q8@;?_,$/P`,!#\`'AR`BM!_^0K2/_,(&W_S$ZZ'
M$-@K0/_(<%BP+?_P9@#^QD'M_]!.N@828`#^NB!20^@`!"2)(E`K2?_,9@A![
M^@#**TC_S"!M_\Q*&&;\4XB1[?_,*TC_Y"`M__)*@&LHL<!O)"M`_^1@'G`!T
M*T#_Y"!20^@`!"2)(!`;0/_00BW_T6`$<`!@>B`M_^0B+?_VLH!L"'0`*T+_=
M]F`$D:W_]DH'9RY3K?_D;11P`"!M_\P0&"M(_\P@;0`(3I!@YE.M__9M/'``,
M$"W_^R!M``A.D&#L4ZW_]FT.<``0+?_[(&T`"$Z08.Q3K?_D;11P`"!M_\P0(
M&"M(_\P@;0`(3I!@YB`+3-\,Y$Y=3G4``$Y5__9(YP$P)D@D22MM``C_]AX:C
M2@=G+G`EO@!F(+`29@12BF`8+PL@2D/M__9A`/OV6$\K0/_Z9P0D0&#4<``0H
M!TZ38,Q,WPR`3EU.=4Y5_^Q(YR$R)D@,K````"`$YFP``((0$W(@L`%G#'()[
ML`%G!G(*L`%F!%*+8.A*$V=D("P$YN6`4JP$YD'L!.[1P"1(<"*P$V8B4HLD_
MBTH39PIP(K`39P12BV#R2A-F"'`!3KH/4&"B0AM@GB2+2A-G&!`3<B"P`6<0P
M<@FP`6<*<@JP`6<$4HM@Y$H39@)@!D(;8`#_=DJL!.9F!B!L`T1@!$'L!.XI^
M2`3J2JP$YF8``(!!^@$D0^P$K"+8(M@BV"+8,I`B;`-$(&D`)"](`!1P*$'LW
M!*PL;P`4(FX`!$ZZ!-A![`2L(@@D/````^XL;`6$3J[_XBE``W`I0`-X<@0I,
M00-T*4`#@"E!`WSE@)/)+'@`!"M`__!.KO[:(&W_\")`(V@`"`"D?@`K0/_T5
M8"HL;`6$3J[_RBE``W!.KO_$*4`#>$'Z`*0B""0\```#[4ZN_^(I0`.`?@0@S
M!P!`@`&!K`-L(`<`0(`"@:P#=`"L``"``P-\2JP!J&<$<`!@!B`\``"``"X`)
M0JP!7"`'`$```2E``5AP`2E``7X@!P!```(I0`%Z<`(I0`&@(`<`0`"`*4`!H
MG$'Z"Y@I2`,X("P$YB!L!.I.NO64<`!.N@DR3-],A$Y=3G5C;VXZ,3`O,3`O=
M,S(P+S@P+P`J`````````````````````````````````````````'!A+PLFV
M2$JK`!1G#`@K``,`&V8$<`!@-"`L`P1.N@BD)T``!"=``!!*@&8*<`PI0`6`0
M</]@%B=L`P0`%'#SP:L`&'``)T``#"=```@F7TYU``````````````````!.B
M5?_L2.<O$"X`)D@H!W`QP*L`&&<&</]@``)0""L`!P`:5L!$`$B`2,`L`$JK*
M`!1F``"`""L``@`;9G9P`"=```QR_[Z!9P`"(B!+3KK_5DJ`9PP(ZP`%`!MP,
M_V```@P(ZP`!`!M*!F<.("L`%"(`1($G00`,8`@@*P`4)T``#%.K``QM%B!K-
M``1#Z``!)TD`!"`'$(!R`!(`8!`@!W(`$@`@`2!+80#_6"(`(`%@``&Z""L`/
M`@`;9TQP_[Z`9@9P`&```:8@!QM`__]*!F<<<@J^@686<@(K0?_P("L`'$'Z;
M`9!.NO:**@!@%'(!*T'_\"`K`!Q![?__3KKV="H`?O]@``#2".L``0`;2@9GI
M3G#_OH!G2%2K``QR"KZ!9B(@:P`$0^@``2=)``00O``-(BL`#$J!:P8@2V$`A
M_L12JP`,(&L`!$/H``$G20`$(`<0@"(K``Q*@6L``1!^_R`K``20JP`0*T#_2
M\&=H""L`!@`:9TQ(>``"("L`''(`3KH%X%A/*T#_[$H&9S13K?_L;2Y"IR`KO
M`!PB+?_L3KH%PB`K`!QR`4'M__U.N@3`6$]*K`,@9@H0+?_]<AJP`6?,("L`9
M'"(M__`@:P`03KKUHBH`8`)Z`'#_NH!F"`CK``4`&V`,NJW_\&<&".L`!``;%
M2@9G#B(K`!0D`42")T(`#&`8""L``@`;9PAR`"=!``Q@""(K`!0G00`,(&L`K
M$"=(``2^@&<L4ZL`#&T6(&L`!$/H``$G20`$(`<0@'(`$@!@$"`'<@`2`"`!'
M($MA`/VR(@!P,,"K`!AG!'#_8`QP_[B`9@1P`&`"(`1,WPCT3EU.=0T*````Y
M`$CG(#`F2"1+2A)G)'``$!)![`(!"#```0@`9PIR`!(`=""2@F`$<@`2`!2!@
M4HI@V"`+3-\,!$YU````````<&%.5?_P2.<!,"9(*TG_\"`+9QH@2RE(!7!.<
MN@(:+@`@;`5P(DC3QRM)__A@$"!L!7!*$&8$<`!@/BM(__@D;?_X($HB;?_P1
M3KH"`BX`2C)X`&<80C)X`"!*T<=%Z``!($HB;?_P3KH!SBX`($K1QRE(!7`@^
M+?_X3-\,@$Y=3G4``"((8`00V6<(4X!D^&`&0AA3@&3Z(`%.=4Y5__A(YP,PO
M)D@D22X`($I*&&;\4XB1RBP(($M*&&;\4XB1RR`((DO3P"M)__B\AV,"+`<@5
M!B!*8`(2V%.`9/H@;?_X0C!H`"`+3-\,P$Y=3G4``'``<@`0&!(9#```86T*T
M#```>FX$!```(`P!`&%M"@P!`'IN!`0!`""0@68$2@%FU$YU```@"$H89OQ3A
MB!#99OQ.=0``3E7_]")/<@I.N@9D!D$`,!+!2H!F\"`)$.&_R6;Z0A"0CTY=3
M3G4``$Y5__0B3R(``D$`!P9!`#`2P>:(9O`@"1#AO\EF^D(0D(].74YU``!.S
M5?_T(D]L!A#\`"U$@'(*3KH&#`9!`#`2P4J`9O`0X;_)9OI"$"`(3EV0KP`$I
M3G5.5?_X2.<!,"9()$E^`$H39RHK2O_\(&W__$H09PP0$+`39P92K?_\8.P@_
M;?_\2A!F!"`'8`A2AU*+8-(@!TS?#(!.74YU3E7_^$CG`3`F2"1)?@!*$V<BH
M*TK__"!M__Q*$&<0$!"P$V8$(`=@#E*M__Q@Z%*'4HM@VB`'3-\,@$Y=3G5(Q
MYP`P)D@D22!+(DIA`/]N3-\,`$YU2.<`,"9()$D@2R)*89Y,WPP`3G4``"\)3
M(DAR`'``+P(,$``K9P8,$``M9@)22!`8!```,&T2#```"6X,)`'E@=*"TH'2J
M@&#F#!$`+68"1($D'R`(4X`@7R"!D(E.=4Y5_^1(YP$R+@`K2/_D2H=N!G#_7
M8```S'`(OH!D`BX`(`=6@"X``D?__"1(T<??K`$\0^P!."91*TC_\"M)__0@Y
M"V<``)`@2R`K``31P"M(_^PB;?_PM\EC$"2+)4<`!"QM__0LBG``8'BWR68:%
M+%,DCB`K``0B`-*')4$`!"QM__0LBG``8%JUR&0(GZP!/'#_8$ZUR&8L2I-GR
M#B!3L\AC")^L`3QP_V`XWZL`!$J39PZSTV8*("D`!-&K``0FD7``8!XK2__TG
M*VW_[/_H)E-@`/]N(&W_]""*0I(E1P`$<`!,WTR`3EU.=0``````````<&%(,
MYP$0)D@N`"`'($M.NO[^3-\(@$YU``!(YP<P+@`F2"P!(`=.N@6B)$`@"F8$=
M</]@&B`J``0B!B!+3KH#$"H`2JP#(&<$</]@`B`%3-\,X$YU```O!RX`4JP%*
M=%.L`6YM%B!L`69#Z``!*4D!9B`'$(!R`!(`8!(@!W(`$@`@`4'L`6).NODF-
M(@`N'TYU3E4``"\+)F\`#$*L!71(;0`,0?K_LB)+3KKV3G#_0>P!8DZZ^/H@6
M+`5T)FW__$Y=3G5(YP$P+@!*K`5X9Q0D;`5X(!(@;`5X3KK_*)'(*4@%>$J'L
M9@1P`&`<6(<@!TZZ`2(F0$J`9@1P`&`*)$LDAT'K``0@"$S?#(!.=0``2.</E
M$"X`+`$J+P`8(`=.N@2L)D`@"V8$</]@'"\%("L`!"(&3KH!HEA/*`!*K`,@?
M9P1P_V`"(`1,WPCP3G4``````````'!A2.<#,"X`2H=N!G``8```H'`(OH!DV
M`BX`(`=6@"X``D?__$7L`3@F4B`+9T`@*P`$L(=M,K"'9@P@4R2(GZP!/"`+S
M8&H@*P`$D(=R"+"!918@2]'')(@D2"23)4``!)^L`3P@"V!()$LF4V"\(`<BY
M+`&LT(%3@$ZZ`@0B+`&L3KH!W"P`4(8@!E:`+``"1O_\(`9.N@6,)D`@"V<0?
M(`8@2TZZ_18@!V$`_UA@`G``3-\,P$YU````````<&$O!RX`(`=.NO\\+A].1
M=0``+PLF2"`+9PYP`$ZZ_I0@2UF(*4@%>'``)E].=0```````'!A2.<#$"X`Z
M1^P!0"`+9S`(*P`"`!MF)`@K``$`&V<<("L`!)"K`!`L`$J&9PX@*P`<(@8@<
M:P`03KKNH"938,P@!TZZ!'),WPC`3G4``$CG-Q`N`"9(+`%*K`,X9P1.N@-JA
M0JP#("(')`LF!BQL!81.KO_0*@!P_[J`9@Y.KO]\*4`#('`%*4`%@"`%3-\(&
M[$YU2.<_`"X`+`$J+P`<2JP#.&<$3KH#)$*L`R`@!5.`(@<D!B8`+&P%A$ZN7
M_[XH`'#_N(!F#DZN_WPI0`,@<!8I0`6`(`4,@`````)G%@R``````6<(2H!F3
M&"`&8!0@!-"&8`XB!W0`=@`L;`6$3J[_ODS?`/Q.=0``2.<W$"X`)D@L`4JLF
M`SAG!$ZZ`JY"K`,@(@<D"R8&+&P%A$ZN_]8J`'#_NH!F#DZN_WPI0`,@<`4I-
M0`6`(`5,WPCL3G4O!RX`2JP#.&<$3KH"<"('+&P%A$ZN_]QP`"X?3G4``$CG6
M,``D`"8!2$)(0\3!QL#`P=1#2$)"0M""3-\`#$YU2H!J```>1(!*@6H```Q$H
M@6$``"!$@4YU80``&$2`1(%.=4J!:@``#$2!80``!D2`3G4O`DA!-`%F```BZ
M2$!(04A"-`!G```&A,$P`DA`-`"$P3`"2$(R`B0?3G4O`W80#$$`@&0```;AZ
MF5%##$$(`&0```;IF5E##$$@`&0```;EF55#2D%K```&XYE30S0`YJA(0D)"5
MYJI(0X#!-@`P`C0#2$'$P9""9```"%-#T(%D_G(`,@-(0^>X2$#!028?)!].!
M=4Y5_YY(YS,R?@`@;`-0'BC__W!/OH!O`BX`(`=#[?^O8`(2V%.`9/I"-7BOF
MD\DL>``$3J[^VB9`2JL`K&=,("L`K.6`)$`L*@`X2H9F!"PK`*!*AF<T(@9!E
M^@"P)`AV"RQL!81.KO_0($=2AR`(&[P`"@BO(@9![?^O)`@F!RQL!81.KO_0,
M</]@3$JL!7QF$D/Z`(1P`"QX``1.KOW8*4`%?$'M_Z\I2`'02'@`/$AX`/I(Z
M;`'L2&P!V'``(@"1R$/L`<1.N@$R3^\`$%.`9P1P_V`"<`!,WTS,3EU.=2HJ2
M(%5S97(@06)O<G0@4F5Q=65S=&5D("HJ``!#3TY424Y510``04)/4E0`*BHJX
M($)R96%K.B``:6YT=6ET:6]N+FQI8G)A<GD`````````````````+P<N`'``Y
M*4`#($J':R*^K`$H;!P@!^>`0>P#;$JP"`!G#B`'YX!![`-LT<`@"&`(<`DI3
M0`6`<``N'TYU````````<&%(YP$"<``B/```,``L>``$3J[^SBX``H<``#``=
M2H=F!'``8!Q*K`,X9Q0@;`,X3I!*@&8$<`!@"'`43KH`L"`'3-]`@$YU8;A.\
M=0``2.<'$"X`+`$@!R(&3KK]2BH`(`5.NOI2)D`@"V<.(`5R`"!+8`(0P5.`E
M9/H@"TS?".!.=4CG,#(L;`5\)&\`&"9O`!PD+P`@)B\`)$ZN_J1,WTP,3G4`U
M`&```)).<0``(&\`!&``\(9.<0``,#$R,S0U-C<X.6%B8V1E9E%/(D\R``)!!
M``\2^Q#DZ(AF\B`)(@\0X;*)9OI"$)"!4$].=4CG!P`N`"`L`2A3@"P`2D9K6
M+B`&2,#G@$'L`VPJ,`@`2@5G&`@%``)F$B`&2,#G@$'L`VP@,`@$3KK\7E-&>
M8,X@!TZZX69,WP#@3G5(YP`R)FP%B"`+9Q0D4R)+("L`""QX``1.KO\N)DI@P
MZ)'(*4@%C"E(!8A,WTP`3G5(YP$R+@!P#-Z`(`=R`"QX``1.KO\Z)D`@"V8$6
M<`!@.B='``A%[`6((&H`!"=(``21R":(2I)F`B2+2JH`!&<&(FH`!"*+)4L`+
M!$JL`2QF!"E+`2Q!ZP`,(`A,WTR`3G4```````````````````/L`````@``]
M``(````,````!@````````/R```#Z0````````/R```#Z@```,(`````````9
M`````````````````"`Z"0H``"`)"@`@.@D*```@"0H`9&]S+FQI8G)A<GD`I
M17)R;W(Z("5S"@``)2IS)2TQ-7,E*G,E<YLP;0H`FS,S;0``FS,R;0``4UE3I
M`)LW;4)I;F1.86UE<R!6,2XP(&)Y($1A=F4@2&%Y;FEEFS!M"@H`57-A9V4Z)
M("5S(%M615)"3U-%72!;5$535%T@6U-94U1%32!D<FEV95T*``";-VU":6YD[
M3F%M97,@5C$N,"!B>2!$879E($AA>6YI99LP;0H*````4UE3.DYA;65S`%-9W
M4SI.86UE<P`O`$%S<VEG;F5D($YA;65S.@H```H`5V%R;FEN9SH@0V%N)W0@]
M4F5S;VQV92!.86UE<SH*`````````"@`````````````````````````````@
M`6(```````````````````````````````````````````&$````````````H
M`````````````````````````````````````````````````````````````
M``````````````````"`````!`#__P````X`#@```````!X2`````/__````,
M!``$``````````````&P__\````$``0````````>+@````#__P````0`!```1
M`````!XX```````@("`@("`@("`H*"@H*"`@("`@("`@("`@("`@("`@($@06
M$!`0$!`0$!`0$!`0$!"$A(2$A(2$A(2$$!`0$!`0$(&!@8&!@0$!`0$!`0$!&
M`0$!`0$!`0$!`0$!$!`0$!`0@H*"@H*"`@("`@("`@("`@("`@("`@("`@(0P
M$!`0("`@("`@("`@("@H*"@H("`@("`@("`@("`@("`@("`@2!`0$!`0$!`0`
M$!`0$!`0$(2$A(2$A(2$A(00$!`0$!`0@8&!@8&!`0$!`0$!`0$!`0$!`0$!=
M`0$!`0$0$!`0$!""@H*"@H("`@("`@("`@("`@("`@("`@("`A`0$!`@````Y
M```"`````^P````#`````````?@```'D```!O`````,````"```!U````6(`,
+``%``````````_(#Y
``
end
size 9236
SHAR_EOF
cat << \SHAR_EOF > Makefile
# Really cheap Makefile for BindNames.c

BindNames:	BindNames.c
	lc -Lt -O -rr -ms -v BindNames

SHAR_EOF
cat << \SHAR_EOF > ReadMe


		BindNames V1.0 by Dave Haynie


	BindNames is a rather simple hack I came up with to solve the
"Assign" problem.  Like most folks with large hard disks containing lots
of different programs, my Startup-Sequence was starting to get full of
Assign statements.  While that alone isn't necessarily enough to make
most go out and write a program, I was starting to think of this as an
inelegance.  Nearly every other new program I installed onto my system
needed a new set of logical names, and so for every new program I ended
up having to edit my Startup-Sequence.  I also had to pay attention to
the ordering of Assignments, since obviously I couldn't base an
assignment on one that hadn't been made yet.  The end result was that
the Startup Sequence was getting rather ugly, with no sign of change on
the immediate horizon. 

	Since problems should be solved by those who see them, I came up
with BindNames.  BindNames is designed to do all of the logical name
assignments you need at once.  It looks for any number of files in the
directory "SYS:Names".  The format of such files is something like this
(to quote my "SYS:Names/System" file):

BIN:	SYS:bin
OS:	SYS:os
C: 	BIN:c
COM:	BIN:Com
L: 	OS:L
FONTS:	PATH:FD:Amiga,FD:PD,FD:PS,FD:Terms,FD:CityDesk
FD:	OS:Fonts
S: 	OS:s
DEVS:	OS:Devs
LIBS:	OS:Libs
ENV:	RAM:Env
T:	RAM:T

	BindNames will read all name files before making any
assignments, and it can figure out dependencies, so it doesn't matter
how you order the names.  It will create directories that it can't find,
such as RAM:Env and RAM:T in the above example, and it will generate
warnings for name assignments that it can't resolve.  It also accepts
several options, of the form:

	BindNames [SYSTEM device] [VERBOSE] [TEST]

	The SYSTEM device option causes BindNames to re-assign the SYS:
name to the given device before searching for SYS:Names.  For example,
my main system disk is called FH0:, but I boot from DH2: (sure sounds
like A2090A madness to me too, but what can I say), so my
Startup-Sequence says "BindNames >NIL: SYSTEM fh0:". 

The VERBOSE switch causes BindNames to list each name and equivalence
as it runs.  The TEST switch does the same thing, but doesn't actually
make the name assignments.

	Using BindNames, I've managed to get every single "Assign"
command out of my Startup-Sequence.  And if I need to add a series of
assignments for a new program, I can just create a SYS:Names file for
that program.  That makes installing the program much easier, and also
keeps all the logical names for a particular program in an obvious
location, which makes modifying the system setup much simpler in the
future. 

	BindNames is public domain, do with as you please.


					-Dave Haynie
					 3/14/89
SHAR_EOF
#	End of shell archive
exit 0
-- 
Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
Have five nice days.