VirtualBox

Changeset 76167 in vbox for trunk/src/VBox/Main/src-all


Ignore:
Timestamp:
Dec 11, 2018 5:03:05 PM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
127415
Message:

Main: Split out the two text script classes from UnattendedScript since they are now used separately from unattended installation. bugref:9152

File:
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-all/TextScript.cpp

    r76159 r76167  
    11/* $Id$ */
    22/** @file
    3  * Implementeation of algorithms which read/parse/save scripts for unattended installation.
     3 * Classes for reading/parsing/saving text scripts (unattended installation, ++).
    44 */
    55
     
    2222#define LOG_GROUP LOG_GROUP_MAIN_UNATTENDED
    2323#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"
    3025
    3126#include <VBox/err.h>
     
    3429#include <iprt/file.h>
    3530#include <iprt/vfs.h>
    36 #include <iprt/getopt.h>
    3731#include <iprt/path.h>
    3832
     
    4034
    4135
    42 //////////////////////////////////////////////////////////////////////////////////////////////////////
    43 /*
    44 *
    45 *
    46 *  Implementation BaseTextScript functions
    47 *
    48 */
    49 //////////////////////////////////////////////////////////////////////////////////////////////////////
     36/*********************************************************************************************************************************
     37*   BaseTextScript Implementation                                                                                                *
     38*********************************************************************************************************************************/
     39
    5040HRESULT BaseTextScript::read(const Utf8Str &rStrFilename)
    5141{
     
    197187}
    198188
    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
    651195HRESULT GeneralTextScript::parse()
    652196{
     
    813357}
    814358
    815 #if 0 /* Keeping this a reference */
    816 //////////////////////////////////////////////////////////////////////////////////////////////////////
    817 /*
    818 *
    819 *
    820 *  Implementation UnattendedSUSEXMLScript functions
    821 *
    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 (   pelmRoot
    834             && strcmp(pelmRoot->getName(), "profile") == 0)
    835         {
    836             /*
    837              * Work thought the sections.
    838              */
    839             try
    840             {
    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         else
    853             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         try
    867         {
    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_ENABLED
    910         if (!RTStrCmp(pelmCur->getName(), "uid"))
    911             LogRelFunc(("UnattendedSUSEXMLScript::HandleUserAccountsSection profile/users/%s/%s = %s\n",
    912                         pelmSection->getName(), pelmCur->getName(), pszValue));
    913 #endif
    914 
    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.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette