Changeset 76 for trunk/src/helpers/dosh2.c
- Timestamp:
- May 27, 2001, 8:10:36 AM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/helpers/dosh2.c
r71 r76 349 349 350 350 return (arc); // V0.9.9 (2001-04-04) [umoeller] 351 }352 353 /*354 *@@category: Helpers\Control program helpers\Environment management355 * helpers for managing those ugly environment string arrays356 * that are used with DosStartSession and WinStartApp.357 */358 359 /* ******************************************************************360 *361 * Environment helpers362 *363 ********************************************************************/364 365 /*366 *@@ doshParseEnvironment:367 * this takes one of those ugly environment strings368 * as used by DosStartSession and WinStartApp (with369 * lots of zero-terminated strings one after another370 * and a duplicate zero byte as a terminator) as371 * input and splits it into an array of separate372 * strings in pEnv.373 *374 * The newly allocated strings are stored in in375 * pEnv->papszVars. The array count is stored in376 * pEnv->cVars.377 *378 * Each environment variable will be copied into379 * one newly allocated string in the array. Use380 * doshFreeEnvironment to free the memory allocated381 * 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:\TEMP399 + // ...400 + // next environment string401 + 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 else417 {418 PSZ pszVarThis = (PSZ)pcszEnv;419 ULONG cVars = 0;420 // count strings421 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 else436 {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 current458 * process environment, which is retrieved from459 * 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 else470 {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 else480 arc = ERROR_BAD_ENVIRONMENT;481 }482 }483 484 return (arc);485 }486 487 /*488 *@@ doshFindEnvironmentVar:489 * returns the PSZ* in the pEnv->papszVars array490 * which specifies the environment variable in pszVarName.491 *492 * With pszVarName, you can either specify the variable493 * name only ("VARNAME") or a full environment string494 * ("VARNAME=BLAH"). In any case, only the variable name495 * is compared.496 *497 * Returns NULL if no such variable name was found in498 * the array.499 *500 *@@added V0.9.4 (2000-07-19) [umoeller]501 *@@changed V0.9.12 (2001-05-21) [umoeller]: fixed memory leak502 */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 else522 {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 string545 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 specified558 * environment, which must have been initialized559 * using doshGetEnvironment first.560 *561 * pszNewEnv must be a full environment string562 * in the form "VARNAME=VALUE".563 *564 * If "VARNAME" has already been set to something565 * in the string array in pEnv, that array item566 * is replaced.567 *568 * OTOH, if "VARNAME" has not been set yet, a new569 * item is added to the array, and pEnv->cVars is570 * raised by one. In that case, fAddFirst determines571 * whether the new array item is added to the front572 * 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 fAddFirst576 *@@changed V0.9.12 (2001-05-21) [umoeller]: fixed memory leak577 */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 else587 {588 if ((!pEnv->papszVars) || (!pszNewEnv))589 arc = ERROR_INVALID_PARAMETER;590 else591 {592 PSZ *ppszEnvLine = doshFindEnvironmentVar(pEnv, pszNewEnv);593 if (ppszEnvLine)594 {595 // was set already: replace596 free(*ppszEnvLine);597 *ppszEnvLine = strdup(pszNewEnv);598 if (!(*ppszEnvLine))599 arc = ERROR_NOT_ENOUGH_MEMORY;600 }601 else602 {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 entry611 ppszNew = papszNew;612 // copy old entries613 memcpy(papszNew + 1, // second new entry614 pEnv->papszVars, // first old entry615 sizeof(PSZ) * pEnv->cVars);616 }617 else618 {619 // append at the tail:620 // reallocate array and add new string621 papszNew = (PSZ*)realloc(pEnv->papszVars,622 sizeof(PSZ) * (pEnv->cVars + 1));623 // overwrite last entry624 ppszNew = papszNew + pEnv->cVars;625 }626 627 if (!papszNew)628 arc = ERROR_NOT_ENOUGH_MEMORY;629 else630 {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 doshGetEnvironment648 * to the string format required by WinStartApp and DosExecPgm,649 * that is, one memory block is allocated in *ppszEnv and all650 * strings in pEnv->papszVars are copied to that block. Each651 * string is terminated with a null character; the last string652 * is terminated with two null characters.653 *654 * Use free() to free the memory block allocated by this655 * 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 string662 PULONG pulSize) // out: size of block allocated in *ppszEnv; ptr can be NULL663 {664 APIRET arc = NO_ERROR;665 if (!pEnv)666 arc = ERROR_INVALID_PARAMETER;667 else668 {669 if (!pEnv->papszVars)670 arc = ERROR_INVALID_PARAMETER;671 else672 {673 // count memory needed for all strings674 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 terminator683 684 // next environment string685 ppszThis++;686 }687 688 cbNeeded++; // for another null terminator689 690 *ppszEnv = (PSZ)malloc(cbNeeded);691 if (!(*ppszEnv))692 arc = ERROR_NOT_ENOUGH_MEMORY;693 else694 {695 PSZ pTarget = *ppszEnv;696 if (pulSize)697 *pulSize = cbNeeded;698 ppszThis = pEnv->papszVars;699 700 // now copy each string701 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 string711 712 // next environment string713 ppszThis++;714 }715 716 *pTarget++ = 0; // append second null terminator717 }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 else737 {738 if (!pEnv->papszVars)739 arc = ERROR_INVALID_PARAMETER;740 else741 {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 string754 ppszThis++;755 }756 757 free(pEnv->papszVars);758 pEnv->cVars = 0;759 }760 }761 762 return (arc);763 351 } 764 352
Note:
See TracChangeset
for help on using the changeset viewer.