/generator/generator
/generator/stamp-generator
/install-sh
+/lib/call.c
/lib/free_structs.c
-/lib/internal-procs.h
/lib/internal-procs.c
-/lib/proto-xdr-impl.c
+/lib/internal-procs.h
+/lib/internal-procs-lookup.c
+/lib/internal-procs-lookup.gperf
/lib/wrappi.h
+/lib/xdr.c
/libtool
/local*
/ltmain.sh
dnl Check support for 64 bit file offsets.
AC_SYS_LARGEFILE
+dnl Check for gperf.
+AC_CHECK_PROG([GPERF],[gperf],[gperf],[no])
+test "x$GPERF" = "xno" &&
+ AC_MSG_ERROR([gperf must be installed])
+
dnl Check for OCaml compiler.
AC_PROG_OCAML
if test "$OCAMLC" = "no"; then
wrappid_SOURCES = \
../lib/wrappi.h \
- ../lib/internal.h \
- ../lib/internal-procs.h \
../lib/proto-xdr.h \
+ ../lib/proto-xdr.c \
wrappid.c
wrappid_CFLAGS = -I../lib $(WARN_CFLAGS) $(WERROR_CFLAGS)
wrappid_LDADD = ../lib/libwrappi.la
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <rpc/xdr.h>
#include "wrappi.h"
-
-/* XXX XDR code should be in its own mini-library.
- * OR we should export a way to serialize function calls.
- */
-#include "internal.h"
+#include "../lib/proto-xdr.h"
static void main_loop (void);
main_loop (void)
{
XDR xdr;
- xdrproc_t xdrp_args;
- xdrproc_t xdrp_ret;
struct wrap_int_message_header hdr;
struct wrap_int_message_error err;
- size_t i;
+ xdrproc_t args_xdrproc;
+ xdrproc_t ret_xdrproc;
+ void *argsv, *retv;
for (;;) {
/* Receive the request header. */
memset (&hdr, 0, sizeof hdr);
if (!wrap_int_xdr_message_header (&xdr, &hdr)) {
fprintf (stderr, "error receiving request header\n");
+ xdr_destroy (&xdr);
return;
}
if (hdr.magic != WRAP_INT_PROTO_MAGIC) {
fprintf (stderr, "error in request: unexpected magic (%x)\n",
hdr.magic);
- return;
+ xdr_destroy (&xdr);
+ return;
}
if (hdr.protocol != WRAP_INT_PROTOCOL) {
fprintf (stderr, "error in request: unexpected protocol number (%d)\n",
hdr.protocol);
+ xdr_destroy (&xdr);
return;
}
if (hdr.type != WRAP_INT_PROTO_TYPE_REQUEST) {
fprintf (stderr, "error in request: unexpected type (%d)\n",
hdr.type);
+ xdr_destroy (&xdr);
return;
}
- /* Convert the proc name to the internal entry point. */
- /* XXX We're going to use gperf here, as we do in libguestfs. */
- for (i = 0; i < wrap_int_nr_procs; ++i) {
- if (STREQ (wrap_int_proc_table[i].name, hdr.proc))
- goto found;
+ args_xdrproc = wrap_call_get_args_xdrproc (w, hdr.proc);
+ if (wrap_error (w)) {
+ xdr_destroy (&xdr);
+ return;
+ }
+ ret_xdrproc = wrap_call_get_ret_xdrproc (w, hdr.proc);
+ if (wrap_error (w)) {
+ xdr_destroy (&xdr);
+ return;
}
- fprintf (stderr, "unknown proc name in request: %s\n", hdr.proc);
- exit (EXIT_FAILURE);
- found:
- xdrp_args = wrap_int_proc_table[i].xdr_args;
- assert (xdrp_args);
- xdrp_ret = wrap_int_proc_table[i].xdr_ret;
- assert (xdrp_ret);
+ argsv = calloc (1, wrap_call_get_args_struct_size (w, hdr.proc));
+ if (argsv == NULL) {
+ perror ("malloc");
+ exit (EXIT_FAILURE);
+ }
+ retv = calloc (1, wrap_call_get_ret_struct_size (w, hdr.proc));
+ if (retv == NULL) {
+ perror ("malloc");
+ exit (EXIT_FAILURE);
+ }
/* Receive the arguments. */
-
+ if (!args_xdrproc (&xdr, argsv)) {
+ fprintf (stderr, "error receiving request arguments\n");
+ xdr_destroy (&xdr);
+ free (argsv);
+ free (retv);
+ return;
+ }
+
+ xdr_destroy (&xdr);
+
+ /* Call the underlying API. */
+ wrap_call (w, hdr.proc, argsv, retv);
+ free (argsv);
+ xdrstdio_create (&xdr, stdout, XDR_ENCODE);
+ if (! wrap_error (w)) {
+ /* Send back a normal reply. */
+ hdr.type = WRAP_INT_PROTO_TYPE_REPLY;
+
+ if (!wrap_int_xdr_message_header (&xdr, &hdr)) {
+ fprintf (stderr, "error sending reply header\n");
+ xdr_destroy (&xdr);
+ free (retv);
+ return;
+ }
+
+ if (!ret_xdrproc (&xdr, retv)) {
+ fprintf (stderr, "error sending reply return value\n");
+ xdr_destroy (&xdr);
+ free (retv);
+ return;
+ }
+ }
+ else {
+ /* Send back an error reply. */
+ err.error_message = (char *) wrap_get_error (w);
+ err.error_func = (char *) wrap_get_error_func (w);
+ err.error_errno = (char *) ""; /* XXX set this properly */
+
+ hdr.type = WRAP_INT_PROTO_TYPE_ERROR;
+
+ if (!wrap_int_xdr_message_header (&xdr, &hdr)) {
+ fprintf (stderr, "error sending reply error header\n");
+ xdr_destroy (&xdr);
+ free (retv);
+ return;
+ }
+
+ if (!wrap_int_xdr_message_error (&xdr, &err)) {
+ fprintf (stderr, "error sending reply error struct\n");
+ xdr_destroy (&xdr);
+ free (retv);
+ return;
+ }
+ }
+ free (retv);
+ xdr_destroy (&xdr);
+ xdr_free ((xdrproc_t) wrap_int_xdr_message_header, (void *) &hdr);
}
}
pr "\
+/* C API introspection. */
+";
+ iter_entry_points api (
+ fun ep ->
+ let name = ep.ep_name in
+ let ret, req, opt = ep.ep_ftype in
+
+ pr "struct wrap_%s_args {\n" name;
+ List.iter (
+ fun (n, t, _) ->
+ let t = c_of_ptype ~param:true t in
+ let sep = (* "const char *" - omit space after asterisk *)
+ let len = String.length t in
+ if isalnum t.[len-1] then " " else "" in
+ pr " %s%s%s;\n" t sep n
+ ) req;
+ pr "};\n";
+ pr "\n";
+
+ if opt <> [] then assert false; (* XXX not implemented *)
+
+ pr "struct wrap_%s_ret {\n" name;
+ (match ret with
+ | RVoid -> ()
+ | RStaticString -> pr " const char *r;\n";
+ | Return t ->
+ let t = c_of_ptype ~param:false t in
+ let sep = (* "const char *" - omit space after asterisk *)
+ let len = String.length t in
+ if isalnum t.[len-1] then " " else "" in
+ pr " %s%sr;\n" t sep
+ );
+
+ pr "};\n";
+ pr "\n";
+ );
+
+ pr "\
+extern void wrap_call (wrap_h *w, const char *name, const void *args, void *ret);
+extern size_t wrap_call_get_args_struct_size (wrap_h *w, const char *name);
+extern size_t wrap_call_get_ret_struct_size (wrap_h *w, const char *name);
+extern /* xdrproc_t */ void *wrap_call_get_args_xdrproc (wrap_h *w, const char *name);
+extern /* xdrproc_t */ void *wrap_call_get_ret_xdrproc (wrap_h *w, const char *name);
+
#ifdef __cplusplus
}
#endif
#endif /* WRAPPI_H_ */
"
+let generate_lib_call_c api =
+ generate_header inputs CStyle LGPLv2plus;
+
+ pr "\
+#include <config.h>
+
+#include <stdio.h>
+
+#include \"wrappi.h\"
+#include \"internal.h\"
+
+void
+wrap_call (wrap_h *w, const char *name, const void *args, void *ret)
+{
+ int proc;
+
+ proc = wrap_int_lookup_proc_entry (name);
+ if (proc == -1) {
+ set_error (\"procedure not found: %%s\", name);
+ return;
+ }
+
+ /* This ends up calling wrap_int_call_<name>. */
+ wrap_int_proc_table[proc].call (w, args, ret);
+}
+
+size_t
+wrap_call_get_args_struct_size (wrap_h *w, const char *name)
+{
+ int proc;
+
+ proc = wrap_int_lookup_proc_entry (name);
+ if (proc == -1) {
+ set_error (\"procedure not found: %%s\", name);
+ return 0;
+ }
+
+ return wrap_int_proc_table[proc].args_struct_size;
+}
+
+size_t
+wrap_call_get_ret_struct_size (wrap_h *w, const char *name)
+{
+ int proc;
+
+ proc = wrap_int_lookup_proc_entry (name);
+ if (proc == -1) {
+ set_error (\"procedure not found: %%s\", name);
+ return 0;
+ }
+
+ return wrap_int_proc_table[proc].ret_struct_size;
+}
+
+/* Really this returns xdrproc_t but we don't want to have to include
+ * XDR headers in the public API.
+ */
+void *
+wrap_call_get_args_xdrproc (wrap_h *w, const char *name)
+{
+ int proc;
+
+ proc = wrap_int_lookup_proc_entry (name);
+ if (proc == -1) {
+ set_error (\"procedure not found: %%s\", name);
+ return 0;
+ }
+
+ return wrap_int_proc_table[proc].args_xdrproc;
+}
+
+/* Really this returns xdrproc_t but we don't want to have to include
+ * XDR headers in the public API.
+ */
+void *
+wrap_call_get_ret_xdrproc (wrap_h *w, const char *name)
+{
+ int proc;
+
+ proc = wrap_int_lookup_proc_entry (name);
+ if (proc == -1) {
+ set_error (\"procedure not found: %%s\", name);
+ return 0;
+ }
+
+ return wrap_int_proc_table[proc].ret_xdrproc;
+}
+";
+
+ iter_entry_points api (
+ fun ep ->
+ pr "\n";
+
+ let name = ep.ep_name in
+ let ret, req, opt = ep.ep_ftype in
+
+ pr "void\n";
+ pr "wrap_int_call_%s (wrap_h *w, const void *argsv, void *retv)\n" name;
+ pr "{\n";
+ if req <> [] || opt <> [] then
+ pr " const struct wrap_%s_args *args = argsv;\n" name;
+ if ret <> RVoid then
+ pr " struct wrap_%s_ret *ret = retv;\n" name;
+ pr "\n";
+
+ pr " ";
+ (match ret with
+ | RVoid -> ()
+ | _ -> pr "ret->r = "
+ );
+
+ pr "wrap_%s (w" name;
+ List.iter (fun (n, _, _) -> pr ", args->%s" n) req;
+
+ if opt <> [] then assert false; (* XXX not implemented *)
+
+ pr ");\n";
+ pr "}\n";
+ )
+
(* Functions for freeing structs are part of the C bindings. We don't
* want them to be exposed in other languages, although they will be
* used by other bindings.
generate_header inputs CStyle LGPLv2plus;
pr "\
+#include <config.h>
+
#include <stdlib.h>
#include \"wrappi.h\"
let generate api =
output_to "lib/wrappi.h" generate_lib_wrappi_h api;
+ output_to "lib/call.c" generate_lib_call_c api;
output_to "lib/free_structs.c" generate_lib_free_structs_c api
pr " } else {\n";
pr " /* Remote connection. */\n";
- pr " struct wrap_int_%s_args args;\n" name;
- pr " struct wrap_int_%s_ret ret;\n" name;
+ pr " struct wrap_%s_args args;\n" name;
+ pr " struct wrap_%s_ret ret;\n" name;
pr "\n";
List.iter (fun (n, _, _) -> pr " args.%s = %s;\n" n n) req;
pr "#define wrap_int_nr_procs %d\n" (StringMap.cardinal api.api_entry_points);
pr "\n";
+ pr "#endif /* WRAPPI_INTERNAL_PROCS_H_ */\n"
+
+let generate_lib_internal_procs_c api =
+ generate_header inputs CStyle LGPLv2plus;
pr "\
-/* These structures are used as the first stage of marshalling
- * arguments and return types of entry points. It is much more
- * convenient to be able to pass around one of these structs,
- * than to have to pass a variable list of arguments. They must
- * not be exposed externally.
- */
+#include <config.h>
+
+#include <stdlib.h>
+
+#include \"wrappi.h\"
+#include \"internal.h\"
+
+/* Defined in lib/call.c */
";
iter_entry_points api (
fun ep ->
- let name = ep.ep_name in
- let ret, req, opt = ep.ep_ftype in
-
- pr "struct wrap_int_%s_args {\n" name;
- List.iter (
- fun (n, t, _) ->
- let t = c_of_ptype ~param:true t in
- let sep = (* "const char *" - omit space after asterisk *)
- let len = String.length t in
- if isalnum t.[len-1] then " " else "" in
- pr " %s%s%s;\n" t sep n
- ) req;
- pr "};\n";
- pr "\n";
+ pr "extern void wrap_int_call_%s (wrap_h *w, const void *args, void *ret);\n" ep.ep_name
+ );
+ pr "\n";
- if opt <> [] then assert false; (* XXX not implemented *)
-
- pr "struct wrap_int_%s_ret {\n" name;
- (match ret with
- | RVoid -> ()
- | RStaticString -> pr " const char *r;\n";
- | Return t ->
- let t = c_of_ptype ~param:false t in
- let sep = (* "const char *" - omit space after asterisk *)
- let len = String.length t in
- if isalnum t.[len-1] then " " else "" in
- pr " %s%sr;\n" t sep
- );
-
- pr "};\n";
- pr "\n";
+ pr "/* Defined in lib/xdr.c */\n";
+
+ iter_entry_points api (
+ fun ep ->
+ let name = ep.ep_name in
+ pr "extern bool_t wrap_int_xdr_%s_args (XDR *, struct wrap_%s_args *);\n" name name;
+ pr "extern bool_t wrap_int_xdr_%s_ret (XDR *, struct wrap_%s_ret *);\n" name name
);
+ pr "\n";
+
+ pr "const struct proc_table wrap_int_proc_table[] = {\n";
iter_entry_points api (
fun ep ->
- if not ep.ep_local then (
- let name = ep.ep_name in
- pr "extern bool_t wrap_int_xdr_%s_args (XDR *, struct wrap_int_%s_args *);\n" name name;
- pr "extern bool_t wrap_int_xdr_%s_ret (XDR *, struct wrap_int_%s_ret *);\n" name name
- )
+ let name = ep.ep_name in
+ pr " [wrap_int_%s_num] = {\n" name;
+ pr " .name = \"%s\",\n" name;
+ pr " .args_struct_size = sizeof (struct wrap_%s_args),\n" name;
+ pr " .ret_struct_size = sizeof (struct wrap_%s_ret),\n" name;
+ pr " .call = &wrap_int_call_%s,\n" name;
+ pr " .args_xdrproc = (xdrproc_t) &wrap_int_xdr_%s_args,\n" name;
+ pr " .ret_xdrproc = (xdrproc_t) &wrap_int_xdr_%s_ret,\n" name;
+ pr " },\n"
);
- pr "\n";
- pr "#endif /* WRAPPI_INTERNAL_PROCS_H_ */\n"
+ pr "};\n"
-let generate_lib_internal_procs_c api =
+let generate_lib_internal_procs_lookup_gperf api =
generate_header inputs CStyle LGPLv2plus;
pr "\
+%%language=ANSI-C
+%%define lookup-function-name wrap_int_gperf_lookup_proc_entry
+%%readonly-tables
+%%null-strings
+
+%%{
+#include <config.h>
+
#include <stdlib.h>
+#include <string.h>
#include \"wrappi.h\"
#include \"internal.h\"
+%%}
-";
+struct proc_entry;
- pr "const struct proc_table wrap_int_proc_table[] = {\n";
+%%%%
+";
iter_entry_points api (
fun ep ->
let name = ep.ep_name in
- pr " [wrap_int_%s_num] = {\n" name;
- pr " .name = \"%s\",\n" name;
- if not ep.ep_local then (
- pr " .xdr_args = (xdrproc_t) &wrap_int_xdr_%s_args,\n" name;
- pr " .xdr_ret = (xdrproc_t) &wrap_int_xdr_%s_ret,\n" name;
- );
- pr " },\n"
- );
-
- pr "};\n"
+ pr "%s, wrap_int_%s_num\n" name name
+ )
(* Make a unique, reproducible filename for each entry point. *)
let filename_of_ep ep =
output_to "lib/internal-procs.c"
generate_lib_internal_procs_c api;
+ output_to "lib/internal-procs-lookup.gperf"
+ generate_lib_internal_procs_lookup_gperf api;
+
output_to "lib/implementation_files.mk"
generate_lib_implementation_files_mk api;
| TUnion uname ->
pr " if (!xdr_union_%s (xdrs, %s)) return FALSE;\n" uname n
-let generate_lib_proto_xdr_impl_c api =
+let generate_lib_xdr_c api =
generate_header inputs CStyle LGPLv2plus;
pr "\
+#include <config.h>
+
#include <stdlib.h>
#include <rpc/xdr.h>
iter_entry_points api (
fun ep ->
- if not ep.ep_local then (
- let name = ep.ep_name in
- let ret, req, opt = ep.ep_ftype in
-
- pr "\n";
- pr "bool_t\n";
- pr "wrap_int_xdr_%s_args (XDR *xdrs, struct wrap_int_%s_args *args)\n"
- name name;
- pr "{\n";
-
- List.iter (
- fun (n, t, _) ->
- pr_xdr_of_ptype (sprintf "args->%s" n) t
- ) req;
-
- if opt <> [] then assert false; (* XXX not implemented *)
-
- pr " return TRUE;\n";
- pr "}\n";
-
- pr "\n";
- pr "bool_t\n";
- pr "wrap_int_xdr_%s_ret (XDR *xdrs, struct wrap_int_%s_ret *ret)\n"
- name name;
- pr "{\n";
-
- (match ret with
- | RVoid -> ()
- | RStaticString ->
- assert false (* RStaticString cannot be used for remote functions. *)
- | Return t ->
- pr_xdr_of_ptype "ret->r" t
- );
-
- pr " return TRUE;\n";
- pr "}\n"
- )
+ let name = ep.ep_name in
+ let ret, req, opt = ep.ep_ftype in
+
+ pr "\n";
+ pr "bool_t\n";
+ pr "wrap_int_xdr_%s_args (XDR *xdrs, struct wrap_%s_args *args)\n"
+ name name;
+ pr "{\n";
+
+ List.iter (
+ fun (n, t, _) ->
+ pr_xdr_of_ptype (sprintf "args->%s" n) t
+ ) req;
+
+ if opt <> [] then assert false; (* XXX not implemented *)
+
+ pr " return TRUE;\n";
+ pr "}\n";
+
+ pr "\n";
+ pr "bool_t\n";
+ pr "wrap_int_xdr_%s_ret (XDR *xdrs, struct wrap_%s_ret *ret)\n"
+ name name;
+ pr "{\n";
+
+ (match ret with
+ | RVoid -> ()
+ | RStaticString ->
+ pr_xdr_of_ptype "ret->r" TString (* XXX is this right? *)
+ | Return t ->
+ pr_xdr_of_ptype "ret->r" t
+ );
+
+ pr " return TRUE;\n";
+ pr "}\n"
)
let generate api =
- output_to "lib/proto-xdr-impl.c" generate_lib_proto_xdr_impl_c api
+ output_to "lib/xdr.c" generate_lib_xdr_c api
libwrappi_la_SOURCES = \
wrappi.h \
wrappi.c \
+ call.c \
connect.c \
free_structs.c \
internal-procs.c \
+ internal-procs-lookup.c \
internal-procs.h \
proto-ssh.c \
proto-xdr.c \
proto-xdr.h \
- proto-xdr-impl.c \
+ proto-xdr-request.c \
+ xdr.c \
$(local_implementation_files) \
$(remote_implementation_files)
libwrappi_la_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS)
+internal-procs-lookup.c: internal-procs-lookup.gperf
+ rm -f $@
+ $(GPERF) -t $< > $@-t
+ mv $@-t $@
+
CLEANFILES = *~
wrap_int_set_error_errno ((struct wrap_internal_h *)w, (errno), __func__, fs)
extern void wrap_int_connect_ssh (wrap_h *w);
+extern int wrap_int_lookup_proc_entry (const char *name);
extern void wrap_int_make_request (wrap_h *w, int proc_nr, const void *args, void *ret);
extern void wrap_int_make_request_xdr (wrap_h *w, int proc_nr, const void *args, void *ret);
extern void wrap_int_set_error (struct wrap_internal_h *w, const char *func, const char *fs, ...);
struct proc_table {
const char *name; /* The name of this entry point. */
+ /* Size of the args and ret structs. */
+ size_t args_struct_size;
+ size_t ret_struct_size;
+
+ /* Call this procedure. */
+ void (*call) (wrap_h *w, const void *args, void *ret);
+
/* XDR encode/decode functions for serializing the args and ret. */
- xdrproc_t xdr_args;
- xdrproc_t xdr_ret;
+ xdrproc_t args_xdrproc;
+ xdrproc_t ret_xdrproc;
};
extern const struct proc_table wrap_int_proc_table[];
#include "internal-procs.h"
+/* Defined and used by lib/internal-procs-lookup.gperf */
+struct proc_entry { char *name; int proc_nr; };
+extern const struct proc_entry *wrap_int_gperf_lookup_proc_entry (register const char *str, register unsigned int len);
+
#endif /* WRAPPI_INTERNAL_H_ */
--- /dev/null
+/* wrappi
+ * Copyright (C) 2011-2012 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <rpc/xdr.h>
+
+#include "wrappi.h"
+#include "internal.h"
+#include "proto-xdr.h"
+
+void
+wrap_int_make_request_xdr (wrap_h *w, int proc_nr, const void *args, void *ret)
+{
+ XDR xdr;
+ xdrproc_t args_xdrproc;
+ xdrproc_t ret_xdrproc;
+ struct wrap_int_message_header hdr;
+ struct wrap_int_message_error err;
+
+ memset (&hdr, 0, sizeof hdr);
+
+ hdr.proc = (char *) wrap_int_proc_table[proc_nr].name;
+ assert (hdr.proc);
+ args_xdrproc = wrap_int_proc_table[proc_nr].args_xdrproc;
+ ret_xdrproc = wrap_int_proc_table[proc_nr].ret_xdrproc;
+
+ /* Construct the header. */
+ w->serial++;
+
+ hdr.magic = WRAP_INT_PROTO_MAGIC;
+ hdr.protocol = WRAP_INT_PROTOCOL;
+ hdr.serial = w->serial;
+ hdr.type = WRAP_INT_PROTO_TYPE_REQUEST;
+
+ /* Send the header. */
+ xdrstdio_create (&xdr, w->wfp, XDR_ENCODE);
+ if (!wrap_int_xdr_message_header (&xdr, &hdr)) {
+ set_error ("error sending request header");
+ xdr_destroy (&xdr);
+ return;
+ }
+
+ /* Send the request arguments. */
+ if (!args_xdrproc (&xdr, (void *) args)) {
+ set_error ("error sending request arguments");
+ xdr_destroy (&xdr);
+ return;
+ }
+ xdr_destroy (&xdr);
+
+ /* Receive the reply header. */
+ xdrstdio_create (&xdr, w->rfp, XDR_DECODE);
+ memset (&hdr, 0, sizeof hdr);
+ if (!wrap_int_xdr_message_header (&xdr, &hdr)) {
+ set_error ("error receiving reply header");
+ xdr_destroy (&xdr);
+ return;
+ }
+
+ /* Check the reply header. */
+ if (hdr.magic != WRAP_INT_PROTO_MAGIC) {
+ set_error ("error in reply: unexpected magic (%x)", hdr.magic);
+ xdr_destroy (&xdr);
+ xdr_free ((xdrproc_t) wrap_int_xdr_message_header, (void *) &hdr);
+ return;
+ }
+ if (hdr.protocol != WRAP_INT_PROTOCOL) {
+ set_error ("error in reply: unexpected protocol number (%d)", hdr.protocol);
+ xdr_destroy (&xdr);
+ xdr_free ((xdrproc_t) wrap_int_xdr_message_header, (void *) &hdr);
+ return;
+ }
+ if (hdr.serial != w->serial) {
+ set_error ("error in reply: unexpected serial (%d)", hdr.serial);
+ xdr_destroy (&xdr);
+ xdr_free ((xdrproc_t) wrap_int_xdr_message_header, (void *) &hdr);
+ return;
+ }
+
+ switch (hdr.type) {
+ case WRAP_INT_PROTO_TYPE_REPLY:
+ /* Receive the return value. */
+ if (!ret_xdrproc (&xdr, (void *) ret)) {
+ set_error ("error receiving return value");
+ xdr_destroy (&xdr);
+ xdr_free ((xdrproc_t) wrap_int_xdr_message_header, (void *) &hdr);
+ return;
+ }
+ break;
+
+ case WRAP_INT_PROTO_TYPE_ERROR:
+ /* Receive the error message etc. */
+ memset (&err, 0, sizeof err);
+ if (!wrap_int_xdr_message_error (&xdr, &err)) {
+ set_error ("error receiving error message");
+ xdr_destroy (&xdr);
+ xdr_free ((xdrproc_t) wrap_int_xdr_message_header, (void *) &hdr);
+ return;
+ }
+
+ /* XXX errno should be converted to an integer here */
+ /* XXX func should be set, but it's not static! */
+ set_error ("%s", err.error_message);
+ xdr_free ((xdrproc_t) wrap_int_xdr_message_error, (void *) &err);
+ xdr_free ((xdrproc_t) wrap_int_xdr_message_header, (void *) &hdr);
+
+ break;
+
+ default:
+ set_error ("error in reply: unexpected type (%x)", hdr.type);
+ xdr_destroy (&xdr);
+ xdr_free ((xdrproc_t) wrap_int_xdr_message_header, (void *) &hdr);
+ return;
+ }
+
+ xdr_destroy (&xdr);
+ xdr_free ((xdrproc_t) wrap_int_xdr_message_header, (void *) &hdr);
+}
#include <assert.h>
#include <rpc/xdr.h>
-#include "wrappi.h"
-#include "internal.h"
#include "proto-xdr.h"
bool_t
return TRUE;
}
-
-void
-wrap_int_make_request_xdr (wrap_h *w, int proc_nr, const void *args, void *ret)
-{
- XDR xdr;
- xdrproc_t xdrp_args;
- xdrproc_t xdrp_ret;
- struct wrap_int_message_header hdr;
- struct wrap_int_message_error err;
-
- memset (&hdr, 0, sizeof hdr);
-
- hdr.proc = (char *) wrap_int_proc_table[proc_nr].name;
- assert (hdr.proc);
- xdrp_args = wrap_int_proc_table[proc_nr].xdr_args;
- assert (xdrp_args);
- xdrp_ret = wrap_int_proc_table[proc_nr].xdr_ret;
- assert (xdrp_ret);
-
- /* Construct the header. */
- w->serial++;
-
- hdr.magic = WRAP_INT_PROTO_MAGIC;
- hdr.protocol = WRAP_INT_PROTOCOL;
- hdr.serial = w->serial;
- hdr.type = WRAP_INT_PROTO_TYPE_REQUEST;
-
- /* Send the header. */
- xdrstdio_create (&xdr, w->wfp, XDR_ENCODE);
- if (!wrap_int_xdr_message_header (&xdr, &hdr)) {
- set_error ("error sending request header");
- xdr_destroy (&xdr);
- return;
- }
-
- /* Send the request arguments. */
- if (!xdrp_args (&xdr, (void *) args)) {
- set_error ("error sending request arguments");
- xdr_destroy (&xdr);
- return;
- }
- xdr_destroy (&xdr);
-
- /* Receive the reply header. */
- xdrstdio_create (&xdr, w->rfp, XDR_DECODE);
- memset (&hdr, 0, sizeof hdr);
- if (!wrap_int_xdr_message_header (&xdr, &hdr)) {
- set_error ("error receiving reply header");
- xdr_destroy (&xdr);
- return;
- }
-
- /* Check the reply header. */
- if (hdr.magic != WRAP_INT_PROTO_MAGIC) {
- set_error ("error in reply: unexpected magic (%x)", hdr.magic);
- xdr_destroy (&xdr);
- return;
- }
- if (hdr.protocol != WRAP_INT_PROTOCOL) {
- set_error ("error in reply: unexpected protocol number (%d)", hdr.protocol);
- xdr_destroy (&xdr);
- return;
- }
- if (hdr.serial != w->serial) {
- set_error ("error in reply: unexpected serial (%d)", hdr.serial);
- xdr_destroy (&xdr);
- return;
- }
-
- switch (hdr.type) {
- case WRAP_INT_PROTO_TYPE_REPLY:
- /* Receive the return value. */
- if (!xdrp_ret (&xdr, (void *) ret)) {
- set_error ("error receiving return value");
- xdr_destroy (&xdr);
- return;
- }
- break;
-
- case WRAP_INT_PROTO_TYPE_ERROR:
- /* Receive the error message etc. */
- memset (&err, 0, sizeof err);
- if (!wrap_int_xdr_message_error (&xdr, &err)) {
- set_error ("error receiving error message");
- xdr_destroy (&xdr);
- return;
- }
-
- /* XXX errno should be converted to an integer here */
- /* XXX func should be set, but it's not static! */
- set_error ("%s", err.error_message);
- xdr_free ((xdrproc_t) wrap_int_xdr_message_error, (void *) &err);
-
- break;
-
- default:
- set_error ("error in reply: unexpected type (%x)", hdr.type);
- xdr_destroy (&xdr);
- return;
- }
-
- xdr_destroy (&xdr);
-}
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifndef PROTO_XDR_H_
-#define PROTO_XDR_H_
+#ifndef WRAPPI_PROTO_XDR_H_
+#define WRAPPI_PROTO_XDR_H_
#include <stdint.h>
-#include <string.h>
-#include <errno.h>
#include <rpc/types.h>
#include <rpc/xdr.h>
extern bool_t wrap_int_xdr_message_header (XDR *, struct wrap_int_message_header *);
extern bool_t wrap_int_xdr_message_error (XDR *, struct wrap_int_message_error *);
-#endif /* WRAPPI_INTERNAL_H_ */
+#endif /* WRAPPI_PROTO_XDR_H_ */
set_error_buf (w, msg, errnum, func);
}
+
+/* Note the gperf perfect hash in lib/internal-procs-lookup.gperf */
+int
+wrap_int_lookup_proc_entry (const char *name)
+{
+ const struct proc_entry *v =
+ wrap_int_gperf_lookup_proc_entry (name, strlen (name));
+ if (v)
+ return v->proc_nr;
+ else
+ return -1;
+}