home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_02_02 / appenv.msc < prev    next >
Text File  |  1991-01-23  |  6KB  |  181 lines

  1. /*
  2.  *  APPENV - APPend to ENVironment  --2.0--  Copyright (c) Mark Lord, 1989
  3.  *
  4.  *  Feel free to copy, use and/or modify this for any non-commercial
  5.  *  purpose(s).  Please keep this copyright header in place.
  6.  *
  7.  *  Compile this under TINY model of Turbo-C 2.0 and then use EXE2BIN to
  8.  *  convert the resulting .EXE to a .COM file.
  9.  *
  10.  *    Hacked, November 1989, by Fred C. Smith into a form that can be
  11.  *    compiled with MSC 5.1. Didn't do too much damage in the process,
  12.  *    but it turns into a .EXE that is a bit bigger than the .COM produced
  13.  *    by Turbo C.
  14.  */
  15.  
  16. #include <dos.h>
  17. #include <ctype.h>
  18. #include <stdlib.h>
  19. #include <stdio.h>
  20.  
  21.  
  22. char helptext [] =
  23. "\r\nAPPENV  --  APPend to ENVironment  --  Version 2.00 (c) 1989 by Mark Lord\r\n\n"\
  24. "This command allows appending data to the end of an existing  environment\r\n"\
  25. "variable, such as PATH.     Usage:     APPENV <var>=<data>\r\n"\
  26. "Where  <var> is the name of the environment variable,  and  <data> is the\r\n"\
  27. "value to be assigned to it.   If <var> does not already exist, it will be\r\n$";
  28. char helptext2 [] =
  29. "created with a value of <data>,  otherwise <data> will be appended to the\r\n"\
  30. "current value of <var>.  If no <data> is given, then <var> will be erased\r\n"\
  31. "from the environment.   If there is not enough environment space left for\r\n"\
  32. "<data>,  it will be truncated and a beep! will be sounded on the speaker.\r\n$";
  33.  
  34. void help ()
  35. {
  36.         /* Output the help text and exit with ERRORLEVEL=2. */
  37.  
  38.         union REGS regs;
  39.         regs.h.ah = 9;
  40.         regs.x.dx = (unsigned int)helptext;
  41.         intdos (®s, ®s);
  42.         regs.x.dx = (unsigned int)helptext2;
  43.         intdos (®s, ®s);
  44.         exit (2);
  45. }
  46.  
  47. char far * MK_FP(short seg, short off)
  48.     {
  49.     char far * p;
  50.  
  51.     FP_SEG(p) = seg;
  52.     FP_OFF(p) = off;
  53.     return p;
  54.     }
  55.  
  56. void main ()
  57. {
  58.         int size;
  59.         unsigned psp, far *tmp;
  60.         char far *env, far *e, far *p, varbuf[1024], *v;
  61.  
  62.         /* _psp is our PSP.  Follow the "parent" links back
  63.            until we find a PSP for COMMAND.COM, which has
  64.            a parent link that points at itself. */
  65.  
  66.         psp = _psp;
  67.         while (psp != *(tmp = (unsigned int far *)MK_FP(psp,22)))
  68.                 psp = *tmp;
  69.  
  70.         /* Now get the address of COMMAND.COM's environment block
  71.            from its PSP. */
  72.  
  73.         env = MK_FP(*(unsigned far *)MK_FP(psp,44),0);
  74.  
  75.         /* Get the block size from the MCB which immediately
  76.            preceeds the environment block.  This is a paragraph count,
  77.            which must be multiplied by 16 to get a byte count. */
  78.  
  79.         size = 16 * *(int far *) MK_FP(FP_SEG(env)-1,3);
  80.  
  81.         /* Back to our own PSP again, where our command line
  82.            parameters are stored, terminated by a carriage return. */
  83.  
  84.         p = MK_FP(_psp,129);
  85.  
  86.         /* Ignore leading spaces (there is usually one or more),
  87.            and give the user some help if there is nothing else there. */
  88.  
  89.         while (*p == ' ') ++p;
  90.         if ((*p == '\r') || (*p == '=')) help ();
  91.  
  92.         /* Now some tricky parsing to extract the variable name and
  93.            equal sign into varbuf[], ignoring spaces between the name
  94.            and the equal sign.  If there is no equal sign, give the
  95.            user some help instead. */
  96.  
  97.         v = (char *) varbuf;
  98.         while ((*p != '\r') && ((*v = toupper(*p)) != '='))
  99.                 {
  100.                 p++;
  101.                 if (*v != ' ')
  102.                     ++v;
  103.                 }
  104.         p++;
  105.         if (*v != '=') help ();
  106.         *++v = '\0';
  107.  
  108.         /* The outer loop below searches for an existing environment
  109.            variable of the same name as we have in varbuf[]. */
  110.  
  111.         while (*env) {
  112.  
  113.                 /* Compare current env variable with varbuf[]. */
  114.  
  115.                 e = env;
  116.                 v = (char *) varbuf;
  117.                 while (*e == *v)
  118.                     v++, e++;
  119.  
  120.                 /* If they matched, copy old value into varbuf[], and
  121.                    then delete it from the environment.  Otherwise,
  122.                    move env to point at the next environment variable
  123.                    for the next iteration of our main loop. */
  124.  
  125.                 if (!*v) {
  126.                         while (*v++ = *e++);
  127.                         if (*e)
  128.                                 while ((--size) && (*env++ = *e++) || (*e));
  129.                         *env = '\0';
  130.                 } else
  131.                         while ((--size) && (*env++));
  132.         }
  133.  
  134.         /* If no data was entered after the equal sign, then we are
  135.            supposed to delete the variable, which we've already done.
  136.            Otherwise, some work remains.  We have to re-add the variable
  137.            at the end of the environment with its old value, and then
  138.            append the new value after it. */
  139.  
  140.         if (*p != '\r') {
  141.  
  142.                 /* Copy name, equal sign, and old value into env. */
  143.  
  144.                 v = (char *) varbuf;
  145.                 while (*env = *v++) ++env, --size;
  146.  
  147.                 /* Now append new data to the end of the old value. */
  148.  
  149.                 while ((--size) && ((*env++ = *p++) != '\r'));
  150.  
  151.                 /* Ensure the environment is properly terminated with
  152.            two consecutive zeros. */
  153.  
  154.                 *env = '\0';
  155.                 *--env = '\0';
  156.  
  157.                 /* If we ran out of space somewhere above, sound a beep
  158.                    sequence to alert the user that something is fishy. */
  159.  
  160.                 if (size <= 0) {
  161.                         union REGS regs;
  162.                         static char bell [] = {0x07,'$',0};
  163.  
  164.                         regs.h.ah = 9;
  165.                         regs.x.dx = (unsigned int)bell;
  166.                         intdos (®s, ®s);
  167.  
  168.                         /*    Sorry, sound() is a Turbo routine!
  169.                         for (size = 3; (--size);) {
  170.                                 sound (650);
  171.                                 delay (60);
  172.                                 nosound ();
  173.                                 delay (50);
  174.                         };
  175.                         */
  176.                         exit (1);
  177.                 }
  178.         }
  179. }
  180.  
  181.