VirtualBox

source: vbox/trunk/src/VBox/Additions/common/VBoxControl/VBoxControl.cpp@ 10143

Last change on this file since 10143 was 10143, checked in by vboxsync, 17 years ago

Additions/common: make the VBoxControl guest property functions utf8-safe

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 10.0 KB
Line 
1/** $Id: VBoxControl.cpp 10143 2008-07-03 09:19:25Z vboxsync $ */
2/** @file
3 * VBoxControl - Guest Additions Command Line Management Interface
4 */
5
6/*
7 * Copyright (C) 2007 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.215389.xyz. 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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22
23
24/*******************************************************************************
25* Header Files *
26*******************************************************************************/
27#include <iprt/thread.h>
28#include <iprt/string.h>
29#include <iprt/stream.h>
30#include <iprt/path.h>
31#include <iprt/initterm.h>
32#include <VBox/VBoxGuest.h>
33#include <VBox/version.h>
34#ifdef VBOX_WITH_INFO_SVC
35# include <VBox/HostServices/VBoxInfoSvc.h>
36#endif
37#include "VBoxControl.h"
38
39/*******************************************************************************
40* Global Variables *
41*******************************************************************************/
42/** The program name (derived from argv[0]). */
43char const *g_pszProgName = "";
44/** The current verbosity level. */
45int g_cVerbosity = 0;
46
47
48/**
49 * Displays the program usage message.
50 *
51 * @param u64Which
52 *
53 * @{
54 */
55
56/** Helper function */
57static void doUsage(char const *line, char const *name = "", char const *command = "")
58{
59 RTPrintf("%s %-*s%s", name, 30 - strlen(name), command, line);
60}
61
62/** Enumerate the different parts of the usage we might want to print out */
63enum g_eUsage
64{
65#ifdef VBOX_WITH_INFO_SVC
66 GET_GUEST_PROP,
67 SET_GUEST_PROP,
68#endif
69 USAGE_ALL = UINT32_MAX
70};
71
72static void usage(g_eUsage eWhich = USAGE_ALL)
73{
74 RTPrintf("Usage:\n\n");
75 RTPrintf("%s [-v|--version] print version number and exit\n", g_pszProgName);
76 RTPrintf("%s --nologo ... suppress the logo\n\n", g_pszProgName);
77
78 if ((GET_GUEST_PROP == eWhich) || (USAGE_ALL == eWhich))
79 doUsage("<key>\n", g_pszProgName, "getguestproperty");
80 if ((SET_GUEST_PROP == eWhich) || (USAGE_ALL == eWhich))
81 doUsage("<key> [<value>] (no value deletes key)\n", g_pszProgName, "setguestproperty");
82}
83/** @} */
84
85/**
86 * Displays an error message.
87 *
88 * @param pszFormat The message text.
89 * @param ... Format arguments.
90 */
91static void VBoxControlError(const char *pszFormat, ...)
92{
93 // RTStrmPrintf(g_pStdErr, "%s: error: ", g_pszProgName);
94
95 va_list va;
96 va_start(va, pszFormat);
97 RTStrmPrintfV(g_pStdErr, pszFormat, va);
98 va_end(va);
99}
100
101#ifdef VBOX_WITH_INFO_SVC
102/**
103 * Retrieves a value from the host/guest configuration registry.
104 * This is accessed through the "VBoxSharedInfoSvc" HGCM service.
105 *
106 * @returns 0 on success, 1 on failure
107 * @param key (string) the key which the value is stored under.
108 */
109int getGuestProperty(int argc, char **argv)
110{
111 using namespace svcInfo;
112
113 uint32_t u32ClientID = 0;
114 int rc = VINF_SUCCESS;
115 char *pszKey = NULL;
116 char szValue[KEY_MAX_VALUE_LEN];
117
118 if (argc != 1)
119 {
120 usage(GET_GUEST_PROP);
121 return 1;
122 }
123 rc = RTStrCurrentCPToUtf8(&pszKey, argv[0]);
124 if (!RT_SUCCESS(rc))
125 VBoxControlError("Failed to convert the key name to Utf8, error %Rrc\n", rc);
126 if (RT_SUCCESS(rc))
127 {
128 rc = VbglR3InfoSvcConnect(&u32ClientID);
129 if (!RT_SUCCESS(rc))
130 VBoxControlError("Failed to connect to the guest property service, error %Rrc\n", rc);
131 }
132 if (RT_SUCCESS(rc))
133 {
134 rc = VbglR3InfoSvcReadKey(u32ClientID, argv[0], szValue, sizeof(szValue), NULL);
135 if (!RT_SUCCESS(rc) && (rc != VERR_NOT_FOUND))
136 VBoxControlError("Failed to retrieve the property value, error %Rrc\n", rc);
137 }
138 if (VERR_NOT_FOUND == rc)
139 RTPrintf("No value set!\n");
140 if (RT_SUCCESS(rc))
141 RTPrintf("Value: %S\n", szValue);
142 if (u32ClientID != 0)
143 VbglR3InfoSvcDisconnect(u32ClientID);
144 RTStrFree(pszKey);
145 return RT_SUCCESS(rc) ? 0 : 1;
146}
147
148
149/**
150 * Writes a value to the host/guest configuration registry.
151 * This is accessed through the "VBoxSharedInfoSvc" HGCM service.
152 *
153 * @returns 0 on success, 1 on failure
154 * @param key (string) the key which the value is stored under.
155 * @param value (string) the value to write. If empty, the key will be
156 * removed.
157 */
158static int setGuestProperty(int argc, char *argv[])
159{
160 uint32_t u32ClientID = 0;
161 int rc = VINF_SUCCESS;
162 char *pszKey = NULL;
163 char *pszValue = NULL;
164
165 if (argc != 1 && argc != 2)
166 {
167 usage();
168 return 1;
169 }
170 rc = RTStrCurrentCPToUtf8(&pszKey, argv[0]);
171 if (!RT_SUCCESS(rc))
172 VBoxControlError("Failed to convert the key name to Utf8, error %Rrc\n", rc);
173 if (RT_SUCCESS(rc) && (2 == argc))
174 {
175 rc = RTStrCurrentCPToUtf8(&pszValue, argv[1]);
176 if (!RT_SUCCESS(rc))
177 VBoxControlError("Failed to convert the key value to Utf8, error %Rrc\n", rc);
178 }
179 if (RT_SUCCESS(rc))
180 {
181 rc = VbglR3InfoSvcConnect(&u32ClientID);
182 if (!RT_SUCCESS(rc))
183 VBoxControlError("Failed to connect to the host/guest registry service, error %Rrc\n", rc);
184 }
185 if (RT_SUCCESS(rc))
186 {
187 rc = VbglR3InfoSvcWriteKey(u32ClientID, argv[0], pszValue);
188 if (!RT_SUCCESS(rc))
189 VBoxControlError("Failed to store the property value, error %Rrc\n", rc);
190 }
191 if (u32ClientID != 0)
192 VbglR3InfoSvcDisconnect(u32ClientID);
193 RTStrFree(pszKey);
194 RTStrFree(pszValue);
195 return RT_SUCCESS(rc) ? 0 : 1;
196}
197#endif
198
199/** command handler type */
200typedef DECLCALLBACK(int) FNHANDLER(int argc, char *argv[]);
201typedef FNHANDLER *PFNHANDLER;
202
203/** The table of all registered command handlers. */
204struct COMMANDHANDLER
205{
206 const char *command;
207 PFNHANDLER handler;
208} g_commandHandlers[] =
209{
210#ifdef VBOX_WITH_INFO_SVC
211 { "getguestproperty", getGuestProperty },
212 { "setguestproperty", setGuestProperty }
213#endif
214};
215
216/** Main function */
217int main(int argc, char **argv)
218{
219 /** The application's global return code */
220 int rc = 0;
221 /** An IPRT return code for local use */
222 int rrc = VINF_SUCCESS;
223 /** The index of the command line argument we are currently processing */
224 int iArg = 1;
225 /** Should we show the logo text? */
226 bool showlogo = true;
227 /** Should we print the usage after the logo? For the --help switch. */
228 bool dohelp = false;
229 /** Will we be executing a command or just printing information? */
230 bool onlyinfo = false;
231
232/*
233 * Start by handling command line switches
234 */
235
236 /** Are we finished with handling switches? */
237 bool done = false;
238 while (!done && (iArg < argc))
239 {
240 if ( (0 == strcmp(argv[iArg], "-v"))
241 || (0 == strcmp(argv[iArg], "--version"))
242 )
243 {
244 /* Print version number, and do nothing else. */
245 RTPrintf("%sr%d\n", VBOX_VERSION_STRING, VBoxSVNRev ());
246 onlyinfo = true;
247 showlogo = false;
248 done = true;
249 }
250 else if (0 == strcmp(argv[iArg], "--nologo"))
251 showlogo = false;
252 else if (0 == strcmp(argv[iArg], "--help"))
253 {
254 onlyinfo = true;
255 dohelp = true;
256 done = true;
257 }
258 else
259 /* We have found an argument which isn't a switch. Exit to the
260 * command processing bit. */
261 done = true;
262 if (!done)
263 ++iArg;
264 }
265
266/*
267 * Find the application name, show our logo if the user hasn't suppressed it,
268 * and show the usage if the user asked us to
269 */
270
271 g_pszProgName = RTPathFilename(argv[0]);
272 if (showlogo)
273 RTPrintf("VirtualBox Guest Additions Command Line Management Interface Version "
274 VBOX_VERSION_STRING "\n"
275 "(C) 2008 Sun Microsystems, Inc.\n"
276 "All rights reserved\n\n");
277 if (dohelp)
278 usage();
279
280/*
281 * Do global initialisation for the programme if we will be handling a command
282 */
283
284 if (!onlyinfo)
285 {
286 rrc = RTR3Init(false, 0);
287 if (!RT_SUCCESS(rrc))
288 {
289 VBoxControlError("Failed to initialise the VirtualBox runtime - error %Rrc\n", rrc);
290 rc = 1;
291 }
292 if (0 == rc)
293 {
294 if (!RT_SUCCESS(VbglR3Init()))
295 {
296 VBoxControlError("Could not contact the host system. Make sure that you are running this\n"
297 "application inside a VirtualBox guest system, and that you have sufficient\n"
298 "user permissions.\n");
299 rc = 1;
300 }
301 }
302 }
303
304/*
305 * Now look for an actual command in the argument list and handle it.
306 */
307
308 if (!onlyinfo && (0 == rc))
309 {
310 if (argc > iArg)
311 {
312 /** Is next parameter a known command? */
313 bool found = false;
314 /** And if so, what is its position in the table? */
315 unsigned index = 0;
316 while (index < RT_ELEMENTS(g_commandHandlers) && !found)
317 {
318 if (0 == strcmp(argv[iArg], g_commandHandlers[index].command))
319 found = true;
320 else
321 ++index;
322 }
323 if (found)
324 rc = g_commandHandlers[index].handler(argc - iArg - 1, argv + iArg + 1);
325 else
326 {
327 rc = 1;
328 usage();
329 }
330 }
331 else
332 {
333 /* The user didn't specify a command. */
334 rc = 1;
335 usage();
336 }
337 }
338
339/*
340 * And exit, returning the status
341 */
342
343 return rc;
344}
Note: See TracBrowser for help on using the repository browser.

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