home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 September
/
Simtel20_Sept92.cdr
/
msdos
/
sysutl
/
appenv21.arc
/
APPENV.C
next >
Wrap
Text File
|
1989-10-20
|
5KB
|
152 lines
/*
* APPENV - APPend to ENVironment --2.1-- Copyright (c) Mark Lord, 1989
*
* Feel free to copy, use and/or modify this for any non-commercial
* purpose(s). Please keep this copyright header in place.
*
* Compile this under TINY model of Turbo-C 2.0 and use the /t with TLINK
* to produce a small .COM file.
*/
#include <dos.h>
#include <ctype.h>
char cant_find_env [] = "APPENV: can't find master environment\n$";
char helptext [] =
"\r\nAPPENV -- APPend to ENVironment --- Version 2.1 (c) 1989 by Mark Lord\r\n\n"\
"This command allows appending data to the end of an existing environment\r\n"\
"variable, such as PATH. Usage: APPENV <var>=<data>\r\n"\
"Where <var> is the name of the environment variable, and <data> is the\r\n"\
"value to be assigned to it. If <var> does not already exist, it will be\r\n"\
"created with a value of <data>, otherwise <data> will be appended to the\r\n"\
"current value of <var>. If no <data> is given, then <var> will be erased\r\n"\
"from the environment. If there is not enough environment space left for\r\n"\
"<data>, it will be truncated and a beep! will be sounded on the speaker.\r\n"\
"Works only with DOS 3.3 or higher.\r\n$";
void quit (char *text)
{
/* Output the help text and exit with ERRORLEVEL=2. */
union REGS regs;
regs.h.ah = 9;
regs.x.dx = FP_OFF (text);
intdos (®s, ®s);
exit (2);
}
void main ()
{
int size, env_para;
unsigned psp, far *tmp;
char far *env, far *e, far *p, varbuf[1024], *v;
/* _psp is our PSP. Follow the "parent" links back
until we find a PSP for COMMAND.COM, which has
a parent link that points at itself. */
psp = _psp;
while (psp != *(tmp = MK_FP(psp,22)))
psp = *tmp;
/* Now get the address of COMMAND.COM's environment block
from its PSP. */
if (!(env_para = *(unsigned far *)MK_FP(psp,44)))
quit (cant_find_env);
env = MK_FP(env_para,0);
/* Get the block size from the MCB which immediately
preceeds the environment block. This is a paragraph count,
which must be multiplied by 16 to get a byte count. */
size = 16 * *(int far *) MK_FP(FP_SEG(env)-1,3);
/* Back to our own PSP again, where our command line
parameters are stored, terminated by a carriage return. */
p = MK_FP(_psp,129);
/* Ignore leading spaces (there is usually one or more),
and give the user some help if there is nothing else there. */
while (*p == ' ') ++p;
if ((*p == '\r') || (*p == '=')) quit (helptext);
/* Now some tricky parsing to extract the variable name and
equal sign into varbuf[], ignoring spaces between the name
and the equal sign. If there is no equal sign, give the
user some help instead. */
v = (char *) &varbuf;
while ((*p != '\r') && ((*v = toupper(*p++)) != '='))
if (*v != ' ') ++v;
if (*v != '=') quit (helptext);
*++v = '\0';
/* The outer loop below searches for an existing environment
variable of the same name as we have in varbuf[]. */
while (*env) {
/* Compare current env variable with varbuf[]. */
e = env;
v = (char *) &varbuf;
while (*e == *v) ++v, ++e;
/* If they matched, copy old value into varbuf[], and
then delete it from the environment. Otherwise,
move env to point at the next environment variable
for the next iteration of our main loop. */
if (!*v) {
while (*v++ = *e++);
if (*e)
while ((--size) && (*env++ = *e++) || (*e));
*env = '\0';
} else
while ((--size) && (*env++));
}
/* If no data was entered after the equal sign, then we are
supposed to delete the variable, which we've already done.
Otherwise, some work remains. We have to re-add the variable
at the end of the environment with its old value, and then
append the new value after it. */
if (*p != '\r') {
/* Copy name, equal sign, and old value into env. */
v = (char *) &varbuf;
while (*env = *v++) ++env, --size;
/* Now append new data to the end of the old value. */
while ((--size) && ((*env++ = *p++) != '\r'));
/* Ensure the environment is properly terminated with
two consecutive zeros. */
*env = '\0';
*--env = '\0';
/* If we ran out of space somewhere above, sound a beep
sequence to alert the user that something is fishy. */
if (size <= 0) {
for (size = 3; (--size);) {
sound (650);
delay (60);
nosound ();
delay (50);
};
exit (1);
}
}
}