summaryrefslogtreecommitdiffstats
path: root/src/VBox/Main/include/UnattendedScript.h
blob: f61821b8c5a33b311afe800a0e92f4e39f0b6e8e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/* $Id: UnattendedScript.h $ */
/** @file
 * Classes for reading/parsing/saving scripts for unattended installation.
 */

/*
 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
 *
 * This file is part of VirtualBox base platform packages, as
 * available from https://www.virtualbox.org.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation, in version 3 of the
 * License.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <https://www.gnu.org/licenses>.
 *
 * SPDX-License-Identifier: GPL-3.0-only
 */

#ifndef MAIN_INCLUDED_UnattendedScript_h
#define MAIN_INCLUDED_UnattendedScript_h
#ifndef RT_WITHOUT_PRAGMA_ONCE
# pragma once
#endif

#include "TextScript.h"
#include "iprt/expreval.h"

using namespace xml;

class Unattended;


/**
 * Generic unattended text script template editor.
 *
 * This just perform variable replacements, no other editing possible.
 *
 * Everything happens during saveToString, parse is a noop.
 */
class UnattendedScriptTemplate : public BaseTextScript
{
protected:
    /** Where to get the replacement strings from. */
    Unattended *mpUnattended;

public:
    DECLARE_TRANSLATE_METHODS(UnattendedScriptTemplate)

    UnattendedScriptTemplate(Unattended *pUnattended, const char *pszDefaultTemplateFilename, const char *pszDefaultFilename);
    virtual ~UnattendedScriptTemplate()             {}

    HRESULT parse()                                 { return S_OK; }
    HRESULT saveToString(Utf8Str &rStrDst);

protected:
    typedef enum
    {
        kValueEscaping_None,
        kValueEscaping_Bourne,
        kValueEscaping_XML_Element,
        kValueEscaping_XML_Attribute_Double_Quotes
    } kEvalEscaping_T;

    /**
     * Gets the replacement value for the given placeholder.
     *
     * @returns COM status code.
     * @param   pachPlaceholder The placholder string.  Not zero terminated.
     * @param   cchPlaceholder  The length of the placeholder.
     * @param   fOutputting     Indicates whether we actually need the correct value
     *                          or is just syntax checking excluded template parts.
     * @param   rValue          Where to return the value.
     */
    HRESULT getReplacement(const char *pachPlaceholder, size_t cchPlaceholder, bool fOutputting, RTCString &rValue);

    /**
     * Gets the replacement value for the given expression placeholder
     * (@@VBOX_INSERT[expr]@@ and friends).
     *
     * @returns COM status code.
     * @param   hEvaluator      The evaluator to use for the expression.
     * @param   pachPlaceholder The placholder string.  Not zero terminated.
     * @param   cchPlaceholder  The length of the placeholder.
     * @param   fOutputting     Indicates whether we actually need the correct value
     *                          or is just syntax checking excluded template parts.
     * @param   ppszValue       Where to return the value.  Free by calling
     *                          RTStrFree.  Set to NULL for empty string.
     */
    HRESULT getReplacementForExpr(RTEXPREVAL hEvaluator, const char *pachPlaceholder, size_t cchPlaceholder,
                                  bool fOutputting, char **ppszValue) RT_NOEXCEPT;

    /**
     * Resolves a conditional expression.
     *
     * @returns COM status code.
     * @param   hEvaluator      The evaluator to use for the expression.
     * @param   pachPlaceholder The placholder string.  Not zero terminated.
     * @param   cchPlaceholder  The length of the placeholder.
     * @param   pfOutputting    Where to return the result of the conditional. This
     *                          holds the current outputting state on input in case
     *                          someone want to sanity check anything.
     */
    HRESULT resolveConditionalExpr(RTEXPREVAL hEvaluator, const char *pachPlaceholder, size_t cchPlaceholder,
                                   bool *pfOutputting) RT_NOEXCEPT;

    /** @callback_method_impl{FNRTEXPREVALQUERYVARIABLE}  */
    static DECLCALLBACK(int) queryVariableForExpr(const char *pchName, size_t cchName, void *pvUser,
                                                  char **ppszValue) RT_NOEXCEPT;

    /**
     * Gets a variable.
     *
     * This is used both for getting replacements (@@VBOX_INSERT_XXX@@) and in
     * expressions (@@VBOX_INSERT[expr]@@, @@VBOX_COND[expr]@@).
     *
     * @returns VBox status code.
     * @retval  VERR_NOT_FOUND if variable does not exist.
     *
     * @param   pchName             The variable name.  Not zero terminated.
     * @param   cchName             The length of the name.
     * @param   rstrTmp             String object that can be used for keeping the
     *                              value returned via @a *ppszValue.
     * @param   ppszValue           If a value is desired, this is where to return
     *                              it.  This points to a string that should be
     *                              accessible for a little while after the function
     *                              returns.  Use @a rstrTmp for storage if
     *                              necessary.
     *
     *                              This will be NULL when called from the 'defined'
     *                              operator.  In which case no errors should be
     *                              set.
     * @throws  std::bad_alloc
     * @see     FNRTEXPREVALQUERYVARIABLE
     */
    virtual int queryVariable(const char *pchName, size_t cchName, Utf8Str &rstrTmp, const char **ppszValue);

    /**
     * Get the result of a conditional.
     *
     * @returns COM status code.
     * @param   pachPlaceholder     The placholder string.  Not zero terminated.
     * @param   cchPlaceholder      The length of the placeholder.
     * @param   pfOutputting        Where to return the result of the conditional.
     *                              This holds the current outputting state on input
     *                              in case someone want to sanity check anything.
     */
    virtual HRESULT getConditional(const char *pachPlaceholder, size_t cchPlaceholder, bool *pfOutputting);
};

#if 0 /* convert when we fix SUSE */
/**
 * SUSE unattended XML file editor.
 */
class UnattendedSUSEXMLScript : public UnattendedXMLScript
{
public:
    DECLARE_TRANSLATE_METHODS(UnattendedSUSEXMLScript)

    UnattendedSUSEXMLScript(VirtualBoxBase *pSetError, const char *pszDefaultFilename = "autoinst.xml")
        : UnattendedXMLScript(pSetError, pszDefaultFilename) {}
    ~UnattendedSUSEXMLScript() {}

    HRESULT parse();

protected:
    HRESULT setFieldInElement(xml::ElementNode *pElement, const DataId enmDataId, const Utf8Str &rStrValue);

private:
    //////////////////New functions//////////////////////////////
    /** @throws std::bad_alloc */
    HRESULT LoopThruSections(const xml::ElementNode *pelmRoot);
    /** @throws std::bad_alloc */
    HRESULT HandleUserAccountsSection(const xml::ElementNode *pelmSection);
    /** @throws std::bad_alloc */
    Utf8Str createProbableValue(const DataId enmDataId, const xml::ElementNode *pCurElem);
    /** @throws std::bad_alloc */
    Utf8Str createProbableUserHomeDir(const xml::ElementNode *pCurElem);
    //////////////////New functions//////////////////////////////
};
#endif


#endif /* !MAIN_INCLUDED_UnattendedScript_h */