Ignore:
Timestamp:
May 27, 2001, 8:10:36 AM (24 years ago)
Author:
umoeller
Message:

Misc changes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/helpers/dosh2.c

    r71 r76  
    349349
    350350    return (arc);       // V0.9.9 (2001-04-04) [umoeller]
    351 }
    352 
    353 /*
    354  *@@category: Helpers\Control program helpers\Environment management
    355  *      helpers for managing those ugly environment string arrays
    356  *      that are used with DosStartSession and WinStartApp.
    357  */
    358 
    359 /* ******************************************************************
    360  *
    361  *   Environment helpers
    362  *
    363  ********************************************************************/
    364 
    365 /*
    366  *@@ doshParseEnvironment:
    367  *      this takes one of those ugly environment strings
    368  *      as used by DosStartSession and WinStartApp (with
    369  *      lots of zero-terminated strings one after another
    370  *      and a duplicate zero byte as a terminator) as
    371  *      input and splits it into an array of separate
    372  *      strings in pEnv.
    373  *
    374  *      The newly allocated strings are stored in in
    375  *      pEnv->papszVars. The array count is stored in
    376  *      pEnv->cVars.
    377  *
    378  *      Each environment variable will be copied into
    379  *      one newly allocated string in the array. Use
    380  *      doshFreeEnvironment to free the memory allocated
    381  *      by this function.
    382  *
    383  *      Use the following code to browse thru the array:
    384  +
    385  +          DOSENVIRONMENT Env = {0};
    386  +          if (doshParseEnvironment(pszEnv,
    387  +                                   &Env)
    388  +                  == NO_ERROR)
    389  +          {
    390  +              if (Env.papszVars)
    391  +              {
    392  +                  PSZ *ppszThis = Env.papszVars;
    393  +                  for (ul = 0;
    394  +                       ul < Env.cVars;
    395  +                       ul++)
    396  +                  {
    397  +                      PSZ pszThis = *ppszThis;
    398  +                      // pszThis now has something like PATH=C:\TEMP
    399  +                      // ...
    400  +                      // next environment string
    401  +                      ppszThis++;
    402  +                  }
    403  +              }
    404  +              doshFreeEnvironment(&Env);
    405  +          }
    406  *
    407  *@@added V0.9.4 (2000-08-02) [umoeller]
    408  */
    409 
    410 APIRET doshParseEnvironment(const char *pcszEnv,
    411                             PDOSENVIRONMENT pEnv)
    412 {
    413     APIRET arc = NO_ERROR;
    414     if (!pcszEnv)
    415         arc = ERROR_INVALID_PARAMETER;
    416     else
    417     {
    418         PSZ     pszVarThis = (PSZ)pcszEnv;
    419         ULONG   cVars = 0;
    420         // count strings
    421         while (*pszVarThis)
    422         {
    423             cVars++;
    424             pszVarThis += strlen(pszVarThis) + 1;
    425         }
    426 
    427         pEnv->cVars = cVars;
    428         pEnv->papszVars = 0;
    429 
    430         if (cVars)
    431         {
    432             PSZ *papsz = (PSZ*)malloc(sizeof(PSZ) * cVars);
    433             if (!papsz)
    434                 arc = ERROR_NOT_ENOUGH_MEMORY;
    435             else
    436             {
    437                 PSZ *ppszTarget = papsz;
    438                 memset(papsz, 0, sizeof(PSZ) * cVars);
    439                 pszVarThis = (PSZ)pcszEnv;
    440                 while (*pszVarThis)
    441                 {
    442                     *ppszTarget = strdup(pszVarThis);
    443                     ppszTarget++;
    444                     pszVarThis += strlen(pszVarThis) + 1;
    445                 }
    446 
    447                 pEnv->papszVars = papsz;
    448             }
    449         }
    450     }
    451 
    452     return (arc);
    453 }
    454 
    455 /*
    456  *@@ doshGetEnvironment:
    457  *      calls doshParseEnvironment for the current
    458  *      process environment, which is retrieved from
    459  *      the info blocks.
    460  *
    461  *@@added V0.9.4 (2000-07-19) [umoeller]
    462  */
    463 
    464 APIRET doshGetEnvironment(PDOSENVIRONMENT pEnv)
    465 {
    466     APIRET  arc = NO_ERROR;
    467     if (!pEnv)
    468         arc = ERROR_INVALID_PARAMETER;
    469     else
    470     {
    471         PTIB    ptib = 0;
    472         PPIB    ppib = 0;
    473         arc = DosGetInfoBlocks(&ptib, &ppib);
    474         if (arc == NO_ERROR)
    475         {
    476             PSZ pszEnv = ppib->pib_pchenv;
    477             if (pszEnv)
    478                 arc = doshParseEnvironment(pszEnv, pEnv);
    479             else
    480                 arc = ERROR_BAD_ENVIRONMENT;
    481         }
    482     }
    483 
    484     return (arc);
    485 }
    486 
    487 /*
    488  *@@ doshFindEnvironmentVar:
    489  *      returns the PSZ* in the pEnv->papszVars array
    490  *      which specifies the environment variable in pszVarName.
    491  *
    492  *      With pszVarName, you can either specify the variable
    493  *      name only ("VARNAME") or a full environment string
    494  *      ("VARNAME=BLAH"). In any case, only the variable name
    495  *      is compared.
    496  *
    497  *      Returns NULL if no such variable name was found in
    498  *      the array.
    499  *
    500  *@@added V0.9.4 (2000-07-19) [umoeller]
    501  *@@changed V0.9.12 (2001-05-21) [umoeller]: fixed memory leak
    502  */
    503 
    504 PSZ* doshFindEnvironmentVar(PDOSENVIRONMENT pEnv,
    505                             PSZ pszVarName)
    506 {
    507     PSZ *ppszRet = 0;
    508     if (pEnv)
    509     {
    510         if ((pEnv->papszVars) && (pszVarName))
    511         {
    512             PSZ     *ppszThis = pEnv->papszVars;
    513             PSZ     pszThis;
    514             ULONG   ul = 0;
    515             ULONG   ulVarNameLen = 0;
    516 
    517             PSZ     pszSearch = NULL; // receives "VARNAME="
    518             PSZ     pFirstEqual = strchr(pszVarName, '=');
    519             if (pFirstEqual)
    520                 pszSearch = strhSubstr(pszVarName, pFirstEqual + 1);
    521             else
    522             {
    523                 ulVarNameLen = strlen(pszVarName);
    524                 pszSearch = (PSZ)malloc(ulVarNameLen + 2);
    525                 memcpy(pszSearch, pszVarName, ulVarNameLen);
    526                 *(pszSearch + ulVarNameLen) = '=';
    527                 *(pszSearch + ulVarNameLen + 1) = 0;
    528             }
    529 
    530             ulVarNameLen = strlen(pszSearch);
    531 
    532             for (ul = 0;
    533                  ul < pEnv->cVars;
    534                  ul++)
    535             {
    536                 pszThis = *ppszThis;
    537 
    538                 if (strnicmp(*ppszThis, pszSearch, ulVarNameLen) == 0)
    539                 {
    540                     ppszRet = ppszThis;
    541                     break;
    542                 }
    543 
    544                 // next environment string
    545                 ppszThis++;
    546             }
    547 
    548             free(pszSearch);        // was missing V0.9.12 (2001-05-21) [umoeller]
    549         }
    550     }
    551 
    552     return (ppszRet);
    553 }
    554 
    555 /*
    556  *@@ doshSetEnvironmentVar:
    557  *      sets an environment variable in the specified
    558  *      environment, which must have been initialized
    559  *      using doshGetEnvironment first.
    560  *
    561  *      pszNewEnv must be a full environment string
    562  *      in the form "VARNAME=VALUE".
    563  *
    564  *      If "VARNAME" has already been set to something
    565  *      in the string array in pEnv, that array item
    566  *      is replaced.
    567  *
    568  *      OTOH, if "VARNAME" has not been set yet, a new
    569  *      item is added to the array, and pEnv->cVars is
    570  *      raised by one. In that case, fAddFirst determines
    571  *      whether the new array item is added to the front
    572  *      or the tail of the environment list.
    573  *
    574  *@@added V0.9.4 (2000-07-19) [umoeller]
    575  *@@changed V0.9.7 (2000-12-17) [umoeller]: added fAddFirst
    576  *@@changed V0.9.12 (2001-05-21) [umoeller]: fixed memory leak
    577  */
    578 
    579 APIRET doshSetEnvironmentVar(PDOSENVIRONMENT pEnv,
    580                              PSZ pszNewEnv,
    581                              BOOL fAddFirst)
    582 {
    583     APIRET  arc = NO_ERROR;
    584     if (!pEnv)
    585         arc = ERROR_INVALID_PARAMETER;
    586     else
    587     {
    588         if ((!pEnv->papszVars) || (!pszNewEnv))
    589             arc = ERROR_INVALID_PARAMETER;
    590         else
    591         {
    592             PSZ *ppszEnvLine = doshFindEnvironmentVar(pEnv, pszNewEnv);
    593             if (ppszEnvLine)
    594             {
    595                 // was set already: replace
    596                 free(*ppszEnvLine);
    597                 *ppszEnvLine = strdup(pszNewEnv);
    598                 if (!(*ppszEnvLine))
    599                     arc = ERROR_NOT_ENOUGH_MEMORY;
    600             }
    601             else
    602             {
    603                 PSZ *ppszNew = NULL;
    604                 PSZ *papszNew = NULL;
    605                 // not set already:
    606                 if (fAddFirst)
    607                 {
    608                     // add as first entry:
    609                     papszNew = (PSZ*)malloc(sizeof(PSZ) * (pEnv->cVars + 1));
    610                     // overwrite first entry
    611                     ppszNew = papszNew;
    612                     // copy old entries
    613                     memcpy(papszNew + 1,                // second new entry
    614                            pEnv->papszVars,             // first old entry
    615                            sizeof(PSZ) * pEnv->cVars);
    616                 }
    617                 else
    618                 {
    619                     // append at the tail:
    620                     // reallocate array and add new string
    621                     papszNew = (PSZ*)realloc(pEnv->papszVars,
    622                                              sizeof(PSZ) * (pEnv->cVars + 1));
    623                     // overwrite last entry
    624                     ppszNew = papszNew + pEnv->cVars;
    625                 }
    626 
    627                 if (!papszNew)
    628                     arc = ERROR_NOT_ENOUGH_MEMORY;
    629                 else
    630                 {
    631                     if (pEnv->papszVars)
    632                         free(pEnv->papszVars);      // was missing V0.9.12 (2001-05-21) [umoeller]
    633 
    634                     pEnv->papszVars = papszNew;
    635                     pEnv->cVars++;
    636                     *ppszNew = strdup(pszNewEnv);
    637                 }
    638             }
    639         }
    640     }
    641 
    642     return (arc);
    643 }
    644 
    645 /*
    646  *@@ doshConvertEnvironment:
    647  *      converts an environment initialized by doshGetEnvironment
    648  *      to the string format required by WinStartApp and DosExecPgm,
    649  *      that is, one memory block is allocated in *ppszEnv and all
    650  *      strings in pEnv->papszVars are copied to that block. Each
    651  *      string is terminated with a null character; the last string
    652  *      is terminated with two null characters.
    653  *
    654  *      Use free() to free the memory block allocated by this
    655  *      function in *ppszEnv.
    656  *
    657  *@@added V0.9.4 (2000-07-19) [umoeller]
    658  */
    659 
    660 APIRET doshConvertEnvironment(PDOSENVIRONMENT pEnv,
    661                               PSZ *ppszEnv,     // out: environment string
    662                               PULONG pulSize)  // out: size of block allocated in *ppszEnv; ptr can be NULL
    663 {
    664     APIRET  arc = NO_ERROR;
    665     if (!pEnv)
    666         arc = ERROR_INVALID_PARAMETER;
    667     else
    668     {
    669         if (!pEnv->papszVars)
    670             arc = ERROR_INVALID_PARAMETER;
    671         else
    672         {
    673             // count memory needed for all strings
    674             ULONG   cbNeeded = 0,
    675                     ul = 0;
    676             PSZ     *ppszThis = pEnv->papszVars;
    677 
    678             for (ul = 0;
    679                  ul < pEnv->cVars;
    680                  ul++)
    681             {
    682                 cbNeeded += strlen(*ppszThis) + 1; // length of string plus null terminator
    683 
    684                 // next environment string
    685                 ppszThis++;
    686             }
    687 
    688             cbNeeded++;     // for another null terminator
    689 
    690             *ppszEnv = (PSZ)malloc(cbNeeded);
    691             if (!(*ppszEnv))
    692                 arc = ERROR_NOT_ENOUGH_MEMORY;
    693             else
    694             {
    695                 PSZ     pTarget = *ppszEnv;
    696                 if (pulSize)
    697                     *pulSize = cbNeeded;
    698                 ppszThis = pEnv->papszVars;
    699 
    700                 // now copy each string
    701                 for (ul = 0;
    702                      ul < pEnv->cVars;
    703                      ul++)
    704                 {
    705                     PSZ pSource = *ppszThis;
    706 
    707                     while ((*pTarget++ = *pSource++))
    708                         ;
    709 
    710                     // *pTarget++ = 0;     // append null terminator per string
    711 
    712                     // next environment string
    713                     ppszThis++;
    714                 }
    715 
    716                 *pTarget++ = 0;     // append second null terminator
    717             }
    718         }
    719     }
    720 
    721     return (arc);
    722 }
    723 
    724 /*
    725  *@@ doshFreeEnvironment:
    726  *      frees memory allocated by doshGetEnvironment.
    727  *
    728  *@@added V0.9.4 (2000-07-19) [umoeller]
    729  */
    730 
    731 APIRET doshFreeEnvironment(PDOSENVIRONMENT pEnv)
    732 {
    733     APIRET  arc = NO_ERROR;
    734     if (!pEnv)
    735         arc = ERROR_INVALID_PARAMETER;
    736     else
    737     {
    738         if (!pEnv->papszVars)
    739             arc = ERROR_INVALID_PARAMETER;
    740         else
    741         {
    742             PSZ     *ppszThis = pEnv->papszVars;
    743             PSZ     pszThis;
    744             ULONG   ul = 0;
    745 
    746             for (ul = 0;
    747                  ul < pEnv->cVars;
    748                  ul++)
    749             {
    750                 pszThis = *ppszThis;
    751                 free(pszThis);
    752                 // *ppszThis = NULL;
    753                 // next environment string
    754                 ppszThis++;
    755             }
    756 
    757             free(pEnv->papszVars);
    758             pEnv->cVars = 0;
    759         }
    760     }
    761 
    762     return (arc);
    763351}
    764352
Note: See TracChangeset for help on using the changeset viewer.