232 lines
6.1 KiB
C
232 lines
6.1 KiB
C
|
/* RCS $Id: environ.c,v 1.1.1.1 2000-09-22 15:33:27 hr Exp $
|
||
|
--
|
||
|
-- SYNOPSIS
|
||
|
-- Set up and free for environ
|
||
|
--
|
||
|
-- DESCRIPTION
|
||
|
-- This file contains routines that will fill in and dispose of the
|
||
|
-- list of environmental variables in the environ global variable.
|
||
|
--
|
||
|
-- AUTHOR
|
||
|
-- Dennis Vadura, dvadura@dmake.wticorp.com
|
||
|
--
|
||
|
--
|
||
|
-- WWW
|
||
|
-- http://dmake.wticorp.com/
|
||
|
--
|
||
|
-- COPYRIGHT
|
||
|
-- Copyright (c) 1996,1997 by WTI Corp. All rights reserved.
|
||
|
--
|
||
|
-- This program is NOT free software; you can redistribute it and/or
|
||
|
-- modify it under the terms of the Software License Agreement Provided
|
||
|
-- in the file <distribution-root>/readme/license.txt.
|
||
|
--
|
||
|
-- LOG
|
||
|
-- Use cvs log to obtain detailed change logs.
|
||
|
*/
|
||
|
|
||
|
#include "extern.h"
|
||
|
|
||
|
/* The char used to replace the equal signs in environmental variable names. */
|
||
|
const char kEqualReplace = '_';
|
||
|
|
||
|
/* Maximum size of a "name=value" environmental string, including the ending '\0'.
|
||
|
Larger environmental variables will be clipped before dmake sees them.
|
||
|
(Caution: When I tested the program, the Mac or dmake trashed memory
|
||
|
when environmental variables of >4K were read in. I looked around a bit
|
||
|
and couldn't find out the exact cause, so I simply made this variable.
|
||
|
The memory trashing may be related to the value for MAXLINELENGTH.) */
|
||
|
const int kMaxEnvLen = 1024;
|
||
|
|
||
|
|
||
|
/* The list of environmental variables in the form "name=value".
|
||
|
(Once make_env() has been called.) */
|
||
|
char **environ = NULL;
|
||
|
|
||
|
/* Characters replaced during make_env() */
|
||
|
struct ReplaceChar {
|
||
|
char *fpPos;
|
||
|
char fC;
|
||
|
struct ReplaceChar *fpNext;
|
||
|
}; /* struct ReplaceChar */
|
||
|
struct ReplaceChar *gpReplaceList = NULL;
|
||
|
|
||
|
|
||
|
void AddReplace (char *pReplacePos);
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Set up the environmental variables in a format used by
|
||
|
* the environ global variable.
|
||
|
*
|
||
|
* environ has already been set to main's envp argument when
|
||
|
* this suboroutine is called. We assume that envp is a copy
|
||
|
* MPW makes for this process' use alone, so we can modify it
|
||
|
* below.
|
||
|
*/
|
||
|
PUBLIC void
|
||
|
make_env()
|
||
|
{
|
||
|
char **ppCurEnv;
|
||
|
char *pCurPos;
|
||
|
#if 0
|
||
|
char **ppMacEnv;
|
||
|
char *pMacPos;
|
||
|
|
||
|
if (!gMECalled) {
|
||
|
gMECalled = TRUE;
|
||
|
|
||
|
environ = MALLOC (1, char *);
|
||
|
*environ = NULL;
|
||
|
#endif
|
||
|
#if 0
|
||
|
{
|
||
|
int numenv;
|
||
|
int len;
|
||
|
int firstnil;
|
||
|
|
||
|
numenv = 1;
|
||
|
ppMacEnv = environ;
|
||
|
while (*(ppMacEnv++) != NULL) {
|
||
|
++numenv;
|
||
|
} /* while */
|
||
|
|
||
|
ppMacEnv = environ;
|
||
|
if ((environ = MALLOC (numenv, char *)) == NULL) {
|
||
|
No_ram ();
|
||
|
} /* if */
|
||
|
|
||
|
numenv = 80;
|
||
|
for (ppCurEnv = environ; (numenv-- > 0) && (*ppMacEnv != NULL); ++ppCurEnv, ++ppMacEnv) {
|
||
|
pMacPos = *ppMacEnv;
|
||
|
len = strlen (pMacPos) + 1;
|
||
|
len += strlen (pMacPos + len) + 1;
|
||
|
#define MAXLEN 4098
|
||
|
if (len > MAXLEN) len = MAXLEN;
|
||
|
if ((*ppCurEnv = MALLOC (len, char)) == NULL) {
|
||
|
No_ram ();
|
||
|
} /* if */
|
||
|
|
||
|
firstnil = TRUE;
|
||
|
for (pCurPos = *ppCurEnv; ((pCurPos - *ppCurEnv) < MAXLEN - 1); ++pCurPos, ++pMacPos) {
|
||
|
if (*pMacPos == '=') {
|
||
|
*pCurPos = gEqualReplace;
|
||
|
|
||
|
} else if (*pMacPos == '\0') {
|
||
|
if (firstnil) {
|
||
|
*pCurPos = '=';
|
||
|
firstnil = FALSE;
|
||
|
} else {
|
||
|
*pCurPos = *pMacPos;
|
||
|
break;
|
||
|
} /* if ... else */
|
||
|
|
||
|
} else {
|
||
|
*pCurPos = *pMacPos;
|
||
|
} /* if ... elses */
|
||
|
} /* for */
|
||
|
firstnil = FALSE;
|
||
|
} /* for */
|
||
|
*ppCurEnv = NULL;
|
||
|
}
|
||
|
#endif
|
||
|
{
|
||
|
int firstnil;
|
||
|
|
||
|
/* Get rid of any equal signs in any environmental name, and put
|
||
|
equal signs between the names and their values */
|
||
|
for (ppCurEnv = environ; *ppCurEnv != NULL; ++ppCurEnv) {
|
||
|
|
||
|
firstnil = TRUE;
|
||
|
for (pCurPos = *ppCurEnv;
|
||
|
((pCurPos - *ppCurEnv < kMaxEnvLen - 1) &&
|
||
|
((*pCurPos != '\0') || firstnil));
|
||
|
++pCurPos) {
|
||
|
if (*pCurPos == '=') {
|
||
|
AddReplace (pCurPos);
|
||
|
*pCurPos = kEqualReplace;
|
||
|
|
||
|
} else if (*pCurPos == '\0') {
|
||
|
AddReplace (pCurPos);
|
||
|
*pCurPos = '=';
|
||
|
firstnil = FALSE;
|
||
|
} /* if ... else if */
|
||
|
} /* for */
|
||
|
|
||
|
/* If the environtmental variable was too large ... */
|
||
|
if (*pCurPos != '\0') {
|
||
|
AddReplace (pCurPos);
|
||
|
*pCurPos = '\0';
|
||
|
if (firstnil) {
|
||
|
AddReplace (--pCurPos);
|
||
|
*pCurPos = '=';
|
||
|
} /* if */
|
||
|
} /* if */
|
||
|
} /* for */
|
||
|
}
|
||
|
#if 0
|
||
|
} /* if */
|
||
|
#endif
|
||
|
} /* PUBLIC void make_env () */
|
||
|
|
||
|
|
||
|
/*
|
||
|
* The character at pReplacePos is about to be replaced. Remember the
|
||
|
* old value so we can restore it when we're done.
|
||
|
*/
|
||
|
void AddReplace (char *pReplacePos) {
|
||
|
struct ReplaceChar *pReplaceChar;
|
||
|
|
||
|
if ((pReplaceChar = MALLOC (1, struct ReplaceChar)) == NULL) {
|
||
|
No_ram ();
|
||
|
} /* if */
|
||
|
pReplaceChar->fpPos = pReplacePos;
|
||
|
pReplaceChar->fC = *pReplacePos;
|
||
|
pReplaceChar->fpNext = gpReplaceList;
|
||
|
gpReplaceList = pReplaceChar;
|
||
|
} /* void AddReplace () */
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Restore the old environmental variables to the way they looked before
|
||
|
* the make_env() call, on the unlikely chance that something else will look
|
||
|
* at our copy of the environmental variables during the program execution.
|
||
|
*
|
||
|
*/
|
||
|
PUBLIC void
|
||
|
free_env()
|
||
|
{
|
||
|
struct ReplaceChar *pReplaceChar;
|
||
|
|
||
|
while (gpReplaceList != NULL) {
|
||
|
pReplaceChar = gpReplaceList;
|
||
|
gpReplaceList = pReplaceChar->fpNext;
|
||
|
|
||
|
*(pReplaceChar->fpPos) = pReplaceChar->fC;
|
||
|
|
||
|
FREE (pReplaceChar);
|
||
|
} /* while */
|
||
|
|
||
|
#if 0
|
||
|
char **ppCurEnv;
|
||
|
char *pCurPos;
|
||
|
|
||
|
if (!gFECalled) {
|
||
|
gFECalled = TRUE;
|
||
|
|
||
|
//FREE (environ);
|
||
|
environ = NULL;
|
||
|
#endif
|
||
|
#if 0
|
||
|
/* Restore the environment list to what it was before we
|
||
|
read it in. */
|
||
|
for (ppCurEnv = environ; *ppCurEnv != NULL; ++ppCurEnv) {
|
||
|
for (pCurPos = *ppCurEnv; *pCurPos != '='; ++pCurPos)
|
||
|
;
|
||
|
*pCurPos = '\0';
|
||
|
} /* for */
|
||
|
} /* if */
|
||
|
#endif
|
||
|
} /* PUBLIC void free_env () */
|