summaryrefslogtreecommitdiff
path: root/dmake/mac/environ.c
blob: 1aa7d29b4f73aa1377deb4700210113a8426641f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/* 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;
{
        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 */
}

} /* 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 */

} /* PUBLIC void free_env () */