gboolean RpcChannel_SendOneRaw(const char *data, size_t dataLen, char **result, size_t *resultLen) { RpcChannel *chan; gboolean status; status = FALSE; chan = RpcChannel_New(); if (chan == NULL) { if (result != NULL) { *result = Util_SafeStrdup("RpcChannel: Unable to create " "the RpcChannel object"); if (resultLen != NULL) { *resultLen = strlen(*result); } } goto sent; } else if (!RpcChannel_Start(chan)) { if (result != NULL) { *result = Util_SafeStrdup("RpcChannel: Unable to open the " "communication channel"); if (resultLen != NULL) { *resultLen = strlen(*result); } } goto sent; } else if (!RpcChannel_Send(chan, data, dataLen, result, resultLen)) { /* We already have the description of the error */ goto sent; } status = TRUE; sent: Debug(LGPFX "Request %s: reqlen=%"FMTSZ"u, replyLen=%"FMTSZ"u\n", status ? "OK" : "FAILED", dataLen, resultLen ? *resultLen : 0); if (chan) { RpcChannel_Stop(chan); RpcChannel_Destroy(chan); } return status; }
static gboolean RpcChannelRestart(gpointer _chan) { RpcChannelInt *chan = _chan; RpcChannel_Stop(&chan->impl); if (!RpcChannel_Start(&chan->impl)) { Warning("Channel restart failed [%d]\n", chan->rpcErrorCount); if (chan->resetCb != NULL) { chan->resetCb(&chan->impl, FALSE, chan->resetData); } } else { chan->rpcError = FALSE; } return FALSE; }
gboolean ToolsCmd_SendRPC(const char *rpc, // IN size_t rpcLen, // IN char **result, // OUT size_t *resultLen) // OUT { char *lrpc = (char *) rpc; RpcChannel *chan = BackdoorChannel_New(); gboolean ret = RpcChannel_Start(chan); if (!ret) { g_warning("Error starting RPC channel."); goto exit; } ret = RpcChannel_Send(chan, lrpc, rpcLen, result, resultLen); exit: RpcChannel_Destroy(chan); return ret; }
static int ToolsCoreRunLoop(ToolsServiceState *state) { if (!ToolsCore_InitRpc(state)) { return 1; } /* * Start the RPC channel if it's been created. The channel may be NULL if this is * not running in the context of a VM. */ if (state->ctx.rpc && !RpcChannel_Start(state->ctx.rpc)) { return 1; } if (!ToolsCore_LoadPlugins(state)) { return 1; } /* * The following criteria needs to hold for the main loop to be run: * * . no plugin has requested the service to shut down during initialization. * . we're either on a VMware hypervisor, or running an unknown service name. * . we're running in debug mode. * * In the non-VMware hypervisor case, just exit with a '0' return status (see * bug 297528 for why '0'). */ if (state->ctx.errorCode == 0 && (state->ctx.isVMware || ToolsCore_GetTcloName(state) == NULL || state->debugPlugin != NULL)) { ToolsCore_RegisterPlugins(state); /* * Listen for the I/O freeze signal. We have to disable the config file * check when I/O is frozen or the (Win32) sync driver may cause the service * to hang (and make the VM unusable until it times out). */ if (g_signal_lookup(TOOLS_CORE_SIG_IO_FREEZE, G_OBJECT_TYPE(state->ctx.serviceObj)) != 0) { g_signal_connect(state->ctx.serviceObj, TOOLS_CORE_SIG_IO_FREEZE, G_CALLBACK(ToolsCoreIOFreezeCb), state); } state->configCheckTask = g_timeout_add(CONF_POLL_TIME * 10, ToolsCoreConfFileCb, state); #if defined(__APPLE__) ToolsCore_CFRunLoop(state); #else g_main_loop_run(state->ctx.mainLoop); #endif } ToolsCoreCleanup(state); return state->ctx.errorCode; }
gboolean RpcChannel_Send(RpcChannel *chan, char const *data, size_t dataLen, char **result, size_t *resultLen) { gboolean ok; char *res = NULL; size_t resLen = 0; const RpcChannelFuncs *funcs; Debug(LGPFX "Sending: %"FMTSZ"u bytes\n", dataLen); ASSERT(chan && chan->funcs); g_static_mutex_lock(&chan->outLock); funcs = chan->funcs; ASSERT(funcs->send); if (result != NULL) { *result = NULL; } if (resultLen != NULL) { *resultLen = 0; } ok = funcs->send(chan, data, dataLen, &res, &resLen); if (!ok && (funcs->getType(chan) != RPCCHANNEL_TYPE_BKDOOR) && (funcs->stopRpcOut != NULL)) { free(res); res = NULL; resLen = 0; /* retry once */ Debug(LGPFX "Stop RpcOut channel and try to send again ...\n"); funcs->stopRpcOut(chan); if (RpcChannel_Start(chan)) { /* The channel may get switched from vsocket to backdoor */ funcs = chan->funcs; ASSERT(funcs->send); ok = funcs->send(chan, data, dataLen, &res, &resLen); goto done; } ok = FALSE; goto exit; } done: if (ok) { Debug(LGPFX "Recved %"FMTSZ"u bytes\n", resLen); } if (result != NULL) { *result = res; } if (resultLen != NULL) { *resultLen = resLen; } exit: g_static_mutex_unlock(&chan->outLock); return ok; }