VirtualBox

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

Last change on this file since 24073 was 24073, checked in by vboxsync, 15 years ago

VBoxClient: Added more D-BUS error checking.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.3 KB
Line 
1/** @file
2 * X11 guest client - host version check.
3 */
4
5/*
6 * Copyright (C) 2009 Sun Microsystems, Inc.
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
17 * Clara, CA 95054 USA or visit http://www.sun.com if you need
18 * additional information or have any questions.
19 */
20#include <stdio.h>
21#include <iprt/assert.h>
22#include <iprt/err.h>
23#include <iprt/ldr.h>
24#include <iprt/string.h>
25#include <iprt/thread.h>
26
27#ifdef VBOX_WITH_DBUS
28 #include <VBox/dbus.h>
29#endif
30#include <VBox/log.h>
31#include <VBox/VBoxGuestLib.h>
32
33#include "VBoxClient.h"
34
35class HostVersionService : public VBoxClient::Service
36{
37
38public:
39
40 virtual const char *getPidFilePath()
41 {
42 return ".vboxclient-hostversion.pid";
43 }
44
45 virtual int showNotify(const char *pcHeader, const char *pcBody)
46 {
47 int rc;
48# ifdef VBOX_WITH_DBUS
49 DBusConnection *conn;
50 DBusMessage* msg;
51 conn = dbus_bus_get (DBUS_BUS_SESSON, NULL);
52 if (conn == NULL)
53 {
54 LogFlow(("Could not retrieve D-BUS session bus!\n"));
55 rc = VERR_INVALID_HANDLE;
56 }
57 else
58 {
59 msg = dbus_message_new_method_call("org.freedesktop.Notifications",
60 "/org/freedesktop/Notifications",
61 "org.freedesktop.Notifications",
62 "Notify");
63 if (conn == NULL)
64 {
65 Log(("Could not create D-BUS message!\n"));
66 rc = VERR_INVALID_HANDLE;
67 }
68 }
69 if (RT_SUCCESS(rc))
70 {
71 uint32_t msg_replace_id = 0;
72 const char *msg_app = "VBoxClient";
73 const char *msg_icon = "";
74 const char *msg_summary = pcHeader;
75 const char *msg_body = pcBody;
76 int32_t msg_timeout = -1; /* Let the notification server decide */
77
78 DBusMessageIter iter;
79 DBusMessageIter array;
80 DBusMessageIter dict;
81 DBusMessageIter value;
82 DBusMessageIter variant;
83 DBusMessageIter data;
84
85 /* Format: UINT32 org.freedesktop.Notifications.Notify
86 * (STRING app_name, UINT32 replaces_id, STRING app_icon, STRING summary, STRING body,
87 * ARRAY actions, DICT hints, INT32 expire_timeout)
88 */
89 dbus_message_iter_init_append(msg,&iter);
90 dbus_message_iter_append_basic(&iter,DBUS_TYPE_STRING,&msg_app);
91 dbus_message_iter_append_basic(&iter,DBUS_TYPE_UINT32,&msg_replace_id);
92 dbus_message_iter_append_basic(&iter,DBUS_TYPE_STRING,&msg_icon);
93 dbus_message_iter_append_basic(&iter,DBUS_TYPE_STRING,&msg_summary);
94 dbus_message_iter_append_basic(&iter,DBUS_TYPE_STRING,&msg_body);
95 dbus_message_iter_open_container(&iter,DBUS_TYPE_ARRAY,DBUS_TYPE_STRING_AS_STRING,&array);
96 dbus_message_iter_close_container(&iter,&array);
97 dbus_message_iter_open_container(&iter,DBUS_TYPE_ARRAY,"{sv}",&array);
98 dbus_message_iter_close_container(&iter,&array);
99 dbus_message_iter_append_basic(&iter,DBUS_TYPE_INT32,&msg_timeout);
100
101 DBusError err;
102 DBusMessage *reply;
103 reply = dbus_connection_send_with_reply_and_block(conn, msg,
104 30 * 1000 /* 30 seconds timeout */, &err);
105 if (dbus_error_is_set(&err))
106 {
107 Log(("D-BUS returned an error while sending the notification: %s", err.message));
108 }
109 else if (reply)
110 {
111 dbus_connection_flush(conn);
112 dbus_message_unref(reply);
113 }
114 }
115 if (msg != NULL)
116 dbus_message_unref(msg);
117# else
118 /* TODO: Implement me */
119 rc = VINF_SUCCESS;
120# endif /* VBOX_WITH_DBUS */
121 return rc;
122 }
123
124 /** @todo Move this part in VbglR3 and just provide a callback for the platform-specific
125 notification stuff, since this is very similar to the VBoxTray code. */
126 virtual int run(bool fDaemonised /* = false */)
127 {
128 int rc;
129 LogFlowFunc(("\n"));
130
131 /* Because we need desktop notifications to be displayed, wait
132 * some time to make the desktop environment load (as a work around). */
133 if (fDaemonised)
134 RTThreadSleep(30 * 1000 /* Wait 30 seconds */);
135
136# ifdef VBOX_WITH_DBUS
137 rc = RTDBusLoadLib();
138 if (RT_FAILURE(rc))
139 LogRel(("VBoxClient: D-Bus seems not to be installed; no host version check/notification done.\n"));
140# else
141 rc = VERR_NOT_IMPLEMENTED;
142# endif /* VBOX_WITH_DBUS */
143
144# ifdef VBOX_WITH_GUEST_PROPS
145 uint32_t uGuestPropSvcClientID;
146 if (RT_SUCCESS(rc))
147 {
148 rc = VbglR3GuestPropConnect(&uGuestPropSvcClientID);
149 if (RT_FAILURE(rc))
150 Log(("Cannot connect to guest property service! rc = %Rrc\n", rc));
151 }
152
153 if (RT_SUCCESS(rc))
154 {
155 char *pszHostVersion;
156 char *pszGuestVersion;
157 bool bUpdate;
158
159 rc = VbglR3HostVersionCheckForUpdate(uGuestPropSvcClientID, &bUpdate, &pszHostVersion, &pszGuestVersion);
160 if (RT_SUCCESS(rc))
161 {
162 if (bUpdate)
163 {
164 char szMsg[256];
165 char szTitle[64];
166
167 /** @todo add some translation macros here */
168 RTStrPrintf(szTitle, sizeof(szTitle), "VirtualBox Guest Additions update available!");
169 RTStrPrintf(szMsg, sizeof(szMsg), "Your guest is currently running the Guest Additions version %s. "
170 "We recommend updating to the latest version (%s) by choosing the "
171 "install option from the Devices menu.", pszGuestVersion, pszHostVersion);
172 rc = showNotify(szTitle, szMsg);
173 LogRel(("VBoxClient: VirtualBox Guest Additions update available!"));
174 if (RT_FAILURE(rc))
175 Log(("VBoxClient: Could not show version notifier tooltip! rc = %d\n", rc));
176 }
177
178 /* Store host version to not notify again */
179 rc = VbglR3HostVersionLastCheckedStore(uGuestPropSvcClientID, pszHostVersion);
180
181 VbglR3GuestPropReadValueFree(pszHostVersion);
182 VbglR3GuestPropReadValueFree(pszGuestVersion);
183 }
184 VbglR3GuestPropDisconnect(uGuestPropSvcClientID);
185 }
186# endif /* VBOX_WITH_GUEST_PROPS */
187 LogFlowFunc(("returning %Rrc\n", rc));
188 return rc;
189 }
190
191 virtual void cleanup()
192 {
193
194 }
195};
196
197/* Static factory */
198VBoxClient::Service *VBoxClient::GetHostVersionService()
199{
200 return new HostVersionService;
201}
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