コード例 #1
0
ファイル: rpcChannel.c プロジェクト: nf-mlo/open-vm-tools
gboolean
RpcChannel_Dispatch(RpcInData *data)
{
   char *name = NULL;
   unsigned int index = 0;
   size_t nameLen;
   Bool status;
   RpcChannelCallback *rpc = NULL;
   RpcChannelInt *chan = data->clientData;

   name = StrUtil_GetNextToken(&index, data->args, " ");
   if (name == NULL) {
      Debug(LGPFX "Bad command (null) received.\n");
      status = RPCIN_SETRETVALS(data, "Bad command", FALSE);
      goto exit;
   }

   if (chan->rpcs != NULL) {
      rpc = g_hash_table_lookup(chan->rpcs, name);
   }

   if (rpc == NULL) {
      Debug(LGPFX "Unknown Command '%s': Handler not registered.\n", name);
      status = RPCIN_SETRETVALS(data, "Unknown Command", FALSE);
      goto exit;
   }

   /* Adjust the RPC arguments. */
   nameLen = strlen(name);
   data->name = name;
   data->args = data->args + nameLen;
   data->argsSize -= nameLen;
   data->appCtx = chan->appCtx;
   data->clientData = rpc->clientData;

   if (rpc->xdrIn != NULL || rpc->xdrOut != NULL) {
      status = RpcChannelXdrWrapper(data, rpc);
   } else {
      status = rpc->callback(data);
   }

   ASSERT(data->result != NULL);

exit:
   data->name = NULL;
   free(name);
   return status;
}
コード例 #2
0
gboolean
ToolsDaemonTcloSyncDriverThaw(RpcInData *data) // IN
{
   static char resultBuffer[DEFAULT_RESULT_MSG_MAX_LENGTH];
   VixError err = VIX_OK;
   DECLARE_SYNCDRIVER_ERROR(sysError);
   Debug(">ToolsDaemonTcloSyncDriverThaw\n");

   /*
    * This function has no arguments that we care about.
    */

   Debug("SYNCDRIVE: Got request to thaw\n");

   if (gSyncDriverHandle == SYNCDRIVER_INVALID_HANDLE) {
      err = VIX_E_GUEST_VOLUMES_NOT_FROZEN;
      sysError = SYNCDRIVERERROR;
      Debug("ToolsDaemonTcloSyncDriverThaw: No drives are frozen.\n");
   } else if (!SyncDriver_Thaw(gSyncDriverHandle)) {
      err = VIX_E_FAIL;
      sysError = SYNCDRIVERERROR;
      Debug("ToolsDaemonTcloSyncDriverThaw: Failed to Thaw drives\n");
   }

   SyncDriver_CloseHandle(&gSyncDriverHandle);

   /*
    * All Foundry tools commands return results that start with a
    * foundry error and a guest-OS-specific error.
    */
   Str_Sprintf(resultBuffer, sizeof resultBuffer, "%"FMT64"d %d", err, sysError);
   Debug("<ToolsDaemonTcloSyncDriverThaw\n");
   return RPCIN_SETRETVALS(data, resultBuffer, TRUE);
}
コード例 #3
0
ファイル: toolsRpc.c プロジェクト: angelovescio/open-vm-tools
static gboolean
ToolsCoreRpcCapReg(RpcInData *data)
{
   char *confPath = GuestApp_GetConfPath();
   gchar *msg;
   GArray *pcaps = NULL;
   ToolsServiceState *state = data->clientData;

   g_signal_emit_by_name(state->ctx.serviceObj,
                         TOOLS_CORE_SIG_CAPABILITIES,
                         &state->ctx,
                         TRUE,
                         &pcaps);

   if (pcaps != NULL) {
      ToolsCore_SetCapabilities(state->ctx.rpc, pcaps, TRUE);
      g_array_free(pcaps, TRUE);
   }

   /* Tell the host the location of the conf directory. */
   msg = g_strdup_printf("tools.capability.guest_conf_directory %s", confPath);
   if (!RpcChannel_Send(state->ctx.rpc, msg, strlen(msg) + 1, NULL, NULL)) {
      g_debug("Unable to register guest conf directory capability.\n");
   }
   g_free(msg);
   msg = NULL;

   /* Send the tools version to the VMX. */
   if (state->mainService) {
      uint32 version;
      char *result = NULL;
      size_t resultLen;
      gchar *toolsVersion;

#if defined(OPEN_VM_TOOLS)
      version = TOOLS_VERSION_UNMANAGED;
#else
      gboolean disableVersion;

      disableVersion = g_key_file_get_boolean(state->ctx.config,
                                              "vmtools",
                                              CONFNAME_DISABLETOOLSVERSION,
                                              NULL);
      version = disableVersion ? TOOLS_VERSION_UNMANAGED : TOOLS_VERSION_CURRENT;
#endif

      toolsVersion = g_strdup_printf("tools.set.version %u", version);

      if (!RpcChannel_Send(state->ctx.rpc, toolsVersion, strlen(toolsVersion) + 1,
                           &result, &resultLen)) {
         g_debug("Error setting tools version: %s.\n", result);
      }
      vm_free(result);
      g_free(toolsVersion);
   }

   state->capsRegistered = TRUE;
   free(confPath);
   return RPCIN_SETRETVALS(data, "", TRUE);
}
コード例 #4
0
ファイル: toolsRpc.c プロジェクト: angelovescio/open-vm-tools
static gboolean
ToolsCoreRpcSetOption(RpcInData *data)
{

   gboolean retVal = FALSE;
   char *option;
   char *value;
   unsigned int index = 0;
   ToolsServiceState *state = data->clientData;

   /* Parse the option & value string. */
   option = StrUtil_GetNextToken(&index, data->args, " ");
   /* Ignore leading space before value. */
   index++;
   value = StrUtil_GetNextToken(&index, data->args, "");

   if (option != NULL && value != NULL && strlen(value) != 0) {

      g_debug("Setting option '%s' to '%s'.\n", option, value);
      g_signal_emit_by_name(state->ctx.serviceObj,
                            TOOLS_CORE_SIG_SET_OPTION,
                            &state->ctx,
                            option,
                            value,
                            &retVal);
   }

   vm_free(option);
   vm_free(value);

   RPCIN_SETRETVALS(data, retVal ? "" : "Unknown or invalid option", retVal);

   return retVal;
}
コード例 #5
0
static gboolean
VmBackupStart(RpcInData *data)
{
   g_debug("*** %s\n", __FUNCTION__);
   if (gBackupState != NULL) {
      return RPCIN_SETRETVALS(data, "Quiesce operation already in progress.",
                              FALSE);
   }
   gBackupState = g_new0(VmBackupState, 1);
   if (data->argsSize > 0) {
      int generateManifests = 0;
      uint32 index = 0;

      if (StrUtil_GetNextIntToken(&generateManifests, &index, data->args, " ")) {
         gBackupState->generateManifests = generateManifests;
      }
      gBackupState->quiesceApps = TRUE;
      gBackupState->quiesceFS = TRUE;
      gBackupState->allowHWProvider = TRUE;
      gBackupState->execScripts = TRUE;
      gBackupState->scriptArg = NULL;
      gBackupState->timeout = 0;

      /* get volume uuids if provided */
      if (data->args[index] != '\0') {
         gBackupState->volumes = g_strndup(data->args + index,
                                           data->argsSize - index);
      }
   }
   return VmBackupStartCommon(data, FALSE);
}
コード例 #6
0
gboolean
ToolsDaemonTcloMountHGFS(RpcInData *data) // IN
{
   VixError err = VIX_OK;
   static char resultBuffer[DEFAULT_RESULT_MSG_MAX_LENGTH];

#if defined(linux)
   /*
    * Look for a vmhgfs mount at /mnt/hgfs. If one exists, nothing
    * else needs to be done.  If one doesn't exist, then mount at
    * that location.
    */
   FILE *mtab;
   struct mntent *mnt;
   if ((mtab = setmntent(_PATH_MOUNTED, "r")) == NULL) {
      err = VIX_E_FAIL;
   } else {
      Bool vmhgfsMntFound = FALSE;
      while ((mnt = getmntent(mtab)) != NULL) {
         if ((strcmp(mnt->mnt_fsname, ".host:/") == 0) &&
             (strcmp(mnt->mnt_type, HGFS_NAME) == 0) &&
             (strcmp(mnt->mnt_dir, "/mnt/hgfs") == 0)) {
             vmhgfsMntFound = TRUE;
             break;
         }
      }
      endmntent(mtab);

      if (!vmhgfsMntFound) {
         /*
          * We need to call the mount program, not the mount system call. The
          * mount program does several additional things, like compute the mount
          * options from the contents of /etc/fstab, and invoke custom mount
          * programs like the one needed for HGFS.
          */
         int ret = system("mount -t vmhgfs .host:/ /mnt/hgfs");
         if (ret == -1 || WIFSIGNALED(ret) ||
             (WIFEXITED(ret) && WEXITSTATUS(ret) != 0)) {
            err = VIX_E_HGFS_MOUNT_FAIL;
         }
      }
   }
#endif

   /*
    * All tools commands return results that start with an error
    * and a guest-OS-specific error.
    */
   Str_Sprintf(resultBuffer,
               sizeof(resultBuffer),
               "%"FMT64"d %d",
               err,
               Err_Errno());
   RPCIN_SETRETVALS(data, resultBuffer, TRUE);

   return TRUE;
} // ToolsDaemonTcloMountHGFS
コード例 #7
0
static gboolean
ResolutionChangeHost3DAvailabilityHintCB(RpcInData *data)
{
   unsigned int set;
   gboolean success = FALSE;
   unsigned int index = 0;

   g_debug("%s: enter\n", __FUNCTION__);

   if (!StrUtil_GetNextUintToken(&set, &index, data->args, " ")) {
      g_debug("%s: invalid arguments\n", __FUNCTION__);
      return RPCIN_SETRETVALS(data,
                              "Invalid arguments. Expected \"set\"",
                              FALSE);
   }

   success = ResolutionChangeHost3DAvailabilityHint(set?TRUE:FALSE);

   RPCIN_SETRETVALS(data, success ? "" : "ResolutionChangeHost3DAvailabilityHint failed", success);

   g_debug("%s: leave\n", __FUNCTION__);
   return success;
}
コード例 #8
0
static gboolean
HgfsServerRpcDispatch(RpcInData *data)
{
   HgfsServerMgrData *mgrData;
   size_t replySize;
   static char reply[HGFS_LARGE_PACKET_MAX];


   ASSERT(data->clientData != NULL);
   mgrData = data->clientData;

   if (data->argsSize == 0) {
      return RPCIN_SETRETVALS(data, "1 argument required", FALSE);
   }

   replySize = sizeof reply;
   HgfsServerManager_ProcessPacket(mgrData, data->args + 1, data->argsSize - 1, reply, &replySize);

   data->result = reply;
   data->resultLen = replySize;
   return TRUE;
}
コード例 #9
0
static gboolean
GuestInfoVMSupport(RpcInData *data)
{
#if defined(_WIN32)

    char vmSupportCmd[] = "vm-support.vbs";
    char *vmSupportPath = NULL;
    gchar *vmSupport = NULL;

    SECURITY_ATTRIBUTES saProcess = {0}, saThread = {0};

    ProcMgr_AsyncProc *vmSupportProc = NULL;
    ProcMgr_ProcArgs vmSupportProcArgs = {0};

    /*
     * Construct the commandline to be passed during execution
     * This will be the path of our vm-support.vbs
     */
    vmSupportPath = GuestApp_GetInstallPath();

    if (vmSupportPath == NULL) {
       return RPCIN_SETRETVALS(data,
                               "GuestApp_GetInstallPath failed", FALSE);
    }

    /* Put together absolute vm-support filename. */
    vmSupport = g_strdup_printf("cscript \"%s%s%s\" -u",
                                vmSupportPath, DIRSEPS, vmSupportCmd);
    vm_free(vmSupportPath);

    saProcess.nLength = sizeof saProcess;
    saProcess.bInheritHandle = TRUE;

    saThread.nLength = sizeof saThread;

    vmSupportProcArgs.lpProcessAttributes = &saProcess;
    vmSupportProcArgs.lpThreadAttributes = &saThread;
    vmSupportProcArgs.dwCreationFlags = CREATE_NO_WINDOW;

    g_message("Starting vm-support script - %s\n", vmSupport);
    vmSupportProc = ProcMgr_ExecAsync(vmSupport, &vmSupportProcArgs);
    g_free(vmSupport);

    if (vmSupportProc == NULL) {
       g_warning("Error starting vm-support script\n");
       return RPCIN_SETRETVALS(data,
                               "Error starting vm-support script", FALSE);
    }

    ProcMgr_Free(vmSupportProc);
    return RPCIN_SETRETVALS(data, "", TRUE);

#else

     gchar *vmSupportCmdArgv[] = {"vm-support", "-u", NULL};

     g_message("Starting vm-support script - %s\n", vmSupportCmdArgv[0]);
     if (!g_spawn_async(NULL, vmSupportCmdArgv, NULL,
                        G_SPAWN_SEARCH_PATH |
                        G_SPAWN_STDOUT_TO_DEV_NULL |
                        G_SPAWN_STDERR_TO_DEV_NULL,
                        NULL, NULL, NULL, NULL)) {
        g_warning("Error starting vm-support script\n");
        return RPCIN_SETRETVALS(data,
                                "Error starting vm-support script", FALSE);
     }

     return RPCIN_SETRETVALS(data, "", TRUE);

#endif
}
コード例 #10
0
gboolean
FoundryToolsDaemonRunProgram(RpcInData *data) // IN
{
   VixError err = VIX_OK;
   char *requestName = NULL;
   char *commandLine = NULL;
   char *commandLineArgs = NULL;
   char *credentialTypeStr = NULL;
   char *obfuscatedNamePassword = NULL;
   char *directoryPath = NULL;
   char *environmentVariables = NULL;
   static char resultBuffer[DEFAULT_RESULT_MSG_MAX_LENGTH];
   Bool impersonatingVMWareUser = FALSE;
   void *userToken = NULL;
   ProcMgr_Pid pid;
   GMainLoop *eventQueue = ((ToolsAppCtx *)data->appCtx)->mainLoop;

   /*
    * Parse the arguments. Some of these are optional, so they
    * may be NULL.
    */
   requestName = ToolsDaemonTcloGetQuotedString(data->args, &data->args);

   err = ToolsDaemonTcloGetEncodedQuotedString(data->args, &data->args,
                                               &commandLine);
   if (err != VIX_OK) {
      goto abort;
   }

   err = ToolsDaemonTcloGetEncodedQuotedString(data->args, &data->args,
                                               &commandLineArgs);
   if (err != VIX_OK) {
      goto abort;
   }

   credentialTypeStr = ToolsDaemonTcloGetQuotedString(data->args, &data->args);
   obfuscatedNamePassword = ToolsDaemonTcloGetQuotedString(data->args, &data->args);
   directoryPath = ToolsDaemonTcloGetQuotedString(data->args, &data->args);
   environmentVariables = ToolsDaemonTcloGetQuotedString(data->args, &data->args);

   /*
    * Make sure we are passed the correct arguments.
    * Some of these arguments (like credentialTypeStr and obfuscatedNamePassword) are optional,
    * so they may be NULL.
    */
   if ((NULL == requestName) || (NULL == commandLine)) {
      err = VIX_E_INVALID_ARG;
      goto abort;
   }

   if ((NULL != credentialTypeStr)
         && (*credentialTypeStr) 
         && (thisProcessRunsAsRoot)) {
      impersonatingVMWareUser = VixToolsImpersonateUserImpl(credentialTypeStr, 
                                                            VIX_USER_CREDENTIAL_NONE,
                                                            obfuscatedNamePassword, 
                                                            &userToken);
      if (!impersonatingVMWareUser) {
         err = VIX_E_GUEST_USER_PERMISSIONS;
         goto abort;
      }
   }

   err = VixToolsRunProgramImpl(requestName,
                                commandLine,
                                commandLineArgs,
                                0,
                                userToken,
                                eventQueue,
                                (int64 *) &pid);

abort:
   if (impersonatingVMWareUser) {
      VixToolsUnimpersonateUser(userToken);
   }
   VixToolsLogoutUser(userToken);

   /*
    * All VMXI tools commands return results that start with a VMXI error
    * and a guest-OS-specific error.
    */
   Str_Sprintf(resultBuffer,
               sizeof(resultBuffer),
               "%"FMT64"d %d %"FMT64"d",
               err,
               Err_Errno(),
               (int64) pid);
   RPCIN_SETRETVALS(data, resultBuffer, TRUE);

   /*
    * These were allocated by ToolsDaemonTcloGetQuotedString.
    */
   free(requestName);
   free(commandLine);
   free(credentialTypeStr);
   free(obfuscatedNamePassword);
   free(directoryPath);
   free(environmentVariables);
   free(commandLineArgs);

   return TRUE;
} // FoundryToolsDaemonRunProgram
コード例 #11
0
static gboolean
VmBackupStartCommon(RpcInData *data,
                    gboolean forceVss)
{
   GError *err = NULL;
   ToolsAppCtx *ctx = data->appCtx;
   VmBackupSyncProvider *provider = NULL;

   size_t i;

   /* List of available providers, in order of preference for loading. */
   struct SyncProvider {
      VmBackupSyncProvider *(*ctor)(void);
      const gchar *cfgEntry;
   } providers[] = {
#if defined(_WIN32)
      { VmBackup_NewVssProvider, "enableVSS" },
#endif
      { VmBackup_NewSyncDriverProvider, "enableSyncDriver" },
      { VmBackup_NewNullProvider, NULL },
   };

   if (forceVss) {
      if (gBackupState->quiesceApps || gBackupState->quiesceFS) {
          /* If quiescing is requested, only allow VSS provider */
#if defined(_WIN32)
          if (VmBackupConfigGetBoolean(ctx->config, "enableVSS", TRUE)) {
             provider = VmBackup_NewVssProvider();
          }
#endif
      } else {
         /* If no quiescing is requested only allow null provider */
         provider = VmBackup_NewNullProvider();
      }
      if (provider == NULL) {
         g_warning("Requested quiescing cannot be initialized.");
         goto error;
      }
   } else {
      /* Instantiate the sync provider. */
      for (i = 0; i < ARRAYSIZE(providers); i++) {
         struct SyncProvider *sp = &providers[i];

         if (VmBackupConfigGetBoolean(ctx->config, sp->cfgEntry, TRUE)) {
            provider = sp->ctor();
            if (provider != NULL) {
               break;
            }
         }
      }
   }

   ASSERT(provider != NULL);

   /* Instantiate the backup state and start the operation. */
   gBackupState->ctx = data->appCtx;
   gBackupState->pollPeriod = 1000;
   gBackupState->machineState = VMBACKUP_MSTATE_IDLE;
   gBackupState->provider = provider;
   g_debug("Using quiesceApps = %d, quiesceFS = %d, allowHWProvider = %d,"
           "execScripts = %d, scriptArg = %s, timeout = %u\n",
           gBackupState->quiesceApps, gBackupState->quiesceFS,
           gBackupState->allowHWProvider, gBackupState->execScripts,
           (gBackupState->scriptArg != NULL) ? gBackupState->scriptArg : "",
           gBackupState->timeout);
   g_debug("Quiescing volumes: %s",
           (gBackupState->volumes) ? gBackupState->volumes : "(null)");

   gBackupState->configDir = GuestApp_GetConfPath();
   if (gBackupState->configDir == NULL) {
      g_warning("Error getting configuration directory.");
      goto error;
   }

   VmBackup_SendEvent(VMBACKUP_EVENT_RESET, VMBACKUP_SUCCESS, "");

   if (!VmBackupStartScripts(VMBACKUP_SCRIPT_FREEZE)) {
      goto error;
   }

   /*
    * VC has a 15 minute timeout for quiesced snapshots. After that timeout,
    * it just discards the operation and sends an error to the caller. But
    * Tools can still keep running, blocking any new quiesced snapshot
    * requests. So we set up our own timer (which is configurable, in case
    * anyone wants to play with it), so that we abort any ongoing operation
    * if we also hit that timeout.
    *
    * First check if the timeout is specified by the RPC command, if not,
    * check the tools.conf file, otherwise use the default.
    *
    * See bug 506106.
    */
   if (gBackupState->timeout == 0) {
      gBackupState->timeout = (guint) g_key_file_get_integer(
                                               gBackupState->ctx->config,
                                               "vmbackup",
                                               "timeout",
                                               &err);
      if (err != NULL) {
         g_clear_error(&err);
         gBackupState->timeout = 15 * 60;
      }
   }

   /* Treat "0" as no timeout. */
   if (gBackupState->timeout != 0) {
      gBackupState->abortTimer =
          g_timeout_source_new_seconds(gBackupState->timeout);
      VMTOOLSAPP_ATTACH_SOURCE(gBackupState->ctx,
                               gBackupState->abortTimer,
                               VmBackupAbortTimer,
                               NULL,
                               NULL);
   }

   VMBACKUP_ENQUEUE_EVENT();
   return RPCIN_SETRETVALS(data, "", TRUE);

error:
   if (gBackupState->provider) {
      gBackupState->provider->release(gBackupState->provider);
   }
   g_free(gBackupState->scriptArg);
   g_free(gBackupState->volumes);
   g_free(gBackupState);
   gBackupState = NULL;
   return RPCIN_SETRETVALS(data, "Error initializing quiesce operation.",
                           FALSE);
}
コード例 #12
0
static gboolean
ResolutionDisplayTopologySetCB(RpcInData *data)
{
   DisplayTopologyInfo *displays = NULL;
   unsigned int count, i;
   gboolean success = FALSE;
   const char *p;

   ResolutionInfoType *resInfo = &resolutionInfo;

   if (!resInfo->initialized) {
      g_debug("%s: FAIL! Request for topology set but plugin is not initialized\n",
              __FUNCTION__);
      RPCIN_SETRETVALS(data, "Invalid guest state: topology set not initialized", FALSE);
      goto out;
   }

   /*
    * The argument string will look something like:
    *   <count> [ , <x> <y> <w> <h> ] * count.
    *
    * e.g.
    *    3 , 0 0 640 480 , 640 0 800 600 , 0 480 640 480
    */

   if (sscanf(data->args, "%u", &count) != 1) {
      return RPCIN_SETRETVALS(data,
                              "Invalid arguments. Expected \"count\"",
                              FALSE);
   }

   displays = malloc(sizeof *displays * count);
   if (!displays) {
      RPCIN_SETRETVALS(data,
                       "Failed to alloc buffer for display info",
                       FALSE);
      goto out;
   }

   for (p = data->args, i = 0; i < count; i++) {
      p = strchr(p, ',');
      if (!p) {
         RPCIN_SETRETVALS(data,
                          "Expected comma separated display list",
                          FALSE);
         goto out;
      }
      p++; /* Skip past the , */

      if (sscanf(p, " %d %d %d %d ", &displays[i].x,
                 &displays[i].y, &displays[i].width, &displays[i].height) != 4) {
         RPCIN_SETRETVALS(data,
                          "Expected x, y, w, h in display entry",
                          FALSE);
         goto out;
      }
   }

   success = ResolutionSetTopology(count, displays);

   RPCIN_SETRETVALS(data, success ? "" : "ResolutionSetTopology failed", success);

out:
   free(displays);
   return success;
}
コード例 #13
0
ファイル: powerOps.c プロジェクト: AlissonGiron/open-vm-tools
static gboolean
PowerOpsStateChange(RpcInData *data)
{
   size_t i;
   PowerOpState *state = data->clientData;

   if (state->pid != INVALID_PID) {
      g_debug("State change already in progress.\n");
      return RPCIN_SETRETVALS(data,  "State change already in progress", FALSE);
   }

   g_debug("State change: %s\n", data->name);

   for (i = 0; i < ARRAYSIZE(stateChangeCmdTable); i++) {
      if (strcmp(data->name, stateChangeCmdTable[i].tcloCmd) == 0) {
         gchar *script;
         const char *result;
         const char *confName;
         Bool ret;

         state->stateChgInProgress = stateChangeCmdTable[i].id;

         /* Check for the toolScripts option. */
         if (!state->scriptEnabled[stateChangeCmdTable[i].id]) {
            PowerOpsStateChangeDone(state, TRUE);
            g_debug("Script for %s not configured to run\n",
                    stateChangeCmdTable[i].tcloCmd);
            return RPCIN_SETRETVALS(data, "", TRUE);
         }

         confName = stateChgConfNames[stateChangeCmdTable[i].id];
         script = g_key_file_get_string(state->ctx->config,
                                        "powerops",
                                        confName,
                                        NULL);

         if (script == NULL) {
            /* Use default script if not set in config file. */
            const char *dfltScript = GuestApp_GetDefaultScript(confName);
            if (dfltScript == NULL) {
               g_debug("No default script to run for state change %s.\n",
                       stateChangeCmdTable[i].name);
               PowerOpsStateChangeDone(state, TRUE);
               return RPCIN_SETRETVALS(data, "", TRUE);
            }
            script = g_strdup(dfltScript);
         } else if (strlen(script) == 0) {
            g_debug("No script to run for state change %s.\n",
                    stateChangeCmdTable[i].name);
            g_free(script);
            PowerOpsStateChangeDone(state, TRUE);
            return RPCIN_SETRETVALS(data, "", TRUE);
         }

         /* If script path is not absolute, assume the Tools install path. */
         if (!g_path_is_absolute(script)) {
            char *dfltPath;
            char *tmp;

            dfltPath = GuestApp_GetInstallPath();
            ASSERT(dfltPath != NULL);

            /*
             * Before the switch to vmtoolsd, the config file was saved with
             * quotes around the script path to make the old VMware dict code
             * happy. Now we need to undo that when modifying the script path.
             *
             * PowerOpsRunScript will "re-quote" the script path.
             */
            if (script[0] == '"') {
                script[strlen(script) - 1] = '\0';
                tmp = g_strdup_printf("%s%c%s", dfltPath, DIRSEPC, script + 1);
            } else {
               tmp = g_strdup_printf("%s%c%s", dfltPath, DIRSEPC, script);
            }

            g_free(script);
            vm_free(dfltPath);
            script = tmp;
         }

         if (PowerOpsRunScript(state, script)) {
            result = "";
            ret = TRUE;
         } else {
            PowerOpsStateChangeDone(state, FALSE);
            result = "Error starting script";
            ret = FALSE;
         }

         g_free(script);
         return RPCIN_SETRETVALS(data, (char *) result, ret);
      }
   }

   g_warning("Invalid state change command.\n");
   return RPCIN_SETRETVALS(data, "Invalid state change command", FALSE);
}
コード例 #14
0
static gboolean
RecvMsgCB(RpcInData *data) // IN/OUT
{
   LOG(4, ("%s: receiving\n", __FUNCTION__));

   const uint8 *packet = (const uint8 *)(data->args + 1);
   size_t packetSize = data->argsSize - 1;

   /* '- 1' is to ignore empty space between command and args. */
   if ((data->argsSize - 1) <= 0) {
      Debug("%s: invalid argsSize\n", __FUNCTION__);
      return RPCIN_SETRETVALS(data, "invalid arg size", FALSE);
   }
   GuestRpcCBCtx *ctx = (GuestRpcCBCtx *)data->clientData;
#else
/**
 * Received a message from guestRpc. Forward the message to transport class.
 *
 * @param[in] clientData callback client data.
 * @param[ignored] channelId
 * @param[in] args argument list.
 * @param[in] argsSize argument list size in byte.
 * @param[out] result reply string.
 * @param[out] resultSize reply string length in byte.
 *
 * @return TRUE if success, FALSE otherwise.
 */

static Bool
RecvMsgCB(void *clientData,
          GuestRpcChannel *chan,
          const unsigned char *args,
          uint32 argsSize,
          unsigned char **result,
          uint32 *resultSize)
{
   const uint8 *packet = args;
   size_t packetSize = argsSize;
   GuestRpcCBCtx *ctx = (GuestRpcCBCtx *)clientData;
#endif

   ASSERT(ctx);
   ASSERT(ctx->transport);
   ctx->transport->OnRecvPacket(ctx->type, packet, packetSize);

#ifdef VMX86_TOOLS
   return RPCIN_SETRETVALS(data, "", TRUE);
#else
   return GuestRpc_SetRetVals(result, resultSize, (char *)"", TRUE);
#endif
}


/**
 * Constructor.
 */

TransportGuestRpcTables::TransportGuestRpcTables(void)
{
   for (int i = 0; i < TRANSPORT_INTERFACE_MAX; i++) {
      mRpcList[i] = NULL;
      mCmdStrTable[i] = NULL;
      mDisableStrTable[i] = NULL;
#ifdef VMX86_TOOLS
   }
#else
      mCmdTable[i] = GUESTRPC_CMD_MAX;
   }
   mCmdTable[TRANSPORT_GUEST_CONTROLLER_DND] = GUESTRPC_CMD_DND_TRANSPORT;
   mCmdTable[TRANSPORT_GUEST_CONTROLLER_CP] = GUESTRPC_CMD_COPYPASTE_TRANSPORT;
#endif

   mCmdStrTable[TRANSPORT_GUEST_CONTROLLER_DND] = (char *)GUEST_RPC_CMD_STR_DND;
   mCmdStrTable[TRANSPORT_GUEST_CONTROLLER_CP] = (char *)GUEST_RPC_CMD_STR_CP;

   mDisableStrTable[TRANSPORT_GUEST_CONTROLLER_DND] = (char *)GUEST_RPC_DND_DISABLE;
   mDisableStrTable[TRANSPORT_GUEST_CONTROLLER_CP] = (char *)GUEST_RPC_CP_DISABLE;
}
コード例 #15
0
ファイル: rpcChannel.c プロジェクト: nf-mlo/open-vm-tools
static Bool
RpcChannelXdrWrapper(RpcInData *data,
                     RpcChannelCallback *rpc)
{
   Bool ret;
   RpcInData copy;
   void *xdrData = NULL;

   if (rpc->xdrIn != NULL) {
      xdrData = malloc(rpc->xdrInSize);
      if (xdrData == NULL) {
         ret = RPCIN_SETRETVALS(data, "Out of memory.", FALSE);
         goto exit;
      }

      memset(xdrData, 0, rpc->xdrInSize);
      if (!XdrUtil_Deserialize(data->args + 1, data->argsSize - 1,
                               rpc->xdrIn, xdrData)) {
         ret = RPCIN_SETRETVALS(data, "XDR deserialization failed.", FALSE);
         free(xdrData);
         goto exit;
      }

      copy.name = data->name;
      copy.args = xdrData;
      copy.argsSize = rpc->xdrInSize;
      copy.result = data->result;
      copy.resultLen = data->resultLen;
      copy.freeResult = data->freeResult;
      copy.appCtx = data->appCtx;
      copy.clientData = rpc->clientData;
   } else {
      memcpy(&copy, data, sizeof copy);
   }

   ret = rpc->callback(&copy);

   if (rpc->xdrIn != NULL) {
      VMX_XDR_FREE(rpc->xdrIn, xdrData);
      free(xdrData);
      copy.args = NULL;
      data->result = copy.result;
      data->resultLen = copy.resultLen;
      data->freeResult = copy.freeResult;
   }

   if (rpc->xdrOut != NULL && copy.result != NULL) {
      XDR xdrs;
      xdrproc_t xdrProc = rpc->xdrOut;

      if (DynXdr_Create(&xdrs) == NULL) {
         ret = RPCIN_SETRETVALS(data, "Out of memory.", FALSE);
         goto exit;
      }

      if (!xdrProc(&xdrs, copy.result)) {
         ret = RPCIN_SETRETVALS(data, "XDR serialization failed.", FALSE);
         DynXdr_Destroy(&xdrs, TRUE);
         goto exit;
      }

      if (copy.freeResult) {
         VMX_XDR_FREE(rpc->xdrOut, copy.result);
      }
      data->result = DynXdr_Get(&xdrs);
      data->resultLen = XDR_GETPOS(&xdrs);
      data->freeResult = TRUE;
      DynXdr_Destroy(&xdrs, FALSE);
   }

exit:
   if (copy.freeResult && copy.result != NULL) {
      g_free(copy.result);
   }
   return ret;
}
コード例 #16
0
gboolean
ToolsDaemonTcloSyncDriverFreeze(RpcInData *data)
{
   static char resultBuffer[DEFAULT_RESULT_MSG_MAX_LENGTH];
   VixError err = VIX_OK;
   char *driveList = NULL;
   char *timeout = NULL;
   int timeoutVal;
   DECLARE_SYNCDRIVER_ERROR(sysError);
   ToolsAppCtx *ctx = data->appCtx;
   GSource *timer;
   
   Debug(">ToolsDaemonTcloSyncDriverFreeze\n");

   /*
    * Parse the arguments
    */
   driveList = ToolsDaemonTcloGetQuotedString(data->args, &data->args);
   timeout = ToolsDaemonTcloGetQuotedString(data->args, &data->args);

   /*
    * Validate the arguments.
    */
   if (NULL == driveList || NULL == timeout) {
      err = VIX_E_INVALID_ARG;
      Debug("ToolsDaemonTcloSyncDriverFreeze: Failed to get string args\n");
      goto abort;
   }

   if (!StrUtil_StrToInt(&timeoutVal, timeout) || timeoutVal < 0) {
      Debug("ToolsDaemonTcloSyncDriverFreeze: Bad args, timeout '%s'\n", timeout);
      err = VIX_E_INVALID_ARG;
      goto abort;
   }

   Debug("SYNCDRIVE: Got request to freeze '%s', timeout %d\n", driveList,
         timeoutVal);

   /* Disallow multiple freeze calls. */
   if (gSyncDriverHandle != SYNCDRIVER_INVALID_HANDLE) {
      err = VIX_E_OBJECT_IS_BUSY;
      goto abort;
   }

   /* Perform the actual freeze. */
   if (!SyncDriver_Freeze(driveList, &gSyncDriverHandle) ||
       SyncDriver_QueryStatus(gSyncDriverHandle, INFINITE) != SYNCDRIVER_IDLE) {
      Debug("ToolsDaemonTcloSyncDriverFreeze: Failed to Freeze drives '%s'\n",
            driveList);
      err = VIX_E_FAIL;
      sysError = SYNCDRIVERERROR;
      if (gSyncDriverHandle != SYNCDRIVER_INVALID_HANDLE) {
         SyncDriver_Thaw(gSyncDriverHandle);
         SyncDriver_CloseHandle(&gSyncDriverHandle);
      }
      goto abort;
   }

   /* Start the timer callback to automatically thaw. */
   if (0 != timeoutVal) {
      Debug("ToolsDaemonTcloSyncDriverFreeze: Starting timer callback %d\n", timeoutVal);
      timer = g_timeout_source_new(timeoutVal * 10);
      VMTOOLSAPP_ATTACH_SOURCE(ctx, timer, ToolsDaemonSyncDriverThawCallback, NULL, NULL);
      g_source_unref(timer);
   }

abort:
   /*
    * These were allocated by ToolsDaemonTcloGetQuotedString.
    */
   free(driveList);
   free(timeout);

   /*
    * All Foundry tools commands return results that start with a
    * foundry error and a guest-OS-specific error.
    */
   Str_Sprintf(resultBuffer, sizeof resultBuffer, "%"FMT64"d %d", err, sysError);
   Debug("<ToolsDaemonTcloSyncDriverFreeze\n");
   return RPCIN_SETRETVALS(data, resultBuffer, TRUE);
}
コード例 #17
0
gboolean
FoundryToolsDaemonGetToolsProperties(RpcInData *data) // IN
{
   VixError err = VIX_OK;
   int additionalError = 0;
   static char resultBuffer[DEFAULT_RESULT_MSG_MAX_LENGTH];
   char *serializedBuffer = NULL;
   size_t serializedBufferLength = 0;
   char *base64Buffer = NULL;
   size_t base64BufferLength = 0;
   Bool success;
   char *returnBuffer = NULL;
   GKeyFile *confDictRef;
   
   /*
    * Collect some values about the host.
    */
   confDictRef = data->clientData;

   err = VixTools_GetToolsPropertiesImpl(confDictRef,
                                         &serializedBuffer,
                                         &serializedBufferLength);
   if (VIX_OK == err) {
      base64BufferLength = Base64_EncodedLength(serializedBuffer, serializedBufferLength) + 1;
      base64Buffer = Util_SafeMalloc(base64BufferLength);
      success = Base64_Encode(serializedBuffer, 
                              serializedBufferLength, 
                              base64Buffer, 
                              base64BufferLength, 
                              &base64BufferLength);
      if (!success) {
         base64Buffer[0] = 0;
         err = VIX_E_FAIL;
         goto abort;
      }
      base64Buffer[base64BufferLength] = 0;
   }


abort:
   returnBuffer = base64Buffer;
   if (NULL == base64Buffer) {
      returnBuffer = "";
   }
   if (VIX_OK != err) {
      additionalError = Err_Errno();
   }

   /*
    * All VMXI tools commands return results that start with a VMXI error
    * and a guest-OS-specific error.
    */
   Str_Sprintf(resultBuffer,
               sizeof(resultBuffer),
               "%"FMT64"d %d %s",
               err,
               additionalError,
               returnBuffer);
   RPCIN_SETRETVALS(data, resultBuffer, TRUE);

   free(serializedBuffer);
   free(base64Buffer);
   
   return TRUE;
} // FoundryToolsDaemonGetToolsProperties
コード例 #18
0
static gboolean
ResolutionDisplayTopologyModesSetCB(RpcInData *data)
{
   DisplayTopologyInfo *displays = NULL;
   unsigned int count;
   unsigned int i;
   unsigned int cmd;
   unsigned int screen;
   gboolean success = FALSE;
   const char *p;

   g_debug("%s: enter\n", __FUNCTION__);

   /*
    * The argument string will look something like:
    *   <count> <screen> <cmd> [ , <w> <h> ] * count.
    *
    * e.g.
    *    3 0 1, 640 480 , 800 600 , 1024 768
    */

   if (sscanf(data->args, "%u %u %u", &count, &screen, &cmd) != 3) {
      g_debug("%s: invalid arguments\n", __FUNCTION__);
      return RPCIN_SETRETVALS(data,
                              "Invalid arguments. Expected \"count\", \"screen\",  and \"cmd\"",
                              FALSE);
   }

   displays = malloc(sizeof *displays * count);
   if (!displays) {
      g_debug("%s: alloc failed\n", __FUNCTION__);
      RPCIN_SETRETVALS(data,
                       "Failed to alloc buffer for display modes",
                       FALSE);
      goto out;
   }

   for (p = data->args, i = 0; i < count; i++) {
      p = strchr(p, ',');
      if (!p) {
         g_debug("%s: expected comma separated display modes list\n", __FUNCTION__);
         RPCIN_SETRETVALS(data,
                          "Expected comma separated display modes list",
                          FALSE);
         goto out;
      }
      p++; /* Skip past the , */

      if (sscanf(p, " %d %d ", &displays[i].width, &displays[i].height) != 2) {
         g_debug("%s: expected w, h in display modes entry\n", __FUNCTION__);
         RPCIN_SETRETVALS(data,
                          "Expected w, h in display modes entry",
                          FALSE);
         goto out;
      }
   }

   success = ResolutionSetTopologyModes(screen, cmd, count, displays);

   RPCIN_SETRETVALS(data, success ? "" : "ResolutionSetTopologyModes failed", success);

out:
   free(displays);
   g_debug("%s: leave\n", __FUNCTION__);
   return success;
}
コード例 #19
0
ファイル: rpcChannel.c プロジェクト: nf-mlo/open-vm-tools
static gboolean
RpcChannelPing(RpcInData *data)
{
   return RPCIN_SETRETVALS(data, "", TRUE);
}