#include "debug.h"
#include "strutil.h"
#include "str.h"
-#include "dictll.h"
#include "msg.h"
#include "file.h"
#include "posix.h"
# define GUESTAPP_TOOLS_INSTALL_PATH "/etc/vmware-tools"
#endif
-/*
- * An option name/value pair stored locally in the guest app.
- */
-typedef struct GuestApp_DictEntry {
- char *name;
- char *value;
- char *defaultVal;
- struct GuestApp_DictEntry *next;
-} GuestApp_DictEntry;
-
-/*
- * A name/value dictionary.
- */
-struct GuestApp_Dict {
- GuestApp_DictEntry head;
- int64 fileModTime;
- char *fileName;
-};
-
-
-/*
- *----------------------------------------------------------------------
- *
- * GuestAppNewDictEntry --
- *
- * Allocate & add a new entry to the dict list.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-void
-GuestAppNewDictEntry(GuestApp_DictEntry **pCur, // IN/OUT: add after this entry
- const char *name, // IN
- const char *value, // IN
- const char *defaultVal) // IN
-{
- GuestApp_DictEntry *p;
-
- ASSERT(pCur);
-
- /* Not found so allocate & init a new entry */
- p = (GuestApp_DictEntry *) malloc(sizeof(GuestApp_DictEntry));
- ASSERT_NOT_IMPLEMENTED(p);
-
- if (name) {
- p->name = strdup(name);
- } else {
- p->name = NULL;
- }
-
- if (value) {
- p->value = strdup(value);
- } else {
- p->value = NULL;
- }
-
- if (defaultVal) {
- p->defaultVal = strdup(defaultVal);
- } else {
- p->defaultVal = NULL;
- }
-
- p->next = *pCur;
- *pCur = p;
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * GuestApp_ConstructDict --
- *
- * Construct a new dict. A dict is used to store name/value pairs
- * within the guest app for later lookup.
- *
- * Results:
- * The new dict.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-GuestApp_Dict *
-GuestApp_ConstructDict(char *fileName) // IN: you give up your right to free this
-{
- GuestApp_Dict *dict;
-
- dict = (GuestApp_Dict *) malloc(sizeof(GuestApp_Dict));
- ASSERT_NOT_IMPLEMENTED(dict);
-
- dict->head.next = NULL;
-
- dict->fileName = fileName;
-
- return dict;
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * GuestApp_SetDictEntry --
- *
- * Set the value of a dict entry.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-void
-GuestApp_SetDictEntry(GuestApp_Dict *dict, // IN/OUT
- const char *name, // IN
- const char *value) // IN
-{
- GuestApp_DictEntry *p;
-
- ASSERT(dict);
- ASSERT(name);
- ASSERT(value);
-
- for (p = dict->head.next; p; p = p->next) {
- if (strcmp(p->name, name) == 0) {
- if (strcmp(p->value, value) != 0) {
- Debug("Changing dict entry: %s = %s -> %s\n", p->name, p->value, value);
-
- free(p->value);
- p->value = strdup(value);
- }
-
- return;
- }
- }
-
- Debug("Adding dict entry: %s = %s\n", name, value);
-
- /* Not found so create a new entry right after the dummy */
- GuestAppNewDictEntry(&dict->head.next, name, value, NULL);
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * GuestApp_SetDictEntryDefault --
- *
- * Set the default value of a dict entry.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-void
-GuestApp_SetDictEntryDefault(GuestApp_Dict *dict, // IN/OUT
- const char *name, // IN
- const char *defaultVal) // IN
-{
- GuestApp_DictEntry *p;
-
- ASSERT(dict);
- ASSERT(name);
- ASSERT(defaultVal);
-
- for (p = dict->head.next; p; p = p->next) {
- if (strcmp(p->name, name) == 0) {
- Debug("Changing dict entry default: %s = %s -> %s\n",
- p->name, p->defaultVal, defaultVal);
-
- free(p->defaultVal);
- p->defaultVal = strdup(defaultVal);
- free(p->value);
- p->value = strdup(defaultVal);
- return;
- }
- }
-
- Debug("Adding dict entry default: %s = %s\n", name, defaultVal);
-
- /* Not found so create a new entry right after the dummy */
- GuestAppNewDictEntry(&dict->head.next, name, defaultVal, defaultVal);
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * GuestApp_GetDictEntry --
- *
- * Get the value of a dict entry.
- *
- * Results:
- * The value or NULL if not found.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-const char *
-GuestApp_GetDictEntry(GuestApp_Dict *dict, // IN
- const char *name) // IN
-{
- GuestApp_DictEntry *p;
- const char *value = NULL;
-
- ASSERT(dict);
- ASSERT(name);
-
- for (p = dict->head.next; p; p = p->next) {
- //Debug("-Found dict entry %s = %s while looking for %s\n", p->name, p->value, name);
- if (strcmp(p->name, name) == 0) {
- value = p->value;
- break;
- }
- }
-
- return value;
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * GuestApp_GetDictEntryDefault --
- *
- * Get the default value of a dict entry.
- *
- * Results:
- * The value or NULL if not found.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-const char *
-GuestApp_GetDictEntryDefault(GuestApp_Dict *dict, // IN
- const char *name) // IN
-{
- GuestApp_DictEntry *p;
- const char *value = NULL;
-
- ASSERT(dict);
- ASSERT(name);
-
- for (p = dict->head.next; p; p = p->next) {
- //Debug("-Found dict entry default %s = %s while looking for %s\n", p->name, p->defaultVal, name);
- if (strcmp(p->name, name) == 0) {
- value = p->defaultVal;
- break;
- }
- }
-
- return value;
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * GuestApp_GetDictEntryInt --
- *
- * Get a dict entry's value & convert it to an int.
- *
- * Results:
- * TRUE on success
- * FALSE if:
- * -the value was NULL
- * -the value was not an int
- *
- * Side effects:
- * Warns if the value is NULL or not an int.
- *
- *----------------------------------------------------------------------
- */
-
-Bool
-GuestApp_GetDictEntryInt(GuestApp_Dict *dict, // IN
- const char *name, // IN
- int32 *out) // OUT
-{
- const char *value;
- int32 intVal;
-
- ASSERT(dict);
- ASSERT(name);
- ASSERT(out);
-
- value = GuestApp_GetDictEntry(dict, name);
- if (!value) {
- Warning("GuestApp: no value for option '%s'\n", name);
-
- return FALSE;
- }
-
- if (!StrUtil_StrToInt(&intVal, value)) {
- Warning("GuestApp: invalid int value for option '%s'; "
- "value='%s'\n", name, value);
-
- return FALSE;
- }
-
- *out = intVal;
- return TRUE;
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * GuestApp_GetDictEntryBool --
- *
- * Get a dict entry's value & convert it to an Bool.
- *
- * Results:
- * Returns TRUE is the dict entry is a case-insensitive match
- * to "TRUE", FALSE otherwise. If there is no entry, for
- * "name" or dict is NULL, return FALSE as well.
- *
- * Side effects:
- *
- *
- *----------------------------------------------------------------------
- */
-
-Bool
-GuestApp_GetDictEntryBool(GuestApp_Dict *dict, // IN
- const char *name) // IN
-{
- const char *value;
-
- ASSERT(dict);
-
- value = GuestApp_GetDictEntry(dict, name);
- if (!value) {
- return FALSE;
- }
-
-#if defined (_WIN32)
- return (stricmp(value, "TRUE") == 0);
-#else
- return (strcasecmp(value, "TRUE") == 0);
-#endif
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * GetApp_FreeDict --
- *
- * Free the dict.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-void
-GuestApp_FreeDict(GuestApp_Dict *dict) // IN/OUT
-{
- ASSERT(dict);
-
- while (dict->head.next) {
- GuestApp_DictEntry *p = dict->head.next;
-
- dict->head.next = p->next;
-
- free(p->name);
- free(p->value);
- free(p->defaultVal);
- free(p);
- }
-
- free(dict->fileName);
-
- free(dict);
-}
-
/*
*-----------------------------------------------------------------------------
}
-/*
- *-----------------------------------------------------------------------------
- *
- * GuestApp_OldSetOptions --
- *
- * Send the tools options to VMware using the old (deprecated) method.
- *
- * Return value:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-GuestApp_OldSetOptions(uint32 options) // IN
-{
- Backdoor_proto bp;
-
- Debug("Setting tools options (old)\n");
-
- bp.in.cx.halfs.low = BDOOR_CMD_SETGUIOPTIONS;
- bp.in.size = options;
- Backdoor(&bp);
-}
-
-
/*
*----------------------------------------------------------------------
*
}
-/*
- *----------------------------------------------------------------------
- *
- * GuestApp_LoadDict --
- *
- * Load the dict file into memory. Assumes the
- * given dict has been constructed.
- *
- * Results:
- * TRUE/FALSE: success/failure
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-Bool
-GuestApp_LoadDict(GuestApp_Dict *dict) // IN/OUT
-{
- FILE *stream;
- Bool retVal = TRUE;
-
- ASSERT(dict);
- ASSERT(dict->fileName);
-
- stream = Posix_Fopen(dict->fileName, "r");
- if (stream == NULL) {
- Debug("Unable to open \"%s\"\n", dict->fileName);
-
- return FALSE;
- }
-
- for (;;) {
- char *name;
- char *value;
- char *line;
- int status;
-
- status = DictLL_ReadLine(stream, &line, &name, &value);
- if (status == 0) {
- Warning("Unable to read a line from \"%s\": %s\n", dict->fileName,
- Msg_ErrString());
-
- retVal = FALSE;
- goto close;
- } else if (status == 1) {
- retVal = TRUE;
- goto close;
- } else if (status != 2) {
- NOT_IMPLEMENTED();
- }
-
- if (name) {
- ASSERT(value);
-
- /*
- * We've gotten a valid name/value pair so store it.
- */
- GuestApp_SetDictEntry(dict, name, value);
-
- free(name);
- free(value);
- free(line);
- }
- }
-
- close:
- if (fclose(stream)) {
- Warning("Unable to close \"%s\": %s\n", dict->fileName, Msg_ErrString());
-
- return FALSE;
- }
-
- if (retVal) {
- dict->fileModTime = File_GetModTime(dict->fileName);
- Debug("Loaded dict from '%s' with mod time=%"FMT64"d\n",
- dict->fileName, dict->fileModTime);
- }
-
- return retVal;
-}
-
-
/*
*-----------------------------------------------------------------------------
*
#include <glib/gstdio.h>
#include "vm_assert.h"
+#include "dictll.h"
#include "conf.h"
+#include "err.h"
#include "guestApp.h"
#include "str.h"
+#include "strutil.h"
#include "util.h"
/** Data types supported for translation. */
/**
* Loads the legacy configuration file in the VMware dictionary format.
*
- * @return A dictionary with the config data.
+ * @return A dictionary with the config data, NULL on error.
*/
-static GuestApp_Dict *
+static GHashTable *
VMToolsConfigLoadLegacy(void)
{
- GuestApp_Dict *confDict;
- char *path;
+ gchar *path;
+ gchar *localPath;
char *confPath = GuestApp_GetConfPath();
- char *installPath = GuestApp_GetInstallPath();
+ gboolean success = FALSE;
+ FILE *stream = NULL;
+ GHashTable *dict = NULL;
if (confPath == NULL) {
Panic("Could not get path to Tools configuration file.\n");
}
- path = Str_Asprintf(NULL, "%s%c%s", confPath, DIRSEPC, CONF_FILE);
- ASSERT_NOT_IMPLEMENTED(path);
- confDict = GuestApp_ConstructDict(path);
- /* don't free path; it's used by the dict */
-
- /* Set default conf values */
- if (installPath != NULL) {
- path = Str_Asprintf(NULL, "%s%c%s", installPath, DIRSEPC,
- CONFVAL_POWERONSCRIPT_DEFAULT);
- ASSERT_NOT_IMPLEMENTED(path);
- GuestApp_SetDictEntryDefault(confDict, CONFNAME_POWERONSCRIPT, path);
- free(path);
-
- path = Str_Asprintf(NULL, "%s%c%s", installPath, DIRSEPC,
- CONFVAL_POWEROFFSCRIPT_DEFAULT);
- ASSERT_NOT_IMPLEMENTED(path);
- GuestApp_SetDictEntryDefault(confDict, CONFNAME_POWEROFFSCRIPT, path);
- free(path);
-
- path = Str_Asprintf(NULL, "%s%c%s", installPath, DIRSEPC,
- CONFVAL_RESUMESCRIPT_DEFAULT);
- ASSERT_NOT_IMPLEMENTED(path);
- GuestApp_SetDictEntryDefault(confDict, CONFNAME_RESUMESCRIPT, path);
- free(path);
-
- path = Str_Asprintf(NULL, "%s%c%s", installPath, DIRSEPC,
- CONFVAL_SUSPENDSCRIPT_DEFAULT);
- ASSERT_NOT_IMPLEMENTED(path);
- GuestApp_SetDictEntryDefault(confDict, CONFNAME_SUSPENDSCRIPT, path);
- free(path);
-
- free(installPath);
- } else {
- Warning("Could not get path to Tools installation.\n");
+ /* Load the data from the old config file. */
+ path = g_strdup_printf("%s%c%s", confPath, DIRSEPC, CONF_FILE);
+ localPath = VMTOOLS_GET_FILENAME_LOCAL(path, NULL);
+ if (localPath == NULL) {
+ g_warning("Error converting path to local encoding.");
+ goto exit;
+ }
+
+ stream = g_fopen(localPath, "r");
+ if (stream == NULL) {
+ goto exit;
}
- /* Load the user-configured values from the conf file if it's there */
- GuestApp_LoadDict(confDict);
+ dict = g_hash_table_new_full(g_str_hash, g_str_equal, free, free);
+
+ for (;;) {
+ char *name;
+ char *value;
+ char *line;
+ int status;
+ status = DictLL_ReadLine(stream, &line, &name, &value);
+ if (status == 0) {
+ g_warning("Unable to read a line from \"%s\": %s\n", path,
+ Err_ErrString());
+ goto exit;
+ } else if (status == 1) {
+ break;
+ } else if (status != 2) {
+ NOT_IMPLEMENTED();
+ }
+
+ if (name && value) {
+ g_hash_table_insert(dict, name, value);
+ } else {
+ free(name);
+ free(value);
+ }
+
+ free(line);
+ }
+
+ success = TRUE;
+
+exit:
+ if (stream != NULL && fclose(stream)) {
+ g_warning("Unable to close \"%s\": %s\n", path, Err_ErrString());
+ success = FALSE;
+ }
+
+ VMTOOLS_RELEASE_FILENAME_LOCAL(localPath);
+ g_free(path);
free(confPath);
- return confDict;
+ if (!success) {
+ if (dict != NULL) {
+ g_hash_table_destroy(dict);
+ dict = NULL;
+ }
+ }
+
+ return dict;
}
*/
static void
-VMToolsConfigUpgrade(GuestApp_Dict *old,
+VMToolsConfigUpgrade(GHashTable *old,
GKeyFile *dst)
{
const ConfigEntry entries[] = {
const ConfigEntry *entry;
for (entry = entries; entry->key != NULL; entry++) {
- const char *value = GuestApp_GetDictEntry(old, entry->key);
- const char *dfltValue = GuestApp_GetDictEntryDefault(old, entry->key);
+ const char *value = g_hash_table_lookup(old, entry->key);
- if (value == NULL || (dfltValue != NULL && strcmp(value, dfltValue) == 0)) {
+ if (value == NULL) {
continue;
}
switch (entry->type) {
case CFG_BOOLEAN:
{
- gboolean val = GuestApp_GetDictEntryBool(old, entry->key);
+ gboolean val = Str_Strcasecmp(value, "TRUE") == 0;
g_key_file_set_boolean(dst, entry->destGroup, entry->destKey, val);
break;
}
case CFG_INTEGER:
{
gint val;
- if (GuestApp_GetDictEntryInt(old, entry->key, &val)) {
+ if (StrUtil_StrToInt(&val, value)) {
g_key_file_set_integer(dst, entry->destGroup, entry->destKey, val);
}
break;
gchar *defaultPath = NULL;
gchar *localPath = NULL;
struct stat confStat;
- GuestApp_Dict *old = NULL;
+ GHashTable *old = NULL;
GError *err = NULL;
GKeyFile *cfg = NULL;
exit:
g_clear_error(&err);
if (old != NULL) {
- GuestApp_FreeDict(old);
+ g_hash_table_destroy(old);
}
if (cfg != NULL) {
if (*config != NULL) {