static Bool VMGuestLibIoctl(const GuestLibIoctlParam *param, char **reply, size_t *replySize) { XDR xdrs; Bool ret; static const char *request = VMGUESTLIB_IOCTL_COMMAND_STRING " "; if (param == NULL || param->d >= GUESTLIB_IOCTL_MAX) { return FALSE; } if (NULL == DynXdr_Create(&xdrs)) { return FALSE; } if (!DynXdr_AppendRaw(&xdrs, request, strlen(request)) || !xdr_GuestLibIoctlParam(&xdrs, (GuestLibIoctlParam *)param)) { DynXdr_Destroy(&xdrs, TRUE); return FALSE; } ret = RpcChannel_SendOneRaw(DynXdr_Get(&xdrs), xdr_getpos(&xdrs), reply, replySize); DynXdr_Destroy(&xdrs, TRUE); return ret; }
gboolean RpcChannel_BuildXdrCommand(const char *cmd, void *xdrProc, void *xdrData, char **result, size_t *resultLen) { Bool ret = FALSE; xdrproc_t proc = xdrProc; XDR xdrs; if (DynXdr_Create(&xdrs) == NULL) { return FALSE; } if (!DynXdr_AppendRaw(&xdrs, cmd, strlen(cmd))) { goto exit; } if (!DynXdr_AppendRaw(&xdrs, " ", 1)) { goto exit; } if (!proc(&xdrs, xdrData)) { goto exit; } *result = DynXdr_Get(&xdrs); *resultLen = xdr_getpos(&xdrs); ret = TRUE; exit: DynXdr_Destroy(&xdrs, !ret); return ret; }
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(©, data, sizeof copy); } ret = rpc->callback(©); 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; }