int main(int argc, char *argv[], const char *envp[]) { int i; int ret = EXIT_FAILURE; char **argvCopy; GSource *src; Unicode_Init(argc, &argv, NULL); /* * ToolsCore_ParseCommandLine() uses g_option_context_parse(), which modifies * argv. We don't want that to happen, so we make a copy of the array and * use that as the argument instead. */ argvCopy = g_malloc(argc * sizeof *argvCopy); for (i = 0; i < argc; i++) { argvCopy[i] = argv[i]; } setlocale(LC_ALL, ""); VMTools_ConfigLogging(G_LOG_DOMAIN, NULL, FALSE, FALSE); VMTools_BindTextDomain(VMW_TEXT_DOMAIN, NULL, NULL); if (!ToolsCore_ParseCommandLine(&gState, argc, argvCopy)) { g_free(argvCopy); goto exit; } g_free(argvCopy); argvCopy = NULL; if (gState.pidFile != NULL) { /* * If argv[0] is not an absolute path, make it so; all other path * arguments should have been given as absolute paths if '--background' * was used, or things may not work as expected. */ if (!g_path_is_absolute(argv[0])) { gchar *abs = g_find_program_in_path(argv[0]); if (abs == NULL || strcmp(abs, argv[0]) == 0) { char *cwd = File_Cwd(NULL); g_free(abs); abs = g_strdup_printf("%s%c%s", cwd, DIRSEPC, argv[0]); vm_free(cwd); } argv[0] = abs; } /* * Need to remove --background from the command line or we'll get * into an infinite loop. ToolsCore_ParseCommandLine() already * validated that "-b" has an argument, so it's safe to assume the * data is there. */ for (i = 1; i < argc; i++) { size_t count = 0; if (strcmp(argv[i], "--background") == 0 || strcmp(argv[i], "-b") == 0) { count = 2; } else if (g_str_has_prefix(argv[i], "--background=")) { count = 1; } if (count) { memmove(argv + i, argv + i + count, (argc - i - count) * sizeof *argv); argv[argc - count] = NULL; break; } } if (!Hostinfo_Daemonize(argv[0], argv, HOSTINFO_DAEMONIZE_LOCKPID, gState.pidFile, NULL, 0)) { goto exit; } return 0; } ToolsCore_Setup(&gState); src = VMTools_NewSignalSource(SIGHUP); VMTOOLSAPP_ATTACH_SOURCE(&gState.ctx, src, ToolsCoreSigHUPCb, &gState, NULL); g_source_unref(src); src = VMTools_NewSignalSource(SIGINT); VMTOOLSAPP_ATTACH_SOURCE(&gState.ctx, src, ToolsCoreSigHandler, gState.ctx.mainLoop, NULL); g_source_unref(src); src = VMTools_NewSignalSource(SIGQUIT); VMTOOLSAPP_ATTACH_SOURCE(&gState.ctx, src, ToolsCoreSigHandler, gState.ctx.mainLoop, NULL); g_source_unref(src); src = VMTools_NewSignalSource(SIGTERM); VMTOOLSAPP_ATTACH_SOURCE(&gState.ctx, src, ToolsCoreSigHandler, gState.ctx.mainLoop, NULL); g_source_unref(src); src = VMTools_NewSignalSource(SIGUSR1); VMTOOLSAPP_ATTACH_SOURCE(&gState.ctx, src, ToolsCoreSigUsrHandler, NULL, NULL); g_source_unref(src); /* Ignore SIGUSR2 by default. */ signal(SIGUSR2, SIG_IGN); /* * Save the original environment so that we can safely spawn other * applications (since we may have to modify the original environment * to launch vmtoolsd successfully). */ gState.ctx.envp = System_GetNativeEnviron(envp); ret = ToolsCore_Run(&gState); if (gState.pidFile != NULL) { g_unlink(gState.pidFile); } exit: return ret; }
main(int argc, // IN: length of command line arguments char **argv) // IN: Command line arguments #endif { Bool show_help = FALSE; Bool show_version = FALSE; CmdTable *cmd = NULL; GKeyFile *conf = NULL; int c; int retval = EXIT_FAILURE; #if defined(_WIN32) char **argv; Unicode_InitW(argc, wargv, NULL, &argv, NULL); #else Unicode_Init(argc, &argv, NULL); #endif setlocale(LC_ALL, ""); VMTools_LoadConfig(NULL, G_KEY_FILE_NONE, &conf, NULL); VMTools_ConfigLogging("toolboxcmd", conf, FALSE, FALSE); VMTools_BindTextDomain(VMW_TEXT_DOMAIN, NULL, NULL); /* * Check if we are in a VM */ if (!VmCheck_IsVirtualWorld()) { g_printerr(SU_(error.novirtual, "%s must be run inside a virtual machine.\n"), argv[0]); goto exit; } /* * Parse the command line optional arguments */ while (1) { int option_index = 0; c = getopt_long(argc, argv, options, long_options, &option_index); /* Detect the end of the options. */ if (c == -1) { break; } switch (c) { case 'h': show_help = TRUE; break; case 'v': show_version = TRUE; break; case 'q': gQuiet = TRUE; break; case '?': /* getopt_long already printed an error message. */ g_printerr(SU_(help.hint, "Try '%s %s%s%s' for more information.\n"), argv[0], "-h", "", ""); goto exit; default: goto exit; } } if (show_version) { g_print("%s (%s)\n", TOOLBOXCMD_VERSION_STRING, BUILD_NUMBER); retval = EXIT_SUCCESS; } else if (show_help) { ToolboxCmdHelp(argv[0], "help"); retval = EXIT_SUCCESS; } else { /* Process any remaining command line arguments (not options), and * execute corresponding command */ if (optind >= argc) { ToolsCmd_MissingEntityError(argv[0], SU_(arg.command, "command")); retval = EX_USAGE; } else if ((cmd = ParseCommand(argv, argc)) == NULL) { ToolsCmd_UnknownEntityError(argv[0], SU_(arg.command, "command"), argv[optind]); retval = EX_USAGE; } else if (cmd->requireRoot && !System_IsUserAdmin()) { #if defined(_WIN32) g_printerr(SU_(error.noadmin.win, "%s: Administrator permissions are needed to perform %s operations.\n" "Use an administrator command prompt to complete these tasks.\n"), argv[0], cmd->command); #else g_printerr(SU_(error.noadmin.posix, "%s: You must be root to perform %s operations.\n"), argv[0], cmd->command); #endif retval = EX_NOPERM; } else if (cmd->requireArguments && ++optind >= argc) { ToolsCmd_MissingEntityError(argv[0], SU_(arg.subcommand, "subcommand")); retval = EX_USAGE; } else { retval = cmd->func(argv, argc, gQuiet); } if (retval == EX_USAGE && (cmd == NULL || strcmp(cmd->command, "help"))) { g_printerr(SU_(help.hint, "Try '%s %s%s%s' for more information.\n"), argv[0], "help", cmd ? " " : "", cmd ? cmd->command : ""); } } exit: if (conf != NULL) { g_key_file_free(conf); } return retval; }
gboolean ToolsCore_LoadPlugins(ToolsServiceState *state) { gboolean pluginDirExists; gboolean ret = FALSE; gchar *pluginRoot; guint i; GPtrArray *plugins = NULL; #if defined(sun) && defined(__x86_64__) const char *subdir = "/amd64"; #else const char *subdir = ""; #endif #if defined(OPEN_VM_TOOLS) pluginRoot = g_strdup(VMTOOLSD_PLUGIN_ROOT); #else char *instPath = GuestApp_GetInstallPath(); pluginRoot = g_strdup_printf("%s%cplugins", instPath, DIRSEPC); vm_free(instPath); #endif ASSERT(g_module_supported()); #ifdef USE_APPLOADER { Bool ret = FALSE; GModule *mainModule = g_module_open(NULL, G_MODULE_BIND_LAZY); ASSERT(mainModule); ret = g_module_symbol(mainModule, "AppLoader_LoadLibraryDependencies", (gpointer *)&LoadDependencies); g_module_close(mainModule); if (!ret) { g_critical("Unable to locate library dependency loading function.\n"); goto exit; } } #endif plugins = g_ptr_array_new(); /* * First, load plugins from the common directory. The common directory * is not required to exist unless provided on the command line. */ if (state->commonPath == NULL) { state->commonPath = g_strdup_printf("%s%s%c%s", pluginRoot, subdir, DIRSEPC, TOOLSCORE_COMMON); } else if (!g_file_test(state->commonPath, G_FILE_TEST_IS_DIR)) { g_warning("Common plugin path is not a directory: %s\n", state->commonPath); goto exit; } if (g_file_test(state->commonPath, G_FILE_TEST_IS_DIR) && !ToolsCoreLoadDirectory(&state->ctx, state->commonPath, plugins)) { goto exit; } /* * Load the container-specific plugins. Ignore if the plugin directory * doesn't exist when running in debug mode. */ if (state->pluginPath == NULL) { state->pluginPath = g_strdup_printf("%s%s%c%s", pluginRoot, subdir, DIRSEPC, state->name); } pluginDirExists = g_file_test(state->pluginPath, G_FILE_TEST_IS_DIR); if (state->debugPlugin == NULL && !pluginDirExists) { g_warning("Plugin path is not a directory: %s\n", state->pluginPath); goto exit; } if (pluginDirExists && !ToolsCoreLoadDirectory(&state->ctx, state->pluginPath, plugins)) { goto exit; } /* * All plugins are loaded, now initialize them. */ state->plugins = g_ptr_array_new(); for (i = 0; i < plugins->len; i++) { ToolsPlugin *plugin = g_ptr_array_index(plugins, i); plugin->data = plugin->onload(&state->ctx); if (plugin->data == NULL) { g_info("Plugin '%s' didn't provide deployment data, unloading.\n", plugin->fileName); ToolsCoreFreePlugin(plugin); } else if (state->ctx.errorCode != 0) { /* Break early if a plugin has requested the container to quit. */ ToolsCoreFreePlugin(plugin); break; } else { ASSERT(plugin->data->name != NULL); g_module_make_resident(plugin->module); g_ptr_array_add(state->plugins, plugin); VMTools_BindTextDomain(plugin->data->name, NULL, NULL); g_message("Plugin '%s' initialized.\n", plugin->data->name); } } /* * If there is a debug plugin, see if it exports standard plugin registration * data too. */ if (state->debugData != NULL && state->debugData->debugPlugin->plugin != NULL) { ToolsPluginData *data = state->debugData->debugPlugin->plugin; ToolsPlugin *plugin = g_malloc(sizeof *plugin); plugin->fileName = NULL; plugin->module = NULL; plugin->data = data; VMTools_BindTextDomain(data->name, NULL, NULL); g_ptr_array_add(state->plugins, plugin); } ret = TRUE; exit: if (plugins != NULL) { g_ptr_array_free(plugins, TRUE); } g_free(pluginRoot); return ret; }