home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 June
/
SIMTEL_0692.cdr
/
msdos
/
microcrn
/
issue_42.arc
/
GLOBENV.C
< prev
next >
Wrap
Text File
|
1988-05-20
|
8KB
|
242 lines
/* Support code for C column in Micro C issue #42
Module: GlobEnv (Global Environment Access)
Version: 1.02
Date: April 11, 1988
Compilers: Microsoft C v5.10
Turbo C 1.5
Datalight/Zortech Optimum-C (requires -a compiler switch)
Environment: generic MS-DOS, version 2.1 and higher
Allows direct access to the global (system) environment. This module
has been tested with MS-DOS versions 2.11, 3.10, 3.2x, and 3.30.
Copyright (c) 1988 by Scott Robert Ladd.
This source-code file is released for non-commercial use by anyone
who wants to use it. No warranties are expressed or implied.
*/
#include "stddef.h"
#include "string.h"
#define TRUE -1
#define FALSE 0
/* external pointer to Program Segment Prefix (PSP) */
extern unsigned _psp;
/* structures for PSP and DOS Memory Control Block (MCB) */
typedef struct
{
char fill1[22];
unsigned parent_seg; /* segment of the parent of the current program */
char fill2[20];
unsigned env_seg; /* environment segment for current program */
}
PSP;
/* This structure needs to be compiled exactly as shown -- no aligning! */
/* The pack() pragma ensures Microsoft C will byte-align this structure. */
/* Since most compilers have no such pargma, this module must be compiled */
/* with BYTE alignment. This goes for Turbo C and Datalight C. */
#pragma pack(1)
typedef struct
{
char indicator; /* indicates whether this block is in chain */
unsigned PSP_seg; /* the PSP segment of this block's owner */
unsigned block_len; /* the size (in paragraphs) of this block */
}
MCB;
#pragma pack()
/* global variables */
static char far *envptr; /* pointer to first byte of global env. */
static unsigned int envlen; /* length of global environment */
static int initdone=FALSE; /* indicates whether the module is initialized */
/* function prototypes */
char *getgenv(char *varname);
int putgenv(char *varname, char *vartext);
int delgenv(char *varname);
static void findgenv(void);
/*
getgenv : Returns a pointer to the value of the environment variable
pointed to by varname. If the string is not found, NULL is
returned. Note that each call to this function erases the
array s, destroying any previous variable value.
*/
char *getgenv(char *varname)
{
char far *e;
char *v;
static char s[128];
register int i;
/* has the module been initialized? If not, do it! */
if (!initdone)
findgenv();
e = envptr;
/* search for varname */
while (*e)
{
v = varname;
for (;(*e == *v) && (*e != '=') && *e && *v; ++e, ++v);
if ((!*v) && (*e == '=')) /* varname found */
{
++e;
/* copy value to s */
/* can't use strcpy() due to possibly different-sized pointers */
for (i = 0; (i < 127) && *e; ++i)
{
s[i] = *e;
++e;
}
if (i < 127)
s[i] = 0;
return s; /* contains value of varname */
}
/* skip to the next environment variable */
for (; *e; ++e);
++e;
}
/* varname wasn't found */
return NULL;
}
/*
putgenv : Varstring is built from the variable name (varname) and vartext.
Stores the varstring into the current global environment.
Returns -1 if there is not enough room in the environment for
the new string; otherwise, 0 is returned.
*/
int putgenv(char *varname, char *vartext)
{
char far *e;
unsigned int l;
char varstring[256];
char *v;
/* has the module been initialized? If not, do it! */
if (!initdone)
findgenv();
/* make a complete environment string from the components given */
strcpy(varstring,varname);
strupr(varstring); /* make sure the name of the variable is uppercase */
strcat(varstring,"=");
strcat(varstring,vartext);
/* delete any existing variables of the same name */
delgenv(varname);
/* find the end of the current variables (mark by two nulls) */
for (e = envptr, l = 0; !(!*e && !*(e+1)); ++e, ++l);
/* get the amount of remaining space */
l = envlen - l;
/* if the new variable won't fit, return an error */
if (l < strlen(varstring))
return -1;
v = varstring;
/* otherwise, copy varstring onto the end of the current environment */
for (++e; *v; *e++ = *v++);
/* and end the environment with two NUL bytes */
*e = 0;
++e;
*e = 0;
/* it worked! */
return 0;
}
/*
delgenv : Deletes a global environment variable.
*/
int delgenv(char *varname)
{
char far *e1; /* used in search & marks beginning of next variable */
char far *e2; /* marks beginning of the variable */
char *v; /* varname pointer used in serach */
int searching = TRUE; /* flag to indicate serach end */
/* has the module been initialized? If not, do it! */
if (!initdone)
findgenv();
e1 = envptr;
/* find the beginning of the variable to be deleted */
while (*e1 && searching)
{
v = varname;
e2 = e1;
for (;(*e1 == *v) && (*e1 != '=') && *e1 && *v; ++e1, ++v);
if ((!*v) && (*e1 == '='))
searching = FALSE; /* the variable we want was found! */
for (; *e1; ++e1);
++e1;
}
/* if varname wasn't found, return with an error */
if (!*e1 && searching)
return -1;
/* otherwise, copy the remainder of the environment over varname */
for (; !(!*e1 && !*(e1+1)); *e2++ = *e1++);
/* end the environment with double NUL bytes */
*e2 = 0;
++e2;
*e2 = 0;
/* it worked */
return 0;
}
/*
findgenv : This function must be called before the other functions
in the module will work.
*/
static void findgenv()
{
PSP far *curPSP; /* current PSP */
PSP far *parPSP; /* parent PSP */
MCB far *parMCB; /* parent MCB */
MCB far *envMCB; /* environment MCB */
/* set pointers to the PSPs of the current program and its parent */
curPSP = (PSP far *)((long)_psp << 16);
parPSP = (PSP far *)((long)(curPSP->parent_seg) << 16);
if (parPSP->env_seg == 0)
{
/* the environment is in the block after the parent program */
parMCB = (MCB far *)((long)parPSP - 0x10000L);
envptr = (char far *)((long)parPSP + 0x10000L + ((long)parMCB->block_len << 16));
}
else
/* we have a direct pointer to the environment */
envptr = (char far *)((long)(parPSP->env_seg) << 16);
/* the MCB of the environment is one segment lower in memory */
envMCB = (MCB far *)((long)(envptr) - 0x10000L);
/* save the length of the environment */
envlen = envMCB->block_len;
/* make sure the other functions know that findgenv is done */
initdone = TRUE;
}