Changeset 76167 in vbox for trunk/src/VBox/Main/src-all
- Timestamp:
- Dec 11, 2018 5:03:05 PM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 127415
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-all/TextScript.cpp
r76159 r76167 1 1 /* $Id$ */ 2 2 /** @file 3 * Implementeation of algorithms which read/parse/save scripts for unattended installation.3 * Classes for reading/parsing/saving text scripts (unattended installation, ++). 4 4 */ 5 5 … … 22 22 #define LOG_GROUP LOG_GROUP_MAIN_UNATTENDED 23 23 #include "LoggingNew.h" 24 #include "VirtualBoxBase.h" 25 #include "AutoCaller.h" 26 #include <VBox/com/ErrorInfo.h> 27 28 #include "UnattendedScript.h" 29 #include "UnattendedImpl.h" 24 #include "TextScript.h" 30 25 31 26 #include <VBox/err.h> … … 34 29 #include <iprt/file.h> 35 30 #include <iprt/vfs.h> 36 #include <iprt/getopt.h>37 31 #include <iprt/path.h> 38 32 … … 40 34 41 35 42 ////////////////////////////////////////////////////////////////////////////////////////////////////// 43 /* 44 * 45 * 46 * Implementation BaseTextScript functions 47 * 48 */ 49 ////////////////////////////////////////////////////////////////////////////////////////////////////// 36 /********************************************************************************************************************************* 37 * BaseTextScript Implementation * 38 *********************************************************************************************************************************/ 39 50 40 HRESULT BaseTextScript::read(const Utf8Str &rStrFilename) 51 41 { … … 197 187 } 198 188 199 #ifdef VBOX_WITH_UNATTENDED 200 201 ////////////////////////////////////////////////////////////////////////////////////////////////////// 202 /* 203 * 204 * 205 * Implementation UnattendedScriptTemplate methods 206 * 207 */ 208 ////////////////////////////////////////////////////////////////////////////////////////////////////// 209 210 UnattendedScriptTemplate::UnattendedScriptTemplate(Unattended *pUnattended, const char *pszDefaultTemplateFilename, 211 const char *pszDefaultFilename) 212 : BaseTextScript(pUnattended, pszDefaultTemplateFilename, pszDefaultFilename), mpUnattended(pUnattended) 213 { 214 } 215 216 217 HRESULT UnattendedScriptTemplate::saveToString(Utf8Str &rStrDst) 218 { 219 static const char s_szPrefix[] = "@@VBOX_"; 220 static const char s_szPrefixInsert[] = "@@VBOX_INSERT_"; 221 static const char s_szPrefixCond[] = "@@VBOX_COND_"; 222 static const char s_szPrefixCondEnd[] = "@@VBOX_COND_END@@"; 223 224 struct 225 { 226 bool fSavedOutputting; 227 } aConds[8]; 228 unsigned cConds = 0; 229 bool fOutputting = true; 230 HRESULT hrc = E_FAIL; 231 size_t offTemplate = 0; 232 size_t cchTemplate = mStrScriptFullContent.length(); 233 rStrDst.setNull(); 234 for (;;) 235 { 236 /* 237 * Find the next placeholder and add any text before it to the output. 238 */ 239 size_t offPlaceholder = mStrScriptFullContent.find(s_szPrefix, offTemplate); 240 size_t cchToCopy = offPlaceholder != RTCString::npos ? offPlaceholder - offTemplate : cchTemplate - offTemplate; 241 if (cchToCopy > 0) 242 { 243 if (fOutputting) 244 { 245 try 246 { 247 rStrDst.append(mStrScriptFullContent, offTemplate, cchToCopy); 248 } 249 catch (std::bad_alloc &) 250 { 251 hrc = E_OUTOFMEMORY; 252 break; 253 } 254 } 255 offTemplate += cchToCopy; 256 } 257 258 /* 259 * Process placeholder. 260 */ 261 if (offPlaceholder != RTCString::npos) 262 { 263 /* 264 * First we must find the end of the placeholder string. 265 */ 266 const char *pszPlaceholder = mStrScriptFullContent.c_str() + offPlaceholder; 267 size_t cchPlaceholder = sizeof(s_szPrefix) - 1; 268 char ch; 269 while ( offPlaceholder + cchPlaceholder < cchTemplate 270 && (ch = pszPlaceholder[cchPlaceholder]) != '\0' 271 && ( ch == '_' 272 || RT_C_IS_UPPER(ch) 273 || RT_C_IS_DIGIT(ch)) ) 274 cchPlaceholder++; 275 276 if ( offPlaceholder + cchPlaceholder < cchTemplate 277 && pszPlaceholder[cchPlaceholder] == '@') 278 { 279 cchPlaceholder++; 280 if ( offPlaceholder + cchPlaceholder < cchTemplate 281 && pszPlaceholder[cchPlaceholder] == '@') 282 cchPlaceholder++; 283 } 284 285 if ( pszPlaceholder[cchPlaceholder - 1] != '@' 286 || pszPlaceholder[cchPlaceholder - 2] != '@' 287 || ( strncmp(pszPlaceholder, s_szPrefixInsert, sizeof(s_szPrefixInsert) - 1) != 0 288 && strncmp(pszPlaceholder, s_szPrefixCond, sizeof(s_szPrefixCond) - 1) != 0) ) 289 { 290 hrc = mpSetError->setError(E_FAIL, mpSetError->tr("Malformed template placeholder '%.*s'"), 291 cchPlaceholder, pszPlaceholder); 292 break; 293 } 294 295 offTemplate += cchPlaceholder; 296 297 /* 298 * @@VBOX_INSERT_XXX@@: 299 */ 300 if (strncmp(pszPlaceholder, s_szPrefixInsert, sizeof(s_szPrefixInsert) - 1) == 0) 301 { 302 /* 303 * Get the placeholder value and add it to the output. 304 */ 305 RTCString strValue; 306 hrc = getReplacement(pszPlaceholder, cchPlaceholder, fOutputting, strValue); 307 if (SUCCEEDED(hrc)) 308 { 309 if (fOutputting) 310 { 311 try 312 { 313 rStrDst.append(strValue); 314 } 315 catch (std::bad_alloc &) 316 { 317 hrc = E_OUTOFMEMORY; 318 break; 319 } 320 } 321 } 322 else 323 break; 324 } 325 /* 326 * @@VBOX_COND_END@@: Pop one item of the conditional stack. 327 */ 328 else if ( cchPlaceholder == sizeof(s_szPrefixCondEnd) - 1U 329 && strncmp(pszPlaceholder, s_szPrefixCondEnd, sizeof(s_szPrefixCondEnd) - 1U) == 0) 330 { 331 if (cConds > 0) 332 { 333 cConds--; 334 fOutputting = aConds[cConds].fSavedOutputting; 335 } 336 else 337 { 338 hrc = mpSetError->setErrorBoth(E_FAIL, VERR_PARSE_ERROR, 339 mpSetError->tr("%s without @@VBOX_COND_XXX@@ at offset %zu (%#zx)"), 340 s_szPrefixCondEnd, offPlaceholder, offPlaceholder); 341 break; 342 } 343 } 344 /* 345 * @@VBOX_COND_XXX@@: Push the previous outputting state and combine it with the 346 * one from the condition. 347 */ 348 else 349 { 350 Assert(strncmp(pszPlaceholder, s_szPrefixCond, sizeof(s_szPrefixCond) - 1) == 0); 351 if (cConds + 1 < RT_ELEMENTS(aConds)) 352 { 353 aConds[cConds].fSavedOutputting = fOutputting; 354 bool fNewOutputting = fOutputting; 355 hrc = getConditional(pszPlaceholder, cchPlaceholder, &fNewOutputting); 356 if (SUCCEEDED(hrc)) 357 fOutputting = fOutputting && fNewOutputting; 358 else 359 break; 360 cConds++; 361 } 362 else 363 { 364 hrc = mpSetError->setErrorBoth(E_FAIL, VERR_PARSE_ERROR, 365 mpSetError->tr("Too deep conditional nesting at offset %zu (%#zx)"), 366 offPlaceholder, offPlaceholder); 367 break; 368 } 369 } 370 } 371 372 /* 373 * Done? 374 */ 375 if (offTemplate >= cchTemplate) 376 { 377 if (cConds == 0) 378 return S_OK; 379 if (cConds == 1) 380 hrc = mpSetError->setErrorBoth(E_FAIL, VERR_PARSE_ERROR, mpSetError->tr("Missing @@VBOX_COND_END@@")); 381 else 382 hrc = mpSetError->setErrorBoth(E_FAIL, VERR_PARSE_ERROR, mpSetError->tr("Missing %u @@VBOX_COND_END@@"), cConds); 383 break; 384 } 385 } 386 387 /* failed */ 388 rStrDst.setNull(); 389 return hrc; 390 } 391 392 HRESULT UnattendedScriptTemplate::getReplacement(const char *pachPlaceholder, size_t cchPlaceholder, 393 bool fOutputting, RTCString &rValue) 394 { 395 /* 396 * Check for an escaping suffix. Drop the '@@'. 397 */ 398 size_t const cchFullPlaceholder = cchPlaceholder; 399 enum 400 { 401 kValueEscaping_None, 402 kValueEscaping_Bourne, 403 kValueEscaping_XML_Element, 404 kValueEscaping_XML_Attribute_Double_Quotes 405 } enmEscaping; 406 407 #define PLACEHOLDER_ENDS_WITH(a_szSuffix) \ 408 ( cchPlaceholder > sizeof(a_szSuffix) - 1U \ 409 && memcmp(&pachPlaceholder[cchPlaceholder - sizeof(a_szSuffix) + 1U], a_szSuffix, sizeof(a_szSuffix) - 1U) == 0) 410 if (PLACEHOLDER_ENDS_WITH("_SH@@")) 411 { 412 cchPlaceholder -= 3 + 2; 413 enmEscaping = kValueEscaping_Bourne; 414 } 415 else if (PLACEHOLDER_ENDS_WITH("_ELEMENT@@")) 416 { 417 cchPlaceholder -= 8 + 2; 418 enmEscaping = kValueEscaping_XML_Element; 419 } 420 else if (PLACEHOLDER_ENDS_WITH("_ATTRIB_DQ@@")) 421 { 422 cchPlaceholder -= 10 + 2; 423 enmEscaping = kValueEscaping_XML_Attribute_Double_Quotes; 424 } 425 else 426 { 427 Assert(PLACEHOLDER_ENDS_WITH("@@")); 428 cchPlaceholder -= 2; 429 enmEscaping = kValueEscaping_None; 430 } 431 432 /* 433 * Resolve and escape the value. 434 */ 435 HRESULT hrc; 436 try 437 { 438 switch (enmEscaping) 439 { 440 case kValueEscaping_None: 441 hrc = getUnescapedReplacement(pachPlaceholder, cchPlaceholder, cchFullPlaceholder, fOutputting, rValue); 442 if (SUCCEEDED(hrc)) 443 return hrc; 444 break; 445 446 case kValueEscaping_Bourne: 447 case kValueEscaping_XML_Element: 448 case kValueEscaping_XML_Attribute_Double_Quotes: 449 { 450 RTCString strUnescaped; 451 hrc = getUnescapedReplacement(pachPlaceholder, cchPlaceholder, cchFullPlaceholder, fOutputting, strUnescaped); 452 if (SUCCEEDED(hrc)) 453 { 454 switch (enmEscaping) 455 { 456 case kValueEscaping_Bourne: 457 { 458 const char * const papszArgs[2] = { strUnescaped.c_str(), NULL }; 459 char *pszEscaped = NULL; 460 int vrc = RTGetOptArgvToString(&pszEscaped, papszArgs, RTGETOPTARGV_CNV_QUOTE_BOURNE_SH); 461 if (RT_SUCCESS(vrc)) 462 { 463 try 464 { 465 rValue = pszEscaped; 466 RTStrFree(pszEscaped); 467 return S_OK; 468 } 469 catch (std::bad_alloc &) 470 { 471 hrc = E_OUTOFMEMORY; 472 } 473 RTStrFree(pszEscaped); 474 } 475 break; 476 } 477 478 case kValueEscaping_XML_Element: 479 rValue.printf("%RMes", strUnescaped.c_str()); 480 return S_OK; 481 482 case kValueEscaping_XML_Attribute_Double_Quotes: 483 { 484 RTCString strTmp; 485 strTmp.printf("%RMas", strUnescaped.c_str()); 486 rValue = RTCString(strTmp, 1, strTmp.length() - 2); 487 return S_OK; 488 } 489 490 default: 491 hrc = E_FAIL; 492 break; 493 } 494 } 495 break; 496 } 497 498 default: 499 AssertFailedStmt(hrc = E_FAIL); 500 break; 501 } 502 } 503 catch (std::bad_alloc &) 504 { 505 hrc = E_OUTOFMEMORY; 506 } 507 rValue.setNull(); 508 return hrc; 509 } 510 511 HRESULT UnattendedScriptTemplate::getUnescapedReplacement(const char *pachPlaceholder, size_t cchPlaceholder, 512 size_t cchFullPlaceholder, bool fOutputting, RTCString &rValue) 513 { 514 RT_NOREF(fOutputting); 515 #define IS_PLACEHOLDER_MATCH(a_szMatch) \ 516 ( cchPlaceholder == sizeof("@@VBOX_INSERT_" a_szMatch) - 1U \ 517 && memcmp(pachPlaceholder, "@@VBOX_INSERT_" a_szMatch, sizeof("@@VBOX_INSERT_" a_szMatch) - 1U) == 0) 518 519 if (IS_PLACEHOLDER_MATCH("USER_LOGIN")) 520 rValue = mpUnattended->i_getUser(); 521 else if (IS_PLACEHOLDER_MATCH("USER_PASSWORD")) 522 rValue = mpUnattended->i_getPassword(); 523 else if (IS_PLACEHOLDER_MATCH("ROOT_PASSWORD")) 524 rValue = mpUnattended->i_getPassword(); 525 else if (IS_PLACEHOLDER_MATCH("USER_FULL_NAME")) 526 rValue = mpUnattended->i_getFullUserName(); 527 else if (IS_PLACEHOLDER_MATCH("PRODUCT_KEY")) 528 rValue = mpUnattended->i_getProductKey(); 529 else if (IS_PLACEHOLDER_MATCH("POST_INSTALL_COMMAND")) 530 rValue = mpUnattended->i_getPostInstallCommand(); 531 else if (IS_PLACEHOLDER_MATCH("IMAGE_INDEX")) 532 rValue.printf("%u", mpUnattended->i_getImageIndex()); 533 else if (IS_PLACEHOLDER_MATCH("OS_ARCH")) 534 rValue = mpUnattended->i_isGuestOs64Bit() ? "amd64" : "x86"; 535 else if (IS_PLACEHOLDER_MATCH("OS_ARCH2")) 536 rValue = mpUnattended->i_isGuestOs64Bit() ? "x86_64" : "x86"; 537 else if (IS_PLACEHOLDER_MATCH("OS_ARCH3")) 538 rValue = mpUnattended->i_isGuestOs64Bit() ? "x86_64" : "i386"; 539 else if (IS_PLACEHOLDER_MATCH("OS_ARCH4")) 540 rValue = mpUnattended->i_isGuestOs64Bit() ? "x86_64" : "i486"; 541 else if (IS_PLACEHOLDER_MATCH("OS_ARCH6")) 542 rValue = mpUnattended->i_isGuestOs64Bit() ? "x86_64" : "i686"; 543 else if (IS_PLACEHOLDER_MATCH("TIME_ZONE_UX")) 544 rValue = mpUnattended->i_getTimeZoneInfo() 545 ? mpUnattended->i_getTimeZoneInfo()->pszUnixName : mpUnattended->i_getTimeZone(); 546 else if (IS_PLACEHOLDER_MATCH("TIME_ZONE_WIN_NAME")) 547 { 548 PCRTTIMEZONEINFO pInfo = mpUnattended->i_getTimeZoneInfo(); 549 if (pInfo) 550 rValue = pInfo->pszWindowsName ? pInfo->pszWindowsName : "GMT"; 551 else 552 rValue = mpUnattended->i_getTimeZone(); 553 } 554 else if (IS_PLACEHOLDER_MATCH("TIME_ZONE_WIN_INDEX")) 555 { 556 PCRTTIMEZONEINFO pInfo = mpUnattended->i_getTimeZoneInfo(); 557 if (pInfo) 558 rValue.printf("%u", pInfo->idxWindows ? pInfo->idxWindows : 85 /*GMT*/); 559 else 560 rValue = mpUnattended->i_getTimeZone(); 561 } 562 else if (IS_PLACEHOLDER_MATCH("LOCALE")) 563 rValue = mpUnattended->i_getLocale(); 564 else if (IS_PLACEHOLDER_MATCH("DASH_LOCALE")) 565 { 566 rValue = mpUnattended->i_getLocale(); 567 Assert(rValue[2] == '_'); 568 rValue.replace(2, 1, "-"); 569 } 570 else if (IS_PLACEHOLDER_MATCH("LANGUAGE")) 571 rValue = mpUnattended->i_getLanguage(); 572 else if (IS_PLACEHOLDER_MATCH("COUNTRY")) 573 rValue = mpUnattended->i_getCountry(); 574 else if (IS_PLACEHOLDER_MATCH("HOSTNAME_FQDN")) 575 rValue = mpUnattended->i_getHostname(); 576 else if (IS_PLACEHOLDER_MATCH("HOSTNAME_WITHOUT_DOMAIN")) 577 rValue.assign(mpUnattended->i_getHostname(), 0, mpUnattended->i_getHostname().find(".")); 578 else if (IS_PLACEHOLDER_MATCH("HOSTNAME_WITHOUT_DOMAIN_MAX_15")) 579 rValue.assign(mpUnattended->i_getHostname(), 0, RT_MIN(mpUnattended->i_getHostname().find("."), 15)); 580 else if (IS_PLACEHOLDER_MATCH("HOSTNAME_DOMAIN")) 581 rValue.assign(mpUnattended->i_getHostname(), mpUnattended->i_getHostname().find(".") + 1); 582 else 583 { 584 rValue.setNull(); 585 return mpSetError->setErrorBoth(E_FAIL, VERR_NOT_FOUND, mpSetError->tr("Unknown template placeholder '%.*s'"), 586 cchFullPlaceholder, pachPlaceholder); 587 } 588 return S_OK; 589 #undef IS_PLACEHOLDER_MATCH 590 } 591 592 HRESULT UnattendedScriptTemplate::getConditional(const char *pachPlaceholder, size_t cchPlaceholder, bool *pfOutputting) 593 { 594 #define IS_PLACEHOLDER_MATCH(a_szMatch) \ 595 ( cchPlaceholder == sizeof("@@VBOX_COND_" a_szMatch "@@") - 1U \ 596 && memcmp(pachPlaceholder, "@@VBOX_COND_" a_szMatch "@@", sizeof("@@VBOX_COND_" a_szMatch "@@") - 1U) == 0) 597 598 /* Install guest additions: */ 599 if (IS_PLACEHOLDER_MATCH("IS_INSTALLING_ADDITIONS")) 600 *pfOutputting = mpUnattended->i_getInstallGuestAdditions(); 601 else if (IS_PLACEHOLDER_MATCH("IS_NOT_INSTALLING_ADDITIONS")) 602 *pfOutputting = !mpUnattended->i_getInstallGuestAdditions(); 603 /* User == Administrator: */ 604 else if (IS_PLACEHOLDER_MATCH("IS_USER_LOGIN_ADMINISTRATOR")) 605 *pfOutputting = mpUnattended->i_getUser().compare("Administrator", RTCString::CaseInsensitive) == 0; 606 else if (IS_PLACEHOLDER_MATCH("IS_USER_LOGIN_NOT_ADMINISTRATOR")) 607 *pfOutputting = mpUnattended->i_getUser().compare("Administrator", RTCString::CaseInsensitive) != 0; 608 /* Install TXS: */ 609 else if (IS_PLACEHOLDER_MATCH("IS_INSTALLING_TEST_EXEC_SERVICE")) 610 *pfOutputting = mpUnattended->i_getInstallTestExecService(); 611 else if (IS_PLACEHOLDER_MATCH("IS_NOT_INSTALLING_TEST_EXEC_SERVICE")) 612 *pfOutputting = !mpUnattended->i_getInstallTestExecService(); 613 /* Post install command: */ 614 else if (IS_PLACEHOLDER_MATCH("HAS_POST_INSTALL_COMMAND")) 615 *pfOutputting = mpUnattended->i_getPostInstallCommand().isNotEmpty(); 616 else if (IS_PLACEHOLDER_MATCH("HAS_NO_POST_INSTALL_COMMAND")) 617 *pfOutputting = !mpUnattended->i_getPostInstallCommand().isNotEmpty(); 618 /* Product key: */ 619 else if (IS_PLACEHOLDER_MATCH("HAS_PRODUCT_KEY")) 620 *pfOutputting = mpUnattended->i_getProductKey().isNotEmpty(); 621 else if (IS_PLACEHOLDER_MATCH("HAS_NO_PRODUCT_KEY")) 622 *pfOutputting = !mpUnattended->i_getProductKey().isNotEmpty(); 623 /* Minimal installation: */ 624 else if (IS_PLACEHOLDER_MATCH("IS_MINIMAL_INSTALLATION")) 625 *pfOutputting = mpUnattended->i_isMinimalInstallation(); 626 else if (IS_PLACEHOLDER_MATCH("IS_NOT_MINIMAL_INSTALLATION")) 627 *pfOutputting = !mpUnattended->i_isMinimalInstallation(); 628 /* Is RTC using UTC (i.e. set to UTC time on startup): */ 629 else if (IS_PLACEHOLDER_MATCH("IS_RTC_USING_UTC")) 630 *pfOutputting = mpUnattended->i_isRtcUsingUtc(); 631 else if (IS_PLACEHOLDER_MATCH("IS_NOT_RTC_USING_UTC")) 632 *pfOutputting = !mpUnattended->i_isRtcUsingUtc(); 633 else 634 return mpSetError->setErrorBoth(E_FAIL, VERR_NOT_FOUND, mpSetError->tr("Unknown conditional placeholder '%.*s'"), 635 cchPlaceholder, pachPlaceholder); 636 return S_OK; 637 #undef IS_PLACEHOLDER_MATCH 638 } 639 640 #endif /* VBOX_WITH_UNATTENDED */ 641 642 643 ////////////////////////////////////////////////////////////////////////////////////////////////////// 644 /* 645 * 646 * 647 * Implementation GeneralTextScript functions 648 * 649 */ 650 ////////////////////////////////////////////////////////////////////////////////////////////////////// 189 190 191 /********************************************************************************************************************************* 192 * GeneralTextScript Implementation * 193 *********************************************************************************************************************************/ 194 651 195 HRESULT GeneralTextScript::parse() 652 196 { … … 813 357 } 814 358 815 #if 0 /* Keeping this a reference */816 //////////////////////////////////////////////////////////////////////////////////////////////////////817 /*818 *819 *820 * Implementation UnattendedSUSEXMLScript functions821 *822 */823 /////////////////////////////////////////////////////////////////////////////////////////////////////824 HRESULT UnattendedSUSEXMLScript::parse()825 {826 HRESULT hrc = UnattendedXMLScript::parse();827 if (SUCCEEDED(hrc))828 {829 /*830 * Check that we've got the right root element type.831 */832 const xml::ElementNode *pelmRoot = mDoc.getRootElement();833 if ( pelmRoot834 && strcmp(pelmRoot->getName(), "profile") == 0)835 {836 /*837 * Work thought the sections.838 */839 try840 {841 LoopThruSections(pelmRoot);842 hrc = S_OK;843 }844 catch (std::bad_alloc &)845 {846 hrc = E_OUTOFMEMORY;847 }848 }849 else if (pelmRoot)850 hrc = mpSetError->setError(E_FAIL, mpSetError->tr("XML document root element is '%s' instead of 'profile'"),851 pelmRoot->getName());852 else853 hrc = mpSetError->setError(E_FAIL, mpSetError->tr("Missing XML root element"));854 }855 return hrc;856 }857 858 HRESULT UnattendedSUSEXMLScript::setFieldInElement(xml::ElementNode *pElement, const DataId enmDataId, const Utf8Str &rStrValue)859 {860 /*861 * Don't set empty values.862 */863 if (rStrValue.isEmpty())864 {865 Utf8Str strProbableValue;866 try867 {868 strProbableValue = createProbableValue(enmDataId, pElement);869 }870 catch (std::bad_alloc &)871 {872 return E_OUTOFMEMORY;873 }874 return UnattendedXMLScript::setFieldInElement(pElement, enmDataId, strProbableValue);875 }876 return UnattendedXMLScript::setFieldInElement(pElement, enmDataId, rStrValue);877 }878 879 HRESULT UnattendedSUSEXMLScript::LoopThruSections(const xml::ElementNode *pelmRoot)880 {881 xml::NodesLoop loopChildren(*pelmRoot);882 const xml::ElementNode *pelmOuterLoop;883 while ((pelmOuterLoop = loopChildren.forAllNodes()) != NULL)884 {885 const char *pcszElemName = pelmOuterLoop->getName();886 if (!strcmp(pcszElemName, "users"))887 {888 xml::NodesLoop loopUsers(*pelmOuterLoop);889 const xml::ElementNode *pelmUser;890 while ((pelmUser = loopUsers.forAllNodes()) != NULL)891 {892 HRESULT hrc = HandleUserAccountsSection(pelmUser);893 if (FAILED(hrc))894 return hrc;895 }896 }897 }898 return S_OK;899 }900 901 HRESULT UnattendedSUSEXMLScript::HandleUserAccountsSection(const xml::ElementNode *pelmSection)902 {903 xml::NodesLoop loopUser(*pelmSection);904 905 const xml::ElementNode *pelmCur;906 while ((pelmCur = loopUser.forAllNodes()) != NULL)907 {908 const char *pszValue = pelmCur->getValue();909 #ifdef LOG_ENABLED910 if (!RTStrCmp(pelmCur->getName(), "uid"))911 LogRelFunc(("UnattendedSUSEXMLScript::HandleUserAccountsSection profile/users/%s/%s = %s\n",912 pelmSection->getName(), pelmCur->getName(), pszValue));913 #endif914 915 if (!RTStrCmp(pszValue, "$homedir"))916 mNodesForCorrectionMap.insert(make_pair(USERHOMEDIR_ID, pelmCur));917 918 if (!RTStrCmp(pszValue, "$user"))919 mNodesForCorrectionMap.insert(make_pair(USERNAME_ID, pelmCur));920 921 if (!RTStrCmp(pszValue, "$password"))922 mNodesForCorrectionMap.insert(make_pair(USERPASSWORD_ID, pelmCur));923 }924 return S_OK;925 }926 927 Utf8Str UnattendedSUSEXMLScript::createProbableValue(const DataId enmDataId, const xml::ElementNode *pCurElem)928 {929 const xml::ElementNode *pElem = pCurElem;930 931 switch (enmDataId)932 {933 case USERHOMEDIR_ID:934 // if ((pElem = pElem->findChildElement("home")))935 // {936 return createProbableUserHomeDir(pElem);937 // }938 break;939 default:940 break;941 }942 943 return Utf8Str::Empty;944 }945 946 Utf8Str UnattendedSUSEXMLScript::createProbableUserHomeDir(const xml::ElementNode *pCurElem)947 {948 Utf8Str strCalcValue;949 const xml::ElementNode *pElem = pCurElem->findNextSibilingElement("username");950 if (pElem)951 {952 const char *pszValue = pElem->getValue();953 strCalcValue = "/home/";954 strCalcValue.append(pszValue);955 }956 957 return strCalcValue;958 }959 #endif /* just for reference */960
Note:
See TracChangeset
for help on using the changeset viewer.