home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Guide
/
c-cplusplus-interactive-guide.iso
/
c_ref
/
csource4
/
288_01
/
mstr_env.c
< prev
next >
Wrap
Text File
|
1989-05-25
|
9KB
|
339 lines
/*========================================================================
Module: Mstr_Env (Master Environment Access)
Version: 1.00 11-Mar-1989
Written by Scott Robert Ladd.
This software has been released into the public domain;
no warranties are expressed or implied.
This source code will work with most MS-DOS C compilers. It has been
tested with Microsoft C 5.1 and QuickC 2.0, Borland Turbo C 2.0, and
Zortech C v1.07.
=========================================================================*/
#include "dos.h" /* _psp definition */
#include "stddef.h" /* NULL and other standard definitions */
#include "string.h" /* string functions */
#include "mstr_env.h" /* to get prototypes */
/* define a macro for MSC and QC */
#if defined(_QC) || defined (_MSC)
#define MK_FP(seg,off) ((void far *)(((long)(seg) << 16L) | (long)(off)))
#endif
/*
internal MS-DOS structures
--------------------------
*/
typedef struct
{
char reserved1[22];
unsigned par_seg; /* segment of the parent of the current program */
char reserved2[20];
unsigned env_seg; /* environment segment for current program */
}
PSP;
/*-----------------
IMPORTANT NOTE!
-----------------------------------------------------------------------
The MCB structure must be compiled with byte, not word, alignment. In
Microsoft C, this is accomplished through the use of the pack pragma.
By default, Turbo C uses byte alignment. When compiling this module
with Zortech C, the -a switch must be used to get byte alignment.
----------------------------------------------------------------------- */
#if defined(_QC) || defined(_MSC)
#pragma pack(1)
#endif
typedef struct
{
char status; /* indicates whether this block is in chain */
unsigned owner_PSP; /* the PSP segment of this block's owner */
unsigned len; /* the size (in paragraphs) of this memory block */
}
MCB;
#if defined(_QC) || defined(_MSC)
#pragma pack()
#endif
/*
global declarations
-------------------
*/
char far * env_ptr; /* pointer to first byte of global env. */
static unsigned env_len; /* length of global environment */
static int initialized = 0; /* indicates whether the module is initialized */
static char s[256]; /* internal buffer used for strings */
static void m_findenv(void); /* internal function used to find the master
environment */
#define NUL '\x00' /* the nul (zero) character used by C as a string
terminator */
/*
function definitions
--------------------
*/
/*
function: m_getenv
purpose: retrieves an environment variable's value
parameters: name -- the name of the variable whose value is sought
returns: A pointer to the value of the requested variable, or NULL if the
variable was not found.
NOTE: the return value is a pointer to a static char array in
this module. Thus the previous value is destroyed each time this
function is called.
*/
char * m_getenv(char * name)
{
char far * e;
char * n;
int i;
/* check for initialization */
if (!initialized)
m_findenv();
e = env_ptr;
/* search for name */
while (*e)
{
n = name;
while ((*e == *n) && (*e != '=') && (*e != NUL) && (*n != NUL))
{
++e;
++n;
}
if ((*n == NUL) && (*e == '=')) /* name found */
{
/* copy variable value to s */
++e;
/* strcpy() cannot be used because pointer sizes may differ */
for (i = 0; (i < 256) && (*e != NUL); ++i)
{
s[i] = *e;
++e;
}
if (i < 256)
s[i] = NUL;
return s; /* contains value of name */
}
/* skip to the next environment variable */
while (*e != NUL)
++e;
++e;
}
/* name wasn't found */
return NULL;
}
/*
function: m_putenv
purpose: stores an environment variable
parameters: name -- name of the variable to be stored
text -- the variable's value
returns: 0 if the variable was stored
1 if not
*/
int m_putenv(char *name, char *text)
{
char far * e;
unsigned l = 0;
char * sptr;
/* check for initialization */
if (!initialized)
m_findenv();
e = env_ptr;
/* check to see that the storage required is < 256 bytes */
if ((strlen(name) + 2 + strlen(text)) > 256)
return 1;
/* make a complete environment string from the components given */
strcpy(s,name);
strupr(s);
strcat(s,"=");
strcat(s,text);
/* delete any existing variables of the same name */
m_delenv(name);
/* find the end of the current variables (mark by two nulls) */
e = env_ptr;
l = 0;
/* loop until two NULs are found, signifying the end of the environment */
while (!((*e == NUL) && (*(e+1) == NUL)))
{
++e;
++l;
}
/* get the amount of remaining space */
l = env_len - l - 1;
/* if the new variable won't fit, return an error */
if (l < strlen(s))
return 1;
sptr = s;
/* otherwise, copy s onto the end of the current environment */
++e;
while (*sptr != NUL)
*e++ = *sptr++;
/* end the environment with two NUL bytes */
*e = NUL;
*(e + 1) = NUL;
/* it worked! */
return 0;
}
/*
function: m_delgenv
purpose: deletes an environment variable
parameters: name -- the name of the variable to be deleted
returns: 1 if the variable could not be deleted or does not exit
0 upon success
*/
int m_delenv(char *name)
{
char far * e1; /* used in search & marks beginning of next variable */
char far * e2; /* marks beginning of the variable */
char * n; /* name pointer used in search */
int searching = 1; /* flag to indicate search end */
/* has the module been initialized? If not, do it! */
if (!initialized)
m_findenv();
e1 = env_ptr;
/* find the beginning of the variable to be deleted */
while ((*e1 != NUL) && (searching))
{
n = name;
e2 = e1;
while ((*e1 == *n) && (*e1 != '=') && (*e1 != NUL) && (*n != NUL))
{
++e1;
++n;
}
if ((!*n) && (*e1 == '='))
searching = 0; /* the variable we want was found! */
while (*e1 != NUL)
++e1;
++e1;
}
/* if name wasn't found, return with an error */
if ((*e1 == NUL) && (searching))
return 1;
/* otherwise, copy the remainder of the environment over name */
while (!((*e1 == NUL) && (*(e1+1) == NUL)))
{
*e2 = *e1;
e2++;
e1++;
}
/* end the environment with double NUL bytes */
*e2 = NUL;
*(e2 + 1) = NUL;
/* it worked */
return 0;
}
/*
function: m_findenv
purpose: locates the global environment and sets a pointer to it
parameters: none
returns: nothing
*/
static void m_findenv()
{
union REGS regs;
struct SREGS sregs;
int far * SEGptr; /* set to address of segment of first MCB */
MCB far * CONFIGmcb; /* set to address of CONFIG's MCB */
MCB far * SHELLmcb; /* set to address of COMMAND.COM's MCB */
MCB far * ENVmcb; /* set to address of environment's MCB */
PSP far * SHELLpsp; /* set to address of COMMAND.COM's PSP */
regs.h.ah = 0x52;
intdosx(®s,®s,&sregs);
SEGptr = MK_FP(