VirtualBox

source: vbox/trunk/src/VBox/Frontends/VBoxManage/VBoxManageUpdateCheck.cpp@ 94234

Last change on this file since 94234 was 94234, checked in by vboxsync, 3 years ago

FE/VBoxManage: Remove the now unused VBoxManageHelp build target and the VBOX_ONLY_DOCS #ifdef's in the code, ​bugref:9186

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.9 KB
Line 
1/* $Id: VBoxManageUpdateCheck.cpp 94234 2022-03-15 09:19:29Z vboxsync $ */
2/** @file
3 * VBoxManage - The 'updatecheck' command.
4 */
5
6/*
7 * Copyright (C) 2020-2022 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18/*********************************************************************************************************************************
19* Header Files *
20*********************************************************************************************************************************/
21#include <VBox/com/com.h>
22#include <VBox/com/ErrorInfo.h>
23#include <VBox/com/errorprint.h>
24#include <VBox/com/VirtualBox.h>
25#include <VBox/com/array.h>
26
27#include <iprt/buildconfig.h>
28#include <VBox/version.h>
29
30#include <VBox/log.h>
31#include <iprt/getopt.h>
32#include <iprt/stream.h>
33#include <iprt/ctype.h>
34#include <iprt/message.h>
35
36#include "VBoxManage.h"
37
38DECLARE_TRANSLATION_CONTEXT(UpdateCheck);
39
40using namespace com; // SafeArray
41
42/**
43 * updatecheck getsettings
44 */
45static RTEXITCODE doVBoxUpdateGetSettings(int argc, char **argv, ComPtr<IVirtualBox> aVirtualBox)
46{
47 /*
48 * Parse options.
49 */
50 static const RTGETOPTDEF s_aOptions[] =
51 {
52 { "--machine-readable", 'm', RTGETOPT_REQ_NOTHING }
53 };
54 RTGETOPTSTATE GetState;
55 int vrc = RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0 /* First */, 0);
56 AssertRCReturn(vrc, RTEXITCODE_INIT);
57
58 bool fMachineReadable = false;
59
60 int c;
61 RTGETOPTUNION ValueUnion;
62 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
63 {
64 switch (c)
65 {
66 case 'm':
67 fMachineReadable = true;
68 break;
69
70 default:
71 return errorGetOpt(c, &ValueUnion);
72 }
73 }
74
75 /*
76 * Do the work.
77 */
78 ComPtr<ISystemProperties> pSystemProperties;
79 CHECK_ERROR2I_RET(aVirtualBox, COMGETTER(SystemProperties)(pSystemProperties.asOutParam()), RTEXITCODE_FAILURE);
80
81 BOOL fVBoxUpdateEnabled;
82 CHECK_ERROR2I_RET(pSystemProperties, COMGETTER(VBoxUpdateEnabled)(&fVBoxUpdateEnabled), RTEXITCODE_FAILURE);
83 if (fMachineReadable)
84 outputMachineReadableBool("enabled", &fVBoxUpdateEnabled);
85 else
86 RTPrintf(UpdateCheck::tr("Enabled: %s\n"),
87 fVBoxUpdateEnabled ? UpdateCheck::tr("yes") : UpdateCheck::tr("no"));
88
89 ULONG cVBoxUpdateCount;
90 CHECK_ERROR2I_RET(pSystemProperties, COMGETTER(VBoxUpdateCount)(&cVBoxUpdateCount), RTEXITCODE_FAILURE);
91 if (fMachineReadable)
92 outputMachineReadableULong("count", &cVBoxUpdateCount);
93 else
94 RTPrintf(UpdateCheck::tr("Count: %u\n"), cVBoxUpdateCount);
95
96 ULONG cDaysFrequencey;
97 CHECK_ERROR2I_RET(pSystemProperties, COMGETTER(VBoxUpdateFrequency)(&cDaysFrequencey), RTEXITCODE_FAILURE);
98 if (fMachineReadable)
99 outputMachineReadableULong("frequency", &cDaysFrequencey);
100 else if (cDaysFrequencey == 0)
101 RTPrintf(UpdateCheck::tr("Frequency: never\n")); /** @todo r=bird: Two inconsistencies here. HostUpdateImpl.cpp code will indicate the need for updating if no last-check-date. modifysettings cannot set it to zero (I added the error message, you just skipped setting it originally). */
102 else if (cDaysFrequencey == 1)
103 RTPrintf(UpdateCheck::tr("Frequency: every day\n"));
104 else
105 RTPrintf(UpdateCheck::tr("Frequency: every %u days\n"), cDaysFrequencey);
106
107 VBoxUpdateTarget_T enmVBoxUpdateTarget;
108 CHECK_ERROR2I_RET(pSystemProperties, COMGETTER(VBoxUpdateTarget)(&enmVBoxUpdateTarget), RTEXITCODE_FAILURE);
109 const char *psz;
110 const char *pszMachine;
111 switch (enmVBoxUpdateTarget)
112 {
113 case VBoxUpdateTarget_Stable:
114 psz = UpdateCheck::tr("Stable - new minor and maintenance releases");
115 pszMachine = "stable";
116 break;
117 case VBoxUpdateTarget_AllReleases:
118 psz = UpdateCheck::tr("All releases - new minor, maintenance, and major releases");
119 pszMachine = "all-releases";
120 break;
121 case VBoxUpdateTarget_WithBetas:
122 psz = UpdateCheck::tr("With Betas - new minor, maintenance, major, and beta releases");
123 pszMachine = "with-betas";
124 break;
125 default:
126 AssertFailed();
127 psz = UpdateCheck::tr("Unset");
128 pszMachine = "invalid";
129 break;
130 }
131 if (fMachineReadable)
132 outputMachineReadableString("target", pszMachine);
133 else
134 RTPrintf(UpdateCheck::tr("Target: %s\n"), psz);
135
136 Bstr bstrLastCheckDate;
137 CHECK_ERROR2I_RET(pSystemProperties, COMGETTER(VBoxUpdateLastCheckDate)(bstrLastCheckDate.asOutParam()),
138 RTEXITCODE_FAILURE);
139 if (fMachineReadable)
140 outputMachineReadableString("last-check-date", &bstrLastCheckDate);
141 else if (bstrLastCheckDate.isNotEmpty())
142 RTPrintf(UpdateCheck::tr("Last Check Date: %ls\n"), bstrLastCheckDate.raw());
143
144 return RTEXITCODE_SUCCESS;
145}
146
147/**
148 * updatecheck modifysettings
149 */
150static RTEXITCODE doVBoxUpdateModifySettings(int argc, char **argv, ComPtr<IVirtualBox> aVirtualBox)
151{
152 /*
153 * Parse options.
154 */
155 static const RTGETOPTDEF s_aOptions[] =
156 {
157 { "--enable", 'e', RTGETOPT_REQ_NOTHING },
158 { "--disable", 'd', RTGETOPT_REQ_NOTHING },
159 { "--target", 't', RTGETOPT_REQ_STRING },
160 { "--frequency", 'f', RTGETOPT_REQ_UINT32 },
161 };
162
163 RTGETOPTSTATE GetState;
164 int vrc = RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0 /* First */, 0);
165 AssertRCReturn(vrc, RTEXITCODE_INIT);
166
167 int fEnabled = -1; /* tristate: -1 (not modified), false, true */
168 VBoxUpdateTarget_T const enmVBoxUpdateTargetNil = (VBoxUpdateTarget_T)-999;
169 VBoxUpdateTarget_T enmVBoxUpdateTarget = enmVBoxUpdateTargetNil;
170 uint32_t cDaysUpdateFrequency = 0;
171
172 int c;
173 RTGETOPTUNION ValueUnion;
174 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
175 {
176 switch (c)
177 {
178 case 'e':
179 fEnabled = true;
180 break;
181
182 case 'd':
183 fEnabled = false;
184 break;
185
186 case 't':
187 if (!RTStrICmp(ValueUnion.psz, "stable"))
188 enmVBoxUpdateTarget = VBoxUpdateTarget_Stable;
189 else if (!RTStrICmp(ValueUnion.psz, "withbetas"))
190 enmVBoxUpdateTarget = VBoxUpdateTarget_WithBetas;
191 else if (!RTStrICmp(ValueUnion.psz, "allreleases"))
192 enmVBoxUpdateTarget = VBoxUpdateTarget_AllReleases;
193 else
194 return errorArgument(UpdateCheck::tr("Unknown target specified: '%s'"), ValueUnion.psz);
195 break;
196
197 case 'f':
198 cDaysUpdateFrequency = ValueUnion.u32;
199 if (cDaysUpdateFrequency == 0)
200 return errorArgument(UpdateCheck::tr("The update frequency cannot be zero"));
201 break;
202
203 default:
204 return errorGetOpt(c, &ValueUnion);
205 }
206 }
207
208 if ( fEnabled == -1
209 && enmVBoxUpdateTarget != enmVBoxUpdateTargetNil
210 && cDaysUpdateFrequency == 0)
211 return errorSyntax(UpdateCheck::tr("No change requested"));
212
213 /*
214 * Make the changes.
215 */
216 ComPtr<ISystemProperties> pSystemProperties;
217 CHECK_ERROR2I_RET(aVirtualBox, COMGETTER(SystemProperties)(pSystemProperties.asOutParam()), RTEXITCODE_FAILURE);
218
219 if (enmVBoxUpdateTarget != enmVBoxUpdateTargetNil)
220 {
221 CHECK_ERROR2I_RET(pSystemProperties, COMSETTER(VBoxUpdateTarget)(enmVBoxUpdateTarget), RTEXITCODE_FAILURE);
222 }
223
224 if (fEnabled != -1)
225 {
226 CHECK_ERROR2I_RET(pSystemProperties, COMSETTER(VBoxUpdateEnabled)((BOOL)fEnabled), RTEXITCODE_FAILURE);
227 }
228
229 if (cDaysUpdateFrequency)
230 {
231 CHECK_ERROR2I_RET(pSystemProperties, COMSETTER(VBoxUpdateFrequency)(cDaysUpdateFrequency), RTEXITCODE_FAILURE);
232 }
233
234 return RTEXITCODE_SUCCESS;
235}
236
237/**
238 * updatecheck perform
239 */
240static RTEXITCODE doVBoxUpdate(int argc, char **argv, ComPtr<IVirtualBox> aVirtualBox)
241{
242 /*
243 * Parse arguments.
244 */
245 static const RTGETOPTDEF s_aOptions[] =
246 {
247 { "--machine-readable", 'm', RTGETOPT_REQ_NOTHING }
248 };
249 RTGETOPTSTATE GetState;
250 int vrc = RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0 /* First */, 0);
251 AssertRCReturn(vrc, RTEXITCODE_INIT);
252
253 bool fMachineReadable = false;
254
255 int c;
256 RTGETOPTUNION ValueUnion;
257 while ((c = RTGetOpt(&GetState, &ValueUnion)) != 0)
258 {
259 switch (c)
260 {
261 case 'm':
262 fMachineReadable = true;
263 break;
264
265 default:
266 return errorGetOpt(c, &ValueUnion);
267 }
268 }
269
270 /*
271 * Do the work.
272 */
273 ComPtr<IHost> pHost;
274 CHECK_ERROR2I_RET(aVirtualBox, COMGETTER(Host)(pHost.asOutParam()), RTEXITCODE_FAILURE);
275
276 ComPtr<IHostUpdate> pHostUpdate;
277 CHECK_ERROR2I_RET(pHost, COMGETTER(Update)(pHostUpdate.asOutParam()), RTEXITCODE_FAILURE);
278
279 UpdateCheckType_T updateCheckType = UpdateCheckType_VirtualBox;
280 ComPtr<IProgress> ptrProgress;
281
282 RTPrintf(UpdateCheck::tr("Checking for a new VirtualBox version...\n"));
283
284 // we don't call CHECK_ERROR2I_RET(pHostUpdate, VBoxUpdate(updateCheckType, ...); here so we can check for a specific
285 // return value indicating update checks are disabled.
286 HRESULT rc = pHostUpdate->UpdateCheck(updateCheckType, ptrProgress.asOutParam());
287 if (FAILED(rc))
288 {
289/** @todo r=bird: WTF? This makes no sense. I've commented upon this in the
290 * HostUpdateImpl.cpp code too. */
291 if (rc == E_NOTIMPL)
292 {
293 RTPrintf(UpdateCheck::tr("VirtualBox update checking has been disabled.\n"));
294 return RTEXITCODE_SUCCESS;
295 }
296
297 if (ptrProgress.isNull())
298 RTStrmPrintf(g_pStdErr, UpdateCheck::tr("Failed to create ptrProgress object: %Rhrc\n"), rc);
299 else
300 com::GlueHandleComError(pHostUpdate, "VBoxUpdate(updateCheckType, ptrProgress.asOutParam())",
301 rc, __FILE__, __LINE__);
302 return RTEXITCODE_FAILURE;
303 }
304
305 /* HRESULT hrc = */ showProgress(ptrProgress);
306 CHECK_PROGRESS_ERROR_RET(ptrProgress, (UpdateCheck::tr("Check for update failed.")), RTEXITCODE_FAILURE);
307
308 BOOL fUpdateNeeded = FALSE;
309 CHECK_ERROR2I_RET(pHostUpdate, COMGETTER(UpdateResponse)(&fUpdateNeeded), RTEXITCODE_FAILURE);
310
311 if (fMachineReadable)
312 outputMachineReadableBool("update-needed", &fUpdateNeeded);
313
314 if (fUpdateNeeded)
315 {
316 Bstr bstrUpdateVersion;
317 CHECK_ERROR2I_RET(pHostUpdate, COMGETTER(UpdateVersion)(bstrUpdateVersion.asOutParam()), RTEXITCODE_FAILURE);
318 Bstr bstrUpdateURL;
319 CHECK_ERROR2I_RET(pHostUpdate, COMGETTER(UpdateURL)(bstrUpdateURL.asOutParam()), RTEXITCODE_FAILURE);
320
321 if (fMachineReadable)
322 RTPrintf(UpdateCheck::tr(
323 "A new version of VirtualBox has been released! Version %ls is available at virtualbox.org.\n"
324 "You can download this version here: %ls\n"),
325 bstrUpdateVersion.raw(), bstrUpdateURL.raw());
326 else
327 {
328 outputMachineReadableString("update-version", &bstrUpdateVersion);
329 outputMachineReadableString("update-url", &bstrUpdateURL);
330 }
331 }
332 else if (!fMachineReadable)
333 RTPrintf(UpdateCheck::tr("You are already running the most recent version of VirtualBox.\n"));
334
335 return RTEXITCODE_SUCCESS;
336}
337
338/**
339 * Handles the 'updatecheck' command.
340 *
341 * @returns Appropriate exit code.
342 * @param a Handler argument.
343 */
344RTEXITCODE handleUpdateCheck(HandlerArg *a)
345{
346 if (a->argc < 1)
347 return errorNoSubcommand();
348 if (!strcmp(a->argv[0], "perform"))
349 {
350 setCurrentSubcommand(HELP_SCOPE_UPDATECHECK_PERFORM);
351 return doVBoxUpdate(a->argc - 1, &a->argv[1], a->virtualBox);
352 }
353 if (!strcmp(a->argv[0], "getsettings"))
354 {
355 setCurrentSubcommand(HELP_SCOPE_UPDATECHECK_GETSETTINGS);
356 return doVBoxUpdateGetSettings(a->argc - 1, &a->argv[1], a->virtualBox);
357 }
358 if (!strcmp(a->argv[0], "modifysettings"))
359 {
360 setCurrentSubcommand(HELP_SCOPE_UPDATECHECK_MODIFYSETTINGS);
361 return doVBoxUpdateModifySettings(a->argc - 1, &a->argv[1], a->virtualBox);
362 }
363 return errorUnknownSubcommand(a->argv[0]);
364}
365
366/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracBrowser for help on using the repository browser.

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