VirtualBox

source: vbox/trunk/src/VBox/Additions/x11/VBoxClient/hostversion.cpp@ 97728

Last change on this file since 97728 was 96407, checked in by vboxsync, 2 years ago

scm copyright and license note update

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.5 KB
Line 
1/* $Id: hostversion.cpp 96407 2022-08-22 17:43:14Z vboxsync $ */
2/** @file
3 * X11 guest client - Host version check.
4 */
5
6/*
7 * Copyright (C) 2011-2022 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27#include <stdio.h>
28#include <iprt/assert.h>
29#include <iprt/errcore.h>
30#include <iprt/mem.h>
31#include <iprt/ldr.h>
32#include <iprt/string.h>
33#include <iprt/thread.h>
34
35#ifdef VBOX_WITH_DBUS
36# include <VBox/dbus.h>
37#endif
38#include <VBox/log.h>
39#include <VBox/VBoxGuestLib.h>
40#ifdef VBOX_OSE
41# include <VBox/version.h>
42#endif
43
44#include "VBoxClient.h"
45
46static int showNotify(const char *pszHeader, const char *pszBody)
47{
48 int rc;
49# ifdef VBOX_WITH_DBUS
50 DBusConnection *conn;
51 DBusMessage* msg = NULL;
52 conn = dbus_bus_get(DBUS_BUS_SESSION, NULL);
53 if (conn == NULL)
54 {
55 VBClLogError("Could not retrieve D-BUS session bus\n");
56 rc = VERR_INVALID_HANDLE;
57 }
58 else
59 {
60 msg = dbus_message_new_method_call("org.freedesktop.Notifications",
61 "/org/freedesktop/Notifications",
62 "org.freedesktop.Notifications",
63 "Notify");
64 if (msg == NULL)
65 {
66 VBClLogError("Could not create D-BUS message!\n");
67 rc = VERR_INVALID_HANDLE;
68 }
69 else
70 rc = VINF_SUCCESS;
71 }
72 if (RT_SUCCESS(rc))
73 {
74 uint32_t msg_replace_id = 0;
75 const char *msg_app = "VBoxClient";
76 const char *msg_icon = "";
77 const char *msg_summary = pszHeader;
78 const char *msg_body = pszBody;
79 int32_t msg_timeout = -1; /* Let the notification server decide */
80
81 DBusMessageIter iter;
82 DBusMessageIter array;
83 /*DBusMessageIter dict; - unused */
84 /*DBusMessageIter value; - unused */
85 /*DBusMessageIter variant; - unused */
86 /*DBusMessageIter data; - unused */
87
88 /* Format: UINT32 org.freedesktop.Notifications.Notify
89 * (STRING app_name, UINT32 replaces_id, STRING app_icon, STRING summary, STRING body,
90 * ARRAY actions, DICT hints, INT32 expire_timeout)
91 */
92 dbus_message_iter_init_append(msg,&iter);
93 dbus_message_iter_append_basic(&iter,DBUS_TYPE_STRING,&msg_app);
94 dbus_message_iter_append_basic(&iter,DBUS_TYPE_UINT32,&msg_replace_id);
95 dbus_message_iter_append_basic(&iter,DBUS_TYPE_STRING,&msg_icon);
96 dbus_message_iter_append_basic(&iter,DBUS_TYPE_STRING,&msg_summary);
97 dbus_message_iter_append_basic(&iter,DBUS_TYPE_STRING,&msg_body);
98 dbus_message_iter_open_container(&iter,DBUS_TYPE_ARRAY,DBUS_TYPE_STRING_AS_STRING,&array);
99 dbus_message_iter_close_container(&iter,&array);
100 dbus_message_iter_open_container(&iter,DBUS_TYPE_ARRAY,"{sv}",&array);
101 dbus_message_iter_close_container(&iter,&array);
102 dbus_message_iter_append_basic(&iter,DBUS_TYPE_INT32,&msg_timeout);
103
104 DBusError err;
105 dbus_error_init(&err);
106
107 DBusMessage *reply;
108 reply = dbus_connection_send_with_reply_and_block(conn, msg, 30 * 1000 /* 30 seconds timeout */, &err);
109 if (dbus_error_is_set(&err))
110 VBClLogError("D-BUS returned an error while sending the notification: %s", err.message);
111 else if (reply)
112 {
113 dbus_connection_flush(conn);
114 dbus_message_unref(reply);
115 }
116 if (dbus_error_is_set(&err))
117 dbus_error_free(&err);
118 }
119 if (msg != NULL)
120 dbus_message_unref(msg);
121# else
122 /** @todo Implement me */
123 RT_NOREF(pszHeader, pszBody);
124 rc = VINF_SUCCESS;
125# endif /* VBOX_WITH_DBUS */
126 return rc;
127}
128
129/**
130 * @interface_method_impl{VBCLSERVICE,pfnWorker}
131 */
132static DECLCALLBACK(int) vbclHostVerWorker(bool volatile *pfShutdown)
133{
134 /** @todo Move this part in VbglR3 and just provide a callback for the platform-specific
135 notification stuff, since this is very similar to the VBoxTray code. */
136
137 RT_NOREF(pfShutdown);
138
139 LogFlowFuncEnter();
140
141 int rc;
142# ifdef VBOX_WITH_DBUS
143 rc = RTDBusLoadLib();
144 if (RT_FAILURE(rc))
145 VBClLogError("D-Bus seems not to be installed; no host version check/notification done\n");
146# else
147 rc = VERR_NOT_IMPLEMENTED;
148# endif /* VBOX_WITH_DBUS */
149
150# ifdef VBOX_WITH_GUEST_PROPS
151 uint32_t uGuestPropSvcClientID;
152 if (RT_SUCCESS(rc))
153 {
154 rc = VbglR3GuestPropConnect(&uGuestPropSvcClientID);
155 if (RT_FAILURE(rc))
156 VBClLogError("Cannot connect to guest property service while chcking for host version, rc = %Rrc\n", rc);
157 }
158
159 if (RT_SUCCESS(rc))
160 {
161 /* Let the main thread know that it can continue spawning services. */
162 RTThreadUserSignal(RTThreadSelf());
163
164 /* Because we need desktop notifications to be displayed, wait
165 * some time to make the desktop environment load (as a work around). */
166 if (g_fDaemonized)
167 RTThreadSleep(RT_MS_30SEC);
168
169 char *pszHostVersion;
170 char *pszGuestVersion;
171 bool fUpdate;
172
173 rc = VbglR3HostVersionCheckForUpdate(uGuestPropSvcClientID, &fUpdate, &pszHostVersion, &pszGuestVersion);
174 if (RT_SUCCESS(rc))
175 {
176 if (fUpdate)
177 {
178 char szMsg[1024];
179 char szTitle[64];
180
181 /** @todo add some translation macros here */
182 RTStrPrintf(szTitle, sizeof(szTitle), "VirtualBox Guest Additions update available!");
183#ifndef VBOX_OSE
184 RTStrPrintf(szMsg, sizeof(szMsg), "Your guest is currently running the Guest Additions version %s. "
185 "We recommend updating to the latest version (%s) by choosing the "
186 "install option from the Devices menu.", pszGuestVersion, pszHostVersion);
187#else
188/* This is the message which appears for non-Oracle builds of the
189* Guest Additions. Distributors are encouraged to customise this. */
190 RTStrPrintf(szMsg, sizeof(szMsg), "Your virtual machine is currently running the Guest Additions version %s. Since you are running a version of the Guest Additions provided by the operating system you installed in the virtual machine we recommend that you update it to at least version %s using that system's update features, or alternatively that you remove this version and then install the " VBOX_VENDOR_SHORT " Guest Additions package using the install option from the Devices menu. Please consult the documentation for the operating system you are running to find out how to update or remove the current Guest Additions package.", pszGuestVersion, pszHostVersion);
191#endif
192 rc = showNotify(szTitle, szMsg);
193 VBClLogInfo("VirtualBox Guest Additions update available!\n");
194 if (RT_FAILURE(rc))
195 VBClLogError("Could not show version notifier tooltip! rc = %d\n", rc);
196 }
197
198 /* Store host version to not notify again */
199 rc = VbglR3HostVersionLastCheckedStore(uGuestPropSvcClientID, pszHostVersion);
200
201 VbglR3GuestPropReadValueFree(pszHostVersion);
202 VbglR3GuestPropReadValueFree(pszGuestVersion);
203 }
204 VbglR3GuestPropDisconnect(uGuestPropSvcClientID);
205 }
206# endif /* VBOX_WITH_GUEST_PROPS */
207
208 return rc;
209}
210
211VBCLSERVICE g_SvcHostVersion =
212{
213 "hostversion", /* szName */
214 "VirtualBox host version check", /* pszDescription */
215 ".vboxclient-hostversion.pid", /* pszPidFilePath */
216 NULL, /* pszUsage */
217 NULL, /* pszOptions */
218 NULL, /* pfnOption */
219 NULL, /* pfnInit */
220 vbclHostVerWorker, /* pfnWorker */
221 NULL, /* pfnStop*/
222 NULL /* pfnTerm */
223};
224
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