File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ntp / sntp / libopts / environment.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue May 29 12:08:38 2012 UTC (12 years, 7 months ago) by misho
Branches: ntp, MAIN
CVS tags: v4_2_6p5p0, v4_2_6p5, HEAD
ntp 4.2.6p5

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>