HgfsClient_Init(void)
{
Bool success = FALSE;
- gchar *confFile;
- GKeyFile *conf;
-
- confFile = VMTools_GetToolsConfFile();
- conf = VMTools_LoadConfig(confFile, G_KEY_FILE_NONE, FALSE);
+ GKeyFile *conf = NULL;
+ VMTools_LoadConfig(NULL, G_KEY_FILE_NONE, &conf, NULL);
+ VMTools_ConfigLogging("hgfsclient", conf, FALSE, FALSE);
if (conf != NULL) {
- VMTools_ConfigLogging(conf);
g_key_file_free(conf);
conf = NULL;
}
- g_free(confFile);
- confFile = NULL;
-
if (!VmCheck_IsVirtualWorld()) {
Warning("This application must be run in a Virtual Machine.\n");
goto out;
/**
* @file utils.h
*
- * Public functions from the VMTools shared library.
+ * Public functions from the VMTools shared library, and other definitions.
*
* @addtogroup vmtools_utils
* @{
*/
-#if !defined(G_LOG_DOMAIN)
-# define G_LOG_DOMAIN VMTools_GetDefaultLogDomain()
-#endif
-
#define VMTOOLS_GUEST_SERVICE "vmsvc"
#define VMTOOLS_USER_SERVICE "vmusr"
# define VMTOOLS_EXTERN_C
#endif
-/* Needs to come before glib.h. */
-VMTOOLS_EXTERN_C const char *
-VMTools_GetDefaultLogDomain(void);
-
#include <glib.h>
#if defined(G_PLATFORM_WIN32)
# include <windows.h>
* Converts an UTF-8 path to the local (i.e., glib) file name encoding.
* This is a no-op on Windows, since the local encoding is always UTF-8
* in glib. The returned value should not be freed directly; instead,
- * use VMTOOLS_FREE_FILENAME.
+ * use VMTOOLS_RELEASE_FILENAME_LOCAL.
*
* @param[in] path Path in UTF-8 (should not be NULL).
* @param[out] err Where to store errors (type: GError **; may be NULL).
vm_free(void *ptr);
void
-VMTools_SetDefaultLogDomain(const gchar *domain);
-
-void
-VMTools_ConfigLogging(GKeyFile *cfg);
-
-void
-VMTools_EnableLogging(gboolean enable);
+VMTools_ConfigLogging(const gchar *defaultDomain,
+ GKeyFile *cfg,
+ gboolean force,
+ gboolean reset);
-gchar *
-VMTools_GetToolsConfFile(void);
-
-GKeyFile *
+gboolean
VMTools_LoadConfig(const gchar *path,
GKeyFileFlags flags,
- gboolean autoUpgrade);
-
-
-gboolean
-VMTools_ReloadConfig(const gchar *path,
- GKeyFileFlags flags,
- GKeyFile **config,
- time_t *mtime);
-
-void
-VMTools_ResetLogging(gboolean cleanDefault);
+ GKeyFile **config,
+ time_t *mtime);
gboolean
VMTools_WriteConfig(const gchar *path,
#if defined(_WIN32)
WiperInitData wiperData;
CoreDump_SetUnhandledExceptionFilter();
- VMTools_ResetLogging(FALSE);
wiperData.resourceModule = lib;
success = (NetUtil_LoadIpHlpApiDll() == ERROR_SUCCESS);
ASSERT(success);
success = Wiper_Init(&wiperData);
ASSERT(success);
#else
- VMTools_ResetLogging(FALSE);
success = Wiper_Init(NULL);
ASSERT(success);
#endif
#if defined(_WIN32)
NetUtil_FreeIpHlpApiDll();
#endif
- VMTools_ResetLogging(TRUE);
}
#include <stdlib.h>
#include <string.h>
#include <glib/gstdio.h>
+
+#include "vm_assert.h"
#include "conf.h"
-#include "file.h"
#include "guestApp.h"
-#include "str.h"
-#include "util.h"
/** Data types supported for translation. */
typedef enum {
* @return String with the default config path (should be freed by caller).
*/
-gchar *
-VMTools_GetToolsConfFile(void)
+static gchar *
+VMToolsGetToolsConfFile(void)
{
char *confPath = GuestApp_GetConfPath();
gchar *confFilePath;
confPath = GuestApp_GetConfPath();
ASSERT(confPath != NULL);
}
- confFilePath = g_strdup_printf("%s%c%s", confPath, DIRSEPC, CONF_FILE);
+ confFilePath = g_build_filename(confPath, CONF_FILE, NULL);
free(confPath);
return confFilePath;
/**
- * Loads the configuration file at the given path. If an old configuration
- * file is detected, the caller can request for it to be automatically upgraded
- * to the new configuration format (the old configuration file is saved with a
+ * Loads the configuration file at the given path.
+ *
+ * If an old configuration file is detected and the current process has write
+ * permission to the file, the configuration data will automatically upgraded to
+ * the new configuration format (the old configuration file is saved with a
* ".old" extension).
*
- * @param[in] path Path to the configuration file.
- * @param[in] flags Flags for opening the file.
- * @param[in] autoUpgrade Whether to try to upgrade old tools configuration.
+ * @param[in] path Path to the configuration file, or NULL for default
+ * Tools config file.
+ * @param[in] flags Flags for opening the file.
+ * @param[in,out] config Where to store the config dictionary; when reloading
+ * the file, the old config object will be destroyed.
+ * @param[in,out] mtime Last known modification time of the config file.
+ * When the function succeeds, will contain the new
+ * modification time read from the file. If NULL (or 0),
+ * the config dictionary is always loaded.
*
- * @return A configuration dictionary, or NULL on error.
+ * @return Whether a new config dictionary was loaded.
*/
-GKeyFile *
+gboolean
VMTools_LoadConfig(const gchar *path,
GKeyFileFlags flags,
- gboolean autoUpgrade)
+ GKeyFile **config,
+ time_t *mtime)
{
gchar *backup = NULL;
- gchar *localPath;
+ gchar *defaultPath = NULL;
+ gchar *localPath = NULL;
+ struct stat confStat;
GuestApp_Dict *old = NULL;
GError *err = NULL;
- GKeyFile *cfg;
+ GKeyFile *cfg = NULL;
- cfg = g_key_file_new();
+ g_return_val_if_fail(config != NULL, FALSE);
+
+ if (path == NULL) {
+ defaultPath = VMToolsGetToolsConfFile();
+ }
- localPath = VMTOOLS_GET_FILENAME_LOCAL(path, &err);
+ localPath = VMTOOLS_GET_FILENAME_LOCAL((path != NULL) ? path : defaultPath, &err);
if (err != NULL) {
g_warning("Error converting to local encoding: %s\n", err->message);
goto exit;
}
- if (!File_IsFile(path) || File_GetSizeByPath(path) == 0) {
+ if (g_stat(localPath, &confStat) == -1) {
+ /*
+ * If the file doesn't exist, it's not an error. Just return an
+ * empty dictionary in that case. The mtime will be set to 0 if
+ * the caller requested it.
+ */
+ memset(&confStat, 0, sizeof confStat);
+ if (errno != ENOENT) {
+ g_warning("Failed to stat conf file: %s\n", strerror(errno));
+ goto exit;
+ } else {
+ cfg = g_key_file_new();
+ goto exit;
+ }
+ }
+
+ /* Check if we really need to load the data. */
+ if (mtime != NULL && confStat.st_mtime <= *mtime) {
+ goto exit;
+ }
+
+ /* Need to load the configuration data. */
+
+ cfg = g_key_file_new();
+
+ /* Empty file: just return an empty dictionary. */
+ if (confStat.st_size == 0) {
goto exit;
}
goto error;
}
- /* Failed to load the config file; try to upgrade if requested. */
- if (!autoUpgrade) {
- goto error;
- }
-
- old = Conf_Load();
- if (old == NULL) {
- g_warning("Error loading old tools config data, bailing out.\n");
- goto error;
- }
+ /*
+ * Failed to load the config file; try to upgrade if requested. But only do
+ * it if the user is using the default conf file path; the old "Conf_Load()"
+ * API doesn't allow us to provide a custom config file path.
+ */
+ if (path == NULL) {
+ old = Conf_Load();
+ if (old == NULL) {
+ g_warning("Error loading old tools config data, bailing out.\n");
+ goto error;
+ }
- VMToolsConfigUpgrade(old, cfg);
- backup = g_strdup_printf("%s.old", path);
+ VMToolsConfigUpgrade(old, cfg);
+ backup = g_strdup_printf("%s.old", localPath);
- if (!File_IsFile(backup)) {
- if (!File_Rename(path, backup)) {
- g_warning("Error creating backup of old config file.\n");
- goto error;
+ if (!g_file_test(backup, G_FILE_TEST_IS_REGULAR)) {
+ if (g_rename(localPath, backup) == -1) {
+ g_warning("Error creating backup of old config file.\n");
+ goto error;
+ }
+ } else {
+ g_warning("Backup config exists, skipping backup.\n");
}
- } else {
- g_warning("Backup config exists, skipping backup.\n");
- }
- g_clear_error(&err);
+ g_clear_error(&err);
- if (!VMTools_WriteConfig(path, cfg, NULL)) {
- goto error;
+ if (!VMTools_WriteConfig((path != NULL) ? path : defaultPath, cfg, NULL)) {
+ goto error;
+ }
}
goto exit;
if (old != NULL) {
GuestApp_FreeDict(old);
}
- g_free(backup);
- VMTOOLS_RELEASE_FILENAME_LOCAL(localPath);
- return cfg;
-}
-
-
-/**
- * Reloads the configuration file at the given path if it has changed since the
- * given timestamp. No translation (such as in VMTools_LoadConfig()) will be
- * performed.
- *
- * @param[in] path Path to the config file.
- * @param[in] flags Flags to use when opening the file.
- * @param[in,out] config GKeyFile object; when reloading the file, the old
- * config object will be destroyed.
- * @param[in,out] mtime Last known modification time of the config file.
- * When the function succeeds, will contain the new
- * modification time read from the file.
- *
- * @return Whether the file was reloaded.
- */
-
-gboolean
-VMTools_ReloadConfig(const gchar *path,
- GKeyFileFlags flags,
- GKeyFile **config,
- time_t *mtime)
-{
- struct stat confStat;
- gboolean ret = FALSE;
- GKeyFile *newConfig = NULL;
-
- ASSERT(config != NULL);
- ASSERT(mtime != NULL);
-
- if (g_stat(path, &confStat) == -1) {
- g_debug("Failed to stat conf file: %s\n", strerror(errno));
- goto exit;
- }
-
- if (*mtime == 0 || confStat.st_mtime > *mtime) {
- GError *err = NULL;
- gchar *localPath;
-
- localPath = VMTOOLS_GET_FILENAME_LOCAL(path, &err);
- if (err != NULL) {
- g_warning("Error converting to local encoding: %s\n", err->message);
- goto exit;
- }
-
- newConfig = g_key_file_new();
- g_key_file_load_from_file(newConfig, localPath, flags, &err);
-
- if (err != NULL) {
- g_warning("Error loading conf file: %s\n", err->message);
- g_clear_error(&err);
- g_key_file_free(newConfig);
- newConfig = NULL;
- } else {
- ret = TRUE;
- }
-
- VMTOOLS_RELEASE_FILENAME_LOCAL(localPath);
- }
-
- if (newConfig != NULL) {
+ if (cfg != NULL) {
if (*config != NULL) {
g_key_file_free(*config);
}
- *config = newConfig;
- *mtime = confStat.st_mtime;
+ *config = cfg;
+ if (mtime != NULL) {
+ *mtime = confStat.st_mtime;
+ }
}
-
-exit:
- return ret;
+ g_free(backup);
+ g_free(defaultPath);
+ VMTOOLS_RELEASE_FILENAME_LOCAL(localPath);
+ return (cfg != NULL);
}
{
gboolean ret = FALSE;
gchar *data = NULL;
+ gchar *defaultPath = NULL;
gchar *localPath = NULL;
FILE *out = NULL;
GError *lerr = NULL;
- ASSERT(path != NULL);
ASSERT(config != NULL);
- localPath = VMTOOLS_GET_FILENAME_LOCAL(path, &lerr);
+ if (path == NULL) {
+ defaultPath = VMToolsGetToolsConfFile();
+ }
+
+ localPath = VMTOOLS_GET_FILENAME_LOCAL((path != NULL) ? path : defaultPath, &lerr);
if (lerr != NULL) {
g_warning("Error converting to local encoding: %s\n", lerr->message);
goto exit;
g_clear_error(&lerr);
}
g_free(data);
+ g_free(defaultPath);
VMTOOLS_RELEASE_FILENAME_LOCAL(localPath);
return ret;
}
#define SHOULD_LOG(level, data) (IS_FATAL(level) || \
(gLogEnabled && ((data)->mask & (level))))
+/** Clean up the contents of a log handler. */
+#define CLEAR_LOG_HANDLER(handler) do { \
+ if ((handler)->file != NULL) { \
+ fclose((handler)->file); \
+ } \
+ g_free((handler)->path); \
+ g_free((handler)->domain); \
+} while (0)
+
static void
VMToolsLogFile(const gchar *domain,
ASSERT(path != NULL);
pathLocal = VMTOOLS_GET_FILENAME_LOCAL(path, NULL);
- if (!append && g_file_test(path, G_FILE_TEST_EXISTS)) {
+ if (!append && g_file_test(pathLocal, G_FILE_TEST_EXISTS)) {
/* Back up existing log file. */
gchar *bakFile = g_strdup_printf("%s.old", pathLocal);
if (!g_file_test(bakFile, G_FILE_TEST_IS_DIR) &&
(!g_file_test(bakFile, G_FILE_TEST_EXISTS) ||
g_unlink(bakFile) == 0)) {
g_rename(pathLocal, bakFile);
+ } else {
+ g_unlink(pathLocal);
}
g_free(bakFile);
}
/**
* Configures the given log domain based on the data provided in the given
- * dictionary. If the log domain being configured doesn't match the default
- * (@see VMTools_GetDefaultLogDomain()), and no specific handler is defined
- * for the domain, the handler is inherited from the default domain, instead
- * of using the default handler. This allows reusing the same log file, for
- * example, while maintaining the ability to enable different log levels
- * for different domains.
+ * dictionary. If the log domain being configured doesn't match the default, and
+ * no specific handler is defined for the domain, the handler is inherited from
+ * the default domain, instead of using the default handler. This allows reusing
+ * the same log file, for example, while maintaining the ability to enable
+ * different log levels for different domains.
*
* For the above to properly work, the default log domain has to be configured
* before any other domains.
handler = g_key_file_get_string(cfg, LOGGING_GROUP, key, NULL);
if (handler == NULL) {
- if (strcmp(domain, VMTools_GetDefaultLogDomain()) == 0) {
+ if (strcmp(domain, gLogDomain) == 0) {
handlerFn = DEFAULT_HANDLER;
} else {
handlerFn = gDefaultLogFunc;
data->append = (handler != NULL && strcmp(handler, "file+") == 0);
logpath = NULL;
- if (strcmp(domain, VMTools_GetDefaultLogDomain()) == 0) {
+ if (strcmp(domain, gLogDomain) == 0) {
/*
* Replace the global log configuration. If the default log domain was
* logging to a file and the file path hasn't changed, then keep the old
*/
LogHandlerData *old = gDefaultData;
- if (old->file != NULL) {
+ if (old != NULL && old->file != NULL) {
ASSERT(old->path);
if (data->path != NULL && strcmp(data->path, old->path) == 0) {
g_free(data->path);
gDomains = g_ptr_array_new();
}
g_ptr_array_add(gDomains, data);
- data->handlerId = g_log_set_handler(domain,
+ data->handlerId = g_log_set_handler(domain,
G_LOG_LEVEL_MASK |
G_LOG_FLAG_FATAL |
G_LOG_FLAG_RECURSION,
}
-/* Public API. */
-
/**
- * Returns the default log domain for the application.
+ * Resets the vmtools logging subsystem, freeing up data and restoring the
+ * original glib configuration.
*
- * @return A string with the name of the log domain.
+ * @param[in] hard Whether to do a "hard" reset of the logging system
+ * (cleaning up any log domain existing state and freeing
+ * associated memory).
*/
-const char *
-VMTools_GetDefaultLogDomain(void)
+static void
+VMToolsResetLogging(gboolean hard)
{
- return gLogDomain;
+ gLogEnabled = FALSE;
+ g_log_set_default_handler(g_log_default_handler, NULL);
+
+ if (gDomains != NULL) {
+ guint i;
+ for (i = 0; i < gDomains->len; i++) {
+ LogHandlerData *data = g_ptr_array_index(gDomains, i);
+ g_log_remove_handler(data->domain, data->handlerId);
+ if (hard) {
+ CLEAR_LOG_HANDLER(data);
+ g_free(data);
+ }
+ }
+ if (hard) {
+ g_ptr_array_free(gDomains, TRUE);
+ gDomains = NULL;
+ }
+ }
+
+ if (hard && gDefaultData != NULL) {
+ CLEAR_LOG_HANDLER(gDefaultData);
+ g_free(gDefaultData);
+ gDefaultData = NULL;
+ }
+
+ if (gLogDomain != NULL) {
+ g_free(gLogDomain);
+ gLogDomain = NULL;
+ }
+
+ gDefaultLogFunc = DEFAULT_HANDLER;
}
/**
- * Sets the default log domain. This only changes the output of the default
- * log handler.
+ * Restores the logging configuration in the given config data. This means doing
+ * the following:
+ *
+ * . if the old log domain exists in the current configuration, and in case both
+ * the old and new configuration used log files, then re-use the file that was
+ * already opened.
+ * . if they don't use the same configuration, close the log file for the old
+ * configuration.
+ * . if an old log domain doesn't exist in the new configuration, then
+ * release any resources the old configuration was using for that domain.
*
- * @param[in] domain The log domain.
+ * @param[in] oldDefault Data for the old default domain.
+ * @param[in] oldDomains List of old log domains.
*/
-void
-VMTools_SetDefaultLogDomain(const gchar *domain)
+static void
+VMToolsRestoreLogging(LogHandlerData *oldDefault,
+ GPtrArray *oldDomains)
{
- ASSERT(domain != NULL);
- if (gLogDomain != NULL) {
- g_free(gLogDomain);
+ /* First, restore what needs to be restored. */
+ if (gDomains != NULL && oldDomains != NULL) {
+ guint i;
+ for (i = 0; i < gDomains->len; i++) {
+ guint j;
+ LogHandlerData *data = g_ptr_array_index(gDomains, i);
+
+ /* Try to find the matching old config. */
+ for (j = 0; j < oldDomains->len; j++) {
+ LogHandlerData *olddata = g_ptr_array_index(oldDomains, j);
+ if (strcmp(data->domain, olddata->domain) == 0) {
+ if (data->path != NULL && olddata->file != NULL) {
+ ASSERT(data->file == NULL);
+ data->file = olddata->file;
+ olddata->file = NULL;
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ if (gDefaultData != NULL && oldDefault != NULL) {
+ if (gDefaultData->path != NULL && oldDefault->file != NULL) {
+ ASSERT(gDefaultData->file == NULL);
+ gDefaultData->file = oldDefault->file;
+ oldDefault->file = NULL;
+ }
+ }
+
+ /* Second, clean up the old configuration data. */
+ if (oldDomains != NULL) {
+ while (oldDomains->len > 0) {
+ LogHandlerData *data = g_ptr_array_remove_index_fast(oldDomains,
+ oldDomains->len - 1);
+ CLEAR_LOG_HANDLER(data);
+ g_free(data);
+ }
+ }
+
+ if (oldDefault != NULL) {
+ CLEAR_LOG_HANDLER(oldDefault);
}
- gLogDomain = g_strdup(domain);
}
+/* Public API. */
+
/**
- * Configures the logging system according to the configuration provided from
- * the given dictionary.
+ * Configures the logging system according to the configuration in the given
+ * dictionary.
*
- * @param[in] cfg The configuration data.
+ * Optionally, it's possible to reset the logging subsystem; this will shut
+ * down all log handlers managed by the vmtools library before configuring
+ * the log system, which means that logging will behave as if the application
+ * was just started. A visible side-effect of this is that log files may be
+ * rotated (if they're not configure for appending).
+ *
+ * @param[in] defaultDomain Name of the default log domain.
+ * @param[in] cfg The configuration data. May be NULL.
+ * @param[in] force Whether to force logging to be enabled.
+ * @param[in] reset Whether to reset the logging subsystem first.
*/
void
-VMTools_ConfigLogging(GKeyFile *cfg)
+VMTools_ConfigLogging(const gchar *defaultDomain,
+ GKeyFile *cfg,
+ gboolean force,
+ gboolean reset)
{
gchar **list;
gchar **curr;
+ GPtrArray *oldDomains = NULL;
+ LogHandlerData *oldDefault = NULL;
- VMTools_ResetLogging(FALSE);
+ g_return_if_fail(defaultDomain != NULL);
- if (!g_key_file_has_group(cfg, LOGGING_GROUP)) {
- return;
+ /*
+ * If not resetting the logging system, keep the old domains around. After
+ * we're done loading the new configuration, we'll go through the old domains
+ * and restore any data that needs restoring, and clean up anything else.
+ */
+ VMToolsResetLogging(reset);
+ if (!reset) {
+ oldDefault = gDefaultData;
+ oldDomains = gDomains;
+ gDomains = NULL;
+ gDefaultData = NULL;
+ }
+
+ gLogDomain = g_strdup(defaultDomain);
+
+ /*
+ * If no logging config data exists, then we install a default log handler,
+ * just so we override the default glib one, since the caller has asked us to
+ * enable our logging system.
+ */
+ if (cfg == NULL || !g_key_file_has_group(cfg, LOGGING_GROUP)) {
+ gDefaultData = g_malloc0(sizeof *gDefaultData);
+ gDefaultData->domain = g_strdup(defaultDomain);
+ gDefaultData->mask = G_LOG_LEVEL_ERROR |
+ G_LOG_LEVEL_CRITICAL |
+ G_LOG_LEVEL_WARNING;
+#if defined(VMX86_DEBUG)
+ gDefaultData->mask |= G_LOG_LEVEL_MESSAGE;
+#endif
+ g_log_set_default_handler(gDefaultLogFunc, gDefaultData);
+ goto exit;
}
/*
* Configure the default domain first. See function documentation for
* VMToolsConfigLogDomain() for the reason.
*/
- VMToolsConfigLogDomain(VMTools_GetDefaultLogDomain(), cfg);
+ VMToolsConfigLogDomain(gLogDomain, cfg);
list = g_key_file_get_keys(cfg, LOGGING_GROUP, NULL, NULL);
domain[strlen(domain) - 6] = '\0';
/* Skip the default domain. */
- if (strcmp(domain, VMTools_GetDefaultLogDomain()) == 0) {
+ if (strcmp(domain, gLogDomain) == 0) {
continue;
}
gEnableCoreDump = g_key_file_get_boolean(cfg, LOGGING_GROUP,
"enableCoreDump", NULL);
}
-}
-
-
-/**
- * Enables of disables all the log domains configured by the vmtools library.
- * This doesn't affect other log domains that may have configured by other
- * code.
- *
- * @param[in] enable Whether logging should be enabled.
- */
-void
-VMTools_EnableLogging(gboolean enable)
-{
- gLogEnabled = enable;
-}
-
-
-/**
- * Resets the vmtools logging subsystem, freeing up data and optionally
- * restoring the original glib configuration.
- *
- * @param[in] cleanDefault Whether to clean up the default handler and
- * restore the original glib handler.
- */
-
-void
-VMTools_ResetLogging(gboolean cleanDefault)
-{
- gboolean oldLogEnabled = gLogEnabled;
- gchar *currentPath = NULL;
- FILE *currentFile = NULL;
-
- /* Disable logging while we're playing with the configuration. */
- gLogEnabled = FALSE;
-
- if (cleanDefault) {
- g_log_set_default_handler(g_log_default_handler, NULL);
- }
-
- if (gDomains != NULL) {
- guint i;
- for (i = 0; i < gDomains->len; i++) {
- LogHandlerData *data = g_ptr_array_index(gDomains, i);
- g_log_remove_handler(data->domain, data->handlerId);
- if (data->file != NULL) {
- fclose(data->file);
- }
- g_free(data->path);
- g_free(data->domain);
- g_free(data);
+exit:
+ /* If needed, restore the old configuration. */
+ if (!reset) {
+ VMToolsRestoreLogging(oldDefault, oldDomains);
+ g_free(oldDefault);
+ if (oldDomains != NULL) {
+ g_ptr_array_free(oldDomains, TRUE);
}
- g_ptr_array_free(gDomains, TRUE);
- gDomains = NULL;
- }
-
- if (gDefaultData != NULL) {
- currentFile = gDefaultData->file;
- currentPath = gDefaultData->path;
- g_free(gDefaultData);
- gDefaultData = NULL;
- }
-
- if (cleanDefault && gLogDomain != NULL) {
- g_free(gLogDomain);
- gLogDomain = NULL;
}
- gDefaultLogFunc = DEFAULT_HANDLER;
-
- if (!cleanDefault) {
- if (gLogDomain == NULL) {
- gLogDomain = g_strdup("vmtools");
- }
- gDefaultData = g_malloc0(sizeof *gDefaultData);
- gDefaultData->mask = G_LOG_LEVEL_ERROR |
- G_LOG_LEVEL_CRITICAL |
- G_LOG_LEVEL_WARNING;
-#if defined(VMX86_DEBUG)
- gDefaultData->mask |= G_LOG_LEVEL_MESSAGE;
-#endif
- gDefaultData->file = currentFile;
- gDefaultData->path = currentPath;
- gLogEnabled = oldLogEnabled;
- g_log_set_default_handler(gDefaultLogFunc, gDefaultData);
- } else {
- if (currentFile != NULL) {
- fclose(currentFile);
- }
- g_free(currentPath);
- }
+ gLogEnabled |= force;
}
exit(0);
}
- VMTools_EnableLogging(state->log);
if (state->name == NULL) {
state->name = VMTOOLS_GUEST_SERVICE;
state->mainService = TRUE;
state->mainService = (strcmp(state->name, VMTOOLS_GUEST_SERVICE) == 0);
}
+ VMTools_ConfigLogging(state->name,
+ NULL,
+ state->log,
+ FALSE);
+
#if defined(G_PLATFORM_WIN32)
if (kill) {
exit(ToolsCoreSignalEvent(state->name, QUIT_EVENT_NAME_FMT) ? 0 : 1);
* detected.
*
* @param[in] state Service state.
- * @param[in] force Whether to force reconfiguration of the logging
- * subsystem.
+ * @param[in] reset Whether to reset the logging subsystem.
*/
void
ToolsCore_ReloadConfig(ToolsServiceState *state,
- gboolean force)
+ gboolean reset)
{
- char *confFile;
- gboolean loaded = TRUE;
+ gboolean first = state->ctx.config == NULL;
+ gboolean loaded;
- VMTools_SetDefaultLogDomain(state->name);
+ loaded = VMTools_LoadConfig(state->configFile,
+ G_KEY_FILE_NONE,
+ &state->ctx.config,
+ &state->configMtime);
- confFile = g_strdup(state->configFile);
- if (confFile == NULL) {
- confFile = VMTools_GetToolsConfFile();
- }
-
- if (state->ctx.config == NULL) {
- state->ctx.config = VMTools_LoadConfig(confFile,
- G_KEY_FILE_NONE,
- state->mainService);
- state->configMtime = time(NULL);
- if (state->ctx.config == NULL) {
- /* Couldn't load the config file. Just create an empty dictionary. */
- state->ctx.config = g_key_file_new();
- }
- } else if (VMTools_ReloadConfig(confFile,
- G_KEY_FILE_NONE,
- &state->ctx.config,
- &state->configMtime)) {
+ if (!first && loaded) {
g_debug("Config file reloaded.\n");
/* Inform plugins of config file update. */
g_signal_emit_by_name(state->ctx.serviceObj,
TOOLS_CORE_SIG_CONF_RELOAD,
&state->ctx);
- } else {
- loaded = FALSE;
}
- if (force || loaded) {
- VMTools_ConfigLogging(state->ctx.config);
- if (state->log) {
- VMTools_EnableLogging(state->log);
- }
+ if (state->ctx.config == NULL) {
+ /* Couldn't load the config file. Just create an empty dictionary. */
+ state->ctx.config = g_key_file_new();
}
- g_free(confFile);
+ if (reset || loaded) {
+ VMTools_ConfigLogging(state->name,
+ state->ctx.config,
+ state->log,
+ reset);
+ }
}
ToolsCoreSigHUPCb(const siginfo_t *info,
gpointer data)
{
- VMTools_ResetLogging(TRUE);
ToolsCore_ReloadConfig(data, TRUE);
return TRUE;
}
void
ToolsCore_ReloadConfig(ToolsServiceState *state,
- gboolean force);
+ gboolean reset);
void
ToolsCore_RegisterPlugins(ToolsServiceState *state);
GKeyFile *
Toolbox_LoadToolsConf(void)
{
- gchar *path = VMTools_GetToolsConfFile();
- GKeyFile *config;
+ GKeyFile *config = NULL;
- config = VMTools_LoadConfig(path,
- G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
- TRUE);
+ VMTools_LoadConfig(NULL,
+ G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
+ &config,
+ NULL);
if (config == NULL) {
Debug("Unable to load config file.\n");
config = g_key_file_new();
}
- g_free(path);
return config;
}
Toolbox_SaveToolsConf(GKeyFile *config) // IN
{
gboolean ret = FALSE;
- gchar *path = NULL;
GError *err = NULL;
- path = VMTools_GetToolsConfFile();
- ret = VMTools_WriteConfig(path, config, &err);
+ ret = VMTools_WriteConfig(NULL, config, &err);
if (!ret) {
Warning("Error saving conf data: %s\n", err->message);
g_clear_error(&err);
}
- g_free(path);
return ret;
}
static GKeyFile *
LoadConfFile(void)
{
- gchar *confPath;
- GKeyFile *confDict;
+ GKeyFile *confDict = NULL;
- confPath = VMTools_GetToolsConfFile();
- confDict = VMTools_LoadConfig(confPath,
- G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
- System_IsUserAdmin());
+ VMTools_LoadConfig(NULL,
+ G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
+ &confDict,
+ NULL);
if (confDict == NULL) {
confDict = g_key_file_new();
}
- g_free(confPath);
return confDict;
}
{
const char *path;
const char *confName;
- gchar *confPath;
int ret = EXIT_SUCCESS;
GKeyFile *confDict;
GError *err = NULL;
}
g_key_file_set_string(confDict, "powerops", confName, path);
- confPath = VMTools_GetToolsConfFile();
- if (!VMTools_WriteConfig(confPath, confDict, &err)) {
+ if (!VMTools_WriteConfig(NULL, confDict, &err)) {
fprintf(stderr, "Error writing config: %s\n", err->message);
g_clear_error(&err);
ret = EX_TEMPFAIL;
}
g_key_file_free(confDict);
- g_free(confPath);
return ret;
}
{
const char *confName;
int ret = EXIT_SUCCESS;
- gchar *confPath = NULL;
GKeyFile *confDict = NULL;
GError *err = NULL;
return EX_USAGE;
}
- confPath = VMTools_GetToolsConfFile();
confDict = LoadConfFile();
-
g_key_file_set_string(confDict, "powerops", confName, path);
- if (!VMTools_WriteConfig(confPath, confDict, &err)) {
+ if (!VMTools_WriteConfig(NULL, confDict, &err)) {
fprintf(stderr, "Error writing config: %s\n", err->message);
g_clear_error(&err);
ret = EX_TEMPFAIL;
}
g_key_file_free(confDict);
- g_free(confPath);
return ret;
}