home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_02_02 / 2n02069b < prev    next >
Text File  |  1990-12-18  |  5KB  |  154 lines

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