+ async_rpc_write(req->connection, (const char *)&fragment, sizeof(fragment));
+ async_rpc_write(req->connection, (const char *)&header, sizeof(header));
+ g_io_channel_flush(req->connection->channel, NULL);
+
+ if (req->args != NULL) {
+ char buf[4];
+ XDR xdr;
+ xdrmem_create(&xdr, buf, sizeof(buf), XDR_FREE);
+ if (!req->xdr_args_free(&xdr, req->args)) {
+ fprintf(stderr, "unable to free arguments");
+ }
+ }
+
+ if (req->raw_args != NULL)
+ g_string_free(req->raw_args, TRUE);
+
+ g_free(req);
+}
+
+void
+async_rpc_send_reply(RPCRequest *req, void *result)
+{
+ GString *str = g_string_new("");
+ XDR xdr_out;
+ xdr_string_create(&xdr_out, str, XDR_ENCODE);
+ if (!req->xdr_result(&xdr_out, result)) {
+ async_rpc_send_failure(req, SYSTEM_ERR);
+ g_string_free(str, TRUE);
+ return;
+ }
+
+ struct rpc_reply header;
+ header.xid = htonl(req->xid);
+ header.type = htonl(1); /* REPLY */
+ header.stat = htonl(MSG_ACCEPTED);
+ header.verf_flavor = 0;
+ header.verf_len = 0;
+ header.accept_stat = 0;
+
+ gsize msg_size = str->len;
+ uint32_t fragment = htonl((msg_size + sizeof(header)) | 0x80000000);
+ async_rpc_write(req->connection, (const char *)&fragment, sizeof(fragment));
+ async_rpc_write(req->connection, (const char *)&header, sizeof(header));
+ async_rpc_write(req->connection, str->str, str->len);
+ g_io_channel_flush(req->connection->channel, NULL);
+
+ /* Clean up. */
+ g_string_free(str, TRUE);
+
+ if (req->args != NULL) {
+ char buf[4];
+ XDR xdr;
+ xdrmem_create(&xdr, buf, sizeof(buf), XDR_FREE);
+ if (!req->xdr_args_free(&xdr, req->args)) {
+ fprintf(stderr, "unable to free arguments");
+ }
+ }
+
+ if (req->raw_args != NULL)
+ g_string_free(req->raw_args, TRUE);
+
+ g_free(req);