Coverage Report

Created: 2026-02-26 06:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ntp-dev/sntp/libopts/env.c
Line
Count
Source
1
2
/**
3
 * \file environment.c
4
 *
5
 *  This file contains all of the routines that must be linked into
6
 *  an executable to use the generated option processing.  The optional
7
 *  routines are in separately compiled modules so that they will not
8
 *  necessarily be linked in.
9
 *
10
 * @addtogroup autoopts
11
 * @{
12
 */
13
/*
14
 *  This file is part of AutoOpts, a companion to AutoGen.
15
 *  AutoOpts is free software.
16
 *  AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved
17
 *
18
 *  AutoOpts is available under any one of two licenses.  The license
19
 *  in use must be one of these two and the choice is under the control
20
 *  of the user of the license.
21
 *
22
 *   The GNU Lesser General Public License, version 3 or later
23
 *      See the files "COPYING.lgplv3" and "COPYING.gplv3"
24
 *
25
 *   The Modified Berkeley Software Distribution License
26
 *      See the file "COPYING.mbsd"
27
 *
28
 *  These files have the following sha256 sums:
29
 *
30
 *  8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95  COPYING.gplv3
31
 *  4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b  COPYING.lgplv3
32
 *  13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239  COPYING.mbsd
33
 */
34
35
/*
36
 *  doPrognameEnv - check for preset values from the ${PROGNAME}
37
 *  environment variable.  This is accomplished by parsing the text into
38
 *  tokens, temporarily replacing the arg vector and calling
39
 *  immediate_opts and/or regular_opts.
40
 */
41
static void
42
doPrognameEnv(tOptions * pOpts, teEnvPresetType type)
43
0
{
44
0
    char const *        env_opts = getenv(pOpts->pzPROGNAME);
45
0
    token_list_t *      pTL;
46
0
    int                 sv_argc;
47
0
    proc_state_mask_t   sv_flag;
48
0
    char **             sv_argv;
49
50
    /*
51
     *  No such beast?  Then bail now.
52
     */
53
0
    if (env_opts == NULL)
54
0
        return;
55
56
    /*
57
     *  Tokenize the string.  If there's nothing of interest, we'll bail
58
     *  here immediately.
59
     */
60
0
    pTL = ao_string_tokenize(env_opts);
61
0
    if (pTL == NULL)
62
0
        return;
63
64
    /*
65
     *  Substitute our $PROGNAME argument list for the real one
66
     */
67
0
    sv_argc = (int)pOpts->origArgCt;
68
0
    sv_argv = pOpts->origArgVect;
69
0
    sv_flag = pOpts->fOptSet;
70
71
    /*
72
     *  We add a bogus pointer to the start of the list.  The program name
73
     *  has already been pulled from "argv", so it won't get dereferenced.
74
     *  The option scanning code will skip the "program name" at the start
75
     *  of this list of tokens, so we accommodate this way ....
76
     */
77
0
    {
78
0
        uintptr_t v = (uintptr_t)(pTL->tkn_list);
79
0
        pOpts->origArgVect = VOIDP(v - sizeof(char *));
80
0
    }
81
0
    pOpts->origArgCt   = (unsigned int)pTL->tkn_ct   + 1;
82
0
    pOpts->fOptSet    &= ~OPTPROC_ERRSTOP;
83
84
0
    pOpts->curOptIdx   = 1;
85
0
    pOpts->pzCurOpt    = NULL;
86
87
0
    switch (type) {
88
0
    case ENV_IMM:
89
0
        (void)immediate_opts(pOpts);
90
0
        break;
91
92
0
    case ENV_ALL:
93
0
        (void)immediate_opts(pOpts);
94
0
        pOpts->curOptIdx = 1;
95
0
        pOpts->pzCurOpt  = NULL;
96
        /* FALLTHROUGH */
97
98
0
    case ENV_NON_IMM:
99
0
        (void)regular_opts(pOpts);
100
0
    }
101
102
    /*
103
     *  Free up the temporary arg vector and restore the original program args.
104
     */
105
0
    free(pTL);
106
0
    pOpts->origArgVect = sv_argv;
107
0
    pOpts->origArgCt   = (unsigned int)sv_argc;
108
0
    pOpts->fOptSet     = sv_flag;
109
0
}
110
111
static void
112
do_env_opt(tOptState * os, char * env_name,
113
            tOptions * pOpts, teEnvPresetType type)
