home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d0xx / d031 / set.lha / Set / set.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-08-30  |  5.8 KB  |  244 lines

  1. /*
  2.  *   Written by Tomas Rokicki.
  3.  *
  4.  *   This routine replaces Manx's SET command.  It should have exactly
  5.  *   equivalent functionality.  Do not use the Manx SET command with it,
  6.  *   though; my library structure has an extra field which Manx ignores.
  7.  *   Thus, if the Manx set command modifies a library created by my set
  8.  *   command, or vice versa, a system crash could result.
  9.  *
  10.  *   Another caveat:  the Manx getenv() routine does not do a Forbid()
  11.  *   Permit() around it's library examining code, so it could
  12.  *   conceivably return bad data if someone's executing a set while it
  13.  *   is called.  You might want to rewrite getenv(); it's simple enough.
  14.  *
  15.  *   The following code could easily be hacked to provide setenv() and
  16.  *   getenv() library routines; I leave that as an exersize for the reader.
  17.  */
  18. #include "stdio.h"
  19. #include "exec/memory.h"
  20. /*
  21.  *   The increment size for the string space.
  22.  */
  23. #define ENVINC (128)
  24. /*
  25.  *   The pointer to the environment data.
  26.  */
  27. char **envloc = NULL ;
  28. long *envsize ;
  29. char *envname = "environment" ;
  30. /*
  31.  *   A library structure declaration, pieced together from various
  32.  *   include files and extended a bit.
  33.  */
  34. struct lib {
  35.    struct lib *next, *prev ;
  36.    char type, priority ;
  37.    char *name ;
  38.    short flags ;
  39.    short negsize ;
  40.    short possize ;
  41.    short version ;
  42.    short revision ;
  43.    char *ID ;
  44.    long checksum ;
  45.    short opencount ;
  46.    char *env ;
  47.    long size ;
  48. } ;
  49. /*
  50.  *   The actual library structure.  Note I have relative branches in the
  51.  *   vectors field, and actual assembled code in the code field.  Be
  52.  *   careful if you change any of this!
  53.  */
  54. struct envlib {
  55.    short vectors[12] ;
  56.    struct lib lp ;
  57.    short code[4] ;
  58.    char name[12] ; } envinit =
  59. { { 0x6044, 0x0000, 0x0000,
  60.     0x603e, 0x0000, 0x0000,
  61.     0x6038, 0x0000, 0x0000,
  62.     0x602e, 0x0000, 0x0000 },
  63.   { NULL, NULL,
  64.     0, 0,
  65.     NULL,
  66.     0,
  67.     24,
  68.     42 + 8 + 12 + 2,
  69.     1,
  70.     1,
  71.     NULL,
  72.     0,
  73.     1,
  74.     NULL,
  75.     ENVINC },
  76.   { 0x200e, 0x4e75, 0x7000, 0x4e75 },
  77.   { 'e', 'n', 'v', 'i', 'r', 'o', 'n', 'm', 'e', 'n', 't', 0}
  78. } ;
  79. /*
  80.  *   The main routine is straightforward.  If no arguments are given, we
  81.  *   print out the contents of the environment.  If one ? is given as an
  82.  *   argument, we print out a blurb.  Otherwise, we scan through the
  83.  *   argument list, adding new definitions.
  84.  */
  85. char *index() ;
  86.  
  87. main(argc, argv)
  88. int argc ;
  89. char *argv[] ;
  90. {
  91.    register char *p, *q ;
  92.  
  93.    argc-- ; argv++ ;
  94.    openenv() ;
  95.    if (argc <= 0) {
  96.       if (envloc != NULL)
  97.          for (q=*envloc; *q!=0; ) {
  98.             puts(q) ;
  99.             while (*q++) ;
  100.          }
  101.    } else if (argc==1 && argv[0][0]=='?' && argv[0][1]==0) {
  102.       puts("Environment variable utility---Radical Eye Software") ;
  103.    } else while (argc > 0) {
  104.       if ((p = index(*argv, '=')) && p[1] != 0) {
  105.          deleteenv(*argv) ;
  106.          if (envloc==NULL)
  107.             makeenv() ;
  108.          for (;;) {
  109.             q = *envloc ;
  110.             while (*q!=0)
  111.                while (*q++) ;
  112.             if (q+strlen(*argv)+1 > *envloc + *envsize)
  113.                biggerenv() ;
  114.             else
  115.                break ;
  116.          }
  117.          Forbid() ;
  118.          strcpy(q, *argv) ;
  119.          q[strlen(*argv)+1] = 0 ;
  120.          Permit() ;
  121.       } else {
  122.          deleteenv(*argv) ;
  123.       }
  124.       argv++ ;
  125.       argc-- ;
  126.    }
  127. }
  128. /*
  129.  *   This routines opens the environment library if it exists and sets
  130.  *   the global pointer to the correct location.
  131.  */
  132. openenv()
  133. {
  134.    register struct lib *lp, *_OpenLibrary() ;
  135.  
  136.    if (lp=_OpenLibrary(envname, 0L)) {
  137.       _CloseLibrary(lp) ;
  138.       envloc = &lp->env ;
  139.       envsize = &lp->size ;
  140.    } else
  141.       envloc = NULL ;
  142. }
  143. /*
  144.  *   We need a simple memcopy routine.  Only works for even numbers of bytes.
  145.  */
  146. memcop(dst, src, bytes)
  147. register short *dst, *src ;
  148. register long bytes ;
  149. {
  150.    while (bytes > 0) {
  151.       *dst = *src ;
  152.       dst++ ; src++ ;
  153.       bytes -= 2 ;
  154.    }
  155. }
  156. /*
  157.  *   This is the tricky routine which adds a library.
  158.  */
  159. makeenv()
  160. {
  161.    char *AllocMem() ;
  162.    register struct lib *lp ;
  163.    register struct envlib *elp ;
  164.    register char *p ;
  165.  
  166.    elp = (struct envlib *)AllocMem((long)sizeof(struct envlib), 
  167.               (long)MEMF_PUBLIC) ;
  168.    p = AllocMem((long)ENVINC, (long)MEMF_PUBLIC | MEMF_CLEAR) ;
  169.    if (elp==NULL || p==NULL) {
  170.       puts("Couldn't make environment library!") ;
  171.       if (elp!=NULL)
  172.          FreeMem(elp, (long)sizeof(struct envlib)) ;
  173.       if (p!=NULL)
  174.          FreeMem(p, (long)ENVINC) ;
  175.       exit(1) ;
  176.    }
  177.    memcop(elp, &envinit, (long)sizeof(struct envlib)) ;
  178.    lp = &(elp->lp) ;
  179.    lp->name = elp->name ;
  180.    lp->env = p ;
  181.    AddLibrary(lp) ;
  182.    envloc = &(lp->env) ;
  183.    envsize = &(lp->size) ;
  184.    return ;
  185. }
  186. /*
  187.  *   This routine makes the environment string space bigger if needed.
  188.  */
  189. biggerenv() {
  190.    register char *p ;
  191.    register long size ;
  192.    register char *t ;
  193.  
  194.    size = *envsize + ENVINC ;
  195.    p = AllocMem(size, (long)MEMF_PUBLIC | MEMF_CLEAR) ;
  196.    if (p==NULL) {
  197.       puts("Couldn't increase environment size.\n") ;
  198.       exit(1) ;
  199.    }
  200.    Forbid() ;
  201.    t = *envloc ;
  202.    memcop(p, t, *envsize) ;
  203.    *envloc = p ;
  204.    *envsize = size ;
  205.    Permit() ;
  206.    size -= ENVINC ;
  207.    FreeMem(t, size) ;
  208. }
  209. /*
  210.  *   This routine deletes a symbol definition and moves all other strings
  211.  *   down.  We can afford to use a simple algorithm here.
  212.  */
  213. deleteenv(s)
  214. register char *s ;
  215. {
  216.    register char *q ;
  217.    register int i, j ;
  218.  
  219.    if (envloc==NULL) return ;
  220.    if (q=index(s, '='))
  221.       i = q - s ;
  222.    else
  223.       i = strlen(s) ;
  224.    Forbid() ;
  225.    q = *envloc ;
  226.    while (*q!=0)
  227.       if ((j=index(q, '=')-q) && i==j && strncmp(q, s, i)==0) {
  228.          s = q + strlen(q) + 1 ;
  229.          while (*s != 0) {
  230.             *q++ = *s++ ;
  231.             if (*s == 0)
  232.                *q++ = *s++ ;
  233.          }
  234.          *q++ = 0 ;
  235.          *q++ = 0 ;
  236.          Permit() ;
  237.          return ;
  238.       } else
  239.          q += strlen(q) + 1 ;
  240.    Permit() ;
  241. }
  242.  
  243.  
  244.