VirtualBox

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

Last change on this file since 86117 was 82968, checked in by vboxsync, 5 years ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.2 KB
Line 
1/* $Id: hostversion.cpp 82968 2020-02-04 10:35:17Z vboxsync $ */
2/** @file
3 * X11 guest client - host version check.
4 */
5
6/*
7 * Copyright (C) 2011-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#include <stdio.h>
18#include <iprt/assert.h>
19#include <iprt/errcore.h>
20#include <iprt/mem.h>
21#include <iprt/ldr.h>
22#include <iprt/string.h>
23#include <iprt/thread.h>
24
25#ifdef VBOX_WITH_DBUS
26# include <VBox/dbus.h>
27#endif
28#include <VBox/log.h>
29#include <VBox/VBoxGuestLib.h>
30#ifdef VBOX_OSE
31# include <VBox/version.h>
32#endif
33
34#include "VBoxClient.h"
35
36static const char *getName()
37{
38 return "Host Version Check";
39}
40
41static const char *getPidFilePath()
42{
43 return ".vboxclient-hostversion.pid";
44}
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 LogRelFlowFunc(("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/** @todo Move this part in VbglR3 and just provide a callback for the platform-specific
130 notification stuff, since this is very similar to the VBoxTray code. */
131static int run(struct VBCLSERVICE **ppInterface, bool fDaemonised)
132{
133 int rc;
134 LogFlowFunc(("\n"));
135
136 RT_NOREF(ppInterface);
137
138 /* Because we need desktop notifications to be displayed, wait
139 * some time to make the desktop environment load (as a work around). */
140 if (fDaemonised)
141 RTThreadSleep(30 * 1000 /* Wait 30 seconds */);
142
143# ifdef VBOX_WITH_DBUS
144 rc = RTDBusLoadLib();
145 if (RT_FAILURE(rc))
146 VBClLogError("D-Bus seems not to be installed; no host version check/notification done\n");
147# else
148 rc = VERR_NOT_IMPLEMENTED;
149# endif /* VBOX_WITH_DBUS */
150
151# ifdef VBOX_WITH_GUEST_PROPS
152 uint32_t uGuestPropSvcClientID;
153 if (RT_SUCCESS(rc))
154 {
155 rc = VbglR3GuestPropConnect(&uGuestPropSvcClientID);
156 if (RT_FAILURE(rc))
157 VBClLogError("Cannot connect to guest property service while chcking for host version! rc = %Rrc\n", rc);
158 }
159
160 if (RT_SUCCESS(rc))
161 {
162 char *pszHostVersion;
163 char *pszGuestVersion;
164 bool bUpdate;
165
166 rc = VbglR3HostVersionCheckForUpdate(uGuestPropSvcClientID, &bUpdate, &pszHostVersion, &pszGuestVersion);
167 if (RT_SUCCESS(rc))
168 {
169 if (bUpdate)
170 {
171 char szMsg[1024];
172 char szTitle[64];
173
174 /** @todo add some translation macros here */
175 RTStrPrintf(szTitle, sizeof(szTitle), "VirtualBox Guest Additions update available!");
176#ifndef VBOX_OSE
177 RTStrPrintf(szMsg, sizeof(szMsg), "Your guest is currently running the Guest Additions version %s. "
178 "We recommend updating to the latest version (%s) by choosing the "
179 "install option from the Devices menu.", pszGuestVersion, pszHostVersion);
180#else
181/* This is the message which appears for non-Oracle builds of the
182* Guest Additions. Distributors are encouraged to customise this. */
183 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);
184#endif
185 rc = showNotify(szTitle, szMsg);
186 VBClLogInfo("VirtualBox Guest Additions update available!\n");
187 if (RT_FAILURE(rc))
188 VBClLogError("Could not show version notifier tooltip! rc = %d\n", rc);
189 }
190
191 /* Store host version to not notify again */
192 rc = VbglR3HostVersionLastCheckedStore(uGuestPropSvcClientID, pszHostVersion);
193
194 VbglR3GuestPropReadValueFree(pszHostVersion);
195 VbglR3GuestPropReadValueFree(pszGuestVersion);
196 }
197 VbglR3GuestPropDisconnect(uGuestPropSvcClientID);
198 }
199# endif /* VBOX_WITH_GUEST_PROPS */
200 VbglR3Term();
201 LogFlowFunc(("returning %Rrc\n", rc));
202 return rc;
203}
204
205struct VBCLSERVICE vbclHostVersionInterface =
206{
207 getName,
208 getPidFilePath,
209 VBClServiceDefaultHandler, /* init */
210 run,
211 VBClServiceDefaultCleanup
212};
213
214struct HOSTVERSIONSERVICE
215{
216 struct VBCLSERVICE *pInterface;
217};
218
219/* Static factory */
220struct VBCLSERVICE **VBClGetHostVersionService()
221{
222 struct HOSTVERSIONSERVICE *pService =
223 (struct HOSTVERSIONSERVICE *)RTMemAlloc(sizeof(*pService));
224
225 if (!pService)
226 VBClLogFatalError("Out of memory\n");
227 pService->pInterface = &vbclHostVersionInterface;
228 return &pService->pInterface;
229}
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