VirtualBox

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

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

Main: bugref:1909: Added translation into VBoxManage excluding built-in docbook help. Fixed translation marks in the VBoxManage

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