114
0
{
115
0
    os->pzOptArg = getenv(env_name);
116
0
    if (os->pzOptArg == NULL)
117
0
        return;
118
119
0
    os->flags   = OPTST_PRESET | OPTST_ALLOC_ARG | os->pOD->fOptState;
120
0
    os->optType = TOPT_UNDEFINED;
121
122
0
    if (  (os->pOD->pz_DisablePfx != NULL)
123
0
       && (streqvcmp(os->pzOptArg, os->pOD->pz_DisablePfx) == 0)) {
124
0
        os->flags |= OPTST_DISABLED;
125
0
        os->pzOptArg = NULL;
126
0
        handle_opt(pOpts, os);
127
0
        return;
128
0
    }
129
130
0
    switch (type) {
131
0
    case ENV_IMM:
132
        /*
133
         *  Process only immediate actions
134
         */
135
0
        if (DO_IMMEDIATELY(os->flags))
136
0
            break;
137
0
        return;
138
139
0
    case ENV_NON_IMM:
140
        /*
141
         *  Process only NON immediate actions
142
         */
143
0
        if (DO_NORMALLY(os->flags) || DO_SECOND_TIME(os->flags))
144
0
            break;
145
0
        return;
146
147
0
    default: /* process everything */
148
0
        break;
149
0
    }
150
151
    /*
152
     *  Make sure the option value string is persistent and consistent.
153
     *
154
     *  The interpretation of the option value depends
155
     *  on the type of value argument the option takes
156
     */
157
0
    if (OPTST_GET_ARGTYPE(os->pOD->fOptState) == OPARG_TYPE_NONE) {
158
        /*
159
         *  Ignore any value.
160
         */
161
0
        os->pzOptArg = NULL;
162
163
0
    } else if (os->pzOptArg[0] == NUL) {
164
        /*
165
         * If the argument is the empty string and the argument is
166
         * optional, then treat it as if the option was not specified.
167
         */
168
0
        if ((os->pOD->fOptState & OPTST_ARG_OPTIONAL) == 0)
169
0
            return;
170
0
        os->pzOptArg = NULL;
171
172
0
    } else {
173
0
        AGDUPSTR(os->pzOptArg, os->pzOptArg, "option argument");
174
0
        os->flags |= OPTST_ALLOC_ARG;
175
0
    }
176
177
0
    handle_opt(pOpts, os);
178
0
}
179
180
/*
181
 *  env_presets - check for preset values from the envrionment
182
 *  This routine should process in all, immediate or normal modes....
183
 */
184
static void
185
env_presets(tOptions * pOpts, teEnvPresetType type)
186
0
{
187
0
    int        ct;
188
0
    tOptState  st;
189
0
    char *     pzFlagName;
190
0
    size_t     spaceLeft;
191
0
    char       zEnvName[ AO_NAME_SIZE ];
192
193
    /*
194
     *  Finally, see if we are to look at the environment
195
     *  variables for initial values.
196
     */
197
0
    if ((pOpts->fOptSet & OPTPROC_ENVIRON) == 0)
198
0
        return;
199
200
0
    doPrognameEnv(pOpts, type);
201
202
0
    ct  = pOpts->presetOptCt;
203
0
    st.pOD = pOpts->pOptDesc;
204
205
0
    pzFlagName = zEnvName
206
0
        + snprintf(zEnvName, sizeof(zEnvName), "%s_", pOpts->pzPROGNAME);
207
0
    spaceLeft = AO_NAME_SIZE - (unsigned long)(pzFlagName - zEnvName) - 1;
208
209
0
    for (;ct-- > 0; st.pOD++) {
210
0
        size_t nln;
211
212
        /*
213
         *  If presetting is disallowed, then skip this entry
214
         */
215
0
        if (  ((st.pOD->fOptState & OPTST_NO_INIT) != 0)
216
0
           || (st.pOD->optEquivIndex != NO_EQUIVALENT)  )
217
0
            continue;
218
219
        /*
220
         *  IF there is no such environment variable,
221
         *  THEN skip this entry, too.
222
         */
223
0
        nln = strlen(st.pOD->pz_NAME) + 1;
224
0
        if (nln <= spaceLeft) {
225
            /*
226
             *  Set up the option state
227
             */
228
0
            memcpy(pzFlagName, st.pOD->pz_NAME, nln);
229
0
            do_env_opt(&st, zEnvName, pOpts, type);
230
0
        }
231
0
    }
232
233
    /*
234
     *  Special handling for ${PROGNAME_LOAD_OPTS}
235
     */
236
0
    if (  (pOpts->specOptIdx.save_opts != NO_EQUIVALENT)
237
0
       && (pOpts->specOptIdx.save_opts != 0)) {
238
0
        size_t nln;
239
0
        st.pOD = pOpts->pOptDesc + pOpts->specOptIdx.save_opts + 1;
240
241
0
        if (st.pOD->pz_NAME == NULL)
242
0
            return;
243
244
0
        nln = strlen(st.pOD->pz_NAME) + 1;
245
246
0
        if (nln > spaceLeft)
247
0
            return;
248
249
0
        memcpy(pzFlagName, st.pOD->pz_NAME, nln);
250
0
        do_env_opt(&st, zEnvName, pOpts, type);
251
0
    }
252
0
}
253
254
/** @}
255
 *
256
 * Local Variables:
257
 * mode: C
258
 * c-file-style: "stroustrup"
259
 * indent-tabs-mode: nil
260
 * End:
261
 * end of autoopts/environment.c */