home *** CD-ROM | disk | FTP | other *** search
- /*
- * Written by Tomas Rokicki.
- *
- * This routine replaces Manx's SET command. It should have exactly
- * equivalent functionality. Do not use the Manx SET command with it,
- * though; my library structure has an extra field which Manx ignores.
- * Thus, if the Manx set command modifies a library created by my set
- * command, or vice versa, a system crash could result.
- *
- * Another caveat: the Manx getenv() routine does not do a Forbid()
- * Permit() around it's library examining code, so it could
- * conceivably return bad data if someone's executing a set while it
- * is called. You might want to rewrite getenv(); it's simple enough.
- *
- * The following code could easily be hacked to provide setenv() and
- * getenv() library routines; I leave that as an exersize for the reader.
- */
- #include "stdio.h"
- #include "exec/memory.h"
- /*
- * The increment size for the string space.
- */
- #define ENVINC (128)
- /*
- * The pointer to the environment data.
- */
- char **envloc = NULL ;
- long *envsize ;
- char *envname = "environment" ;
- /*
- * A library structure declaration, pieced together from various
- * include files and extended a bit.
- */
- struct lib {
- struct lib *next, *prev ;
- char type, priority ;
- char *name ;
- short flags ;
- short negsize ;
- short possize ;
- short version ;
- short revision ;
- char *ID ;
- long checksum ;
- short opencount ;
- char *env ;
- long size ;
- } ;
- /*
- * The actual library structure. Note I have relative branches in the
- * vectors field, and actual assembled code in the code field. Be
- * careful if you change any of this!
- */
- struct envlib {
- short vectors[12] ;
- struct lib lp ;
- short code[4] ;
- char name[12] ; } envinit =
- { { 0x6044, 0x0000, 0x0000,
- 0x603e, 0x0000, 0x0000,
- 0x6038, 0x0000, 0x0000,
- 0x602e, 0x0000, 0x0000 },
- { NULL, NULL,
- 0, 0,
- NULL,
- 0,
- 24,
- 42 + 8 + 12 + 2,
- 1,
- 1,
- NULL,
- 0,
- 1,
- NULL,
- ENVINC },
- { 0x200e, 0x4e75, 0x7000, 0x4e75 },
- { 'e', 'n', 'v', 'i', 'r', 'o', 'n', 'm', 'e', 'n', 't', 0}
- } ;
- /*
- * The main routine is straightforward. If no arguments are given, we
- * print out the contents of the environment. If one ? is given as an
- * argument, we print out a blurb. Otherwise, we scan through the
- * argument list, adding new definitions.
- */
- char *index() ;
-
- main(argc, argv)
- int argc ;
- char *argv[] ;
- {
- register char *p, *q ;
-
- argc-- ; argv++ ;
- openenv() ;
- if (argc <= 0) {
- if (envloc != NULL)
- for (q=*envloc; *q!=0; ) {
- puts(q) ;
- while (*q++) ;
- }
- } else if (argc==1 && argv[0][0]=='?' && argv[0][1]==0) {
- puts("Environment variable utility---Radical Eye Software") ;
- } else while (argc > 0) {
- if ((p = index(*argv, '=')) && p[1] != 0) {
- deleteenv(*argv) ;
- if (envloc==NULL)
- makeenv() ;
- for (;;) {
- q = *envloc ;
- while (*q!=0)
- while (*q++) ;
- if (q+strlen(*argv)+1 > *envloc + *envsize)
- biggerenv() ;
- else
- break ;
- }
- Forbid() ;
- strcpy(q, *argv) ;
- q[strlen(*argv)+1] = 0 ;
- Permit() ;
- } else {
- deleteenv(*argv) ;
- }
- argv++ ;
- argc-- ;
- }
- }
- /*
- * This routines opens the environment library if it exists and sets
- * the global pointer to the correct location.
- */
- openenv()
- {
- register struct lib *lp, *_OpenLibrary() ;
-
- if (lp=_OpenLibrary(envname, 0L)) {
- _CloseLibrary(lp) ;
- envloc = &lp->env ;
- envsize = &lp->size ;
- } else
- envloc = NULL ;
- }
- /*
- * We need a simple memcopy routine. Only works for even numbers of bytes.
- */
- memcop(dst, src, bytes)
- register short *dst, *src ;
- register long bytes ;
- {
- while (bytes > 0) {
- *dst = *src ;
- dst++ ; src++ ;
- bytes -= 2 ;
- }
- }
- /*
- * This is the tricky routine which adds a library.
- */
- makeenv()
- {
- char *AllocMem() ;
- register struct lib *lp ;
- register struct envlib *elp ;
- register char *p ;
-
- elp = (struct envlib *)AllocMem((long)sizeof(struct envlib),
- (long)MEMF_PUBLIC) ;
- p = AllocMem((long)ENVINC, (long)MEMF_PUBLIC | MEMF_CLEAR) ;
- if (elp==NULL || p==NULL) {
- puts("Couldn't make environment library!") ;
- if (elp!=NULL)
- FreeMem(elp, (long)sizeof(struct envlib)) ;
- if (p!=NULL)
- FreeMem(p, (long)ENVINC) ;
- exit(1) ;
- }
- memcop(elp, &envinit, (long)sizeof(struct envlib)) ;
- lp = &(elp->lp) ;
- lp->name = elp->name ;
- lp->env = p ;
- AddLibrary(lp) ;
- envloc = &(lp->env) ;
- envsize = &(lp->size) ;
- return ;
- }
- /*
- * This routine makes the environment string space bigger if needed.
- */
- biggerenv() {
- register char *p ;
- register long size ;
- register char *t ;
-
- size = *envsize + ENVINC ;
- p = AllocMem(size, (long)MEMF_PUBLIC | MEMF_CLEAR) ;
- if (p==NULL) {
- puts("Couldn't increase environment size.\n") ;
- exit(1) ;
- }
- Forbid() ;
- t = *envloc ;
- memcop(p, t, *envsize) ;
- *envloc = p ;
- *envsize = size ;
- Permit() ;
- size -= ENVINC ;
- FreeMem(t, size) ;
- }
- /*
- * This routine deletes a symbol definition and moves all other strings
- * down. We can afford to use a simple algorithm here.
- */
- deleteenv(s)
- register char *s ;
- {
- register char *q ;
- register int i, j ;
-
- if (envloc==NULL) return ;
- if (q=index(s, '='))
- i = q - s ;
- else
- i = strlen(s) ;
- Forbid() ;
- q = *envloc ;
- while (*q!=0)
- if ((j=index(q, '=')-q) && i==j && strncmp(q, s, i)==0) {
- s = q + strlen(q) + 1 ;
- while (*s != 0) {
- *q++ = *s++ ;
- if (*s == 0)
- *q++ = *s++ ;
- }
- *q++ = 0 ;
- *q++ = 0 ;
- Permit() ;
- return ;
- } else
- q += strlen(q) + 1 ;
- Permit() ;
- }
-
-
-