From: Oliver Kurth Date: Fri, 15 Sep 2017 18:22:55 +0000 (-0700) Subject: add toolbox-cmd for tools.conf config entries X-Git-Tag: stable-10.2.0~619 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5d1554e30aaa31f18978eedcb06dda1c659c18af;p=thirdparty%2Fopen-vm-tools.git add toolbox-cmd for tools.conf config entries Add a generic tools.conf set/get mechanism that can be used for any config entry. The first specific use case is to enable/disable the allowLocalSystem pref for SRM. --- diff --git a/open-vm-tools/toolbox/Makefile.am b/open-vm-tools/toolbox/Makefile.am index 856e202bf..66d36ac69 100644 --- a/open-vm-tools/toolbox/Makefile.am +++ b/open-vm-tools/toolbox/Makefile.am @@ -26,6 +26,7 @@ vmware_toolbox_cmd_CPPFLAGS += @VMTOOLS_CPPFLAGS@ vmware_toolbox_cmd_SOURCES = vmware_toolbox_cmd_SOURCES += toolbox-cmd.c +vmware_toolbox_cmd_SOURCES += toolboxcmd-config.c vmware_toolbox_cmd_SOURCES += toolboxcmd-devices.c vmware_toolbox_cmd_SOURCES += toolboxcmd-info.c vmware_toolbox_cmd_SOURCES += toolboxcmd-logging.c diff --git a/open-vm-tools/toolbox/toolbox-cmd.c b/open-vm-tools/toolbox/toolbox-cmd.c index 6eb768a8a..1fd91e8dc 100644 --- a/open-vm-tools/toolbox/toolbox-cmd.c +++ b/open-vm-tools/toolbox/toolbox-cmd.c @@ -111,6 +111,7 @@ static CmdTable commands[] = { #endif { "logging", Logging_Command, TRUE, TRUE, Logging_Help}, { "info", Info_Command, TRUE, TRUE, Info_Help}, + { "config", Config_Command, TRUE, TRUE, Config_Help}, { "help", HelpCommand, FALSE, FALSE, ToolboxCmdHelp}, }; @@ -297,6 +298,7 @@ ToolboxCmdHelp(const char *progName, // IN "Use '-q' option to suppress stdout output.\n" "Most commands take a subcommand.\n\n" "Available commands:\n" + " config\n" " device\n" " disk (not available on all operating systems)\n" " info\n" diff --git a/open-vm-tools/toolbox/toolboxCmdInt.h b/open-vm-tools/toolbox/toolboxCmdInt.h index 94acbd5c2..7d5341f08 100644 --- a/open-vm-tools/toolbox/toolboxCmdInt.h +++ b/open-vm-tools/toolbox/toolboxCmdInt.h @@ -129,6 +129,7 @@ DECLARE_COMMAND(Stat); DECLARE_COMMAND(TimeSync); DECLARE_COMMAND(Logging); DECLARE_COMMAND(Info); +DECLARE_COMMAND(Config); #if defined(_WIN32) || \ (defined(linux) && !defined(OPEN_VM_TOOLS) && !defined(USERWORLD)) diff --git a/open-vm-tools/toolbox/toolboxcmd-config.c b/open-vm-tools/toolbox/toolboxcmd-config.c new file mode 100644 index 000000000..bb656ea43 --- /dev/null +++ b/open-vm-tools/toolbox/toolboxcmd-config.c @@ -0,0 +1,298 @@ +/********************************************************* + * Copyright (C) 2016 VMware, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation version 2.1 and no later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + *********************************************************/ + +/* + * toolboxcmd-config.c -- + * + * VMTools config operations. + * + * Supports a basic set/get of individual tools.conf key-value pairs. + * + */ + +#include + +#include "conf.h" +#include "toolboxCmdInt.h" +#include "vmware/tools/i18n.h" +#include "vmware/tools/utils.h" +#include "vmware/tools/log.h" + + +/* + *----------------------------------------------------------------------------- + * + * ConfigSet -- + * + * Set a config entry. + * + * Results: + * Returns EXIT_SUCCESS on success. + * Returns the appropriate exit codes on errors. + * + * Side effects: + * None. + * + *----------------------------------------------------------------------------- + */ + +static int +ConfigSet(const char *section, // config section + const char *key, // key + const char *value) // value +{ + GKeyFile *confDict = NULL; + GError *err = NULL; + int ret = EXIT_SUCCESS; + + VMTools_LoadConfig(NULL, + G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, + &confDict, + NULL); + + if (confDict == NULL) { + confDict = g_key_file_new(); + } + + g_key_file_set_string(confDict, section, + key, value); + + if (!VMTools_WriteConfig(NULL, confDict, &err)) { + ToolsCmd_PrintErr(SU_(script.write.error, "Error writing config: %s\n"), + err ? err->message : ""); + g_clear_error(&err); + ret = EX_TEMPFAIL; + } + + g_key_file_free(confDict); + + return ret; +} + + +/* + *----------------------------------------------------------------------------- + * + * ConfigGet -- + * + * Get config value. + * + * Results: + * Returns EXIT_SUCCESS on success. + * Returns the appropriate exit codes on errors. + * + * Side effects: + * None. + * + *----------------------------------------------------------------------------- + */ + +static int +ConfigGet(const char *section, // section + const char *key) // key +{ + GKeyFile *confDict = NULL; + int ret = EXIT_SUCCESS; + gchar *value = NULL; + + VMTools_LoadConfig(NULL, + G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, + &confDict, + NULL); + + if (confDict) { + value = g_key_file_get_string(confDict, section, + key, NULL); + } else { + ret = EX_UNAVAILABLE; + } + + if (value) { + g_print("[%s] %s = %s\n", section, key, value); + } else { + g_print("[%s] %s UNSET\n", section, key); + } + + g_key_file_free(confDict); + g_free(value); + + return ret; +} + + +/* + *----------------------------------------------------------------------------- + * + * ConfigRemove -- + * + * Remove config key. + * + * Results: + * Returns EXIT_SUCCESS on success. + * Returns the appropriate exit codes on errors. + * + * Side effects: + * None. + * + *----------------------------------------------------------------------------- + */ + +static int +ConfigRemove(const char *section, // section + const char *key) // key +{ + GKeyFile *confDict = NULL; + int ret = EXIT_SUCCESS; + GError *err = NULL; + + VMTools_LoadConfig(NULL, + G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, + &confDict, + NULL); + + // be idempotent -- ignore any error about non-existant config or key + if (confDict) { + /* + * our ancient FreeBSD glib expects g_key_file_remove_key() + * to return void, and since we don't care anyways, ignore the + * return so it builds everywhere. + */ + (void) g_key_file_remove_key(confDict, section, + key, NULL); + } else { + return EX_UNAVAILABLE; + } + + if (!VMTools_WriteConfig(NULL, confDict, &err)) { + ToolsCmd_PrintErr(SU_(script.write.error, "Error writing config: %s\n"), + err ? err->message : ""); + g_clear_error(&err); + ret = EX_TEMPFAIL; + } + + g_key_file_free(confDict); + + return ret; +} + + +/* + *----------------------------------------------------------------------------- + * + * Config_Command -- + * + * Handle and parse config commands. + * + * Results: + * Returns EXIT_SUCCESS on success. + * Returns the appropriate exit codes on errors. + * + * Side effects: + * None. + * + *----------------------------------------------------------------------------- + */ + +int +Config_Command(char **argv, // IN: Command line arguments + int argc, // IN: Length of command line arguments + gboolean quiet) // IN +{ + const char *op; + const char *section; + const char *key; + + if (optind >= argc) { + ToolsCmd_MissingEntityError(argv[0], + SU_(arg.config.operation, "config operation")); + return EX_USAGE; + } + + if ((optind + 1) >= argc) { + ToolsCmd_MissingEntityError(argv[0], + SU_(arg.config.section, "config section")); + return EX_USAGE; + } + + if ((optind + 2) >= argc) { + ToolsCmd_MissingEntityError(argv[0], + SU_(arg.config.key, "config key")); + return EX_USAGE; + } + + op = argv[optind]; + section = argv[optind + 1]; + key = argv[optind + 2]; + + if (toolbox_strcmp(op, "set") == 0) { + const char *value; + + if ((optind + 3) >= argc) { + ToolsCmd_MissingEntityError(argv[0], + SU_(arg.config.value, "config value")); + return EX_USAGE; + } + value = argv[optind + 3]; + + return ConfigSet(section, key, value); + } else if (toolbox_strcmp(op, "get") == 0) { + return ConfigGet(section, key); + } else if (toolbox_strcmp(op, "remove") == 0) { + return ConfigRemove(section, key); + } else { + ToolsCmd_UnknownEntityError(argv[0], + SU_(arg.subcommand, "subcommand"), + argv[optind]); + return EX_USAGE; + } +} + + +/* + *----------------------------------------------------------------------------- + * + * Config_Help -- + * + * Prints the help for the config command. + * + * Results: + * None. + * + * Side effects: + * None. + * + *----------------------------------------------------------------------------- + */ + +void +Config_Help(const char *progName, // IN: The name of the program obtained from argv[0] + const char *cmd) // IN +{ + g_print(SU_(help.config, + "%s: modify Tools configuration\n" + "Usage: %s %s \n\n" + "Subcommands:\n" + " get
: display current value for \n" + " set
: set to \n\n" + " remove
: remove \n\n" + "
can be any supported section, such as logging, guestoperations or guestinfo.\n" + " can be any configuration key.\n" + " can be any value.\n"), + cmd, progName, cmd); +} +