* [RFC] Switching from glibc RPC to TI RPC
@ 2013-03-20 9:37 Marcin Juszkiewicz
2013-03-20 9:37 ` [PATCH 1/6] eglibc: disable RPC in favour of libtirpc Marcin Juszkiewicz
` (6 more replies)
0 siblings, 7 replies; 14+ messages in thread
From: Marcin Juszkiewicz @ 2013-03-20 9:37 UTC (permalink / raw)
To: openembedded-core
The main reasons for me to write this email were decissions made by
Linaro Toolchain WG when they started building AArch64 cross toolchains.
One of them was disabling RPC support in glibc as it is marked obsolete.
So I had two ways of handling it:
- add RPC back into glibc in Linaro's cross toolchain
- check how to switch OpenEmbedded to TI RPC
This patch series is my attempt for the latter. I disabled RPC in
eglibc, expanded libtirpc with code taken from glibc (patchset taken
from OpenMandriva distribution) and then went though build failures.
MOUNT_NFS in busybox is not needed on 2.6.23 Linux kernels and is the
only part of code which requires RPC. I assumed that OE does not support
such old kernels nowadays.
nfs-utils already had libtirpc support which just needed to be enabled.
quota needed to be told how to find out RPC headers and how to link with
libtirpc.
rpcbind needed removal of yellow pages support (whatever it is). I took
patch from Buildroot.
So far I did builds only for AArch64 but not checked 'on target'. Please
take a look and tell me does this work will be useful at all before I go
into other recipes.
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 1/6] eglibc: disable RPC in favour of libtirpc
2013-03-20 9:37 [RFC] Switching from glibc RPC to TI RPC Marcin Juszkiewicz
@ 2013-03-20 9:37 ` Marcin Juszkiewicz
2013-03-20 14:05 ` Khem Raj
2013-03-20 9:37 ` [PATCH 2/6] libtirpc: add RPC parts from glibc - patches from OpenMandriva Marcin Juszkiewicz
` (5 subsequent siblings)
6 siblings, 1 reply; 14+ messages in thread
From: Marcin Juszkiewicz @ 2013-03-20 9:37 UTC (permalink / raw)
To: openembedded-core
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
---
meta/recipes-core/eglibc/eglibc_2.17.bb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/meta/recipes-core/eglibc/eglibc_2.17.bb b/meta/recipes-core/eglibc/eglibc_2.17.bb
index 22129e6..0853c08 100644
--- a/meta/recipes-core/eglibc/eglibc_2.17.bb
+++ b/meta/recipes-core/eglibc/eglibc_2.17.bb
@@ -85,7 +85,7 @@ EXTRA_OECONF = "--enable-kernel=${OLDEST_KERNEL} \
--enable-add-ons \
--with-headers=${STAGING_INCDIR} \
--without-selinux \
- --enable-obsolete-rpc \
+ --disable-obsolete-rpc \
--with-kconfig=${STAGING_BINDIR_NATIVE} \
${GLIBC_EXTRA_OECONF}"
--
1.8.1.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 2/6] libtirpc: add RPC parts from glibc - patches from OpenMandriva
2013-03-20 9:37 [RFC] Switching from glibc RPC to TI RPC Marcin Juszkiewicz
2013-03-20 9:37 ` [PATCH 1/6] eglibc: disable RPC in favour of libtirpc Marcin Juszkiewicz
@ 2013-03-20 9:37 ` Marcin Juszkiewicz
2013-03-20 9:37 ` [PATCH 3/6] busybox: disable MOUNT_NFS option - not needed on 2.6.23+ kernels Marcin Juszkiewicz
` (4 subsequent siblings)
6 siblings, 0 replies; 14+ messages in thread
From: Marcin Juszkiewicz @ 2013-03-20 9:37 UTC (permalink / raw)
To: openembedded-core
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
---
.../libtirpc/libtirpc-0.2.3/key_prot.h | 343 ++
...ibtirpc-0.2.3-add-missing-bits-from-glibc.patch | 1766 ++++++
.../libtirpc-0.2.3/libtirpc-0.2.3-types.h.patch | 14 +
...Add-rpcgen-program-from-nfs-utils-sources.patch | 6408 ++++++++++++++++++++
.../recipes-extended/libtirpc/libtirpc-0.2.3/nis.h | 616 ++
.../libtirpc/libtirpc-0.2.3/nis_tags.h | 129 +
.../libtirpc/libtirpc-0.2.3/nislib.h | 288 +
.../libtirpc/libtirpc-0.2.3/rpc_des.h | 71 +
.../libtirpc/libtirpc-0.2.3/yp_prot.h | 366 ++
.../libtirpc/libtirpc-0.2.3/ypclnt.h | 89 +
meta/recipes-extended/libtirpc/libtirpc_0.2.3.bb | 35 +-
11 files changed, 10121 insertions(+), 4 deletions(-)
create mode 100644 meta/recipes-extended/libtirpc/libtirpc-0.2.3/key_prot.h
create mode 100644 meta/recipes-extended/libtirpc/libtirpc-0.2.3/libtirpc-0.2.3-add-missing-bits-from-glibc.patch
create mode 100644 meta/recipes-extended/libtirpc/libtirpc-0.2.3/libtirpc-0.2.3-types.h.patch
create mode 100644 meta/recipes-extended/libtirpc/libtirpc-0.2.3/libtirpc-0008-Add-rpcgen-program-from-nfs-utils-sources.patch
create mode 100644 meta/recipes-extended/libtirpc/libtirpc-0.2.3/nis.h
create mode 100644 meta/recipes-extended/libtirpc/libtirpc-0.2.3/nis_tags.h
create mode 100644 meta/recipes-extended/libtirpc/libtirpc-0.2.3/nislib.h
create mode 100644 meta/recipes-extended/libtirpc/libtirpc-0.2.3/rpc_des.h
create mode 100644 meta/recipes-extended/libtirpc/libtirpc-0.2.3/yp_prot.h
create mode 100644 meta/recipes-extended/libtirpc/libtirpc-0.2.3/ypclnt.h
diff --git a/meta/recipes-extended/libtirpc/libtirpc-0.2.3/key_prot.h b/meta/recipes-extended/libtirpc/libtirpc-0.2.3/key_prot.h
new file mode 100644
index 0000000..74627e6
--- /dev/null
+++ b/meta/recipes-extended/libtirpc/libtirpc-0.2.3/key_prot.h
@@ -0,0 +1,343 @@
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#ifndef _KEY_PROT_H_RPCGEN
+#define _KEY_PROT_H_RPCGEN
+
+#include <rpc/rpc.h>
+
+/* Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Compiled from key_prot.x using rpcgen.
+ * DO NOT EDIT THIS FILE!
+ * This is NOT source code!
+ */
+#define PROOT 3
+#define HEXMODULUS "d4a0ba0250b6fd2ec626e7efd637df76c716e22d0944b88b"
+#define HEXKEYBYTES 48
+#define KEYSIZE 192
+#define KEYBYTES 24
+#define KEYCHECKSUMSIZE 16
+
+enum keystatus {
+ KEY_SUCCESS = 0,
+ KEY_NOSECRET = 1,
+ KEY_UNKNOWN = 2,
+ KEY_SYSTEMERR = 3,
+};
+typedef enum keystatus keystatus;
+#ifdef __cplusplus
+extern "C" bool_t xdr_keystatus(XDR *, keystatus*);
+#elif __STDC__
+extern bool_t xdr_keystatus(XDR *, keystatus*);
+#else /* Old Style C */
+bool_t xdr_keystatus();
+#endif /* Old Style C */
+
+
+typedef char keybuf[HEXKEYBYTES];
+#ifdef __cplusplus
+extern "C" bool_t xdr_keybuf(XDR *, keybuf);
+#elif __STDC__
+extern bool_t xdr_keybuf(XDR *, keybuf);
+#else /* Old Style C */
+bool_t xdr_keybuf();
+#endif /* Old Style C */
+
+
+typedef char *netnamestr;
+#ifdef __cplusplus
+extern "C" bool_t xdr_netnamestr(XDR *, netnamestr*);
+#elif __STDC__
+extern bool_t xdr_netnamestr(XDR *, netnamestr*);
+#else /* Old Style C */
+bool_t xdr_netnamestr();
+#endif /* Old Style C */
+
+
+struct cryptkeyarg {
+ netnamestr remotename;
+ des_block deskey;
+};
+typedef struct cryptkeyarg cryptkeyarg;
+#ifdef __cplusplus
+extern "C" bool_t xdr_cryptkeyarg(XDR *, cryptkeyarg*);
+#elif __STDC__
+extern bool_t xdr_cryptkeyarg(XDR *, cryptkeyarg*);
+#else /* Old Style C */
+bool_t xdr_cryptkeyarg();
+#endif /* Old Style C */
+
+
+struct cryptkeyarg2 {
+ netnamestr remotename;
+ netobj remotekey;
+ des_block deskey;
+};
+typedef struct cryptkeyarg2 cryptkeyarg2;
+#ifdef __cplusplus
+extern "C" bool_t xdr_cryptkeyarg2(XDR *, cryptkeyarg2*);
+#elif __STDC__
+extern bool_t xdr_cryptkeyarg2(XDR *, cryptkeyarg2*);
+#else /* Old Style C */
+bool_t xdr_cryptkeyarg2();
+#endif /* Old Style C */
+
+
+struct cryptkeyres {
+ keystatus status;
+ union {
+ des_block deskey;
+ } cryptkeyres_u;
+};
+typedef struct cryptkeyres cryptkeyres;
+#ifdef __cplusplus
+extern "C" bool_t xdr_cryptkeyres(XDR *, cryptkeyres*);
+#elif __STDC__
+extern bool_t xdr_cryptkeyres(XDR *, cryptkeyres*);
+#else /* Old Style C */
+bool_t xdr_cryptkeyres();
+#endif /* Old Style C */
+
+#define MAXGIDS 16
+
+struct unixcred {
+ u_int uid;
+ u_int gid;
+ struct {
+ u_int gids_len;
+ u_int *gids_val;
+ } gids;
+};
+typedef struct unixcred unixcred;
+#ifdef __cplusplus
+extern "C" bool_t xdr_unixcred(XDR *, unixcred*);
+#elif __STDC__
+extern bool_t xdr_unixcred(XDR *, unixcred*);
+#else /* Old Style C */
+bool_t xdr_unixcred();
+#endif /* Old Style C */
+
+
+struct getcredres {
+ keystatus status;
+ union {
+ unixcred cred;
+ } getcredres_u;
+};
+typedef struct getcredres getcredres;
+#ifdef __cplusplus
+extern "C" bool_t xdr_getcredres(XDR *, getcredres*);
+#elif __STDC__
+extern bool_t xdr_getcredres(XDR *, getcredres*);
+#else /* Old Style C */
+bool_t xdr_getcredres();
+#endif /* Old Style C */
+
+
+struct key_netstarg {
+ keybuf st_priv_key;
+ keybuf st_pub_key;
+ netnamestr st_netname;
+};
+typedef struct key_netstarg key_netstarg;
+#ifdef __cplusplus
+extern "C" bool_t xdr_key_netstarg(XDR *, key_netstarg*);
+#elif __STDC__
+extern bool_t xdr_key_netstarg(XDR *, key_netstarg*);
+#else /* Old Style C */
+bool_t xdr_key_netstarg();
+#endif /* Old Style C */
+
+
+struct key_netstres {
+ keystatus status;
+ union {
+ key_netstarg knet;
+ } key_netstres_u;
+};
+typedef struct key_netstres key_netstres;
+#ifdef __cplusplus
+extern "C" bool_t xdr_key_netstres(XDR *, key_netstres*);
+#elif __STDC__
+extern bool_t xdr_key_netstres(XDR *, key_netstres*);
+#else /* Old Style C */
+bool_t xdr_key_netstres();
+#endif /* Old Style C */
+
+
+#ifndef opaque
+#define opaque char
+#endif
+
+
+#define KEY_PROG ((u_long)100029)
+#define KEY_VERS ((u_long)1)
+
+#ifdef __cplusplus
+#define KEY_SET ((u_long)1)
+extern "C" keystatus * key_set_1(opaque *, CLIENT *);
+extern "C" keystatus * key_set_1_svc(opaque *, struct svc_req *);
+#define KEY_ENCRYPT ((u_long)2)
+extern "C" cryptkeyres * key_encrypt_1(cryptkeyarg *, CLIENT *);
+extern "C" cryptkeyres * key_encrypt_1_svc(cryptkeyarg *, struct svc_req *);
+#define KEY_DECRYPT ((u_long)3)
+extern "C" cryptkeyres * key_decrypt_1(cryptkeyarg *, CLIENT *);
+extern "C" cryptkeyres * key_decrypt_1_svc(cryptkeyarg *, struct svc_req *);
+#define KEY_GEN ((u_long)4)
+extern "C" des_block * key_gen_1(void *, CLIENT *);
+extern "C" des_block * key_gen_1_svc(void *, struct svc_req *);
+#define KEY_GETCRED ((u_long)5)
+extern "C" getcredres * key_getcred_1(netnamestr *, CLIENT *);
+extern "C" getcredres * key_getcred_1_svc(netnamestr *, struct svc_req *);
+
+#elif __STDC__
+#define KEY_SET ((u_long)1)
+extern keystatus * key_set_1(opaque *, CLIENT *);
+extern keystatus * key_set_1_svc(opaque *, struct svc_req *);
+#define KEY_ENCRYPT ((u_long)2)
+extern cryptkeyres * key_encrypt_1(cryptkeyarg *, CLIENT *);
+extern cryptkeyres * key_encrypt_1_svc(cryptkeyarg *, struct svc_req *);
+#define KEY_DECRYPT ((u_long)3)
+extern cryptkeyres * key_decrypt_1(cryptkeyarg *, CLIENT *);
+extern cryptkeyres * key_decrypt_1_svc(cryptkeyarg *, struct svc_req *);
+#define KEY_GEN ((u_long)4)
+extern des_block * key_gen_1(void *, CLIENT *);
+extern des_block * key_gen_1_svc(void *, struct svc_req *);
+#define KEY_GETCRED ((u_long)5)
+extern getcredres * key_getcred_1(netnamestr *, CLIENT *);
+extern getcredres * key_getcred_1_svc(netnamestr *, struct svc_req *);
+
+#else /* Old Style C */
+#define KEY_SET ((u_long)1)
+extern keystatus * key_set_1();
+extern keystatus * key_set_1_svc();
+#define KEY_ENCRYPT ((u_long)2)
+extern cryptkeyres * key_encrypt_1();
+extern cryptkeyres * key_encrypt_1_svc();
+#define KEY_DECRYPT ((u_long)3)
+extern cryptkeyres * key_decrypt_1();
+extern cryptkeyres * key_decrypt_1_svc();
+#define KEY_GEN ((u_long)4)
+extern des_block * key_gen_1();
+extern des_block * key_gen_1_svc();
+#define KEY_GETCRED ((u_long)5)
+extern getcredres * key_getcred_1();
+extern getcredres * key_getcred_1_svc();
+#endif /* Old Style C */
+#define KEY_VERS2 ((u_long)2)
+
+#ifdef __cplusplus
+extern "C" keystatus * key_set_2(opaque *, CLIENT *);
+extern "C" keystatus * key_set_2_svc(opaque *, struct svc_req *);
+extern "C" cryptkeyres * key_encrypt_2(cryptkeyarg *, CLIENT *);
+extern "C" cryptkeyres * key_encrypt_2_svc(cryptkeyarg *, struct svc_req *);
+extern "C" cryptkeyres * key_decrypt_2(cryptkeyarg *, CLIENT *);
+extern "C" cryptkeyres * key_decrypt_2_svc(cryptkeyarg *, struct svc_req *);
+extern "C" des_block * key_gen_2(void *, CLIENT *);
+extern "C" des_block * key_gen_2_svc(void *, struct svc_req *);
+extern "C" getcredres * key_getcred_2(netnamestr *, CLIENT *);
+extern "C" getcredres * key_getcred_2_svc(netnamestr *, struct svc_req *);
+#define KEY_ENCRYPT_PK ((u_long)6)
+extern "C" cryptkeyres * key_encrypt_pk_2(cryptkeyarg2 *, CLIENT *);
+extern "C" cryptkeyres * key_encrypt_pk_2_svc(cryptkeyarg2 *, struct svc_req *);
+#define KEY_DECRYPT_PK ((u_long)7)
+extern "C" cryptkeyres * key_decrypt_pk_2(cryptkeyarg2 *, CLIENT *);
+extern "C" cryptkeyres * key_decrypt_pk_2_svc(cryptkeyarg2 *, struct svc_req *);
+#define KEY_NET_PUT ((u_long)8)
+extern "C" keystatus * key_net_put_2(key_netstarg *, CLIENT *);
+extern "C" keystatus * key_net_put_2_svc(key_netstarg *, struct svc_req *);
+#define KEY_NET_GET ((u_long)9)
+extern "C" key_netstres * key_net_get_2(void *, CLIENT *);
+extern "C" key_netstres * key_net_get_2_svc(void *, struct svc_req *);
+#define KEY_GET_CONV ((u_long)10)
+extern "C" cryptkeyres * key_get_conv_2(opaque *, CLIENT *);
+extern "C" cryptkeyres * key_get_conv_2_svc(opaque *, struct svc_req *);
+
+#elif __STDC__
+extern keystatus * key_set_2(opaque *, CLIENT *);
+extern keystatus * key_set_2_svc(opaque *, struct svc_req *);
+extern cryptkeyres * key_encrypt_2(cryptkeyarg *, CLIENT *);
+extern cryptkeyres * key_encrypt_2_svc(cryptkeyarg *, struct svc_req *);
+extern cryptkeyres * key_decrypt_2(cryptkeyarg *, CLIENT *);
+extern cryptkeyres * key_decrypt_2_svc(cryptkeyarg *, struct svc_req *);
+extern des_block * key_gen_2(void *, CLIENT *);
+extern des_block * key_gen_2_svc(void *, struct svc_req *);
+extern getcredres * key_getcred_2(netnamestr *, CLIENT *);
+extern getcredres * key_getcred_2_svc(netnamestr *, struct svc_req *);
+#define KEY_ENCRYPT_PK ((u_long)6)
+extern cryptkeyres * key_encrypt_pk_2(cryptkeyarg2 *, CLIENT *);
+extern cryptkeyres * key_encrypt_pk_2_svc(cryptkeyarg2 *, struct svc_req *);
+#define KEY_DECRYPT_PK ((u_long)7)
+extern cryptkeyres * key_decrypt_pk_2(cryptkeyarg2 *, CLIENT *);
+extern cryptkeyres * key_decrypt_pk_2_svc(cryptkeyarg2 *, struct svc_req *);
+#define KEY_NET_PUT ((u_long)8)
+extern keystatus * key_net_put_2(key_netstarg *, CLIENT *);
+extern keystatus * key_net_put_2_svc(key_netstarg *, struct svc_req *);
+#define KEY_NET_GET ((u_long)9)
+extern key_netstres * key_net_get_2(void *, CLIENT *);
+extern key_netstres * key_net_get_2_svc(void *, struct svc_req *);
+#define KEY_GET_CONV ((u_long)10)
+extern cryptkeyres * key_get_conv_2(opaque *, CLIENT *);
+extern cryptkeyres * key_get_conv_2_svc(opaque *, struct svc_req *);
+
+#else /* Old Style C */
+extern keystatus * key_set_2();
+extern keystatus * key_set_2_svc();
+extern cryptkeyres * key_encrypt_2();
+extern cryptkeyres * key_encrypt_2_svc();
+extern cryptkeyres * key_decrypt_2();
+extern cryptkeyres * key_decrypt_2_svc();
+extern des_block * key_gen_2();
+extern des_block * key_gen_2_svc();
+extern getcredres * key_getcred_2();
+extern getcredres * key_getcred_2_svc();
+#define KEY_ENCRYPT_PK ((u_long)6)
+extern cryptkeyres * key_encrypt_pk_2();
+extern cryptkeyres * key_encrypt_pk_2_svc();
+#define KEY_DECRYPT_PK ((u_long)7)
+extern cryptkeyres * key_decrypt_pk_2();
+extern cryptkeyres * key_decrypt_pk_2_svc();
+#define KEY_NET_PUT ((u_long)8)
+extern keystatus * key_net_put_2();
+extern keystatus * key_net_put_2_svc();
+#define KEY_NET_GET ((u_long)9)
+extern key_netstres * key_net_get_2();
+extern key_netstres * key_net_get_2_svc();
+#define KEY_GET_CONV ((u_long)10)
+extern cryptkeyres * key_get_conv_2();
+extern cryptkeyres * key_get_conv_2_svc();
+#endif /* Old Style C */
+
+#endif /* !_KEY_PROT_H_RPCGEN */
diff --git a/meta/recipes-extended/libtirpc/libtirpc-0.2.3/libtirpc-0.2.3-add-missing-bits-from-glibc.patch b/meta/recipes-extended/libtirpc/libtirpc-0.2.3/libtirpc-0.2.3-add-missing-bits-from-glibc.patch
new file mode 100644
index 0000000..43a093b
--- /dev/null
+++ b/meta/recipes-extended/libtirpc/libtirpc-0.2.3/libtirpc-0.2.3-add-missing-bits-from-glibc.patch
@@ -0,0 +1,1766 @@
+diff -urN libtirpc-0.2.3/src/des_crypt.c libtirpc-0.2.3.new/src/des_crypt.c
+--- libtirpc-0.2.3/src/des_crypt.c 2013-02-13 16:13:59.000000000 +0100
++++ libtirpc-0.2.3.new/src/des_crypt.c 2013-03-19 12:24:24.368923058 +0100
+@@ -1,66 +1,60 @@
+ /*
+- * Copyright (c) 2009, Sun Microsystems, Inc.
+- * All rights reserved.
++ * des_crypt.c, DES encryption library routines
++ * Copyright (c) 2010, Oracle America, Inc.
++ * Adaption to work inside tirpc rather than glibc
++ * (c) 2012 Bernhard Rosenkraenzer <bero@lindev.ch>
+ *
+ * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions are met:
+- * - Redistributions of source code must retain the above copyright notice,
+- * this list of conditions and the following disclaimer.
+- * - Redistributions in binary form must reproduce the above copyright notice,
+- * this list of conditions and the following disclaimer in the documentation
+- * and/or other materials provided with the distribution.
+- * - Neither the name of Sun Microsystems, Inc. nor the names of its
+- * contributors may be used to endorse or promote products derived
+- * from this software without specific prior written permission.
++ * modification, are permitted provided that the following conditions are
++ * met:
+ *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+- * POSSIBILITY OF SUCH DAMAGE.
+- */
+-/*
+- * des_crypt.c, DES encryption library routines
+- * Copyright (C) 1986, Sun Microsystems, Inc.
++ * * Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * * Redistributions in binary form must reproduce the above
++ * copyright notice, this list of conditions and the following
++ * disclaimer in the documentation and/or other materials
++ * provided with the distribution.
++ * * Neither the name of the "Oracle America, Inc." nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
++ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
++ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
++ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+ #include <sys/types.h>
+-#include <rpc/types.h>
+ #include <rpc/des_crypt.h>
+-#include <rpc/des.h>
+-#if 0
+-#ifndef lint
+-static char sccsid[] = "@(#)des_crypt.c 2.2 88/08/10 4.0 RPCSRC; from 1.13 88/02/08 SMI";
+-#endif
+-#endif
+-#include <sys/cdefs.h>
+-
+-static int common_crypt( char *, char *, unsigned, unsigned, struct desparams * );
+-int (*__des_crypt_LOCAL)() = 0;
+-extern int _des_crypt_call(char *, int, struct desparams *);
++#include <rpc/rpc_des.h>
++
++extern int _des_crypt (char *, unsigned, struct desparams *);
++
+ /*
+ * Copy 8 bytes
+ */
+ #define COPY8(src, dst) { \
+- char *a = (char *) dst; \
+- char *b = (char *) src; \
++ register char *a = (char *) dst; \
++ register char *b = (char *) src; \
+ *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
+ *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
+ }
+-
++
+ /*
+ * Copy multiple of 8 bytes
+ */
+ #define DESCOPY(src, dst, len) { \
+- char *a = (char *) dst; \
+- char *b = (char *) src; \
+- int i; \
++ register char *a = (char *) dst; \
++ register char *b = (char *) src; \
++ register int i; \
+ for (i = (int) len; i > 0; i -= 8) { \
+ *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
+ *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
+@@ -68,87 +62,56 @@
+ }
+
+ /*
+- * CBC mode encryption
++ * Common code to cbc_crypt() & ecb_crypt()
+ */
+-int
+-cbc_crypt(key, buf, len, mode, ivec)
+- char *key;
+- char *buf;
+- unsigned len;
+- unsigned mode;
+- char *ivec;
++static int
++common_crypt (char *key, char *buf, register unsigned len,
++ unsigned mode, register struct desparams *desp)
+ {
+- int err;
+- struct desparams dp;
++ register int desdev;
+
+-#ifdef BROKEN_DES
+- dp.UDES.UDES_buf = buf;
+- dp.des_mode = ECB;
+-#else
+- dp.des_mode = CBC;
+-#endif
+- COPY8(ivec, dp.des_ivec);
+- err = common_crypt(key, buf, len, mode, &dp);
+- COPY8(dp.des_ivec, ivec);
+- return(err);
+-}
++ if ((len % 8) != 0 || len > DES_MAXDATA)
++ return DESERR_BADPARAM;
++
++ desp->des_dir =
++ ((mode & DES_DIRMASK) == DES_ENCRYPT) ? ENCRYPT : DECRYPT;
++
++ desdev = mode & DES_DEVMASK;
++ COPY8 (key, desp->des_key);
++ /*
++ * software
++ */
++ if (!_des_crypt (buf, len, desp))
++ return DESERR_HWERROR;
+
++ return desdev == DES_SW ? DESERR_NONE : DESERR_NOHWDEVICE;
++}
+
+ /*
+- * ECB mode encryption
++ * CBC mode encryption
+ */
+ int
+-ecb_crypt(key, buf, len, mode)
+- char *key;
+- char *buf;
+- unsigned len;
+- unsigned mode;
++cbc_crypt (char *key, char *buf, unsigned int len, unsigned int mode,
++ char *ivec)
+ {
+- struct desparams dp;
++ int err;
++ struct desparams dp;
+
+-#ifdef BROKEN_DES
+- dp.UDES.UDES_buf = buf;
+- dp.des_mode = CBC;
+-#else
+- dp.des_mode = ECB;
+-#endif
+- return(common_crypt(key, buf, len, mode, &dp));
++ dp.des_mode = CBC;
++ COPY8 (ivec, dp.des_ivec);
++ err = common_crypt (key, buf, len, mode, &dp);
++ COPY8 (dp.des_ivec, ivec);
++ return err;
+ }
+
+-
+-
+ /*
+- * Common code to cbc_crypt() & ecb_crypt()
++ * ECB mode encryption
+ */
+-static int
+-common_crypt(key, buf, len, mode, desp)
+- char *key;
+- char *buf;
+- unsigned len;
+- unsigned mode;
+- struct desparams *desp;
++int
++ecb_crypt (char *key, char *buf, unsigned int len, unsigned int mode)
+ {
+- int desdev;
++ struct desparams dp;
+
+- if ((len % 8) != 0 || len > DES_MAXDATA) {
+- return(DESERR_BADPARAM);
+- }
+- desp->des_dir =
+- ((mode & DES_DIRMASK) == DES_ENCRYPT) ? ENCRYPT : DECRYPT;
+-
+- desdev = mode & DES_DEVMASK;
+- COPY8(key, desp->des_key);
+- /*
+- * software
+- */
+- if (__des_crypt_LOCAL != NULL) {
+- if (!__des_crypt_LOCAL(buf, len, desp)) {
+- return (DESERR_HWERROR);
+- }
+- } else {
+- if (!_des_crypt_call(buf, len, desp)) {
+- return (DESERR_HWERROR);
+- }
+- }
+- return(desdev == DES_SW ? DESERR_NONE : DESERR_NOHWDEVICE);
++ dp.des_mode = ECB;
++ return common_crypt (key, buf, len, mode, &dp);
+ }
+diff -urN libtirpc-0.2.3/src/des_impl.c libtirpc-0.2.3.new/src/des_impl.c
+--- libtirpc-0.2.3/src/des_impl.c 1970-01-01 01:00:00.000000000 +0100
++++ libtirpc-0.2.3.new/src/des_impl.c 2013-03-19 12:24:24.368923058 +0100
+@@ -0,0 +1,593 @@
++/* Copyright (C) 1992 Eric Young */
++/* Collected from libdes and modified for SECURE RPC by Martin Kuck 1994 */
++/* This file is distributed under the terms of the GNU Lesser General */
++/* Public License, version 2.1 or later - see the file COPYING.LIB for details.*/
++/* If you did not receive a copy of the license with this program, please*/
++/* see <http://www.gnu.org/licenses/> to obtain a copy. */
++#include <string.h>
++#include <stdint.h>
++#include <rpc/rpc_des.h>
++
++
++static const uint32_t des_SPtrans[8][64] =
++{
++ { /* nibble 0 */
++ 0x00820200, 0x00020000, 0x80800000, 0x80820200,
++ 0x00800000, 0x80020200, 0x80020000, 0x80800000,
++ 0x80020200, 0x00820200, 0x00820000, 0x80000200,
++ 0x80800200, 0x00800000, 0x00000000, 0x80020000,
++ 0x00020000, 0x80000000, 0x00800200, 0x00020200,
++ 0x80820200, 0x00820000, 0x80000200, 0x00800200,
++ 0x80000000, 0x00000200, 0x00020200, 0x80820000,
++ 0x00000200, 0x80800200, 0x80820000, 0x00000000,
++ 0x00000000, 0x80820200, 0x00800200, 0x80020000,
++ 0x00820200, 0x00020000, 0x80000200, 0x00800200,
++ 0x80820000, 0x00000200, 0x00020200, 0x80800000,
++ 0x80020200, 0x80000000, 0x80800000, 0x00820000,
++ 0x80820200, 0x00020200, 0x00820000, 0x80800200,
++ 0x00800000, 0x80000200, 0x80020000, 0x00000000,
++ 0x00020000, 0x00800000, 0x80800200, 0x00820200,
++ 0x80000000, 0x80820000, 0x00000200, 0x80020200},
++
++ { /* nibble 1 */
++ 0x10042004, 0x00000000, 0x00042000, 0x10040000,
++ 0x10000004, 0x00002004, 0x10002000, 0x00042000,
++ 0x00002000, 0x10040004, 0x00000004, 0x10002000,
++ 0x00040004, 0x10042000, 0x10040000, 0x00000004,
++ 0x00040000, 0x10002004, 0x10040004, 0x00002000,
++ 0x00042004, 0x10000000, 0x00000000, 0x00040004,
++ 0x10002004, 0x00042004, 0x10042000, 0x10000004,
++ 0x10000000, 0x00040000, 0x00002004, 0x10042004,
++ 0x00040004, 0x10042000, 0x10002000, 0x00042004,
++ 0x10042004, 0x00040004, 0x10000004, 0x00000000,
++ 0x10000000, 0x00002004, 0x00040000, 0x10040004,
++ 0x00002000, 0x10000000, 0x00042004, 0x10002004,
++ 0x10042000, 0x00002000, 0x00000000, 0x10000004,
++ 0x00000004, 0x10042004, 0x00042000, 0x10040000,
++ 0x10040004, 0x00040000, 0x00002004, 0x10002000,
++ 0x10002004, 0x00000004, 0x10040000, 0x00042000},
++
++ { /* nibble 2 */
++ 0x41000000, 0x01010040, 0x00000040, 0x41000040,
++ 0x40010000, 0x01000000, 0x41000040, 0x00010040,
++ 0x01000040, 0x00010000, 0x01010000, 0x40000000,
++ 0x41010040, 0x40000040, 0x40000000, 0x41010000,
++ 0x00000000, 0x40010000, 0x01010040, 0x00000040,
++ 0x40000040, 0x41010040, 0x00010000, 0x41000000,
++ 0x41010000, 0x01000040, 0x40010040, 0x01010000,
++ 0x00010040, 0x00000000, 0x01000000, 0x40010040,
++ 0x01010040, 0x00000040, 0x40000000, 0x00010000,
++ 0x40000040, 0x40010000, 0x01010000, 0x41000040,
++ 0x00000000, 0x01010040, 0x00010040, 0x41010000,
++ 0x40010000, 0x01000000, 0x41010040, 0x40000000,
++ 0x40010040, 0x41000000, 0x01000000, 0x41010040,
++ 0x00010000, 0x01000040, 0x41000040, 0x00010040,
++ 0x01000040, 0x00000000, 0x41010000, 0x40000040,
++ 0x41000000, 0x40010040, 0x00000040, 0x01010000},
++
++ { /* nibble 3 */
++ 0x00100402, 0x04000400, 0x00000002, 0x04100402,
++ 0x00000000, 0x04100000, 0x04000402, 0x00100002,
++ 0x04100400, 0x04000002, 0x04000000, 0x00000402,
++ 0x04000002, 0x00100402, 0x00100000, 0x04000000,
++ 0x04100002, 0x00100400, 0x00000400, 0x00000002,
++ 0x00100400, 0x04000402, 0x04100000, 0x00000400,
++ 0x00000402, 0x00000000, 0x00100002, 0x04100400,
++ 0x04000400, 0x04100002, 0x04100402, 0x00100000,
++ 0x04100002, 0x00000402, 0x00100000, 0x04000002,
++ 0x00100400, 0x04000400, 0x00000002, 0x04100000,
++ 0x04000402, 0x00000000, 0x00000400, 0x00100002,
++ 0x00000000, 0x04100002, 0x04100400, 0x00000400,
++ 0x04000000, 0x04100402, 0x00100402, 0x00100000,
++ 0x04100402, 0x00000002, 0x04000400, 0x00100402,
++ 0x00100002, 0x00100400, 0x04100000, 0x04000402,
++ 0x00000402, 0x04000000, 0x04000002, 0x04100400},
++
++ { /* nibble 4 */
++ 0x02000000, 0x00004000, 0x00000100, 0x02004108,
++ 0x02004008, 0x02000100, 0x00004108, 0x02004000,
++ 0x00004000, 0x00000008, 0x02000008, 0x00004100,
++ 0x02000108, 0x02004008, 0x02004100, 0x00000000,
++ 0x00004100, 0x02000000, 0x00004008, 0x00000108,
++ 0x02000100, 0x00004108, 0x00000000, 0x02000008,
++ 0x00000008, 0x02000108, 0x02004108, 0x00004008,
++ 0x02004000, 0x00000100, 0x00000108, 0x02004100,
++ 0x02004100, 0x02000108, 0x00004008, 0x02004000,
++ 0x00004000, 0x00000008, 0x02000008, 0x02000100,
++ 0x02000000, 0x00004100, 0x02004108, 0x00000000,
++ 0x00004108, 0x02000000, 0x00000100, 0x00004008,
++ 0x02000108, 0x00000100, 0x00000000, 0x02004108,
++ 0x02004008, 0x02004100, 0x00000108, 0x00004000,
++ 0x00004100, 0x02004008, 0x02000100, 0x00000108,
++ 0x00000008, 0x00004108, 0x02004000, 0x02000008},
++
++ { /* nibble 5 */
++ 0x20000010, 0x00080010, 0x00000000, 0x20080800,
++ 0x00080010, 0x00000800, 0x20000810, 0x00080000,
++ 0x00000810, 0x20080810, 0x00080800, 0x20000000,
++ 0x20000800, 0x20000010, 0x20080000, 0x00080810,
++ 0x00080000, 0x20000810, 0x20080010, 0x00000000,
++ 0x00000800, 0x00000010, 0x20080800, 0x20080010,
++ 0x20080810, 0x20080000, 0x20000000, 0x00000810,
++ 0x00000010, 0x00080800, 0x00080810, 0x20000800,
++ 0x00000810, 0x20000000, 0x20000800, 0x00080810,
++ 0x20080800, 0x00080010, 0x00000000, 0x20000800,
++ 0x20000000, 0x00000800, 0x20080010, 0x00080000,
++ 0x00080010, 0x20080810, 0x00080800, 0x00000010,
++ 0x20080810, 0x00080800, 0x00080000, 0x20000810,
++ 0x20000010, 0x20080000, 0x00080810, 0x00000000,
++ 0x00000800, 0x20000010, 0x20000810, 0x20080800,
++ 0x20080000, 0x00000810, 0x00000010, 0x20080010},
++
++ { /* nibble 6 */
++ 0x00001000, 0x00000080, 0x00400080, 0x00400001,
++ 0x00401081, 0x00001001, 0x00001080, 0x00000000,
++ 0x00400000, 0x00400081, 0x00000081, 0x00401000,
++ 0x00000001, 0x00401080, 0x00401000, 0x00000081,
++ 0x00400081, 0x00001000, 0x00001001, 0x00401081,
++ 0x00000000, 0x00400080, 0x00400001, 0x00001080,
++ 0x00401001, 0x00001081, 0x00401080, 0x00000001,
++ 0x00001081, 0x00401001, 0x00000080, 0x00400000,
++ 0x00001081, 0x00401000, 0x00401001, 0x00000081,
++ 0x00001000, 0x00000080, 0x00400000, 0x00401001,
++ 0x00400081, 0x00001081, 0x00001080, 0x00000000,
++ 0x00000080, 0x00400001, 0x00000001, 0x00400080,
++ 0x00000000, 0x00400081, 0x00400080, 0x00001080,
++ 0x00000081, 0x00001000, 0x00401081, 0x00400000,
++ 0x00401080, 0x00000001, 0x00001001, 0x00401081,
++ 0x00400001, 0x00401080, 0x00401000, 0x00001001},
++
++ { /* nibble 7 */
++ 0x08200020, 0x08208000, 0x00008020, 0x00000000,
++ 0x08008000, 0x00200020, 0x08200000, 0x08208020,
++ 0x00000020, 0x08000000, 0x00208000, 0x00008020,
++ 0x00208020, 0x08008020, 0x08000020, 0x08200000,
++ 0x00008000, 0x00208020, 0x00200020, 0x08008000,
++ 0x08208020, 0x08000020, 0x00000000, 0x00208000,
++ 0x08000000, 0x00200000, 0x08008020, 0x08200020,
++ 0x00200000, 0x00008000, 0x08208000, 0x00000020,
++ 0x00200000, 0x00008000, 0x08000020, 0x08208020,
++ 0x00008020, 0x08000000, 0x00000000, 0x00208000,
++ 0x08200020, 0x08008020, 0x08008000, 0x00200020,
++ 0x08208000, 0x00000020, 0x00200020, 0x08008000,
++ 0x08208020, 0x00200000, 0x08200000, 0x08000020,
++ 0x00208000, 0x00008020, 0x08008020, 0x08200000,
++ 0x00000020, 0x08208000, 0x00208020, 0x00000000,
++ 0x08000000, 0x08200020, 0x00008000, 0x00208020}};
++
++static const uint32_t des_skb[8][64] =
++{
++ { /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
++ 0x00000000, 0x00000010, 0x20000000, 0x20000010,
++ 0x00010000, 0x00010010, 0x20010000, 0x20010010,
++ 0x00000800, 0x00000810, 0x20000800, 0x20000810,
++ 0x00010800, 0x00010810, 0x20010800, 0x20010810,
++ 0x00000020, 0x00000030, 0x20000020, 0x20000030,
++ 0x00010020, 0x00010030, 0x20010020, 0x20010030,
++ 0x00000820, 0x00000830, 0x20000820, 0x20000830,
++ 0x00010820, 0x00010830, 0x20010820, 0x20010830,
++ 0x00080000, 0x00080010, 0x20080000, 0x20080010,
++ 0x00090000, 0x00090010, 0x20090000, 0x20090010,
++ 0x00080800, 0x00080810, 0x20080800, 0x20080810,
++ 0x00090800, 0x00090810, 0x20090800, 0x20090810,
++ 0x00080020, 0x00080030, 0x20080020, 0x20080030,
++ 0x00090020, 0x00090030, 0x20090020, 0x20090030,
++ 0x00080820, 0x00080830, 0x20080820, 0x20080830,
++ 0x00090820, 0x00090830, 0x20090820, 0x20090830},
++ { /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
++ 0x00000000, 0x02000000, 0x00002000, 0x02002000,
++ 0x00200000, 0x02200000, 0x00202000, 0x02202000,
++ 0x00000004, 0x02000004, 0x00002004, 0x02002004,
++ 0x00200004, 0x02200004, 0x00202004, 0x02202004,
++ 0x00000400, 0x02000400, 0x00002400, 0x02002400,
++ 0x00200400, 0x02200400, 0x00202400, 0x02202400,
++ 0x00000404, 0x02000404, 0x00002404, 0x02002404,
++ 0x00200404, 0x02200404, 0x00202404, 0x02202404,
++ 0x10000000, 0x12000000, 0x10002000, 0x12002000,
++ 0x10200000, 0x12200000, 0x10202000, 0x12202000,
++ 0x10000004, 0x12000004, 0x10002004, 0x12002004,
++ 0x10200004, 0x12200004, 0x10202004, 0x12202004,
++ 0x10000400, 0x12000400, 0x10002400, 0x12002400,
++ 0x10200400, 0x12200400, 0x10202400, 0x12202400,
++ 0x10000404, 0x12000404, 0x10002404, 0x12002404,
++ 0x10200404, 0x12200404, 0x10202404, 0x12202404},
++ { /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
++ 0x00000000, 0x00000001, 0x00040000, 0x00040001,
++ 0x01000000, 0x01000001, 0x01040000, 0x01040001,
++ 0x00000002, 0x00000003, 0x00040002, 0x00040003,
++ 0x01000002, 0x01000003, 0x01040002, 0x01040003,
++ 0x00000200, 0x00000201, 0x00040200, 0x00040201,
++ 0x01000200, 0x01000201, 0x01040200, 0x01040201,
++ 0x00000202, 0x00000203, 0x00040202, 0x00040203,
++ 0x01000202, 0x01000203, 0x01040202, 0x01040203,
++ 0x08000000, 0x08000001, 0x08040000, 0x08040001,
++ 0x09000000, 0x09000001, 0x09040000, 0x09040001,
++ 0x08000002, 0x08000003, 0x08040002, 0x08040003,
++ 0x09000002, 0x09000003, 0x09040002, 0x09040003,
++ 0x08000200, 0x08000201, 0x08040200, 0x08040201,
++ 0x09000200, 0x09000201, 0x09040200, 0x09040201,
++ 0x08000202, 0x08000203, 0x08040202, 0x08040203,
++ 0x09000202, 0x09000203, 0x09040202, 0x09040203},
++ { /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
++ 0x00000000, 0x00100000, 0x00000100, 0x00100100,
++ 0x00000008, 0x00100008, 0x00000108, 0x00100108,
++ 0x00001000, 0x00101000, 0x00001100, 0x00101100,
++ 0x00001008, 0x00101008, 0x00001108, 0x00101108,
++ 0x04000000, 0x04100000, 0x04000100, 0x04100100,
++ 0x04000008, 0x04100008, 0x04000108, 0x04100108,
++ 0x04001000, 0x04101000, 0x04001100, 0x04101100,
++ 0x04001008, 0x04101008, 0x04001108, 0x04101108,
++ 0x00020000, 0x00120000, 0x00020100, 0x00120100,
++ 0x00020008, 0x00120008, 0x00020108, 0x00120108,
++ 0x00021000, 0x00121000, 0x00021100, 0x00121100,
++ 0x00021008, 0x00121008, 0x00021108, 0x00121108,
++ 0x04020000, 0x04120000, 0x04020100, 0x04120100,
++ 0x04020008, 0x04120008, 0x04020108, 0x04120108,
++ 0x04021000, 0x04121000, 0x04021100, 0x04121100,
++ 0x04021008, 0x04121008, 0x04021108, 0x04121108},
++ { /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
++ 0x00000000, 0x10000000, 0x00010000, 0x10010000,
++ 0x00000004, 0x10000004, 0x00010004, 0x10010004,
++ 0x20000000, 0x30000000, 0x20010000, 0x30010000,
++ 0x20000004, 0x30000004, 0x20010004, 0x30010004,
++ 0x00100000, 0x10100000, 0x00110000, 0x10110000,
++ 0x00100004, 0x10100004, 0x00110004, 0x10110004,
++ 0x20100000, 0x30100000, 0x20110000, 0x30110000,
++ 0x20100004, 0x30100004, 0x20110004, 0x30110004,
++ 0x00001000, 0x10001000, 0x00011000, 0x10011000,
++ 0x00001004, 0x10001004, 0x00011004, 0x10011004,
++ 0x20001000, 0x30001000, 0x20011000, 0x30011000,
++ 0x20001004, 0x30001004, 0x20011004, 0x30011004,
++ 0x00101000, 0x10101000, 0x00111000, 0x10111000,
++ 0x00101004, 0x10101004, 0x00111004, 0x10111004,
++ 0x20101000, 0x30101000, 0x20111000, 0x30111000,
++ 0x20101004, 0x30101004, 0x20111004, 0x30111004},
++ { /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
++ 0x00000000, 0x08000000, 0x00000008, 0x08000008,
++ 0x00000400, 0x08000400, 0x00000408, 0x08000408,
++ 0x00020000, 0x08020000, 0x00020008, 0x08020008,
++ 0x00020400, 0x08020400, 0x00020408, 0x08020408,
++ 0x00000001, 0x08000001, 0x00000009, 0x08000009,
++ 0x00000401, 0x08000401, 0x00000409, 0x08000409,
++ 0x00020001, 0x08020001, 0x00020009, 0x08020009,
++ 0x00020401, 0x08020401, 0x00020409, 0x08020409,
++ 0x02000000, 0x0A000000, 0x02000008, 0x0A000008,
++ 0x02000400, 0x0A000400, 0x02000408, 0x0A000408,
++ 0x02020000, 0x0A020000, 0x02020008, 0x0A020008,
++ 0x02020400, 0x0A020400, 0x02020408, 0x0A020408,
++ 0x02000001, 0x0A000001, 0x02000009, 0x0A000009,
++ 0x02000401, 0x0A000401, 0x02000409, 0x0A000409,
++ 0x02020001, 0x0A020001, 0x02020009, 0x0A020009,
++ 0x02020401, 0x0A020401, 0x02020409, 0x0A020409},
++ { /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
++ 0x00000000, 0x00000100, 0x00080000, 0x00080100,
++ 0x01000000, 0x01000100, 0x01080000, 0x01080100,
++ 0x00000010, 0x00000110, 0x00080010, 0x00080110,
++ 0x01000010, 0x01000110, 0x01080010, 0x01080110,
++ 0x00200000, 0x00200100, 0x00280000, 0x00280100,
++ 0x01200000, 0x01200100, 0x01280000, 0x01280100,
++ 0x00200010, 0x00200110, 0x00280010, 0x00280110,
++ 0x01200010, 0x01200110, 0x01280010, 0x01280110,
++ 0x00000200, 0x00000300, 0x00080200, 0x00080300,
++ 0x01000200, 0x01000300, 0x01080200, 0x01080300,
++ 0x00000210, 0x00000310, 0x00080210, 0x00080310,
++ 0x01000210, 0x01000310, 0x01080210, 0x01080310,
++ 0x00200200, 0x00200300, 0x00280200, 0x00280300,
++ 0x01200200, 0x01200300, 0x01280200, 0x01280300,
++ 0x00200210, 0x00200310, 0x00280210, 0x00280310,
++ 0x01200210, 0x01200310, 0x01280210, 0x01280310},
++ { /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
++ 0x00000000, 0x04000000, 0x00040000, 0x04040000,
++ 0x00000002, 0x04000002, 0x00040002, 0x04040002,
++ 0x00002000, 0x04002000, 0x00042000, 0x04042000,
++ 0x00002002, 0x04002002, 0x00042002, 0x04042002,
++ 0x00000020, 0x04000020, 0x00040020, 0x04040020,
++ 0x00000022, 0x04000022, 0x00040022, 0x04040022,
++ 0x00002020, 0x04002020, 0x00042020, 0x04042020,
++ 0x00002022, 0x04002022, 0x00042022, 0x04042022,
++ 0x00000800, 0x04000800, 0x00040800, 0x04040800,
++ 0x00000802, 0x04000802, 0x00040802, 0x04040802,
++ 0x00002800, 0x04002800, 0x00042800, 0x04042800,
++ 0x00002802, 0x04002802, 0x00042802, 0x04042802,
++ 0x00000820, 0x04000820, 0x00040820, 0x04040820,
++ 0x00000822, 0x04000822, 0x00040822, 0x04040822,
++ 0x00002820, 0x04002820, 0x00042820, 0x04042820,
++ 0x00002822, 0x04002822, 0x00042822, 0x04042822},
++};
++
++#define c2l(c,l) (l =((unsigned long)(*((c)++))) , \
++ l|=((unsigned long)(*((c)++)))<< 8, \
++ l|=((unsigned long)(*((c)++)))<<16, \
++ l|=((unsigned long)(*((c)++)))<<24)
++
++#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
++ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
++ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
++ *((c)++)=(unsigned char)(((l)>>24)&0xff))
++
++/*
++ * IP and FP
++ * The problem is more of a geometric problem that random bit fiddling.
++ * 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6
++ * 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4
++ * 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2
++ * 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0
++ *
++ * 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7
++ * 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5
++ * 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3
++ * 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1
++ *
++ * The output has been subject to swaps of the form
++ * 0 1 -> 3 1 but the odd and even bits have been put into
++ * 2 3 2 0
++ * different words. The main trick is to remember that
++ * t=((l>>size)^r)&(mask);
++ * r^=t;
++ * l^=(t<<size);
++ * can be used to swap and move bits between words.
++ *
++ * So l = 0 1 2 3 r = 16 17 18 19
++ * 4 5 6 7 20 21 22 23
++ * 8 9 10 11 24 25 26 27
++ * 12 13 14 15 28 29 30 31
++ * becomes (for size == 2 and mask == 0x3333)
++ * t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19
++ * 6^20 7^21 -- -- 4 5 20 21 6 7 22 23
++ * 10^24 11^25 -- -- 8 9 24 25 10 11 24 25
++ * 14^28 15^29 -- -- 12 13 28 29 14 15 28 29
++ *
++ * Thanks for hints from Richard Outerbridge - he told me IP&FP
++ * could be done in 15 xor, 10 shifts and 5 ands.
++ * When I finally started to think of the problem in 2D
++ * I first got ~42 operations without xors. When I remembered
++ * how to use xors :-) I got it to its final state.
++ */
++
++#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
++ (b)^=(t),\
++ (a)^=((t)<<(n)))
++
++#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
++ (a)=(a)^(t)^(t>>(16-(n))))
++
++
++#define D_ENCRYPT(L,R,S) \
++ u=(R^s[S ]); \
++ t=R^s[S+1]; \
++ t=((t>>4)+(t<<28)); \
++ L^= des_SPtrans[1][(t )&0x3f]| \
++ des_SPtrans[3][(t>> 8)&0x3f]| \
++ des_SPtrans[5][(t>>16)&0x3f]| \
++ des_SPtrans[7][(t>>24)&0x3f]| \
++ des_SPtrans[0][(u )&0x3f]| \
++ des_SPtrans[2][(u>> 8)&0x3f]| \
++ des_SPtrans[4][(u>>16)&0x3f]| \
++ des_SPtrans[6][(u>>24)&0x3f];
++
++#define ITERATIONS 16
++
++static const char shifts2[16] =
++{0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0};
++
++static void des_set_key (unsigned char *, unsigned long *);
++static void des_encrypt (unsigned long *, unsigned long *, int);
++int _des_crypt (char *, unsigned, struct desparams *);
++
++static void
++des_set_key (unsigned char *key, unsigned long *schedule)
++{
++ register unsigned long c, d, t, s;
++ register unsigned char *in;
++ register unsigned long *k;
++ register int i;
++
++ k = (unsigned long *) schedule;
++ in = key;
++
++ c2l (in, c);
++ c2l (in, d);
++
++ /* I now do it in 47 simple operations :-)
++ * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
++ * for the inspiration. :-) */
++ PERM_OP (d, c, t, 4, 0x0f0f0f0f);
++ HPERM_OP (c, t, -2, 0xcccc0000);
++ HPERM_OP (d, t, -2, 0xcccc0000);
++ PERM_OP (d, c, t, 1, 0x55555555);
++ PERM_OP (c, d, t, 8, 0x00ff00ff);
++ PERM_OP (d, c, t, 1, 0x55555555);
++ d = (((d & 0x000000ff) << 16) | (d & 0x0000ff00) |
++ ((d & 0x00ff0000) >> 16) | ((c & 0xf0000000) >> 4));
++ c &= 0x0fffffff;
++
++ for (i = 0; i < ITERATIONS; i++)
++ {
++ if (shifts2[i])
++ {
++ c = ((c >> 2) | (c << 26));
++ d = ((d >> 2) | (d << 26));
++ }
++ else
++ {
++ c = ((c >> 1) | (c << 27));
++ d = ((d >> 1) | (d << 27));
++ }
++ c &= 0x0fffffff;
++ d &= 0x0fffffff;
++ /* could be a few less shifts but I am to lazy at this
++ * point in time to investigate */
++ s = des_skb[0][(c) & 0x3f] |
++ des_skb[1][((c >> 6) & 0x03) | ((c >> 7) & 0x3c)] |
++ des_skb[2][((c >> 13) & 0x0f) | ((c >> 14) & 0x30)] |
++ des_skb[3][((c >> 20) & 0x01) | ((c >> 21) & 0x06) | ((c >> 22) & 0x38)];
++ t = des_skb[4][(d) & 0x3f] |
++ des_skb[5][((d >> 7) & 0x03) | ((d >> 8) & 0x3c)] |
++ des_skb[6][(d >> 15) & 0x3f] |
++ des_skb[7][((d >> 21) & 0x0f) | ((d >> 22) & 0x30)];
++
++ /* table contained 0213 4657 */
++ *(k++) = ((t << 16) | (s & 0x0000ffff)) & 0xffffffff;
++ s = ((s >> 16) | (t & 0xffff0000));
++
++ s = (s << 4) | (s >> 28);
++ *(k++) = s & 0xffffffff;
++ }
++}
++
++
++static void
++des_encrypt (unsigned long *buf, unsigned long *schedule, int encrypt)
++{
++ register unsigned long l, r, t, u;
++ register int i;
++ register unsigned long *s;
++
++ l = buf[0];
++ r = buf[1];
++
++ /* do IP */
++ PERM_OP (r, l, t, 4, 0x0f0f0f0f);
++ PERM_OP (l, r, t, 16, 0x0000ffff);
++ PERM_OP (r, l, t, 2, 0x33333333);
++ PERM_OP (l, r, t, 8, 0x00ff00ff);
++ PERM_OP (r, l, t, 1, 0x55555555);
++ /* r and l are reversed - remember that :-) - fix
++ * it in the next step */
++
++ /* Things have been modified so that the initial rotate is
++ * done outside the loop. This required the
++ * des_SPtrans values in sp.h to be rotated 1 bit to the right.
++ * One perl script later and things have a 5% speed up on a sparc2.
++ * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
++ * for pointing this out. */
++ t = (r << 1) | (r >> 31);
++ r = (l << 1) | (l >> 31);
++ l = t;
++
++ /* clear the top bits on machines with 8byte longs */
++ l &= 0xffffffff;
++ r &= 0xffffffff;
++
++ s = (unsigned long *) schedule;
++ /* I don't know if it is worth the effort of loop unrolling the
++ * inner loop */
++ if (encrypt)
++ {
++ for (i = 0; i < 32; i += 4)
++ {
++ D_ENCRYPT (l, r, i + 0); /* 1 */
++ D_ENCRYPT (r, l, i + 2); /* 2 */
++ }
++ }
++ else
++ {
++ for (i = 30; i > 0; i -= 4)
++ {
++ D_ENCRYPT (l, r, i - 0); /* 16 */
++ D_ENCRYPT (r, l, i - 2); /* 15 */
++ }
++ }
++ l = (l >> 1) | (l << 31);
++ r = (r >> 1) | (r << 31);
++ /* clear the top bits on machines with 8byte longs */
++ l &= 0xffffffff;
++ r &= 0xffffffff;
++
++ /* swap l and r
++ * we will not do the swap so just remember they are
++ * reversed for the rest of the subroutine
++ * luckily FP fixes this problem :-) */
++
++ PERM_OP (r, l, t, 1, 0x55555555);
++ PERM_OP (l, r, t, 8, 0x00ff00ff);
++ PERM_OP (r, l, t, 2, 0x33333333);
++ PERM_OP (l, r, t, 16, 0x0000ffff);
++ PERM_OP (r, l, t, 4, 0x0f0f0f0f);
++
++ buf[0] = l;
++ buf[1] = r;
++
++ l = r = t = u = 0;
++}
++
++
++int
++_des_crypt (char *buf, unsigned len, struct desparams *desp)
++{
++ unsigned long schedule[32];
++ register unsigned long tin0, tin1;
++ register unsigned long tout0, tout1, xor0, xor1;
++ register unsigned char *in, *out;
++ unsigned long tbuf[2];
++ unsigned char *iv, *oiv;
++ int cbc_mode;
++
++ cbc_mode = (desp->des_mode == CBC) ? 1 : 0;
++
++ in = (unsigned char *) buf;
++ out = (unsigned char *) buf;
++ oiv = iv = (unsigned char *) desp->des_ivec;
++
++ des_set_key (desp->des_key, schedule);
++
++ tin0 = tin1 = 0; /* For GCC */
++ if (desp->des_dir == ENCRYPT)
++ {
++ c2l (iv, tout0);
++ c2l (iv, tout1);
++ for (; len > 0; len -= 8)
++ {
++ c2l (in, tin0);
++ c2l (in, tin1);
++ if (cbc_mode)
++ {
++ tin0 ^= tout0;
++ tin1 ^= tout1;
++ }
++ tbuf[0] = tin0;
++ tbuf[1] = tin1;
++ des_encrypt (tbuf, schedule, 1);
++ tout0 = tbuf[0];
++ tout1 = tbuf[1];
++ l2c (tout0, out);
++ l2c (tout1, out);
++ }
++ l2c (tout0, oiv);
++ l2c (tout1, oiv);
++ }
++ else
++ {
++ c2l (iv, xor0);
++ c2l (iv, xor1);
++ for (; len > 0; len -= 8)
++ {
++ c2l (in, tin0);
++ c2l (in, tin1);
++ tbuf[0] = tin0;
++ tbuf[1] = tin1;
++ des_encrypt (tbuf, schedule, 0);
++ if (cbc_mode)
++ {
++ tout0 = tbuf[0] ^ xor0;
++ tout1 = tbuf[1] ^ xor1;
++ xor0 = tin0;
++ xor1 = tin1;
++ }
++ else
++ {
++ tout0 = tbuf[0];
++ tout1 = tbuf[1];
++ }
++ l2c (tout0, out);
++ l2c (tout1, out);
++ }
++ l2c (tin0, oiv);
++ l2c (tin1, oiv);
++ }
++ tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
++ tbuf[0] = tbuf[1] = 0;
++ __bzero (schedule, sizeof (schedule));
++
++ return (1);
++}
+diff -urN libtirpc-0.2.3/src/key_call.c libtirpc-0.2.3.new/src/key_call.c
+--- libtirpc-0.2.3/src/key_call.c 2013-02-13 16:13:59.000000000 +0100
++++ libtirpc-0.2.3.new/src/key_call.c 2013-03-19 12:24:24.368923058 +0100
+@@ -1,452 +1,551 @@
+ /*
+- * Copyright (c) 2009, Sun Microsystems, Inc.
+- * All rights reserved.
++ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions are met:
+- * - Redistributions of source code must retain the above copyright notice,
+- * this list of conditions and the following disclaimer.
+- * - Redistributions in binary form must reproduce the above copyright notice,
+- * this list of conditions and the following disclaimer in the documentation
+- * and/or other materials provided with the distribution.
+- * - Neither the name of Sun Microsystems, Inc. nor the names of its
+- * contributors may be used to endorse or promote products derived
+- * from this software without specific prior written permission.
++ * modification, are permitted provided that the following conditions are
++ * met:
+ *
+- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+- * POSSIBILITY OF SUCH DAMAGE.
++ * * Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * * Redistributions in binary form must reproduce the above
++ * copyright notice, this list of conditions and the following
++ * disclaimer in the documentation and/or other materials
++ * provided with the distribution.
++ * * Neither the name of the "Oracle America, Inc." nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
++ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
++ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
++ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+ /*
+- * Copyright (c) 1986-1991 by Sun Microsystems Inc.
++ * The original source is from the RPCSRC 4.0 package from Sun Microsystems.
++ * The Interface to keyserver protocoll 2, RPC over AF_UNIX and Linux/doors
++ * was added by Thorsten Kukuk <kukuk@suse.de>
++ * Since the Linux/doors project was stopped, I doubt that this code will
++ * ever be useful <kukuk@suse.de>.
+ */
+
+-
+-#include <sys/cdefs.h>
+-
+-/*
+- * key_call.c, Interface to keyserver
+- *
+- * setsecretkey(key) - set your secret key
+- * encryptsessionkey(agent, deskey) - encrypt a session key to talk to agent
+- * decryptsessionkey(agent, deskey) - decrypt ditto
+- * gendeskey(deskey) - generate a secure des key
+- */
+-
+-#include <pthread.h>
+-#include <reentrant.h>
+ #include <stdio.h>
+-#include <stdlib.h>
+-#include <unistd.h>
+ #include <errno.h>
++#include <fcntl.h>
++#include <signal.h>
++#include <unistd.h>
++#include <string.h>
+ #include <rpc/rpc.h>
+ #include <rpc/auth.h>
+-#include <rpc/auth_unix.h>
+-#include <rpc/key_prot.h>
+-#include <string.h>
+-#include <netconfig.h>
+-#include <sys/utsname.h>
+-#include <stdlib.h>
+-#include <signal.h>
+ #include <sys/wait.h>
+-#include <sys/fcntl.h>
++#include <sys/param.h>
++#include <sys/socket.h>
++#include <rpc/key_prot.h>
++#include <bits/libc-lock.h>
+
++#define KEY_TIMEOUT 5 /* per-try timeout in seconds */
++#define KEY_NRETRY 12 /* number of retries */
+
+-#define KEY_TIMEOUT 5 /* per-try timeout in seconds */
+-#define KEY_NRETRY 12 /* number of retries */
++#define debug(msg) /* turn off debugging */
+
+-#ifdef DEBUG
+-#define debug(msg) (void) fprintf(stderr, "%s\n", msg);
+-#else
+-#define debug(msg)
+-#endif /* DEBUG */
++#ifndef SO_PASSCRED
++extern int _openchild (const char *command, FILE **fto, FILE **ffrom);
++#endif
+
+-/*
+- * Hack to allow the keyserver to use AUTH_DES (for authenticated
+- * NIS+ calls, for example). The only functions that get called
+- * are key_encryptsession_pk, key_decryptsession_pk, and key_gendes.
+- *
+- * The approach is to have the keyserver fill in pointers to local
+- * implementations of these functions, and to call those in key_call().
+- */
++static int key_call (u_long, xdrproc_t xdr_arg, char *,
++ xdrproc_t xdr_rslt, char *);
+
+-cryptkeyres *(*__key_encryptsession_pk_LOCAL)() = 0;
+-cryptkeyres *(*__key_decryptsession_pk_LOCAL)() = 0;
+-des_block *(*__key_gendes_LOCAL)() = 0;
+-
+-static int key_call( u_long, xdrproc_t, void *, xdrproc_t, void *);
++static const struct timeval trytimeout = {KEY_TIMEOUT, 0};
++static const struct timeval tottimeout = {KEY_TIMEOUT *KEY_NRETRY, 0};
+
+ int
+-key_setsecret(secretkey)
+- const char *secretkey;
++key_setsecret (const char *secretkey)
+ {
+- keystatus status;
++ keystatus status;
+
+- if (!key_call((u_long) KEY_SET, (xdrproc_t)xdr_keybuf,
+- (void *)secretkey,
+- (xdrproc_t)xdr_keystatus, &status)) {
+- return (-1);
+- }
+- if (status != KEY_SUCCESS) {
+- debug("set status is nonzero");
+- return (-1);
+- }
+- return (0);
++ if (!key_call ((u_long) KEY_SET, (xdrproc_t) xdr_keybuf, secretkey,
++ (xdrproc_t) xdr_keystatus, (char *) &status))
++ return -1;
++ if (status != KEY_SUCCESS)
++ {
++ debug ("set status is nonzero");
++ return -1;
++ }
++ return 0;
+ }
+
+-
+ /* key_secretkey_is_set() returns 1 if the keyserver has a secret key
+ * stored for the caller's effective uid; it returns 0 otherwise
+ *
+ * N.B.: The KEY_NET_GET key call is undocumented. Applications shouldn't
+ * be using it, because it allows them to get the user's secret key.
+ */
+-
+ int
+-key_secretkey_is_set(void)
++key_secretkey_is_set (void)
+ {
+- struct key_netstres kres;
++ struct key_netstres kres;
+
+- memset((void*)&kres, 0, sizeof (kres));
+- if (key_call((u_long) KEY_NET_GET, (xdrproc_t)xdr_void, NULL,
+- (xdrproc_t)xdr_key_netstres, &kres) &&
+- (kres.status == KEY_SUCCESS) &&
+- (kres.key_netstres_u.knet.st_priv_key[0] != 0)) {
+- /* avoid leaving secret key in memory */
+- memset(kres.key_netstres_u.knet.st_priv_key, 0, HEXKEYBYTES);
+- return (1);
+- }
+- return (0);
++ memset (&kres, 0, sizeof (kres));
++ if (key_call ((u_long) KEY_NET_GET, (xdrproc_t) xdr_void,
++ (char *) NULL, (xdrproc_t) xdr_key_netstres,
++ (char *) &kres) &&
++ (kres.status == KEY_SUCCESS) &&
++ (kres.key_netstres_u.knet.st_priv_key[0] != 0))
++ {
++ /* avoid leaving secret key in memory */
++ memset (kres.key_netstres_u.knet.st_priv_key, 0, HEXKEYBYTES);
++ return 1;
++ }
++ return 0;
+ }
+
+ int
+-key_encryptsession_pk(remotename, remotekey, deskey)
+- char *remotename;
+- netobj *remotekey;
+- des_block *deskey;
+-{
+- cryptkeyarg2 arg;
+- cryptkeyres res;
+-
+- arg.remotename = remotename;
+- arg.remotekey = *remotekey;
+- arg.deskey = *deskey;
+- if (!key_call((u_long)KEY_ENCRYPT_PK, (xdrproc_t)xdr_cryptkeyarg2, &arg,
+- (xdrproc_t)xdr_cryptkeyres, &res)) {
+- return (-1);
+- }
+- if (res.status != KEY_SUCCESS) {
+- debug("encrypt status is nonzero");
+- return (-1);
+- }
+- *deskey = res.cryptkeyres_u.deskey;
+- return (0);
+-}
++key_encryptsession (const char *remotename, des_block *deskey)
++{
++ cryptkeyarg arg;
++ cryptkeyres res;
+
+-int
+-key_decryptsession_pk(remotename, remotekey, deskey)
+- char *remotename;
+- netobj *remotekey;
+- des_block *deskey;
+-{
+- cryptkeyarg2 arg;
+- cryptkeyres res;
+-
+- arg.remotename = remotename;
+- arg.remotekey = *remotekey;
+- arg.deskey = *deskey;
+- if (!key_call((u_long)KEY_DECRYPT_PK, (xdrproc_t)xdr_cryptkeyarg2, &arg,
+- (xdrproc_t)xdr_cryptkeyres, &res)) {
+- return (-1);
+- }
+- if (res.status != KEY_SUCCESS) {
+- debug("decrypt status is nonzero");
+- return (-1);
+- }
+- *deskey = res.cryptkeyres_u.deskey;
+- return (0);
++ arg.remotename = remotename;
++ arg.deskey = *deskey;
++ if (!key_call ((u_long) KEY_ENCRYPT, (xdrproc_t) xdr_cryptkeyarg,
++ (char *) &arg, (xdrproc_t) xdr_cryptkeyres,
++ (char *) &res))
++ return -1;
++
++ if (res.status != KEY_SUCCESS)
++ {
++ debug ("encrypt status is nonzero");
++ return -1;
++ }
++ *deskey = res.cryptkeyres_u.deskey;
++ return 0;
+ }
+
+ int
+-key_encryptsession(remotename, deskey)
+- const char *remotename;
+- des_block *deskey;
+-{
+- cryptkeyarg arg;
+- cryptkeyres res;
+-
+- arg.remotename = (char *) remotename;
+- arg.deskey = *deskey;
+- if (!key_call((u_long)KEY_ENCRYPT, (xdrproc_t)xdr_cryptkeyarg, &arg,
+- (xdrproc_t)xdr_cryptkeyres, &res)) {
+- return (-1);
+- }
+- if (res.status != KEY_SUCCESS) {
+- debug("encrypt status is nonzero");
+- return (-1);
+- }
+- *deskey = res.cryptkeyres_u.deskey;
+- return (0);
++key_decryptsession (const char *remotename, des_block *deskey)
++{
++ cryptkeyarg arg;
++ cryptkeyres res;
++
++ arg.remotename = remotename;
++ arg.deskey = *deskey;
++ if (!key_call ((u_long) KEY_DECRYPT, (xdrproc_t) xdr_cryptkeyarg,
++ (char *) &arg, (xdrproc_t) xdr_cryptkeyres,
++ (char *) &res))
++ return -1;
++ if (res.status != KEY_SUCCESS)
++ {
++ debug ("decrypt status is nonzero");
++ return -1;
++ }
++ *deskey = res.cryptkeyres_u.deskey;
++ return 0;
+ }
+
+ int
+-key_decryptsession(remotename, deskey)
+- const char *remotename;
+- des_block *deskey;
+-{
+- cryptkeyarg arg;
+- cryptkeyres res;
+-
+- arg.remotename = (char *) remotename;
+- arg.deskey = *deskey;
+- if (!key_call((u_long)KEY_DECRYPT, (xdrproc_t)xdr_cryptkeyarg, &arg,
+- (xdrproc_t)xdr_cryptkeyres, &res)) {
+- return (-1);
+- }
+- if (res.status != KEY_SUCCESS) {
+- debug("decrypt status is nonzero");
+- return (-1);
+- }
+- *deskey = res.cryptkeyres_u.deskey;
+- return (0);
++key_encryptsession_pk (char *remotename, netobj *remotekey,
++ des_block *deskey)
++{
++ cryptkeyarg2 arg;
++ cryptkeyres res;
++
++ arg.remotename = remotename;
++ arg.remotekey = *remotekey;
++ arg.deskey = *deskey;
++ if (!key_call ((u_long) KEY_ENCRYPT_PK, (xdrproc_t) xdr_cryptkeyarg2,
++ (char *) &arg, (xdrproc_t) xdr_cryptkeyres,
++ (char *) &res))
++ return -1;
++
++ if (res.status != KEY_SUCCESS)
++ {
++ debug ("encrypt status is nonzero");
++ return -1;
++ }
++ *deskey = res.cryptkeyres_u.deskey;
++ return 0;
+ }
+
+ int
+-key_gendes(key)
+- des_block *key;
++key_decryptsession_pk (char *remotename, netobj *remotekey,
++ des_block *deskey)
+ {
+- if (!key_call((u_long)KEY_GEN, (xdrproc_t)xdr_void, NULL,
+- (xdrproc_t)xdr_des_block, key)) {
+- return (-1);
+- }
+- return (0);
++ cryptkeyarg2 arg;
++ cryptkeyres res;
++
++ arg.remotename = remotename;
++ arg.remotekey = *remotekey;
++ arg.deskey = *deskey;
++ if (!key_call ((u_long) KEY_DECRYPT_PK, (xdrproc_t) xdr_cryptkeyarg2,
++ (char *) &arg, (xdrproc_t) xdr_cryptkeyres,
++ (char *) &res))
++ return -1;
++
++ if (res.status != KEY_SUCCESS)
++ {
++ debug ("decrypt status is nonzero");
++ return -1;
++ }
++ *deskey = res.cryptkeyres_u.deskey;
++ return 0;
+ }
+
+ int
+-key_setnet(arg)
+-struct key_netstarg *arg;
++key_gendes (des_block *key)
+ {
+- keystatus status;
++ struct sockaddr_in sin;
++ CLIENT *client;
++ int socket;
++ enum clnt_stat stat;
++
++ sin.sin_family = AF_INET;
++ sin.sin_port = 0;
++ sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
++ __bzero (sin.sin_zero, sizeof (sin.sin_zero));
++ socket = RPC_ANYSOCK;
++ client = clntudp_bufcreate (&sin, (u_long) KEY_PROG, (u_long) KEY_VERS,
++ trytimeout, &socket, RPCSMALLMSGSIZE,
++ RPCSMALLMSGSIZE);
++ if (client == NULL)
++ return -1;
++
++ stat = clnt_call (client, KEY_GEN, (xdrproc_t) xdr_void, NULL,
++ (xdrproc_t) xdr_des_block, (caddr_t) key,
++ tottimeout);
++ clnt_destroy (client);
++ close (socket);
++ if (stat != RPC_SUCCESS)
++ return -1;
+
++ return 0;
++}
+
+- if (!key_call((u_long) KEY_NET_PUT, (xdrproc_t)xdr_key_netstarg, arg,
+- (xdrproc_t)xdr_keystatus, &status)){
+- return (-1);
+- }
++int
++key_setnet (struct key_netstarg *arg)
++{
++ keystatus status;
+
+- if (status != KEY_SUCCESS) {
+- debug("key_setnet status is nonzero");
+- return (-1);
+- }
+- return (1);
++ if (!key_call ((u_long) KEY_NET_PUT, (xdrproc_t) xdr_key_netstarg,
++ (char *) arg,(xdrproc_t) xdr_keystatus,
++ (char *) &status))
++ return -1;
++
++ if (status != KEY_SUCCESS)
++ {
++ debug ("key_setnet status is nonzero");
++ return -1;
++ }
++ return 1;
+ }
+
+-
+ int
+-key_get_conv(pkey, deskey)
+- char *pkey;
+- des_block *deskey;
+-{
+- cryptkeyres res;
+-
+- if (!key_call((u_long) KEY_GET_CONV, (xdrproc_t)xdr_keybuf, pkey,
+- (xdrproc_t)xdr_cryptkeyres, &res)) {
+- return (-1);
+- }
+- if (res.status != KEY_SUCCESS) {
+- debug("get_conv status is nonzero");
+- return (-1);
+- }
+- *deskey = res.cryptkeyres_u.deskey;
+- return (0);
++key_get_conv (char *pkey, des_block *deskey)
++{
++ cryptkeyres res;
++
++ if (!key_call ((u_long) KEY_GET_CONV, (xdrproc_t) xdr_keybuf, pkey,
++ (xdrproc_t) xdr_cryptkeyres, (char *) &res))
++ return -1;
++
++ if (res.status != KEY_SUCCESS)
++ {
++ debug ("get_conv status is nonzero");
++ return -1;
++ }
++ *deskey = res.cryptkeyres_u.deskey;
++ return 0;
+ }
+
+-struct key_call_private {
+- CLIENT *client; /* Client handle */
+- pid_t pid; /* process-id at moment of creation */
+- uid_t uid; /* user-id at last authorization */
+-};
+-static struct key_call_private *key_call_private_main = NULL;
++/*
++ * Hack to allow the keyserver to use AUTH_DES (for authenticated
++ * NIS+ calls, for example). The only functions that get called
++ * are key_encryptsession_pk, key_decryptsession_pk, and key_gendes.
++ *
++ * The approach is to have the keyserver fill in pointers to local
++ * implementations of these functions, and to call those in key_call().
++ */
++
++cryptkeyres *(*__key_encryptsession_pk_LOCAL) (uid_t, char *);
++cryptkeyres *(*__key_decryptsession_pk_LOCAL) (uid_t, char *);
++des_block *(*__key_gendes_LOCAL) (uid_t, char *);
+
+-static void
+-key_call_destroy(void *vp)
++#ifndef SO_PASSCRED
++static int
++key_call_keyenvoy (u_long proc, xdrproc_t xdr_arg, char *arg,
++ xdrproc_t xdr_rslt, char *rslt)
+ {
+- struct key_call_private *kcp = (struct key_call_private *)vp;
++ XDR xdrargs;
++ XDR xdrrslt;
++ FILE *fargs;
++ FILE *frslt;
++ sigset_t oldmask, mask;
++ union wait status;
++ int pid;
++ int success;
++ uid_t ruid;
++ uid_t euid;
++ static const char MESSENGER[] = "/usr/etc/keyenvoy";
++
++ success = 1;
++ sigemptyset (&mask);
++ sigaddset (&mask, SIGCHLD);
++ __sigprocmask (SIG_BLOCK, &mask, &oldmask);
++
++ /*
++ * We are going to exec a set-uid program which makes our effective uid
++ * zero, and authenticates us with our real uid. We need to make the
++ * effective uid be the real uid for the setuid program, and
++ * the real uid be the effective uid so that we can change things back.
++ */
++ euid = geteuid ();
++ ruid = getuid ();
++ __setreuid (euid, ruid);
++ pid = _openchild (MESSENGER, &fargs, &frslt);
++ __setreuid (ruid, euid);
++ if (pid < 0)
++ {
++ debug ("open_streams");
++ __sigprocmask (SIG_SETMASK, &oldmask, NULL);
++ return (0);
++ }
++ xdrstdio_create (&xdrargs, fargs, XDR_ENCODE);
++ xdrstdio_create (&xdrrslt, frslt, XDR_DECODE);
++
++ if (!xdr_u_long (&xdrargs, &proc) || !(*xdr_arg) (&xdrargs, arg))
++ {
++ debug ("xdr args");
++ success = 0;
++ }
++ fclose (fargs);
++
++ if (success && !(*xdr_rslt) (&xdrrslt, rslt))
++ {
++ debug ("xdr rslt");
++ success = 0;
++ }
++ fclose(frslt);
++
++ wait_again:
++ if (__wait4 (pid, &status, 0, NULL) < 0)
++ {
++ if (errno == EINTR)
++ goto wait_again;
++ debug ("wait4");
++ if (errno == ECHILD || errno == ESRCH)
++ perror ("wait");
++ else
++ success = 0;
++ }
++ else
++ if (status.w_retcode)
++ {
++ debug ("wait4 1");
++ success = 0;
++ }
++ __sigprocmask (SIG_SETMASK, &oldmask, NULL);
+
+- if (kcp) {
+- if (kcp->client)
+- clnt_destroy(kcp->client);
+- free(kcp);
+- }
++ return success;
+ }
++#endif
++
++struct key_call_private {
++ CLIENT *client; /* Client handle */
++ pid_t pid; /* process-id at moment of creation */
++ uid_t uid; /* user-id at last authorization */
++};
++#ifdef _RPC_THREAD_SAFE_
++#define key_call_private_main RPC_THREAD_VARIABLE(key_call_private_s)
++#else
++static struct key_call_private *key_call_private_main;
++#endif
+
+ /*
+ * Keep the handle cached. This call may be made quite often.
+ */
+ static CLIENT *
+-getkeyserv_handle(vers)
+-int vers;
++getkeyserv_handle (int vers)
+ {
+- void *localhandle;
+- struct netconfig *nconf;
+- struct netconfig *tpconf;
+- struct key_call_private *kcp = key_call_private_main;
+- struct timeval wait_time;
+- struct utsname u;
+- int fd;
+- extern thread_key_t key_call_key;
+- extern mutex_t tsd_lock;
+-
+-#define TOTAL_TIMEOUT 30 /* total timeout talking to keyserver */
+-#define TOTAL_TRIES 5 /* Number of tries */
+-
+- if (key_call_key == -1) {
+- mutex_lock(&tsd_lock);
+- if (key_call_key == -1)
+- thr_keycreate(&key_call_key, key_call_destroy);
+- mutex_unlock(&tsd_lock);
+- }
+- kcp = (struct key_call_private *)thr_getspecific(key_call_key);
+- if (kcp == (struct key_call_private *)NULL) {
+- kcp = (struct key_call_private *)malloc(sizeof (*kcp));
+- if (kcp == (struct key_call_private *)NULL) {
+- return ((CLIENT *) NULL);
+- }
+- thr_setspecific(key_call_key, (void *) kcp);
+- kcp->client = NULL;
+- }
++ struct key_call_private *kcp = key_call_private_main;
++ struct timeval wait_time;
++ int fd;
++ struct sockaddr_un name;
++ socklen_t namelen = sizeof(struct sockaddr_un);
++
++#define TOTAL_TIMEOUT 30 /* total timeout talking to keyserver */
++#define TOTAL_TRIES 5 /* Number of tries */
++
++ if (kcp == (struct key_call_private *)NULL)
++ {
++ kcp = (struct key_call_private *)malloc (sizeof (*kcp));
++ if (kcp == (struct key_call_private *)NULL)
++ return (CLIENT *) NULL;
++
++ key_call_private_main = kcp;
++ kcp->client = NULL;
++ }
++
++ /* if pid has changed, destroy client and rebuild */
++ if (kcp->client != NULL && kcp->pid != getpid ())
++ {
++ auth_destroy (kcp->client->cl_auth);
++ clnt_destroy (kcp->client);
++ kcp->client = NULL;
++ }
++
++ if (kcp->client != NULL)
++ {
++ /* if other side closed socket, build handle again */
++ clnt_control (kcp->client, CLGET_FD, (char *)&fd);
++ if (getpeername (fd,(struct sockaddr *)&name,&namelen) == -1)
++ {
++ auth_destroy (kcp->client->cl_auth);
++ clnt_destroy (kcp->client);
++ kcp->client = NULL;
++ }
++ }
++
++ if (kcp->client != NULL)
++ {
++ /* if uid has changed, build client handle again */
++ if (kcp->uid != geteuid ())
++ {
++ kcp->uid = geteuid ();
++ auth_destroy (kcp->client->cl_auth);
++ kcp->client->cl_auth =
++ authunix_create ((char *)"", kcp->uid, 0, 0, NULL);
++ if (kcp->client->cl_auth == NULL)
++ {
++ clnt_destroy (kcp->client);
++ kcp->client = NULL;
++ return ((CLIENT *) NULL);
++ }
++ }
++ /* Change the version number to the new one */
++ clnt_control (kcp->client, CLSET_VERS, (void *)&vers);
++ return kcp->client;
++ }
++
++ if ((kcp->client == (CLIENT *) NULL))
++ /* Use the AF_UNIX transport */
++ kcp->client = clnt_create ("/var/run/keyservsock", KEY_PROG, vers, "unix");
++
++ if (kcp->client == (CLIENT *) NULL)
++ return (CLIENT *) NULL;
++
++ kcp->uid = geteuid ();
++ kcp->pid = getpid ();
++ kcp->client->cl_auth = authunix_create ((char *)"", kcp->uid, 0, 0, NULL);
++ if (kcp->client->cl_auth == NULL)
++ {
++ clnt_destroy (kcp->client);
++ kcp->client = NULL;
++ return (CLIENT *) NULL;
++ }
++
++ wait_time.tv_sec = TOTAL_TIMEOUT/TOTAL_TRIES;
++ wait_time.tv_usec = 0;
++ clnt_control (kcp->client, CLSET_RETRY_TIMEOUT,
++ (char *)&wait_time);
++ if (clnt_control (kcp->client, CLGET_FD, (char *)&fd))
++ fcntl (fd, F_SETFD, FD_CLOEXEC); /* make it "close on exec" */
+
+- /* if pid has changed, destroy client and rebuild */
+- if (kcp->client != NULL && kcp->pid != getpid()) {
+- clnt_destroy(kcp->client);
+- kcp->client = NULL;
+- }
++ return kcp->client;
++}
+
+- if (kcp->client != NULL) {
+- /* if uid has changed, build client handle again */
+- if (kcp->uid != geteuid()) {
+- kcp->uid = geteuid();
+- auth_destroy(kcp->client->cl_auth);
+- kcp->client->cl_auth =
+- authsys_create("", kcp->uid, 0, 0, NULL);
+- if (kcp->client->cl_auth == NULL) {
+- clnt_destroy(kcp->client);
+- kcp->client = NULL;
+- return ((CLIENT *) NULL);
+- }
+- }
+- /* Change the version number to the new one */
+- clnt_control(kcp->client, CLSET_VERS, (void *)&vers);
+- return (kcp->client);
+- }
+- if (!(localhandle = setnetconfig())) {
+- return ((CLIENT *) NULL);
+- }
+- tpconf = NULL;
+- if (uname(&u) == -1) {
+- endnetconfig(localhandle);
+- return ((CLIENT *) NULL);
+- }
+- while ((nconf = getnetconfig(localhandle)) != NULL) {
+- if (strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) {
+- /*
+- * We use COTS_ORD here so that the caller can
+- * find out immediately if the server is dead.
+- */
+- if (nconf->nc_semantics == NC_TPI_COTS_ORD) {
+- kcp->client = clnt_tp_create(u.nodename,
+- KEY_PROG, vers, nconf);
+- if (kcp->client)
+- break;
+- } else {
+- tpconf = nconf;
+- }
+- }
+- }
+- if ((kcp->client == (CLIENT *) NULL) && (tpconf))
+- /* Now, try the CLTS or COTS loopback transport */
+- kcp->client = clnt_tp_create(u.nodename,
+- KEY_PROG, vers, tpconf);
+- endnetconfig(localhandle);
+-
+- if (kcp->client == (CLIENT *) NULL) {
+- return ((CLIENT *) NULL);
+- }
+- kcp->uid = geteuid();
+- kcp->pid = getpid();
+- kcp->client->cl_auth = authsys_create("", kcp->uid, 0, 0, NULL);
+- if (kcp->client->cl_auth == NULL) {
+- clnt_destroy(kcp->client);
+- kcp->client = NULL;
+- return ((CLIENT *) NULL);
+- }
++/* returns 0 on failure, 1 on success */
++static int
++key_call_socket (u_long proc, xdrproc_t xdr_arg, char *arg,
++ xdrproc_t xdr_rslt, char *rslt)
++{
++ CLIENT *clnt;
++ struct timeval wait_time;
++ int result = 0;
+
+- wait_time.tv_sec = TOTAL_TIMEOUT/TOTAL_TRIES;
+- wait_time.tv_usec = 0;
+- (void) clnt_control(kcp->client, CLSET_RETRY_TIMEOUT,
+- (char *)&wait_time);
+- if (clnt_control(kcp->client, CLGET_FD, (char *)&fd))
+- fcntl(fd, F_SETFD, 1); /* make it "close on exec" */
++ if ((proc == KEY_ENCRYPT_PK) || (proc == KEY_DECRYPT_PK) ||
++ (proc == KEY_NET_GET) || (proc == KEY_NET_PUT) ||
++ (proc == KEY_GET_CONV))
++ clnt = getkeyserv_handle(2); /* talk to version 2 */
++ else
++ clnt = getkeyserv_handle(1); /* talk to version 1 */
+
+- return (kcp->client);
++ if (clnt != NULL)
++ {
++ wait_time.tv_sec = TOTAL_TIMEOUT;
++ wait_time.tv_usec = 0;
++
++ if (clnt_call (clnt, proc, xdr_arg, arg, xdr_rslt, rslt,
++ wait_time) == RPC_SUCCESS)
++ result = 1;
++ }
++
++ return result;
+ }
+
+-/* returns 0 on failure, 1 on success */
+
++/* returns 0 on failure, 1 on success */
+ static int
+-key_call(proc, xdr_arg, arg, xdr_rslt, rslt)
+- u_long proc;
+- xdrproc_t xdr_arg;
+- void *arg;
+- xdrproc_t xdr_rslt;
+- void *rslt;
+-{
+- CLIENT *clnt;
+- struct timeval wait_time;
+-
+- if (proc == KEY_ENCRYPT_PK && __key_encryptsession_pk_LOCAL) {
+- cryptkeyres *res;
+- res = (*__key_encryptsession_pk_LOCAL)(geteuid(), arg);
+- *(cryptkeyres*)rslt = *res;
+- return (1);
+- } else if (proc == KEY_DECRYPT_PK && __key_decryptsession_pk_LOCAL) {
+- cryptkeyres *res;
+- res = (*__key_decryptsession_pk_LOCAL)(geteuid(), arg);
+- *(cryptkeyres*)rslt = *res;
+- return (1);
+- } else if (proc == KEY_GEN && __key_gendes_LOCAL) {
+- des_block *res;
+- res = (*__key_gendes_LOCAL)(geteuid(), 0);
+- *(des_block*)rslt = *res;
+- return (1);
+- }
+-
+- if ((proc == KEY_ENCRYPT_PK) || (proc == KEY_DECRYPT_PK) ||
+- (proc == KEY_NET_GET) || (proc == KEY_NET_PUT) ||
+- (proc == KEY_GET_CONV))
+- clnt = getkeyserv_handle(2); /* talk to version 2 */
+- else
+- clnt = getkeyserv_handle(1); /* talk to version 1 */
++key_call (u_long proc, xdrproc_t xdr_arg, char *arg,
++ xdrproc_t xdr_rslt, char *rslt)
++{
++#ifndef SO_PASSCRED
++ static int use_keyenvoy;
++#endif
++
++ if (proc == KEY_ENCRYPT_PK && __key_encryptsession_pk_LOCAL)
++ {
++ cryptkeyres *res;
++ res = (*__key_encryptsession_pk_LOCAL) (geteuid (), arg);
++ *(cryptkeyres *) rslt = *res;
++ return 1;
++ }
++ else if (proc == KEY_DECRYPT_PK && __key_decryptsession_pk_LOCAL)
++ {
++ cryptkeyres *res;
++ res = (*__key_decryptsession_pk_LOCAL) (geteuid (), arg);
++ *(cryptkeyres *) rslt = *res;
++ return 1;
++ }
++ else if (proc == KEY_GEN && __key_gendes_LOCAL)
++ {
++ des_block *res;
++ res = (*__key_gendes_LOCAL) (geteuid (), 0);
++ *(des_block *) rslt = *res;
++ return 1;
++ }
+
+- if (clnt == NULL) {
+- return (0);
+- }
++#ifdef SO_PASSCRED
++ return key_call_socket (proc, xdr_arg, arg, xdr_rslt, rslt);
++#else
++ if (!use_keyenvoy)
++ {
++ if (key_call_socket (proc, xdr_arg, arg, xdr_rslt, rslt))
++ return 1;
++ use_keyenvoy = 1;
++ }
++ return key_call_keyenvoy (proc, xdr_arg, arg, xdr_rslt, rslt);
++#endif
++}
+
+- wait_time.tv_sec = TOTAL_TIMEOUT;
+- wait_time.tv_usec = 0;
++#ifdef _RPC_THREAD_SAFE_
++void
++__rpc_thread_key_cleanup (void)
++{
++ struct key_call_private *kcp = RPC_THREAD_VARIABLE(key_call_private_s);
+
+- if (clnt_call(clnt, proc, xdr_arg, arg, xdr_rslt, rslt,
+- wait_time) == RPC_SUCCESS) {
+- return (1);
+- } else {
+- return (0);
++ if (kcp) {
++ if (kcp->client) {
++ if (kcp->client->cl_auth)
++ auth_destroy (kcp->client->cl_auth);
++ clnt_destroy(kcp->client);
++ }
++ free (kcp);
+ }
+ }
++#endif /* _RPC_THREAD_SAFE_ */
+diff -urN libtirpc-0.2.3/src/Makefile.am libtirpc-0.2.3.new/src/Makefile.am
+--- libtirpc-0.2.3/src/Makefile.am 2013-02-13 16:13:59.000000000 +0100
++++ libtirpc-0.2.3.new/src/Makefile.am 2013-03-19 12:24:24.368923058 +0100
+@@ -50,7 +50,7 @@
+ rpc_callmsg.c rpc_generic.c rpc_soc.c rpcb_clnt.c rpcb_prot.c \
+ rpcb_st_xdr.c svc.c svc_auth.c svc_dg.c svc_auth_unix.c svc_auth_none.c \
+ svc_generic.c svc_raw.c svc_run.c svc_simple.c svc_vc.c getpeereid.c \
+- auth_time.c auth_des.c authdes_prot.c
++ auth_time.c auth_des.c authdes_prot.c des_crypt.c key_call.c key_prot_xdr.c netname.c getpublickey.c rpcdname.c des_impl.c
+
+ ## XDR
+ libtirpc_la_SOURCES += xdr.c xdr_rec.c xdr_array.c xdr_float.c xdr_mem.c xdr_reference.c xdr_stdio.c
diff --git a/meta/recipes-extended/libtirpc/libtirpc-0.2.3/libtirpc-0.2.3-types.h.patch b/meta/recipes-extended/libtirpc/libtirpc-0.2.3/libtirpc-0.2.3-types.h.patch
new file mode 100644
index 0000000..2a0768d
--- /dev/null
+++ b/meta/recipes-extended/libtirpc/libtirpc-0.2.3/libtirpc-0.2.3-types.h.patch
@@ -0,0 +1,14 @@
+--- libtirpc-0.2.3/tirpc/rpc/types.h.bero 2013-01-28 23:59:14.383069929 +0100
++++ libtirpc-0.2.3/tirpc/rpc/types.h 2013-01-28 23:59:39.123777626 +0100
+@@ -38,6 +38,11 @@
+ #ifndef _TIRPC_TYPES_H
+ #define _TIRPC_TYPES_H
+
++#ifndef _BSD_SOURCE
++/* For uint_t and friends */
++#define _BSD_SOURCE 1
++#endif
++
+ #include <sys/types.h>
+
+ typedef int32_t bool_t;
diff --git a/meta/recipes-extended/libtirpc/libtirpc-0.2.3/libtirpc-0008-Add-rpcgen-program-from-nfs-utils-sources.patch b/meta/recipes-extended/libtirpc/libtirpc-0.2.3/libtirpc-0008-Add-rpcgen-program-from-nfs-utils-sources.patch
new file mode 100644
index 0000000..60f43df
--- /dev/null
+++ b/meta/recipes-extended/libtirpc/libtirpc-0.2.3/libtirpc-0008-Add-rpcgen-program-from-nfs-utils-sources.patch
@@ -0,0 +1,6408 @@
+--- libtirpc-0.2.3/configure.ac.0005~ 2013-02-11 21:47:03.982289136 +0100
++++ libtirpc-0.2.3/configure.ac 2013-02-11 21:47:03.990289233 +0100
+@@ -25,6 +25,16 @@ AC_CHECK_HEADERS([arpa/inet.h fcntl.h li
+ AC_CHECK_LIB([pthread], [pthread_create])
+ AC_CHECK_LIB([nsl], [yp_get_default_domain])
+
++AM_CONDITIONAL(CROSS_COMPILING, test $cross_compiling = yes)
+
+-AC_CONFIG_FILES([Makefile src/Makefile man/Makefile doc/Makefile])
++
++AC_MSG_CHECKING([for a C compiler for build tools])
++if test $cross_compiling = yes; then
++ AC_CHECK_PROGS(CC_FOR_BUILD, gcc cc)
++else
++ CC_FOR_BUILD=$CC
++fi
++AC_MSG_RESULT([$CC_FOR_BUILD])
++AC_SUBST(CC_FOR_BUILD)
++AC_CONFIG_FILES([Makefile src/Makefile man/Makefile doc/Makefile rpcgen/Makefile])
+ AC_OUTPUT(libtirpc.pc)
+--- libtirpc-0.2.3/Makefile.am.0005~ 2012-04-26 21:54:02.000000000 +0200
++++ libtirpc-0.2.3/Makefile.am 2013-02-11 21:47:03.990289233 +0100
+@@ -1,4 +1,4 @@
+-SUBDIRS = src man doc
++SUBDIRS = src man doc rpcgen
+ ACLOCAL_AMFLAGS = -I m4
+
+ nobase_include_HEADERS = tirpc/netconfig.h \
+--- libtirpc-0.2.3/rpcgen/Makefile.am.0005~ 2013-02-11 21:47:03.990289233 +0100
++++ libtirpc-0.2.3/rpcgen/Makefile.am 2013-02-11 21:49:37.233184084 +0100
+@@ -0,0 +1,24 @@
++INCLUDES = -I$(top_srcdir)/tirpc -DPORTMAP -DINET6 -DVERSION="\"$(VERSION)\"" \
++ -D_GNU_SOURCE -Wall -pipe
++COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
++ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
++LINK = $(CC) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
++
++bin_PROGRAMS = rpcgen
++
++rpcgen_SOURCES = \
++ rpc_clntout.c \
++ rpc_cout.c \
++ rpc_hout.c \
++ rpc_main.c \
++ rpc_parse.c \
++ rpc_sample.c \
++ rpc_scan.c \
++ rpc_svcout.c \
++ rpc_tblout.c \
++ rpc_util.c \
++ rpc_parse.h \
++ rpc_scan.h \
++ rpc_util.h
++
++dist_man1_MANS = rpcgen.1
+--- libtirpc-0.2.3/rpcgen/rpc_clntout.c.0005~ 2013-02-11 21:47:03.990289233 +0100
++++ libtirpc-0.2.3/rpcgen/rpc_clntout.c 2013-02-11 21:47:03.990289233 +0100
+@@ -0,0 +1,217 @@
++/*
++ * Copyright (c) 2009, Sun Microsystems, Inc.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions are met:
++ * - Redistributions of source code must retain the above copyright notice,
++ * this list of conditions and the following disclaimer.
++ * - Redistributions in binary form must reproduce the above copyright notice,
++ * this list of conditions and the following disclaimer in the documentation
++ * and/or other materials provided with the distribution.
++ * - Neither the name of Sun Microsystems, Inc. nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
++ * POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#if 0
++static char sccsid[] = "@(#)rpc_clntout.c 1.11 89/02/22 (C) 1987 SMI";
++#endif
++
++/*
++ * rpc_clntout.c, Client-stub outputter for the RPC protocol compiler
++ * Copyright (C) 1987, Sun Microsytsems, Inc.
++ */
++#include <stdio.h>
++#include <string.h>
++#include <rpc/types.h>
++#include "rpc_parse.h"
++#include "rpc_util.h"
++#include "rpc_output.h"
++
++/* extern pdeclaration(); */
++/* void printarglist(); */
++
++#define DEFAULT_TIMEOUT 25 /* in seconds */
++static char RESULT[] = "clnt_res";
++
++static void write_program(definition *def);
++static void printbody(proc_list *proc);
++
++
++void
++write_stubs(void)
++{
++ list *l;
++ definition *def;
++
++ f_print(fout,
++ "\n/* Default timeout can be changed using clnt_control() */\n");
++ f_print(fout, "static struct timeval TIMEOUT = { %d, 0 };\n",
++ DEFAULT_TIMEOUT);
++ for (l = defined; l != NULL; l = l->next) {
++ def = (definition *) l->val;
++ if (def->def_kind == DEF_PROGRAM) {
++ write_program(def);
++ }
++ }
++}
++
++static void
++write_program(definition *def)
++{
++ version_list *vp;
++ proc_list *proc;
++
++ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
++ for (proc = vp->procs; proc != NULL; proc = proc->next) {
++ f_print(fout, "\n");
++ ptype(proc->res_prefix, proc->res_type, 1);
++ f_print(fout, "*\n");
++ pvname(proc->proc_name, vp->vers_num);
++ printarglist(proc, "clnt", "CLIENT *");
++ f_print(fout, "{\n");
++ printbody(proc);
++ f_print(fout, "}\n");
++ }
++ }
++}
++
++/*
++ * Writes out declarations of procedure's argument list.
++ * In either ANSI C style, in one of old rpcgen style (pass by reference),
++ * or new rpcgen style (multiple arguments, pass by value);
++ */
++
++/* sample addargname = "clnt"; sample addargtype = "CLIENT * " */
++
++void
++printarglist(proc_list *proc, char *addargname, char *addargtype)
++{
++
++ decl_list *l;
++
++ if (!newstyle) { /* old style: always pass arg by reference */
++ if (Cflag) { /* C++ style heading */
++ f_print(fout, "(");
++ ptype(proc->args.decls->decl.prefix, proc->args.decls->decl.type, 1);
++ f_print(fout, "*argp, %s%s)\n", addargtype, addargname);
++ } else {
++ f_print(fout, "(argp, %s)\n", addargname);
++ f_print(fout, "\t");
++ ptype(proc->args.decls->decl.prefix, proc->args.decls->decl.type, 1);
++ f_print(fout, "*argp;\n");
++ }
++ } else if (streq(proc->args.decls->decl.type, "void")) {
++ /* newstyle, 0 argument */
++ if (Cflag)
++ f_print(fout, "(%s%s)\n", addargtype, addargname);
++ else
++ f_print(fout, "(%s)\n", addargname);
++ } else {
++ /* new style, 1 or multiple arguments */
++ if (!Cflag) {
++ f_print(fout, "(");
++ for (l = proc->args.decls; l != NULL; l = l->next)
++ f_print(fout, "%s, ", l->decl.name);
++ f_print(fout, "%s)\n", addargname);
++ for (l = proc->args.decls; l != NULL; l = l->next) {
++ pdeclaration(proc->args.argname, &l->decl, 1, ";\n");
++ }
++ } else { /* C++ style header */
++ f_print(fout, "(");
++ for (l = proc->args.decls; l != NULL; l = l->next) {
++ pdeclaration(proc->args.argname, &l->decl, 0, ", ");
++ }
++ f_print(fout, " %s%s)\n", addargtype, addargname);
++ }
++ }
++
++ if (!Cflag)
++ f_print(fout, "\t%s%s;\n", addargtype, addargname);
++}
++
++
++
++static char *
++ampr(char *type)
++{
++ if (isvectordef(type, REL_ALIAS)) {
++ return ("");
++ } else {
++ return ("&");
++ }
++}
++
++static void
++printbody(proc_list *proc)
++{
++ decl_list *l;
++ bool_t args2 = (proc->arg_num > 1);
++
++ /* For new style with multiple arguments, need a structure in which
++ * to stuff the arguments. */
++ if (newstyle && args2) {
++ f_print(fout, "\t%s", proc->args.argname);
++ f_print(fout, " arg;\n");
++ }
++ f_print(fout, "\tstatic ");
++ if (streq(proc->res_type, "void")) {
++ f_print(fout, "char ");
++ } else {
++ ptype(proc->res_prefix, proc->res_type, 0);
++ }
++ f_print(fout, "%s;\n", RESULT);
++ f_print(fout, "\n");
++ f_print(fout, "\tmemset((char *)%s%s, 0, sizeof(%s));\n",
++ ampr(proc->res_type), RESULT, RESULT);
++ if (newstyle && !args2 && (streq(proc->args.decls->decl.type, "void"))) {
++ /* newstyle, 0 arguments */
++ f_print(fout,
++ "\tif (clnt_call(clnt, %s, (xdrproc_t) xdr_void, (caddr_t) NULL, "
++ "(xdrproc_t) xdr_%s, (caddr_t) %s%s, TIMEOUT) != RPC_SUCCESS) {\n",
++ proc->proc_name,
++ stringfix(proc->res_type), ampr(proc->res_type), RESULT);
++
++ } else if (newstyle && args2) {
++ /* newstyle, multiple arguments: stuff arguments into structure */
++ for (l = proc->args.decls; l != NULL; l = l->next) {
++ f_print(fout, "\targ.%s = %s;\n",
++ l->decl.name, l->decl.name);
++ }
++ f_print(fout,
++ "\tif (clnt_call(clnt, %s, (xdrproc_t) xdr_%s, (caddr_t) &arg, "
++ "(xdrproc_t) xdr_%s, (caddr_t) %s%s, TIMEOUT) != RPC_SUCCESS) {\n",
++ proc->proc_name, proc->args.argname,
++ stringfix(proc->res_type), ampr(proc->res_type), RESULT);
++ } else { /* single argument, new or old style */
++ f_print(fout,
++ "\tif (clnt_call(clnt, %s, (xdrproc_t) xdr_%s, "
++ "(caddr_t) %s%s, (xdrproc_t) xdr_%s, (caddr_t) %s%s, TIMEOUT) != RPC_SUCCESS) {\n",
++ proc->proc_name,
++ stringfix(proc->args.decls->decl.type),
++ (newstyle ? "&" : ""),
++ (newstyle ? proc->args.decls->decl.name : "argp"),
++ stringfix(proc->res_type), ampr(proc->res_type), RESULT);
++ }
++ f_print(fout, "\t\treturn (NULL);\n");
++ f_print(fout, "\t}\n");
++ if (streq(proc->res_type, "void")) {
++ f_print(fout, "\treturn ((void *)%s%s);\n",
++ ampr(proc->res_type), RESULT);
++ } else {
++ f_print(fout, "\treturn (%s%s);\n", ampr(proc->res_type), RESULT);
++ }
++}
+--- libtirpc-0.2.3/rpcgen/rpc_cout.c.0005~ 2013-02-11 21:47:03.991289244 +0100
++++ libtirpc-0.2.3/rpcgen/rpc_cout.c 2013-02-11 21:47:03.991289244 +0100
+@@ -0,0 +1,706 @@
++/*
++ * Copyright (c) 2009, Sun Microsystems, Inc.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions are met:
++ * - Redistributions of source code must retain the above copyright notice,
++ * this list of conditions and the following disclaimer.
++ * - Redistributions in binary form must reproduce the above copyright notice,
++ * this list of conditions and the following disclaimer in the documentation
++ * and/or other materials provided with the distribution.
++ * - Neither the name of Sun Microsystems, Inc. nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
++ * POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#if 0
++static char sccsid[] = "@(#)rpc_cout.c 1.13 89/02/22 (C) 1987 SMI";
++#endif
++
++/*
++ * rpc_cout.c, XDR routine outputter for the RPC protocol compiler
++ */
++#include <stdio.h>
++#include <string.h>
++#include <stdlib.h>
++#include <malloc.h>
++#include <ctype.h>
++#include "rpc_parse.h"
++#include "rpc_util.h"
++
++static int findtype(definition *def, char *type);
++static int undefined(char *type);
++static void print_generic_header(char *procname, int pointerp);
++static void print_header(definition *def);
++static void print_prog_header(proc_list *plist);
++static void print_trailer(void);
++static void print_ifopen(int indent, char *name);
++static void print_ifarg(char *arg);
++static void print_ifsizeof(char *prefix, char *type);
++static void print_ifclose(int indent);
++static void print_ifstat(int indent, char *prefix, char *type, relation rel,
++ char *amax, char *objname, char *name);
++static void emit_enum(definition *def);
++static void emit_program(definition *def);
++static void emit_union(definition *def);
++static void emit_struct(definition *def);
++static void emit_typedef(definition *def);
++static void print_stat(int indent, declaration *dec);
++static void emit_inline(declaration *decl, int flag);
++static void emit_single_in_line(declaration *decl, int flag, relation rel);
++static char * upcase(char *str);
++
++/*
++ * Emit the C-routine for the given definition
++ */
++void
++emit(definition *def)
++{
++ if (def->def_kind == DEF_CONST) {
++ return;
++ }
++ if (def->def_kind == DEF_PROGRAM) {
++ emit_program(def);
++ return;
++ }
++ if (def->def_kind == DEF_TYPEDEF) {
++ /* now we need to handle declarations like
++ * struct typedef foo foo;
++ * since we dont want this to be expanded into 2 calls
++ * to xdr_foo */
++
++ if (strcmp(def->def.ty.old_type, def->def_name) == 0)
++ return;
++ };
++
++ print_header(def);
++ switch (def->def_kind) {
++ case DEF_UNION:
++ emit_union(def);
++ break;
++ case DEF_ENUM:
++ emit_enum(def);
++ break;
++ case DEF_STRUCT:
++ emit_struct(def);
++ break;
++ case DEF_TYPEDEF:
++ emit_typedef(def);
++ break;
++ default:
++ break;
++ }
++ print_trailer();
++}
++
++static int
++findtype(definition *def, char *type)
++{
++
++ if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST) {
++ return (0);
++ } else {
++ return (streq(def->def_name, type));
++ }
++}
++
++static int
++undefined(char *type)
++{
++ definition *def;
++
++ def = (definition *) FINDVAL(defined, type, findtype);
++
++ return (def == NULL);
++}
++
++
++static void
++print_generic_header(char *procname, int pointerp)
++{
++ f_print(fout, "\n");
++ f_print(fout, "bool_t\n");
++ if (Cflag) {
++ f_print(fout, "xdr_%s(", procname);
++ f_print(fout, "XDR *xdrs, ");
++ f_print(fout, "%s ", procname);
++ if (pointerp)
++ f_print(fout, "*");
++ f_print(fout, "objp)\n{\n\n");
++ } else {
++ f_print(fout, "xdr_%s(xdrs, objp)\n", procname);
++ f_print(fout, "\tXDR *xdrs;\n");
++ f_print(fout, "\t%s ", procname);
++ if (pointerp)
++ f_print(fout, "*");
++ f_print(fout, "objp;\n{\n\n");
++ }
++}
++
++static void
++print_header(definition *def)
++{
++ print_generic_header(def->def_name,
++ def->def_kind != DEF_TYPEDEF ||
++ !isvectordef(def->def.ty.old_type, def->def.ty.rel));
++
++ /* Now add Inline support */
++
++
++ if (Inline == 0)
++ return;
++}
++
++static void
++print_prog_header(proc_list *plist)
++{
++ print_generic_header(plist->args.argname, 1);
++}
++
++static void
++print_trailer(void)
++{
++ f_print(fout, "\treturn (TRUE);\n");
++ f_print(fout, "}\n");
++}
++
++
++static void
++print_ifopen(int indent, char *name)
++{
++ tabify(fout, indent);
++ f_print(fout, " if (!xdr_%s(xdrs", name);
++}
++
++static void
++print_ifarg(char *arg)
++{
++ f_print(fout, ", %s", arg);
++}
++
++static void
++print_ifsizeof(char *prefix, char *type)
++{
++ if (streq(type, "bool")) {
++ f_print(fout, ", sizeof(bool_t), (xdrproc_t)xdr_bool");
++ } else {
++ f_print(fout, ", sizeof(");
++ if (undefined(type) && prefix) {
++ f_print(fout, "%s ", prefix);
++ }
++ f_print(fout, "%s), (xdrproc_t)xdr_%s", type, type);
++ }
++}
++
++static void
++print_ifclose(int indent)
++{
++ f_print(fout, ")) {\n");
++ tabify(fout, indent);
++ f_print(fout, "\t return (FALSE);\n");
++ tabify(fout, indent);
++ f_print(fout, " }\n");
++}
++
++static void
++print_ifstat(int indent, char *prefix, char *type, relation rel,
++ char *amax, char *objname, char *name)
++{
++ char *alt = NULL;
++
++ switch (rel) {
++ case REL_POINTER:
++ print_ifopen(indent, "pointer");
++ print_ifarg("(char **)");
++ f_print(fout, "%s", objname);
++ print_ifsizeof(prefix, type);
++ break;
++ case REL_VECTOR:
++ if (streq(type, "string")) {
++ alt = "string";
++ } else if (streq(type, "opaque")) {
++ alt = "opaque";
++ }
++ if (alt) {
++ print_ifopen(indent, alt);
++ print_ifarg(objname);
++ } else {
++ print_ifopen(indent, "vector");
++ print_ifarg("(char *)");
++ f_print(fout, "%s", objname);
++ }
++ print_ifarg(amax);
++ if (!alt) {
++ print_ifsizeof(prefix, type);
++ }
++ break;
++ case REL_ARRAY:
++ if (streq(type, "string")) {
++ alt = "string";
++ } else if (streq(type, "opaque")) {
++ alt = "bytes";
++ }
++ if (streq(type, "string")) {
++ print_ifopen(indent, alt);
++ print_ifarg(objname);
++ } else {
++ if (alt) {
++ print_ifopen(indent, alt);
++ } else {
++ print_ifopen(indent, "array");
++ }
++ /* The (void*) avoids a gcc-4.1 warning */
++ print_ifarg("(char **)(void*)");
++ if (*objname == '&') {
++ f_print(fout, "%s.%s_val, (u_int *)%s.%s_len",
++ objname, name, objname, name);
++ } else {
++ f_print(fout, "&%s->%s_val, (u_int *)&%s->%s_len",
++ objname, name, objname, name);
++ }
++ }
++ print_ifarg(amax);
++ if (!alt) {
++ print_ifsizeof(prefix, type);
++ }
++ break;
++ case REL_ALIAS:
++ print_ifopen(indent, type);
++ print_ifarg(objname);
++ break;
++ }
++ print_ifclose(indent);
++}
++
++static void
++emit_enum(definition *def)
++{
++ print_ifopen(1, "enum");
++ print_ifarg("(enum_t *)objp");
++ print_ifclose(1);
++}
++
++static void
++emit_program(definition *def)
++{
++ decl_list *dl;
++ version_list *vlist;
++ proc_list *plist;
++
++ for (vlist = def->def.pr.versions; vlist != NULL; vlist = vlist->next)
++ for (plist = vlist->procs; plist != NULL; plist = plist->next) {
++ if (!newstyle || plist->arg_num < 2)
++ continue;/* old style, or single argument */
++ print_prog_header(plist);
++ for (dl = plist->args.decls; dl != NULL; dl = dl->next)
++ print_stat(1, &dl->decl);
++ print_trailer();
++ }
++}
++
++
++static void
++emit_union(definition *def)
++{
++ declaration *dflt;
++ case_list *cl;
++ declaration *cs;
++ char *object;
++ char *vecformat = "objp->%s_u.%s";
++ char *format = "&objp->%s_u.%s";
++
++ print_stat(1,&def->def.un.enum_decl);
++ f_print(fout, "\tswitch (objp->%s) {\n", def->def.un.enum_decl.name);
++ for (cl = def->def.un.cases; cl != NULL; cl = cl->next) {
++
++ f_print(fout, "\tcase %s:\n", cl->case_name);
++ if(cl->contflag == 1) /* a continued case statement */
++ continue;
++ cs = &cl->case_decl;
++ if (!streq(cs->type, "void")) {
++ object = alloc(strlen(def->def_name) + strlen(format) +
++ strlen(cs->name) + 1);
++ if (isvectordef (cs->type, cs->rel)) {
++ s_print(object, vecformat, def->def_name,
++ cs->name);
++ } else {
++ s_print(object, format, def->def_name,
++ cs->name);
++ }
++ print_ifstat(2, cs->prefix, cs->type, cs->rel, cs->array_max,
++ object, cs->name);
++ free(object);
++ }
++ f_print(fout, "\t\tbreak;\n");
++ }
++ dflt = def->def.un.default_decl;
++ if (dflt != NULL) {
++ if (!streq(dflt->type, "void")) {
++ f_print(fout, "\tdefault:\n");
++ object = alloc(strlen(def->def_name) + strlen(format) +
++ strlen(dflt->name) + 1);
++ if (isvectordef (dflt->type, dflt->rel)) {
++ s_print(object, vecformat, def->def_name,
++ dflt->name);
++ } else {
++ s_print(object, format, def->def_name,
++ dflt->name);
++ }
++
++ print_ifstat(2, dflt->prefix, dflt->type, dflt->rel,
++ dflt->array_max, object, dflt->name);
++ free(object);
++ f_print(fout, "\t\tbreak;\n");
++ } else {
++ /* Avoid gcc warnings about `value not handled in switch' */
++ f_print(fout, "\tdefault:\n");
++ f_print(fout, "\t\tbreak;\n");
++ }
++ } else {
++ f_print(fout, "\tdefault:\n");
++ f_print(fout, "\t\treturn (FALSE);\n");
++ }
++
++ f_print(fout, "\t}\n");
++}
++
++static void
++emit_struct(definition *def)
++{
++ decl_list *dl;
++ int i, j, size, flag;
++ decl_list *cur = NULL, *psav;
++ bas_type *ptr;
++ char *sizestr, *plus;
++ char ptemp[256];
++ int can_inline;
++ const char *buf_declaration;
++
++
++ if (Inline == 0) {
++ for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
++ print_stat(1, &dl->decl);
++ } else {
++ size = 0;
++ can_inline = 0;
++ for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
++ if ((dl->decl.prefix == NULL) && ((ptr = find_type(dl->decl.type)) != NULL) && ((dl->decl.rel == REL_ALIAS) || (dl->decl.rel == REL_VECTOR))) {
++
++ if (dl->decl.rel == REL_ALIAS)
++ size += ptr->length;
++ else {
++ can_inline = 1;
++ break; /* can be inlined */
++ };
++ } else {
++ if (size >= Inline) {
++ can_inline = 1;
++ break; /* can be inlined */
++ }
++ size = 0;
++ }
++ if (size > Inline)
++ can_inline = 1;
++
++ if (can_inline == 0) { /* can not inline, drop back to old mode */
++ for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
++ print_stat(1, &dl->decl);
++ return;
++ };
++
++
++
++
++ flag = PUT;
++ for (j = 0; j < 2; j++) {
++
++ if (flag == PUT)
++ f_print(fout, "\n\t if (xdrs->x_op == XDR_ENCODE) {\n");
++ else
++ f_print(fout, "\n \t return (TRUE);\n\t} else if (xdrs->x_op == XDR_DECODE) {\n");
++
++
++ i = 0;
++ size = 0;
++ sizestr = NULL;
++ buf_declaration = "int32_t *";
++ for (dl = def->def.st.decls; dl != NULL; dl = dl->next) { /* xxx */
++
++ /* now walk down the list and check for basic types */
++ if ((dl->decl.prefix == NULL) && ((ptr = find_type(dl->decl.type)) != NULL) && ((dl->decl.rel == REL_ALIAS) || (dl->decl.rel == REL_VECTOR))) {
++ if (i == 0)
++ cur = dl;
++ i++;
++
++ if (dl->decl.rel == REL_ALIAS)
++ size += ptr->length;
++ else {
++ /* this is required to handle arrays */
++
++ if (sizestr == NULL)
++ plus = " ";
++ else
++ plus = "+";
++
++ if (ptr->length != 1)
++ s_print(ptemp, " %s %s * %d", plus, dl->decl.array_max, ptr->length);
++ else
++ s_print(ptemp, " %s %s ", plus, dl->decl.array_max);
++
++ /*now concatenate to sizestr !!!! */
++ if (sizestr == NULL)
++ sizestr = strdup(ptemp);
++ else {
++ sizestr = realloc(sizestr, strlen(sizestr) + strlen(ptemp) + 1);
++ if (sizestr == NULL) {
++
++ f_print(stderr, "Fatal error : no memory \n");
++ crash();
++ };
++ sizestr = strcat(sizestr, ptemp); /*build up length of array */
++
++ }
++ }
++
++ } else {
++ if (i > 0)
++ {
++ if (sizestr == NULL && size < Inline) {
++ /* don't expand into inline code if size < inline */
++ while (cur != dl) {
++ print_stat(1, &cur->decl);
++ cur = cur->next;
++ }
++ } else {
++
++
++
++ /* were already looking at a xdr_inlineable structure */
++ if (sizestr == NULL)
++ f_print(fout, "\t %sbuf = XDR_INLINE(xdrs,%d * BYTES_PER_XDR_UNIT);",
++ buf_declaration, size);
++ else if (size == 0)
++ f_print(fout,
++ "\t %sbuf = XDR_INLINE(xdrs,%s * BYTES_PER_XDR_UNIT);",
++ buf_declaration, sizestr);
++ else
++ f_print(fout,
++ "\t %sbuf = XDR_INLINE(xdrs,(%d + %s)* BYTES_PER_XDR_UNIT);",
++ buf_declaration, size, sizestr);
++ buf_declaration = "";
++
++ f_print(fout, "\n\t if (buf == NULL) {\n");
++
++ psav = cur;
++ while (cur != dl) {
++ print_stat(2, &cur->decl);
++ cur = cur->next;
++ }
++
++ f_print(fout, "\n\t }\n\t else {\n");
++
++ cur = psav;
++ while (cur != dl) {
++ emit_inline(&cur->decl, flag);
++ cur = cur->next;
++ }
++
++ f_print(fout, "\t }\n");
++ }
++ }
++ size = 0;
++ i = 0;
++ sizestr = NULL;
++ print_stat(1, &dl->decl);
++ }
++
++ }
++ if (i > 0)
++ {
++ if (sizestr == NULL && size < Inline) {
++ /* don't expand into inline code if size < inline */
++ while (cur != dl) {
++ print_stat(1, &cur->decl);
++ cur = cur->next;
++ }
++ } else {
++
++ /* were already looking at a xdr_inlineable structure */
++ if (sizestr == NULL)
++ f_print(fout, "\t\t%sbuf = XDR_INLINE(xdrs,%d * BYTES_PER_XDR_UNIT);",
++ buf_declaration, size);
++ else if (size == 0)
++ f_print(fout,
++ "\t\t%sbuf = XDR_INLINE(xdrs,%s * BYTES_PER_XDR_UNIT);",
++ buf_declaration, sizestr);
++ else
++ f_print(fout,
++ "\t\t%sbuf = XDR_INLINE(xdrs,(%d + %s)* BYTES_PER_XDR_UNIT);",
++ buf_declaration, size, sizestr);
++ buf_declaration = "";
++
++ f_print(fout, "\n\t\tif (buf == NULL) {\n");
++
++ psav = cur;
++ while (cur != NULL) {
++ print_stat(2, &cur->decl);
++ cur = cur->next;
++ }
++ f_print(fout, "\n\t }\n\t else {\n");
++
++ cur = psav;
++ while (cur != dl) {
++ emit_inline(&cur->decl, flag);
++ cur = cur->next;
++ }
++
++ f_print(fout, "\t }\n");
++
++ }
++ }
++ flag = GET;
++ }
++ f_print(fout, "\t return(TRUE);\n\t}\n\n");
++
++ /* now take care of XDR_FREE case */
++
++ for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
++ print_stat(1, &dl->decl);
++ }
++}
++
++
++
++
++static void
++emit_typedef(definition *def)
++{
++ char *prefix = def->def.ty.old_prefix;
++ char *type = def->def.ty.old_type;
++ char *amax = def->def.ty.array_max;
++ relation rel = def->def.ty.rel;
++
++
++ print_ifstat(1, prefix, type, rel, amax, "objp", def->def_name);
++}
++
++static void
++print_stat(int indent, declaration *dec)
++{
++ char *prefix = dec->prefix;
++ char *type = dec->type;
++ char *amax = dec->array_max;
++ relation rel = dec->rel;
++ char name[256];
++
++ if (isvectordef(type, rel)) {
++ s_print(name, "objp->%s", dec->name);
++ } else {
++ s_print(name, "&objp->%s", dec->name);
++ }
++ print_ifstat(indent, prefix, type, rel, amax, name, dec->name);
++}
++
++
++static void
++emit_inline(declaration *decl, int flag)
++{
++
++ /*check whether an array or not */
++
++ switch (decl->rel) {
++ case REL_ALIAS:
++ emit_single_in_line(decl, flag, REL_ALIAS);
++ break;
++ case REL_VECTOR:
++ f_print(fout, "\t\t{ register %s *genp; \n", decl->type);
++ f_print(fout, "\t\t int i;\n");
++ f_print(fout, "\t\t for ( i = 0,genp=objp->%s;\n \t\t\ti < %s; i++){\n\t\t",
++ decl->name, decl->array_max);
++ emit_single_in_line(decl, flag, REL_VECTOR);
++ f_print(fout, "\t\t }\n\t\t };\n");
++ break;
++ default:
++ break;
++ }
++}
++
++static void
++emit_single_in_line(declaration *decl, int flag, relation rel)
++{
++ char *upp_case;
++ int freed=0;
++
++ if(flag == PUT)
++ f_print(fout,"\t\t (void) IXDR_PUT_");
++ else
++ if(rel== REL_ALIAS)
++ f_print(fout,"\t\t objp->%s = IXDR_GET_",decl->name);
++ else
++ f_print(fout,"\t\t *genp++ = IXDR_GET_");
++
++ upp_case=upcase(decl->type);
++
++ /* hack - XX */
++ if(strcmp(upp_case,"INT") == 0)
++ {
++ free(upp_case);
++ freed=1;
++ upp_case="INT32";
++ }
++
++ if(strcmp(upp_case,"U_INT") == 0)
++ {
++ free(upp_case);
++ freed=1;
++ upp_case="U_INT32";
++ }
++
++
++ if(flag == PUT)
++ if(rel== REL_ALIAS)
++ f_print(fout,"%s(buf,objp->%s);\n",upp_case,decl->name);
++ else
++ f_print(fout,"%s(buf,*genp++);\n",upp_case);
++
++ else
++ f_print(fout,"%s(buf);\n",upp_case);
++ if(!freed)
++ free(upp_case);
++
++}
++
++
++static char *
++upcase(char *str)
++{
++ char *ptr, *hptr;
++
++
++ ptr = (char *) malloc(strlen(str)+1);
++ if (ptr == (char *) NULL) {
++ f_print(stderr, "malloc failed \n");
++ exit(1);
++ };
++
++ hptr = ptr;
++ while (*str != '\0')
++ *ptr++ = toupper(*str++);
++
++ *ptr = '\0';
++ return (hptr);
++
++}
+--- libtirpc-0.2.3/rpcgen/rpcgen.1.0005~ 2013-02-11 21:47:03.991289244 +0100
++++ libtirpc-0.2.3/rpcgen/rpcgen.1 2013-02-11 21:47:03.991289244 +0100
+@@ -0,0 +1,521 @@
++.\" @(#)rpcgen.1 1.35 93/06/02 SMI
++.\" $FreeBSD: src/usr.bin/rpcgen/rpcgen.1,v 1.12.2.4 2002/06/21 15:28:50 charnier Exp $
++.\" Copyright 1985-1993 Sun Microsystems, Inc.
++.Dd March 28, 1993
++.Dt RPCGEN 1
++.Os
++.Sh NAME
++.Nm rpcgen
++.Nd an RPC protocol compiler
++.Sh SYNOPSIS
++.Nm
++.Ar infile
++.Nm
++.Op Fl a
++.Op Fl b
++.Op Fl C
++.Oo
++.Fl D Ns Ar name Ns Op Ar =value
++.Oc
++.Op Fl i Ar size
++.Op Fl I Op Fl K Ar seconds
++.Op Fl L
++.Op Fl M
++.Op Fl N
++.Op Fl T
++.Op Fl Y Ar pathname
++.Ar infile
++.Nm
++.Oo
++.Fl c |
++.Fl h |
++.Fl l |
++.Fl m |
++.Fl t |
++.Fl \&Sc |
++.Fl \&Ss |
++.Fl \&Sm
++.Oc
++.Op Fl o Ar outfile
++.Op Ar infile
++.Nm
++.Op Fl s Ar nettype
++.Op Fl o Ar outfile
++.Op Ar infile
++.Nm
++.Op Fl n Ar netid
++.Op Fl o Ar outfile
++.Op Ar infile
++.\" .SH AVAILABILITY
++.\" .LP
++.\" SUNWcsu
++.Sh DESCRIPTION
++The
++.Nm
++utility is a tool that generates C code to implement an
++.Tn RPC
++protocol.
++The input to
++.Nm
++is a language similar to C known as
++.Tn RPC
++Language (Remote Procedure Call Language).
++.Pp
++The
++.Nm
++utility is normally used as in the first synopsis where
++it takes an input file and generates three output files.
++If the
++.Ar infile
++is named
++.Pa proto.x ,
++then
++.Nm
++generates a header in
++.Pa proto.h ,
++XDR routines in
++.Pa proto_xdr.c ,
++server-side stubs in
++.Pa proto_svc.c ,
++and client-side stubs in
++.Pa proto_clnt.c .
++With the
++.Fl T
++option,
++it also generates the
++.Tn RPC
++dispatch table in
++.Pa proto_tbl.i .
++.Pp
++The
++.Nm
++utility can also generate sample client and server files
++that can be customized to suit a particular application.
++The
++.Fl \&Sc ,
++.Fl \&Ss
++and
++.Fl \&Sm
++options generate sample client, server and makefile, respectively.
++The
++.Fl a
++option generates all files, including sample files.
++If the
++.Ar infile
++is
++.Pa proto.x ,
++then the client side sample file is written to
++.Pa proto_client.c ,
++the server side sample file to
++.Pa proto_server.c
++and the sample makefile to
++.Pa makefile.proto .
++.Pp
++The server created can be started both by the port monitors
++(for example,
++.Xr inetd 8 )
++or by itself.
++When it is started by a port monitor,
++it creates servers only for the transport for which
++the file descriptor
++.Em 0
++was passed.
++The name of the transport must be specified
++by setting up the environment variable
++.Ev PM_TRANSPORT .
++When the server generated by
++.Nm
++is executed,
++it creates server handles for all the transports
++specified in
++.Ev NETPATH
++environment variable,
++or if it is unset,
++it creates server handles for all the visible transports from
++.Pa /etc/netconfig
++file.
++Note:
++the transports are chosen at run time and not at compile time.
++When the server is self-started,
++it backgrounds itself by default.
++A special define symbol
++.Em RPC_SVC_FG
++can be used to run the server process in foreground.
++.Pp
++The second synopsis provides special features which allow
++for the creation of more sophisticated
++.Tn RPC
++servers.
++These features include support for user provided
++.Em #defines
++and
++.Tn RPC
++dispatch tables.
++The entries in the
++.Tn RPC
++dispatch table contain:
++.Bl -bullet -offset indent -compact
++.It
++pointers to the service routine corresponding to that procedure,
++.It
++a pointer to the input and output arguments,
++.It
++the size of these routines.
++.El
++A server can use the dispatch table to check authorization
++and then to execute the service routine;
++a client library may use it to deal with the details of storage
++management and XDR data conversion.
++.Pp
++The other three synopses shown above are used when
++one does not want to generate all the output files,
++but only a particular one.
++See the
++.Sx EXAMPLES
++section below for examples of
++.Nm
++usage.
++When
++.Nm
++is executed with the
++.Fl s
++option,
++it creates servers for that particular class of transports.
++When
++executed with the
++.Fl n
++option,
++it creates a server for the transport specified by
++.Ar netid .
++If
++.Ar infile
++is not specified,
++.Nm
++accepts the standard input.
++.Pp
++The C preprocessor,
++.Em cc -E
++is run on the input file before it is actually interpreted by
++.Nm .
++For each type of output file,
++.Nm
++defines a special preprocessor symbol for use by the
++.Nm
++programmer:
++.Bl -tag -width indent
++.It RPC_HDR
++defined when compiling into headers
++.It RPC_XDR
++defined when compiling into XDR routines
++.It RPC_SVC
++defined when compiling into server-side stubs
++.It RPC_CLNT
++defined when compiling into client-side stubs
++.It RPC_TBL
++defined when compiling into RPC dispatch tables
++.El
++.Pp
++Any line beginning with
++.Dq %
++is passed directly into the output file,
++uninterpreted by
++.Nm .
++To specify the path name of the C preprocessor use
++.Fl Y
++flag.
++.Pp
++For every data type referred to in
++.Ar infile ,
++.Nm
++assumes that there exists a
++routine with the string
++.Em xdr_
++prepended to the name of the data type.
++If this routine does not exist in the
++.Tn RPC/XDR
++library, it must be provided.
++Providing an undefined data type
++allows customization of
++.Xr xdr 3
++routines.
++.Sh OPTIONS
++The following options are available:
++.Bl -tag -width indent
++.It Fl a
++Generate all files, including sample files.
++.It Fl b
++Backward compatibility mode.
++Generate transport specific
++.Tn RPC
++code for older versions
++of the operating system.
++.Pp
++Note: in
++.Fx ,
++this compatibility flag is turned on by
++default since
++.Fx
++supports only the older
++.Tn ONC RPC
++library.
++.It Fl c
++Compile into
++.Tn XDR
++routines.
++.It Fl C
++Generate header and stub files which can be used with
++.Tn ANSI
++C compilers. Headers generated with this flag can also be
++used with C++ programs.
++.It Fl D Ns Ar name
++.It Fl D Ns Ar name=value
++.\".It Fl D Ns Ar name Ns Op Ar =value
++Define a symbol
++.Ar name .
++Equivalent to the
++.Em #define
++directive in the source.
++If no
++.Ar value
++is given,
++.Ar value
++is defined as
++.Em 1 .
++This option may be specified more than once.
++.It Fl h
++Compile into C data-definitions (a header).
++.Fl T
++option can be used in conjunction to produce a
++header which supports
++.Tn RPC
++dispatch tables.
++.It Fl i Ar size
++Size at which to start generating inline code.
++This option is useful for optimization.
++The default size is 5.
++.Pp
++Note: in order to provide backwards compatibility with the older
++.Nm
++on the
++.Fx
++platform, the default is actually 0 (which means
++that inline code generation is disabled by default). You must specify
++a non-zero value explicitly to override this default.
++.It Fl I
++Compile support for
++.Xr inetd 8
++in the server side stubs.
++Such servers can be self-started or can be started by
++.Nm inetd .
++When the server is self-started, it backgrounds itself by default.
++A special define symbol
++.Em RPC_SVC_FG
++can be used to run the
++server process in foreground, or the user may simply compile without
++the
++.Fl I
++option.
++.Pp
++If there are no pending client requests, the
++.Nm inetd
++servers exit after 120 seconds (default).
++The default can be changed with the
++.Fl K
++option.
++All the error messages for
++.Nm inetd
++servers
++are always logged with
++.Xr syslog 3 .
++.\" .IP
++.\" Note:
++.\" this option is supported for backward compatibility only.
++.\" By default,
++.\" .B rpcgen
++.\" generates servers that can be invoked through portmonitors.
++.Pp
++.It Fl K Ar seconds
++By default, services created using
++.Nm
++and invoked through
++port monitors wait 120 seconds
++after servicing a request before exiting.
++That interval can be changed using the
++.Fl K
++flag.
++To create a server that exits immediately upon servicing a request,
++use
++.Fl K Ar 0 .
++To create a server that never exits, the appropriate argument is
++.Fl k Ar -1 .
++.Pp
++When monitoring for a server,
++some portmonitors
++.Em always
++spawn a new process in response to a service request.
++If it is known that a server will be used with such a monitor, the
++server should exit immediately on completion.
++For such servers,
++.Nm
++should be used with
++.Fl K Ar 0 .
++.It Fl l
++Compile into client-side stubs.
++.It Fl L
++When the servers are started in foreground, use
++.Xr syslog 3
++to log the server errors instead of printing them on the standard
++error.
++.It Fl m
++Compile into server-side stubs,
++but do not generate a
++.Qq main
++routine.
++This option is useful for doing callback-routines
++and for users who need to write their own
++.Qq main
++routine to do initialization.
++.It Fl M
++Generate multithread-safe stubs for passing arguments and results between
++rpcgen generated code and user written code.
++This option is useful
++for users who want to use threads in their code.
++However, the
++.Xr rpc_svc_calls 3
++functions are not yet MT-safe, which means that rpcgen generated server-side
++code will not be MT-safe.
++.It Fl N
++This option allows procedures to have multiple arguments.
++It also uses the style of parameter passing that closely resembles C.
++So, when passing an argument to a remote procedure, you do not have to
++pass a pointer to the argument, but can pass the argument itself.
++This behavior is different from the old style of
++.Nm
++generated code.
++To maintain backward compatibility,
++this option is not the default.
++.It Fl n Ar netid
++Compile into server-side stubs for the transport
++specified by
++.Ar netid .
++There should be an entry for
++.Ar netid
++in the
++netconfig database.
++This option may be specified more than once,
++so as to compile a server that serves multiple transports.
++.It Fl o Ar outfile
++Specify the name of the output file.
++If none is specified,
++standard output is used
++(
++.Fl c ,
++.Fl h ,
++.Fl l ,
++.Fl m ,
++.Fl n ,
++.Fl s ,
++.Fl \&Sc ,
++.Fl \&Sm ,
++.Fl \&Ss ,
++and
++.Fl t
++modes only).
++.It Fl s Ar nettype
++Compile into server-side stubs for all the
++transports belonging to the class
++.Ar nettype .
++The supported classes are
++.Em netpath ,
++.Em visible ,
++.Em circuit_n ,
++.Em circuit_v ,
++.Em datagram_n ,
++.Em datagram_v ,
++.Em tcp ,
++and
++.Em udp
++(see
++.Xr rpc 3
++for the meanings associated with these classes).
++This option may be specified more than once.
++Note:
++the transports are chosen at run time and not at compile time.
++.It Fl \&Sc
++Generate sample client code that uses remote procedure calls.
++.It Fl \&Sm
++Generate a sample
++.Pa Makefile
++which can be used for compiling the application.
++.It Fl \&Ss
++Generate sample server code that uses remote procedure calls.
++.It Fl t
++Compile into
++.Tn RPC
++dispatch table.
++.It Fl T
++Generate the code to support
++.Tn RPC
++dispatch tables.
++.Pp
++The options
++.Fl c ,
++.Fl h ,
++.Fl l ,
++.Fl m ,
++.Fl s ,
++.Fl \&Sc ,
++.Fl \&Sm ,
++.Fl \&Ss ,
++and
++.Fl t
++are used exclusively to generate a particular type of file,
++while the options
++.Fl D
++and
++.Fl T
++are global and can be used with the other options.
++.It Fl Y Ar pathname
++Give the name of the directory where
++.Nm
++will start looking for the C-preprocessor.
++.El
++.Sh EXAMPLES
++The following example:
++.Dl example% rpcgen -T prot.x
++.Pp
++generates all the five files:
++.Pa prot.h ,
++.Pa prot_clnt.c ,
++.Pa prot_svc.c ,
++.Pa prot_xdr.c
++and
++.Pa prot_tbl.i .
++.Pp
++The following example sends the C data-definitions (header)
++to the standard output.
++.Dl example% rpcgen -h prot.x
++.Pp
++To send the test version of the
++.Fl D Ns Ar TEST ,
++server side stubs for
++all the transport belonging to the class
++.Ar datagram_n
++to standard output, use:
++.Dl example% rpcgen -s datagram_n -DTEST prot.x
++.Pp
++To create the server side stubs for the transport indicated
++by
++.Ar netid
++tcp,
++use:
++.Dl example% rpcgen -n tcp -o prot_svc.c prot.x
++.Sh SEE ALSO
++.Xr cc 1 ,
++.Xr rpc 3 ,
++.Xr syslog 3 ,
++.Xr inetd 8
++.\" .BR rpc_svc_calls (3)
++.Rs
++.%T The rpcgen chapter in the NETP manual
++.Re
+--- libtirpc-0.2.3/rpcgen/rpc_hout.c.0005~ 2013-02-11 21:47:03.992289257 +0100
++++ libtirpc-0.2.3/rpcgen/rpc_hout.c 2013-02-11 21:47:03.992289257 +0100
+@@ -0,0 +1,490 @@
++/*
++ * Copyright (c) 2009, Sun Microsystems, Inc.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions are met:
++ * - Redistributions of source code must retain the above copyright notice,
++ * this list of conditions and the following disclaimer.
++ * - Redistributions in binary form must reproduce the above copyright notice,
++ * this list of conditions and the following disclaimer in the documentation
++ * and/or other materials provided with the distribution.
++ * - Neither the name of Sun Microsystems, Inc. nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
++ * POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#if 0
++static char sccsid[] = "@(#)rpc_hout.c 1.12 89/02/22 (C) 1987 SMI";
++#endif
++
++/*
++ * rpc_hout.c, Header file outputter for the RPC protocol compiler
++ */
++#include <stdio.h>
++#include <ctype.h>
++#include "rpc_parse.h"
++#include "rpc_util.h"
++#include "rpc_output.h"
++
++
++static int undefined2(char *type, char *stop);
++static void pxdrfuncdecl(char *name, int pointerp);
++static void pconstdef(definition *def);
++static void pargdef(definition *def);
++static void pstructdef(definition *def);
++static void puniondef(definition *def);
++static void pdefine(char *name, char *num);
++static void puldefine(char *name, char *num);
++static int define_printed(proc_list *stop, version_list *start);
++static void pprogramdef(definition *def);
++static void pprocdef(proc_list *proc, version_list *vp,
++ char *addargtype, int server_p, int mode);
++static void parglist(proc_list *proc, char *addargtype);
++static void penumdef(definition *def);
++static void ptypedef(definition *def);
++
++/*
++ * Print the C-version of an xdr definition
++ */
++void
++print_datadef(definition *def)
++{
++
++ if (def->def_kind == DEF_PROGRAM ) /* handle data only */
++ return;
++
++ if (def->def_kind != DEF_CONST) {
++ f_print(fout, "\n");
++ }
++ switch (def->def_kind) {
++ case DEF_STRUCT:
++ pstructdef(def);
++ break;
++ case DEF_UNION:
++ puniondef(def);
++ break;
++ case DEF_ENUM:
++ penumdef(def);
++ break;
++ case DEF_TYPEDEF:
++ ptypedef(def);
++ break;
++ case DEF_PROGRAM:
++ pprogramdef(def);
++ break;
++ case DEF_CONST:
++ pconstdef(def);
++ break;
++ }
++ if (def->def_kind != DEF_PROGRAM && def->def_kind != DEF_CONST) {
++ pxdrfuncdecl( def->def_name,
++ def->def_kind != DEF_TYPEDEF ||
++ !isvectordef(def->def.ty.old_type, def->def.ty.rel));
++
++ }
++}
++
++
++void
++print_funcdef(definition *def)
++{
++ switch (def->def_kind) {
++ case DEF_PROGRAM:
++ f_print(fout, "\n");
++ pprogramdef(def);
++ break;
++ default:
++ break;
++ }
++}
++
++static void
++pxdrfuncdecl(char *name, int pointerp)
++{
++ f_print(fout,
++ "#ifdef __cplusplus \n"
++ "extern \"C\" bool_t xdr_%s(XDR *, %s%s);\n"
++ "#elif __STDC__ \n"
++ "extern bool_t xdr_%s(XDR *, %s%s);\n"
++ "#else /* Old Style C */ \n"
++ "bool_t xdr_%s();\n"
++ "#endif /* Old Style C */ \n\n",
++ name, name, pointerp ? "*" : "",
++ name, name, pointerp ? "*" : "",
++ name);
++}
++
++
++static void
++pconstdef(definition *def)
++{
++ pdefine(def->def_name, def->def.co);
++}
++
++/* print out the definitions for the arguments of functions in the
++ header file
++*/
++static void
++pargdef(definition *def)
++{
++ decl_list *l;
++ version_list *vers;
++ char *name;
++ proc_list *plist;
++
++
++ for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
++ for(plist = vers->procs; plist != NULL;
++ plist = plist->next) {
++
++ if (!newstyle || plist->arg_num < 2) {
++ continue; /* old style or single args */
++ }
++ name = plist->args.argname;
++ f_print(fout, "struct %s {\n", name);
++ for (l = plist->args.decls;
++ l != NULL; l = l->next) {
++ pdeclaration(name, &l->decl, 1, ";\n" );
++ }
++ f_print(fout, "};\n");
++ f_print(fout, "typedef struct %s %s;\n", name, name);
++ pxdrfuncdecl(name, 0);
++ f_print( fout, "\n" );
++ }
++ }
++
++}
++
++
++static void
++pstructdef(definition *def)
++{
++ decl_list *l;
++ char *name = def->def_name;
++
++ f_print(fout, "struct %s {\n", name);
++ for (l = def->def.st.decls; l != NULL; l = l->next) {
++ pdeclaration(name, &l->decl, 1, ";\n");
++ }
++ f_print(fout, "};\n");
++ f_print(fout, "typedef struct %s %s;\n", name, name);
++}
++
++static void
++puniondef(definition *def)
++{
++ case_list *l;
++ char *name = def->def_name;
++ declaration *decl;
++
++ f_print(fout, "struct %s {\n", name);
++ decl = &def->def.un.enum_decl;
++ if (streq(decl->type, "bool")) {
++ f_print(fout, "\tbool_t %s;\n", decl->name);
++ } else {
++ f_print(fout, "\t%s %s;\n", decl->type, decl->name);
++ }
++ f_print(fout, "\tunion {\n");
++ for (l = def->def.un.cases; l != NULL; l = l->next) {
++ if (l->contflag == 0)
++ pdeclaration(name, &l->case_decl, 2, ";\n");
++ }
++ decl = def->def.un.default_decl;
++ if (decl && !streq(decl->type, "void")) {
++ pdeclaration(name, decl, 2, ";\n");
++ }
++ f_print(fout, "\t} %s_u;\n", name);
++ f_print(fout, "};\n");
++ f_print(fout, "typedef struct %s %s;\n", name, name);
++}
++
++static void
++pdefine(char *name, char *num)
++{
++ f_print(fout, "#define %s %s\n", name, num);
++}
++
++static void
++puldefine(char *name, char *num)
++{
++ f_print(fout, "#define %s ((u_int32_t)%s)\n", name, num);
++}
++
++static int
++define_printed(proc_list *stop, version_list *start)
++{
++ version_list *vers;
++ proc_list *proc;
++
++ for (vers = start; vers != NULL; vers = vers->next) {
++ for (proc = vers->procs; proc != NULL; proc = proc->next) {
++ if (proc == stop) {
++ return (0);
++ } else if (streq(proc->proc_name, stop->proc_name)) {
++ return (1);
++ }
++ }
++ }
++ abort();
++ /* NOTREACHED */
++}
++
++static void
++pprogramdef(definition *def)
++{
++ version_list *vers;
++ proc_list *proc;
++ int i;
++ char *ext;
++
++ pargdef(def);
++
++ puldefine(def->def_name, def->def.pr.prog_num);
++ for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
++ if (tblflag) {
++ f_print(fout, "extern struct rpcgen_table %s_%s_table[];\n",
++ locase(def->def_name), vers->vers_num);
++ f_print(fout, "extern %s_%s_nproc;\n",
++ locase(def->def_name), vers->vers_num);
++ }
++ puldefine(vers->vers_name, vers->vers_num);
++
++ /*
++ * Print out 3 definitions, one for ANSI-C, another for C++,
++ * a third for old style C
++ */
++
++ for (i = 0; i < 3; i++) {
++ if (i == 0) {
++ f_print(fout, "\n#ifdef __cplusplus\n");
++ ext = "extern \"C\" ";
++ } else if (i == 1) {
++ f_print(fout, "\n#elif __STDC__\n");
++ ext = "extern ";
++ } else {
++ f_print(fout, "\n#else /* Old Style C */ \n");
++ ext = "extern ";
++ }
++
++
++ for (proc = vers->procs; proc != NULL; proc = proc->next) {
++ if (!define_printed(proc, def->def.pr.versions)) {
++ puldefine(proc->proc_name, proc->proc_num);
++ }
++ f_print(fout, "%s", ext);
++ pprocdef(proc, vers, "CLIENT *", 0, i);
++ f_print(fout, "%s", ext);
++ pprocdef(proc, vers, "struct svc_req *", 1, i);
++
++ }
++
++ }
++ f_print(fout, "#endif /* Old Style C */ \n");
++ }
++}
++
++static void
++pprocdef(proc_list *proc, version_list *vp, char *addargtype,
++ int server_p, int mode)
++{
++ ptype(proc->res_prefix, proc->res_type, 1);
++ f_print(fout, "* ");
++ if (server_p)
++ pvname_svc(proc->proc_name, vp->vers_num);
++ else
++ pvname(proc->proc_name, vp->vers_num);
++
++ /*
++ * mode 0 == cplusplus, mode 1 = ANSI-C, mode 2 = old style C
++ */
++ if (mode == 0 || mode == 1)
++ parglist(proc, addargtype);
++ else
++ f_print(fout, "();\n");
++}
++
++
++
++/* print out argument list of procedure */
++static void
++parglist(proc_list *proc, char *addargtype)
++{
++ decl_list *dl;
++
++ f_print(fout, "(");
++
++ if (proc->arg_num < 2 && newstyle &&
++ streq(proc->args.decls->decl.type, "void")) {
++ /* 0 argument in new style: do nothing */
++ } else {
++ for (dl = proc->args.decls; dl != NULL; dl = dl->next) {
++ ptype(dl->decl.prefix, dl->decl.type, 1);
++ if (!newstyle)
++ f_print(fout, "*"); /* old style passes by reference */
++
++ f_print(fout, ", ");
++ }
++ }
++
++ f_print(fout, "%s);\n", addargtype);
++}
++
++static void
++penumdef(definition *def)
++{
++ char *name = def->def_name;
++ enumval_list *l;
++ char *last = NULL;
++ int count = 0;
++
++ f_print(fout, "enum %s {\n", name);
++ for (l = def->def.en.vals; l != NULL; l = l->next) {
++ f_print(fout, "\t%s", l->name);
++ if (l->assignment) {
++ f_print(fout, " = %s", l->assignment);
++ last = l->assignment;
++ count = 1;
++ } else {
++ if (last == NULL) {
++ f_print(fout, " = %d", count++);
++ } else {
++ f_print(fout, " = %s + %d", last, count++);
++ }
++ }
++ f_print(fout, ",\n");
++ }
++ f_print(fout, "};\n");
++ f_print(fout, "typedef enum %s %s;\n", name, name);
++}
++
++static void
++ptypedef(definition *def)
++{
++ char *name = def->def_name;
++ char *old = def->def.ty.old_type;
++ char prefix[8]; /* enough to contain "struct ", including NUL */
++ relation rel = def->def.ty.rel;
++
++
++ if (!streq(name, old)) {
++ if (streq(old, "string")) {
++ old = "char";
++ rel = REL_POINTER;
++ } else if (streq(old, "opaque")) {
++ old = "char";
++ } else if (streq(old, "bool")) {
++ old = "bool_t";
++ }
++ if (undefined2(old, name) && def->def.ty.old_prefix) {
++ s_print(prefix, "%s ", def->def.ty.old_prefix);
++ } else {
++ prefix[0] = 0;
++ }
++ f_print(fout, "typedef ");
++ switch (rel) {
++ case REL_ARRAY:
++ f_print(fout, "struct {\n");
++ f_print(fout, "\tu_int %s_len;\n", name);
++ f_print(fout, "\t%s%s *%s_val;\n", prefix, old, name);
++ f_print(fout, "} %s", name);
++ break;
++ case REL_POINTER:
++ f_print(fout, "%s%s *%s", prefix, old, name);
++ break;
++ case REL_VECTOR:
++ f_print(fout, "%s%s %s[%s]", prefix, old, name,
++ def->def.ty.array_max);
++ break;
++ case REL_ALIAS:
++ f_print(fout, "%s%s %s", prefix, old, name);
++ break;
++ }
++ f_print(fout, ";\n");
++ }
++}
++
++void
++pdeclaration(char *name, declaration *dec, int tab, char *separator)
++{
++ char buf[8]; /* enough to hold "struct ", include NUL */
++ char *prefix;
++ char *type;
++
++ if (streq(dec->type, "void")) {
++ return;
++ }
++ tabify(fout, tab);
++ if (streq(dec->type, name) && !dec->prefix) {
++ f_print(fout, "struct ");
++ }
++ if (streq(dec->type, "string")) {
++ f_print(fout, "char *%s", dec->name);
++ } else {
++ prefix = "";
++ if (streq(dec->type, "bool")) {
++ type = "bool_t";
++ } else if (streq(dec->type, "opaque")) {
++ type = "char";
++ } else {
++ if (dec->prefix) {
++ s_print(buf, "%s ", dec->prefix);
++ prefix = buf;
++ }
++ type = dec->type;
++ }
++ switch (dec->rel) {
++ case REL_ALIAS:
++ f_print(fout, "%s%s %s", prefix, type, dec->name);
++ break;
++ case REL_VECTOR:
++ f_print(fout, "%s%s %s[%s]", prefix, type, dec->name,
++ dec->array_max);
++ break;
++ case REL_POINTER:
++ f_print(fout, "%s%s *%s", prefix, type, dec->name);
++ break;
++ case REL_ARRAY:
++ f_print(fout, "struct {\n");
++ tabify(fout, tab);
++ f_print(fout, "\tu_int %s_len;\n", dec->name);
++ tabify(fout, tab);
++ f_print(fout, "\t%s%s *%s_val;\n", prefix, type, dec->name);
++ tabify(fout, tab);
++ f_print(fout, "} %s", dec->name);
++ break;
++ }
++ }
++ f_print(fout, separator );
++}
++
++static int
++undefined2(char *type, char *stop)
++{
++ list *l;
++ definition *def;
++
++ for (l = defined; l != NULL; l = l->next) {
++ def = (definition *) l->val;
++ if (def->def_kind != DEF_PROGRAM) {
++ if (streq(def->def_name, stop)) {
++ return (1);
++ } else if (streq(def->def_name, type)) {
++ return (0);
++ }
++ }
++ }
++ return (1);
++}
+--- libtirpc-0.2.3/rpcgen/rpc_main.c.0005~ 2013-02-11 21:47:03.993289269 +0100
++++ libtirpc-0.2.3/rpcgen/rpc_main.c 2013-02-11 21:47:03.993289269 +0100
+@@ -0,0 +1,1067 @@
++/*
++ * Copyright (c) 2009, Sun Microsystems, Inc.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions are met:
++ * - Redistributions of source code must retain the above copyright notice,
++ * this list of conditions and the following disclaimer.
++ * - Redistributions in binary form must reproduce the above copyright notice,
++ * this list of conditions and the following disclaimer in the documentation
++ * and/or other materials provided with the distribution.
++ * - Neither the name of Sun Microsystems, Inc. nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
++ * POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#if 0
++static char sccsid[] = "@(#)rpc_main.c 1.30 89/03/30 (C) 1987 SMI";
++#endif
++
++/*
++ * rpc_main.c, Top level of the RPC protocol compiler.
++ */
++
++#include <sys/types.h>
++#include <sys/param.h>
++#include <sys/file.h>
++#include <sys/stat.h>
++#include <stdio.h>
++#include <string.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <ctype.h>
++#include <errno.h>
++#include "rpc_parse.h"
++#include "rpc_util.h"
++#include "rpc_scan.h"
++
++struct commandline {
++ int cflag; /* xdr C routines */
++ int hflag; /* header file */
++ int lflag; /* client side stubs */
++ int mflag; /* server side stubs */
++ int nflag; /* netid flag */
++ int sflag; /* server stubs for the given transport */
++ int tflag; /* dispatch Table file */
++ int Ssflag; /* produce server sample code */
++ int Scflag; /* produce client sample code */
++ char *infile; /* input module name */
++ char *outfile; /* output module name */
++};
++
++static char * extendfile(char *file, char *ext);
++static void open_output(char *infile, char *outfile);
++static void add_warning(void);
++static void clear_args(void);
++static void open_input(char *infile, char *define);
++static int check_nettype(char *name, char **list_to_check);
++static void c_output(char *infile, char *define, int extend, char *outfile);
++static void c_initialize(void);
++static char * generate_guard(char *pathname);
++static void h_output(char *infile, char *define, int extend, char *outfile);
++static void s_output(int argc, char **argv, char *infile,
++ char *define, int extend, char *outfile,
++ int nomain, int netflag);
++static void l_output(char *infile, char *define, int extend, char *outfile);
++static void t_output(char *infile, char *define, int extend, char *outfile);
++static void svc_output(char *, char *, int, char *);
++static void clnt_output(char *, char *, int, char *);
++static int do_registers(int argc, char **argv);
++static void addarg(char *cp);
++static void putarg(int where, char *cp);
++static void checkfiles(char *infile, char *outfile);
++static int parseargs(int argc, char **argv, struct commandline *cmd);
++static void usage(void);
++static void options_usage(void);
++
++/*
++extern void write_sample_svc();
++int write_sample_clnt();
++void write_sample_clnt_main();
++
++static svc_output();
++ */
++
++#define EXTEND 1 /* alias for TRUE */
++#define DONT_EXTEND 0 /* alias for FALSE */
++
++#define SVR4_CPP "/usr/ccs/lib/cpp"
++#define SUNOS_CPP "/lib/cpp"
++static int cppDefined = 0; /* explicit path for C preprocessor */
++
++
++static char *cmdname;
++
++static char *svcclosetime = "120";
++static char *CPP = SVR4_CPP;
++static char CPPFLAGS[] = "-C";
++static char pathbuf[MAXPATHLEN + 1];
++static char *allv[] = {
++ "rpcgen", "-s", "udp", "-s", "tcp",
++};
++static int allc = sizeof(allv)/sizeof(allv[0]);
++static char *allnv[] = {
++ "rpcgen", "-s", "netpath",
++};
++static int allnc = sizeof(allnv)/sizeof(allnv[0]);
++
++/*
++ * machinations for handling expanding argument list
++ */
++#if 0
++static void addarg(); /* add another argument to the list */
++static void putarg(); /* put argument at specified location */
++static void clear_args(); /* clear argument list */
++static void checkfiles(); /* check if out file already exists */
++#endif
++
++
++
++#define ARGLISTLEN 20
++#define FIXEDARGS 2
++
++static char *arglist[ARGLISTLEN];
++static int argcount = FIXEDARGS;
++
++
++int nonfatalerrors; /* errors */
++int inetdflag/* = 1*/; /* Support for inetd */ /* is now the default */
++int pmflag; /* Support for port monitors */
++int logflag; /* Use syslog instead of fprintf for errors */
++int tblflag; /* Support for dispatch table file */
++
++/* length at which to start doing an inline */
++#define INLINE 3
++
++int Inline = INLINE; /* length at which to start doing an inline. 3 = default
++ * if 0, no xdr_inline code */
++
++int indefinitewait; /* If started by port monitors, hang till it wants */
++int exitnow; /* If started by port monitors, exit after the call */
++int timerflag; /* TRUE if !indefinite && !exitnow */
++int newstyle; /* newstyle of passing arguments (by value) */
++int Cflag = 0 ; /* ANSI C syntax */
++static int allfiles; /* generate all files */
++#ifdef linux
++int tirpcflag = 0; /* no tirpc by default */
++#else
++int tirpcflag = 1; /* generating code for tirpc, by default */
++#endif
++
++int
++main(int argc, char **argv)
++{
++ struct commandline cmd;
++
++ (void) memset((char *) &cmd, 0, sizeof(struct commandline));
++ clear_args();
++ if (!parseargs(argc, argv, &cmd))
++ usage();
++
++ if (cmd.cflag || cmd.hflag || cmd.lflag || cmd.tflag || cmd.sflag ||
++ cmd.mflag || cmd.nflag || cmd.Ssflag || cmd.Scflag) {
++ checkfiles(cmd.infile, cmd.outfile);
++ } else
++ checkfiles(cmd.infile, NULL);
++
++ if (cmd.cflag) {
++ c_output(cmd.infile, "-DRPC_XDR", DONT_EXTEND, cmd.outfile);
++ } else if (cmd.hflag) {
++ h_output(cmd.infile, "-DRPC_HDR", DONT_EXTEND, cmd.outfile);
++ } else if (cmd.lflag) {
++ l_output(cmd.infile, "-DRPC_CLNT", DONT_EXTEND, cmd.outfile);
++ } else if (cmd.sflag || cmd.mflag || (cmd.nflag)) {
++ s_output(argc, argv, cmd.infile, "-DRPC_SVC", DONT_EXTEND,
++ cmd.outfile, cmd.mflag, cmd.nflag);
++ } else if (cmd.tflag) {
++ t_output(cmd.infile, "-DRPC_TBL", DONT_EXTEND, cmd.outfile);
++ } else if (cmd.Ssflag) {
++ svc_output(cmd.infile, "-DRPC_SERVER", DONT_EXTEND, cmd.outfile);
++ } else if (cmd.Scflag) {
++ clnt_output(cmd.infile, "-DRPC_CLIENT", DONT_EXTEND, cmd.outfile);
++ } else {
++ /* the rescans are required, since cpp may effect input */
++ c_output(cmd.infile, "-DRPC_XDR", EXTEND, "_xdr.c");
++ reinitialize();
++ h_output(cmd.infile, "-DRPC_HDR", EXTEND, ".h");
++ reinitialize();
++ l_output(cmd.infile, "-DRPC_CLNT", EXTEND, "_clnt.c");
++ reinitialize();
++ if (inetdflag || !tirpcflag)
++ s_output(allc, allv, cmd.infile, "-DRPC_SVC", EXTEND,
++ "_svc.c", cmd.mflag, cmd.nflag);
++ else
++ s_output(allnc, allnv, cmd.infile, "-DRPC_SVC",
++ EXTEND, "_svc.c", cmd.mflag, cmd.nflag);
++ if (tblflag) {
++ reinitialize();
++ t_output(cmd.infile, "-DRPC_TBL", EXTEND, "_tbl.i");
++ }
++ if (allfiles) {
++ reinitialize();
++ svc_output(cmd.infile, "-DRPC_SERVER", EXTEND, "_server.c");
++ }
++ if (allfiles) {
++ reinitialize();
++ clnt_output(cmd.infile, "-DRPC_CLIENT", EXTEND, "_client.c");
++ }
++ }
++ exit(nonfatalerrors);
++ /* NOTREACHED */
++}
++
++/*
++ * add extension to filename
++ */
++static char *
++extendfile(char *file, char *ext)
++{
++ char *res;
++ char *p;
++
++ res = alloc(strlen(file) + strlen(ext) + 1);
++ if (res == NULL) {
++ abort();
++ }
++ p = strrchr(file, '.');
++ if (p == NULL) {
++ p = file + strlen(file);
++ }
++ (void) strcpy(res, file);
++ (void) strcpy(res + (p - file), ext);
++ return (res);
++}
++
++/*
++ * Open output file with given extension
++ */
++static void
++open_output(char *infile, char *outfile)
++{
++
++ if (outfile == NULL) {
++ fout = stdout;
++ return;
++ }
++
++ if (infile != NULL && streq(outfile, infile)) {
++ f_print(stderr, "%s: output would overwrite %s\n", cmdname,
++ infile);
++ crash();
++ }
++ fout = fopen(outfile, "w");
++ if (fout == NULL) {
++ f_print(stderr, "%s: unable to open ", cmdname);
++ perror(outfile);
++ crash();
++ }
++ record_open(outfile);
++
++}
++
++static void
++add_warning(void)
++{
++ f_print(fout, "/*\n");
++ f_print(fout, " * Please do not edit this file.\n");
++ f_print(fout, " * It was generated using rpcgen.\n");
++ f_print(fout, " */\n\n");
++}
++
++/* clear list of arguments */
++static void
++clear_args(void)
++{
++ int i;
++ for( i=FIXEDARGS; i<ARGLISTLEN; i++ )
++ arglist[i] = NULL;
++ argcount = FIXEDARGS;
++}
++
++/*
++ * Open input file with given define for C-preprocessor
++ */
++static void
++open_input(char *infile, char *define)
++{
++ int pd[2];
++
++ infilename = (infile == NULL) ? "<stdin>" : infile;
++ (void) pipe(pd);
++ switch (fork()) {
++ case 0:
++ putarg(0, "cpp");
++ putarg(1, CPPFLAGS);
++ addarg(define);
++ addarg(infile);
++ addarg((char *)NULL);
++ (void) close(1);
++ (void) dup2(pd[1], 1);
++ (void) close(pd[0]);
++ if (cppDefined)
++ execv(CPP, arglist);
++ else {
++ execvp("cpp", arglist);
++ if (errno == ENOENT)
++ execvp(SVR4_CPP, arglist);
++ if (errno == ENOENT)
++ execvp(SUNOS_CPP, arglist);
++ }
++ perror("execv");
++ exit(1);
++ case -1:
++ perror("fork");
++ exit(1);
++ }
++ (void) close(pd[1]);
++ fin = fdopen(pd[0], "r");
++ if (fin == NULL) {
++ f_print(stderr, "%s: ", cmdname);
++ perror(infilename);
++ crash();
++ }
++}
++
++/* valid tirpc nettypes */
++static char* valid_ti_nettypes[] =
++{
++ "netpath",
++ "visible",
++ "circuit_v",
++ "datagram_v",
++ "circuit_n",
++ "datagram_n",
++ "udp",
++ "tcp",
++ "raw",
++ NULL
++};
++
++/* valid inetd nettypes */
++static char* valid_i_nettypes[] =
++{
++ "udp",
++ "tcp",
++ NULL
++};
++
++static int
++check_nettype(char *name, char **list_to_check)
++{
++ int i;
++ for( i = 0; list_to_check[i] != NULL; i++ ) {
++ if( strcmp( name, list_to_check[i] ) == 0 ) {
++ return 1;
++ }
++ }
++ f_print( stderr, "illegal nettype :\'%s\'\n", name );
++ return 0;
++}
++
++/*
++ * Compile into an XDR routine output file
++ */
++
++static void
++c_output(char *infile, char *define, int extend, char *outfile)
++{
++ definition *def;
++ char *include;
++ char *outfilename;
++ long tell;
++
++ c_initialize();
++ open_input(infile, define);
++ outfilename = extend ? extendfile(infile, outfile) : outfile;
++ open_output(infile, outfilename);
++ add_warning();
++ if (infile && (include = extendfile(infile, ".h"))) {
++ f_print(fout, "#include \"%s\"\n", include);
++ free(include);
++ /* .h file already contains rpc/rpc.h */
++ } else
++ f_print(fout, "#include <rpc/rpc.h>\n");
++ tell = ftell(fout);
++ while ((def = get_definition()) != NULL) {
++ emit(def);
++ }
++ if (extend && tell == ftell(fout)) {
++ (void) unlink(outfilename);
++ }
++}
++
++
++static void
++c_initialize(void)
++{
++
++ /* add all the starting basic types */
++
++ add_type(1,"int");
++ add_type(1,"int32_t");
++ add_type(1,"short");
++ add_type(1,"bool");
++
++ add_type(1,"u_int");
++ add_type(1,"u_int32_t");
++ add_type(1,"u_short");
++
++}
++
++char rpcgen_table_dcl[] = "struct rpcgen_table {\n\
++ char *(*proc)();\n\
++ xdrproc_t xdr_arg;\n\
++ unsigned len_arg;\n\
++ xdrproc_t xdr_res;\n\
++ unsigned len_res;\n\
++};\n";
++
++
++static char *
++generate_guard(char *pathname)
++{
++ char* filename, *guard, *tmp;
++
++ filename = strrchr(pathname, '/' ); /* find last component */
++ filename = ((filename == 0) ? pathname : filename+1);
++ guard = strdup(filename);
++ /* convert to upper case */
++ tmp = guard;
++ while (*tmp) {
++ if (islower(*tmp))
++ *tmp = toupper(*tmp);
++ tmp++;
++ }
++
++ guard = extendfile(guard, "_H_RPCGEN");
++ return( guard );
++}
++
++/*
++ * Compile into an XDR header file
++ */
++static void
++h_output(char *infile, char *define, int extend, char *outfile)
++{
++ definition *def;
++ char *outfilename;
++ long tell;
++ char *guard;
++ list *l;
++
++ open_input(infile, define);
++ outfilename = extend ? extendfile(infile, outfile) : outfile;
++ open_output(infile, outfilename);
++ add_warning();
++ guard = generate_guard( outfilename ? outfilename: infile );
++
++ f_print(fout,"#ifndef _%s\n#define _%s\n\n", guard,
++ guard);
++
++ f_print(fout, "#include <rpc/rpc.h>\n\n");
++
++ f_print(fout, "#ifndef IXDR_GET_INT32\n");
++ f_print(fout, "#define IXDR_GET_INT32(buf) IXDR_GET_LONG((buf))\n");
++ f_print(fout, "#endif\n");
++ f_print(fout, "#ifndef IXDR_PUT_INT32\n");
++ f_print(fout, "#define IXDR_PUT_INT32(buf, v) IXDR_PUT_LONG((buf), (v))\n");
++ f_print(fout, "#endif\n");
++ f_print(fout, "#ifndef IXDR_GET_U_INT32\n");
++ f_print(fout, "#define IXDR_GET_U_INT32(buf) IXDR_GET_U_LONG((buf))\n");
++ f_print(fout, "#endif\n");
++ f_print(fout, "#ifndef IXDR_PUT_U_INT32\n");
++ f_print(fout, "#define IXDR_PUT_U_INT32(buf, v) IXDR_PUT_U_LONG((buf), (v))\n");
++ f_print(fout, "#endif\n");
++
++ tell = ftell(fout);
++ /* print data definitions */
++ while ((def = get_definition()) != NULL) {
++ print_datadef(def);
++ }
++
++ /* print function declarations.
++ Do this after data definitions because they might be used as
++ arguments for functions */
++ for (l = defined; l != NULL; l = l->next) {
++ print_funcdef(l->val);
++ }
++ if (extend && tell == ftell(fout)) {
++ (void) unlink(outfilename);
++ } else if (tblflag) {
++ f_print(fout, rpcgen_table_dcl);
++ }
++ f_print(fout, "\n#endif /* !_%s */\n", guard);
++}
++
++/*
++ * Compile into an RPC service
++ */
++static void
++s_output(int argc, char **argv, char *infile, char *define, int extend,
++ char *outfile, int nomain, int netflag)
++{
++ char *include;
++ definition *def;
++ int foundprogram = 0;
++ char *outfilename;
++
++ open_input(infile, define);
++ outfilename = extend ? extendfile(infile, outfile) : outfile;
++ open_output(infile, outfilename);
++ add_warning();
++ if (infile && (include = extendfile(infile, ".h"))) {
++ f_print(fout, "#include \"%s\"\n", include);
++ free(include);
++ } else
++ f_print(fout, "#include <rpc/rpc.h>\n");
++
++ f_print(fout, "#include <stdio.h>\n");
++ f_print(fout, "#include <stdlib.h>/* getenv, exit */\n");
++ if (Cflag) {
++ f_print (fout, "#include <rpc/pmap_clnt.h> /* for pmap_unset */\n");
++ f_print (fout, "#include <string.h> /* strcmp */ \n");
++ }
++ if (strcmp(svcclosetime, "-1") == 0)
++ indefinitewait = 1;
++ else if (strcmp(svcclosetime, "0") == 0)
++ exitnow = 1;
++ else if (inetdflag || pmflag) {
++ f_print(fout, "#include <signal.h>\n");
++ timerflag = 1;
++ }
++
++#ifndef linux
++ if( !tirpcflag && inetdflag )
++ f_print(fout, "#include <sys/ttycom.h>/* TIOCNOTTY */\n");
++#else
++ if( !tirpcflag )
++ f_print(fout, "#include <sys/ioctl.h>/* TIOCNOTTY */\n");
++#endif
++ if( Cflag && (inetdflag || pmflag ) ) {
++ f_print(fout, "#ifdef __cplusplus\n");
++ f_print(fout, "#include <sysent.h> /* getdtablesize, open */\n");
++ f_print(fout, "#endif /* __cplusplus */\n");
++
++ if( tirpcflag )
++ f_print(fout, "#include <unistd.h> /* setsid */\n");
++ }
++ if( tirpcflag )
++ f_print(fout, "#include <sys/types.h>\n");
++
++ f_print(fout, "#include <memory.h>\n");
++#ifndef linux
++ f_print(fout, "#include <stropts.h>\n");
++#endif
++ if (inetdflag || !tirpcflag ) {
++ f_print(fout, "#include <sys/socket.h>\n");
++ f_print(fout, "#include <netinet/in.h>\n");
++ }
++
++ if ( (netflag || pmflag) && tirpcflag ) {
++ f_print(fout, "#include <netconfig.h>\n");
++ }
++ if (/*timerflag &&*/ tirpcflag)
++ f_print(fout, "#include <sys/resource.h> /* rlimit */\n");
++ if (logflag || inetdflag || pmflag) {
++#ifdef linux
++ f_print(fout, "#include <syslog.h>\n");
++#else
++ f_print(fout, "#ifdef SYSLOG\n");
++ f_print(fout, "#include <syslog.h>\n");
++ f_print(fout, "#else\n");
++ f_print(fout, "#define LOG_ERR 1\n");
++ f_print(fout, "#define openlog(a, b, c)\n");
++ f_print(fout, "#endif\n");
++#endif
++ }
++
++ /* for ANSI-C */
++ f_print(fout, "\n#ifdef __STDC__\n#define SIG_PF void(*)(int)\n#endif\n");
++
++ f_print(fout, "\n#ifdef DEBUG\n#define RPC_SVC_FG\n#endif\n");
++ if (timerflag)
++ f_print(fout, "\n#define _RPCSVC_CLOSEDOWN %s\n", svcclosetime);
++ while ((def = get_definition()) != NULL) {
++ foundprogram |= (def->def_kind == DEF_PROGRAM);
++ }
++ if (extend && !foundprogram) {
++ (void) unlink(outfilename);
++ return;
++ }
++ write_most(infile, netflag, nomain);
++ if (!nomain) {
++ if( !do_registers(argc, argv) ) {
++ if (outfilename)
++ (void) unlink(outfilename);
++ usage();
++ }
++ write_rest();
++ }
++}
++
++/*
++ * generate client side stubs
++ */
++static void
++l_output(char *infile, char *define, int extend, char *outfile)
++{
++ char *include;
++ definition *def;
++ int foundprogram = 0;
++ char *outfilename;
++
++ open_input(infile, define);
++ outfilename = extend ? extendfile(infile, outfile) : outfile;
++ open_output(infile, outfilename);
++ add_warning();
++ if (Cflag)
++ f_print (fout, "#include <memory.h> /* for memset */\n");
++ if (infile && (include = extendfile(infile, ".h"))) {
++ f_print(fout, "#include \"%s\"\n", include);
++ free(include);
++ } else
++ f_print(fout, "#include <rpc/rpc.h>\n");
++ while ((def = get_definition()) != NULL) {
++ foundprogram |= (def->def_kind == DEF_PROGRAM);
++ }
++ if (extend && !foundprogram) {
++ (void) unlink(outfilename);
++ return;
++ }
++ write_stubs();
++}
++
++/*
++ * generate the dispatch table
++ */
++static void
++t_output(char *infile, char *define, int extend, char *outfile)
++{
++ definition *def;
++ int foundprogram = 0;
++ char *outfilename;
++
++ open_input(infile, define);
++ outfilename = extend ? extendfile(infile, outfile) : outfile;
++ open_output(infile, outfilename);
++ add_warning();
++ while ((def = get_definition()) != NULL) {
++ foundprogram |= (def->def_kind == DEF_PROGRAM);
++ }
++ if (extend && !foundprogram) {
++ (void) unlink(outfilename);
++ return;
++ }
++ write_tables();
++}
++
++/* sample routine for the server template */
++static void
++svc_output(char *infile, char *define, int extend, char *outfile)
++{
++ definition *def;
++ char *include;
++ char *outfilename;
++ long tell;
++
++ open_input(infile, define);
++ outfilename = extend ? extendfile(infile, outfile) : outfile;
++ checkfiles(infile,outfilename); /*check if outfile already exists.
++ if so, print an error message and exit*/
++ open_output(infile, outfilename);
++ add_sample_msg();
++
++ if (infile && (include = extendfile(infile, ".h"))) {
++ f_print(fout, "#include \"%s\"\n", include);
++ free(include);
++ } else
++ f_print(fout, "#include <rpc/rpc.h>\n");
++
++ tell = ftell(fout);
++ while ((def = get_definition()) != NULL) {
++ write_sample_svc(def);
++ }
++ if (extend && tell == ftell(fout)) {
++ (void) unlink(outfilename);
++ }
++}
++
++
++/* sample main routine for client */
++static void
++clnt_output(char *infile, char *define, int extend, char *outfile)
++{
++ definition *def;
++ char *include;
++ char *outfilename;
++ long tell;
++ int has_program = 0;
++
++ open_input(infile, define);
++ outfilename = extend ? extendfile(infile, outfile) : outfile;
++ checkfiles(infile, outfilename); /*check if outfile already exists.
++ if so, print an error message and exit*/
++
++ open_output(infile, outfilename);
++ add_sample_msg();
++ if (infile && (include = extendfile(infile, ".h"))) {
++ f_print(fout, "#include \"%s\"\n", include);
++ free(include);
++ } else
++ f_print(fout, "#include <rpc/rpc.h>\n");
++ tell = ftell(fout);
++ while ((def = get_definition()) != NULL) {
++ has_program += write_sample_clnt(def);
++ }
++
++ if (has_program)
++ write_sample_clnt_main();
++
++ if (extend && tell == ftell(fout)) {
++ (void) unlink(outfilename);
++ }
++}
++
++/*
++ * Perform registrations for service output
++ * Return 0 if failed; 1 otherwise.
++ */
++static int
++do_registers(int argc, char **argv)
++{
++ int i;
++
++ if (inetdflag || !tirpcflag) {
++ for (i = 1; i < argc; i++) {
++ if (streq(argv[i], "-s")) {
++ if (!check_nettype(argv[i + 1], valid_i_nettypes))
++ return 0;
++ write_inetd_register(argv[i + 1]);
++ i++;
++ }
++ }
++ } else {
++ for (i = 1; i < argc; i++)
++ if (streq(argv[i], "-s")) {
++ if (!check_nettype(argv[i + 1], valid_ti_nettypes))
++ return 0;
++ write_nettype_register(argv[i + 1]);
++ i++;
++ } else if (streq(argv[i], "-n")) {
++ write_netid_register(argv[i + 1]);
++ i++;
++ }
++ }
++ return 1;
++}
++
++/*
++ * Add another argument to the arg list
++ */
++static void
++addarg(char *cp)
++{
++ if (argcount >= ARGLISTLEN) {
++ f_print(stderr, "rpcgen: too many defines\n");
++ crash();
++ /*NOTREACHED*/
++ }
++ arglist[argcount++] = cp;
++
++}
++
++static void
++putarg(int where, char *cp)
++{
++ if (where >= ARGLISTLEN) {
++ f_print(stderr, "rpcgen: arglist coding error\n");
++ crash();
++ /*NOTREACHED*/
++ }
++ arglist[where] = cp;
++
++}
++
++/*
++ * if input file is stdin and an output file is specified then complain
++ * if the file already exists. Otherwise the file may get overwritten
++ * If input file does not exist, exit with an error
++ */
++
++static void
++checkfiles(char *infile, char *outfile)
++{
++
++ struct stat buf;
++
++ if(infile) /* infile ! = NULL */
++ if(stat(infile,&buf) < 0)
++ {
++ perror(infile);
++ crash();
++ };
++ if (outfile) {
++ if (stat(outfile, &buf) < 0)
++ return; /* file does not exist */
++ else {
++ f_print(stderr,
++ "file '%s' already exists and may be overwritten\n", outfile);
++ crash();
++ }
++ }
++}
++
++/*
++ * Parse command line arguments
++ */
++static int
++parseargs(int argc, char **argv, struct commandline *cmd)
++{
++ int i;
++ int j;
++ char c;
++ char flag[(1 << 8 * sizeof(char))];
++ int nflags;
++
++ cmdname = argv[0];
++ cmd->infile = cmd->outfile = NULL;
++ if (argc < 2) {
++ return (0);
++ }
++ allfiles = 0;
++ flag['c'] = 0;
++ flag['h'] = 0;
++ flag['l'] = 0;
++ flag['m'] = 0;
++ flag['o'] = 0;
++ flag['s'] = 0;
++ flag['n'] = 0;
++ flag['t'] = 0;
++ flag['S'] = 0;
++ flag['C'] = 0;
++ for (i = 1; i < argc; i++) {
++ if (argv[i][0] != '-') {
++ if (cmd->infile) {
++ f_print( stderr, "Cannot specify more than one input file!\n");
++
++ return (0);
++ }
++ cmd->infile = argv[i];
++ } else {
++ for (j = 1; argv[i][j] != 0; j++) {
++ c = argv[i][j];
++ switch (c) {
++ case 'a':
++ allfiles = 1;
++ break;
++ case 'c':
++ case 'h':
++ case 'l':
++ case 'm':
++ case 't':
++ if (flag[(int) c]) {
++ return (0);
++ }
++ flag[(int) c] = 1;
++ break;
++ case 'S':
++ /* sample flag: Ss or Sc.
++ Ss means set flag['S'];
++ Sc means set flag['C']; */
++ c = argv[i][++j]; /* get next char */
++ if( c == 's' )
++ c = 'S';
++ else if( c == 'c' )
++ c = 'C';
++ else
++ return( 0 );
++
++ if (flag[(int) c]) {
++ return (0);
++ }
++ flag[(int) c] = 1;
++ break;
++ case 'C': /* ANSI C syntax */
++ Cflag = 1;
++ break;
++
++ case 'b': /* turn TIRPC flag off for
++ generating backward compatible
++ */
++ tirpcflag = 0;
++ break;
++
++ case 'I':
++ inetdflag = 1;
++ break;
++ case 'N':
++ newstyle = 1;
++ break;
++ case 'L':
++ logflag = 1;
++ break;
++ case 'K':
++ if (++i == argc) {
++ return (0);
++ }
++ svcclosetime = argv[i];
++ goto nextarg;
++ case 'T':
++ tblflag = 1;
++ break;
++ case 'i' :
++ if (++i == argc) {
++ return (0);
++ }
++ Inline = atoi(argv[i]);
++ goto nextarg;
++ case 'n':
++ case 'o':
++ case 's':
++ if (argv[i][j - 1] != '-' ||
++ argv[i][j + 1] != 0) {
++ return (0);
++ }
++ flag[(int) c] = 1;
++ if (++i == argc) {
++ return (0);
++ }
++ if (c == 's') {
++ if (!streq(argv[i], "udp") &&
++ !streq(argv[i], "tcp")) {
++ return (0);
++ }
++ } else if (c == 'o') {
++ if (cmd->outfile) {
++ return (0);
++ }
++ cmd->outfile = argv[i];
++ }
++ goto nextarg;
++ case 'D':
++ if (argv[i][j - 1] != '-') {
++ return (0);
++ }
++ (void) addarg(argv[i]);
++ goto nextarg;
++ case 'Y':
++ if (++i == argc) {
++ return (0);
++ }
++ (void) strcpy(pathbuf, argv[i]);
++ (void) strcat(pathbuf, "/cpp");
++ CPP = pathbuf;
++ cppDefined = 1;
++ goto nextarg;
++
++
++
++ default:
++ return (0);
++ }
++ }
++ nextarg:
++ ;
++ }
++ }
++
++ cmd->cflag = flag['c'];
++ cmd->hflag = flag['h'];
++ cmd->lflag = flag['l'];
++ cmd->mflag = flag['m'];
++ cmd->nflag = flag['n'];
++ cmd->sflag = flag['s'];
++ cmd->tflag = flag['t'];
++ cmd->Ssflag = flag['S'];
++ cmd->Scflag = flag['C'];
++
++ if( tirpcflag ) {
++ pmflag = inetdflag ? 0 : 1; /* pmflag or inetdflag is always TRUE */
++ if( (inetdflag && cmd->nflag)) { /* netid not allowed with inetdflag */
++ f_print(stderr, "Cannot use netid flag with inetd flag!\n");
++ return (0);
++ }
++ } else { /* 4.1 mode */
++ pmflag = 0; /* set pmflag only in tirpcmode */
++ inetdflag = 1; /* inetdflag is TRUE by default */
++ if( cmd->nflag ) { /* netid needs TIRPC */
++ f_print( stderr, "Cannot use netid flag without TIRPC!\n");
++ return( 0 );
++ }
++ }
++
++ if( newstyle && ( tblflag || cmd->tflag) ) {
++ f_print( stderr, "Cannot use table flags with newstyle!\n");
++ return( 0 );
++ }
++
++ /* check no conflicts with file generation flags */
++ nflags = cmd->cflag + cmd->hflag + cmd->lflag + cmd->mflag +
++ cmd->sflag + cmd->nflag + cmd->tflag + cmd->Ssflag + cmd->Scflag;
++
++ if (nflags == 0) {
++ if (cmd->outfile != NULL || cmd->infile == NULL) {
++ return (0);
++ }
++ } else if (nflags > 1) {
++ f_print( stderr, "Cannot have more than one file generation flag!\n");
++ return (0);
++ }
++ return (1);
++}
++
++static void
++usage(void)
++{
++ f_print(stderr, "usage: %s infile\n", cmdname);
++ f_print(stderr, "\t%s [-a][-b][-C][-Dname[=value]] -i size [-I [-K seconds]] [-L][-N][-T] infile\n",
++ cmdname);
++ f_print(stderr, "\t%s [-c | -h | -l | -m | -t | -Sc | -Ss] [-o outfile] [infile]\n",
++ cmdname);
++ f_print(stderr, "\t%s [-s nettype]* [-o outfile] [infile]\n", cmdname);
++ f_print(stderr, "\t%s [-n netid]* [-o outfile] [infile]\n", cmdname);
++ options_usage();
++ exit(1);
++}
++
++static void
++options_usage(void)
++{
++ f_print(stderr, "options:\n");
++ f_print(stderr, "-a\t\tgenerate all files, including samples\n");
++ f_print(stderr, "-b\t\tbackward compatibility mode (generates code for SunOS 4.1)\n");
++ f_print(stderr, "-c\t\tgenerate XDR routines\n");
++ f_print(stderr, "-C\t\tANSI C mode\n");
++ f_print(stderr, "-Dname[=value]\tdefine a symbol (same as #define)\n");
++ f_print(stderr, "-h\t\tgenerate header file\n");
++ f_print(stderr, "-i size\t\tsize at which to start generating inline code\n");
++ f_print(stderr, "-I\t\tgenerate code for inetd support in server (for SunOS 4.1)\n");
++ f_print(stderr, "-K seconds\tserver exits after K seconds of inactivity\n");
++ f_print(stderr, "-l\t\tgenerate client side stubs\n");
++ f_print(stderr, "-L\t\tserver errors will be printed to syslog\n");
++ f_print(stderr, "-m\t\tgenerate server side stubs\n");
++ f_print(stderr, "-n netid\tgenerate server code that supports named netid\n");
++ f_print(stderr, "-N\t\tsupports multiple arguments and call-by-value\n");
++ f_print(stderr, "-o outfile\tname of the output file\n");
++ f_print(stderr, "-s nettype\tgenerate server code that supports named nettype\n");
++ f_print(stderr, "-Sc\t\tgenerate sample client code that uses remote procedures\n");
++ f_print(stderr, "-Ss\t\tgenerate sample server code that defines remote procedures\n");
++ f_print(stderr, "-t\t\tgenerate RPC dispatch table\n");
++ f_print(stderr, "-T\t\tgenerate code to support RPC dispatch tables\n");
++ f_print(stderr, "-Y path\t\tdirectory name to find C preprocessor (cpp)\n");
++
++ exit(1);
++}
+--- libtirpc-0.2.3/rpcgen/rpc_output.h.0005~ 2013-02-11 21:47:03.993289269 +0100
++++ libtirpc-0.2.3/rpcgen/rpc_output.h 2013-02-11 21:47:03.993289269 +0100
+@@ -0,0 +1,16 @@
++/*
++ * rpc_output.h
++ *
++ * Declarations for output functions
++ *
++ */
++
++#ifndef RPCGEN_NEW_OUTPUT_H
++#define RPCGEN_NEW_OUTPUT_H
++
++void write_msg_out(void);
++int nullproc(proc_list *);
++void printarglist(proc_list *, char *, char *);
++void pdeclaration(char *, declaration *, int, char *);
++
++#endif /* RPCGEN_NEW_OUTPUT_H */
+--- libtirpc-0.2.3/rpcgen/rpc_parse.c.0005~ 2013-02-11 21:47:03.993289269 +0100
++++ libtirpc-0.2.3/rpcgen/rpc_parse.c 2013-02-11 21:47:03.993289269 +0100
+@@ -0,0 +1,609 @@
++/*
++ * Copyright (c) 2009, Sun Microsystems, Inc.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions are met:
++ * - Redistributions of source code must retain the above copyright notice,
++ * this list of conditions and the following disclaimer.
++ * - Redistributions in binary form must reproduce the above copyright notice,
++ * this list of conditions and the following disclaimer in the documentation
++ * and/or other materials provided with the distribution.
++ * - Neither the name of Sun Microsystems, Inc. nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
++ * POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#if 0
++static char sccsid[] = "@(#)rpc_parse.c 1.8 89/02/22 (C) 1987 SMI";
++#endif
++
++/*
++ * rpc_parse.c, Parser for the RPC protocol compiler
++ * Copyright (C) 1987 Sun Microsystems, Inc.
++ */
++#include <stdio.h>
++#include <string.h>
++#include "rpc/types.h"
++#include "rpc_scan.h"
++#include "rpc_parse.h"
++#include "rpc_util.h"
++
++#define ARGNAME "arg"
++
++/*
++extern char *make_argname();
++extern char *strdup();
++ */
++
++static void isdefined(definition *defp);
++static void def_struct(definition *defp);
++static void def_program(definition *defp);
++static void def_enum(definition *defp);
++static void def_const(definition *defp);
++static void def_union(definition *defp);
++static void check_type_name(char *name, int new_type);
++static void def_typedef(definition *defp);
++static void get_declaration(declaration *dec, defkind dkind);
++static void get_prog_declaration(declaration *dec, defkind dkind, int num);
++static void get_type(char **prefixp, char **typep, defkind dkind);
++static void unsigned_dec(char **typep);
++
++/*
++ * return the next definition you see
++ */
++definition *
++get_definition(void)
++{
++ definition *defp;
++ token tok;
++
++ defp = ALLOC(definition);
++ get_token(&tok);
++ switch (tok.kind) {
++ case TOK_STRUCT:
++ def_struct(defp);
++ break;
++ case TOK_UNION:
++ def_union(defp);
++ break;
++ case TOK_TYPEDEF:
++ def_typedef(defp);
++ break;
++ case TOK_ENUM:
++ def_enum(defp);
++ break;
++ case TOK_PROGRAM:
++ def_program(defp);
++ break;
++ case TOK_CONST:
++ def_const(defp);
++ break;
++ case TOK_EOF:
++ free(defp);
++ return (NULL);
++ default:
++ error("definition keyword expected");
++ }
++ scan(TOK_SEMICOLON, &tok);
++ isdefined(defp);
++ return (defp);
++}
++
++static void
++isdefined(definition *defp)
++{
++ STOREVAL(&defined, defp);
++}
++
++static void
++def_struct(definition *defp)
++{
++ token tok;
++ declaration dec;
++ decl_list *decls;
++ decl_list **tailp;
++
++ defp->def_kind = DEF_STRUCT;
++
++ scan(TOK_IDENT, &tok);
++ defp->def_name = tok.str;
++ scan(TOK_LBRACE, &tok);
++ tailp = &defp->def.st.decls;
++ do {
++ get_declaration(&dec, DEF_STRUCT);
++ decls = ALLOC(decl_list);
++ decls->decl = dec;
++ *tailp = decls;
++ tailp = &decls->next;
++ scan(TOK_SEMICOLON, &tok);
++ peek(&tok);
++ } while (tok.kind != TOK_RBRACE);
++ get_token(&tok);
++ *tailp = NULL;
++}
++
++static void
++def_program(definition *defp)
++{
++ token tok;
++ declaration dec;
++ decl_list *decls;
++ decl_list **tailp;
++ version_list *vlist;
++ version_list **vtailp;
++ proc_list *plist;
++ proc_list **ptailp;
++ int num_args;
++ bool_t isvoid = FALSE; /* whether first argument is void */
++ defp->def_kind = DEF_PROGRAM;
++ scan(TOK_IDENT, &tok);
++ defp->def_name = tok.str;
++ scan(TOK_LBRACE, &tok);
++ vtailp = &defp->def.pr.versions;
++ tailp = &defp->def.st.decls;
++ scan(TOK_VERSION, &tok);
++ do {
++ scan(TOK_IDENT, &tok);
++ vlist = ALLOC(version_list);
++ vlist->vers_name = tok.str;
++ scan(TOK_LBRACE, &tok);
++ ptailp = &vlist->procs;
++ do {
++ /* get result type */
++ plist = ALLOC(proc_list);
++ get_type(&plist->res_prefix, &plist->res_type,
++ DEF_PROGRAM);
++ if (streq(plist->res_type, "opaque")) {
++ error("illegal result type");
++ }
++ scan(TOK_IDENT, &tok);
++ plist->proc_name = tok.str;
++ scan(TOK_LPAREN, &tok);
++ /* get args - first one*/
++ num_args = 1;
++ isvoid = FALSE;
++ /* type of DEF_PROGRAM in the first
++ * get_prog_declaration and DEF_STURCT in the next
++ * allows void as argument if it is the only argument
++ */
++ get_prog_declaration(&dec, DEF_PROGRAM, num_args);
++ if (streq(dec.type, "void"))
++ isvoid = TRUE;
++ decls = ALLOC(decl_list);
++ plist->args.decls = decls;
++ decls->decl = dec;
++ tailp = &decls->next;
++ /* get args */
++ while(peekscan(TOK_COMMA, &tok)) {
++ num_args++;
++ get_prog_declaration(&dec, DEF_STRUCT,
++ num_args);
++ decls = ALLOC(decl_list);
++ decls->decl = dec;
++ *tailp = decls;
++ if (streq(dec.type, "void"))
++ isvoid = TRUE;
++ tailp = &decls->next;
++ }
++ /* multiple arguments are only allowed in newstyle */
++ if( !newstyle && num_args > 1 ) {
++ error("only one argument is allowed" );
++ }
++ if (isvoid && num_args > 1) {
++ error("illegal use of void in program definition");
++ }
++ *tailp = NULL;
++ scan(TOK_RPAREN, &tok);
++ scan(TOK_EQUAL, &tok);
++ scan_num(&tok);
++ scan(TOK_SEMICOLON, &tok);
++ plist->proc_num = tok.str;
++ plist->arg_num = num_args;
++ *ptailp = plist;
++ ptailp = &plist->next;
++ peek(&tok);
++ } while (tok.kind != TOK_RBRACE);
++ *ptailp = NULL;
++ *vtailp = vlist;
++ vtailp = &vlist->next;
++ scan(TOK_RBRACE, &tok);
++ scan(TOK_EQUAL, &tok);
++ scan_num(&tok);
++ vlist->vers_num = tok.str;
++ /* make the argument structure name for each arg*/
++ for(plist = vlist->procs; plist != NULL;
++ plist = plist->next) {
++ plist->args.argname = make_argname(plist->proc_name,
++ vlist->vers_num);
++ /* free the memory ??*/
++ }
++ scan(TOK_SEMICOLON, &tok);
++ scan2(TOK_VERSION, TOK_RBRACE, &tok);
++ } while (tok.kind == TOK_VERSION);
++ scan(TOK_EQUAL, &tok);
++ scan_num(&tok);
++ defp->def.pr.prog_num = tok.str;
++ *vtailp = NULL;
++}
++
++
++static void
++def_enum(definition *defp)
++{
++ token tok;
++ enumval_list *elist;
++ enumval_list **tailp;
++
++ defp->def_kind = DEF_ENUM;
++ scan(TOK_IDENT, &tok);
++ defp->def_name = tok.str;
++ scan(TOK_LBRACE, &tok);
++ tailp = &defp->def.en.vals;
++ do {
++ scan(TOK_IDENT, &tok);
++ elist = ALLOC(enumval_list);
++ elist->name = tok.str;
++ elist->assignment = NULL;
++ scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok);
++ if (tok.kind == TOK_EQUAL) {
++ scan_num(&tok);
++ elist->assignment = tok.str;
++ scan2(TOK_COMMA, TOK_RBRACE, &tok);
++ }
++ *tailp = elist;
++ tailp = &elist->next;
++ } while (tok.kind != TOK_RBRACE);
++ *tailp = NULL;
++}
++
++static void
++def_const(definition *defp)
++{
++ token tok;
++
++ defp->def_kind = DEF_CONST;
++ scan(TOK_IDENT, &tok);
++ defp->def_name = tok.str;
++ scan(TOK_EQUAL, &tok);
++ scan2(TOK_IDENT, TOK_STRCONST, &tok);
++ defp->def.co = tok.str;
++}
++
++static void
++def_union(definition *defp)
++{
++ token tok;
++ declaration dec;
++ case_list *cases;
++ case_list **tailp;
++
++ defp->def_kind = DEF_UNION;
++ scan(TOK_IDENT, &tok);
++ defp->def_name = tok.str;
++ scan(TOK_SWITCH, &tok);
++ scan(TOK_LPAREN, &tok);
++ get_declaration(&dec, DEF_UNION);
++ defp->def.un.enum_decl = dec;
++ tailp = &defp->def.un.cases;
++ scan(TOK_RPAREN, &tok);
++ scan(TOK_LBRACE, &tok);
++ scan(TOK_CASE, &tok);
++ while (tok.kind == TOK_CASE) {
++ scan2(TOK_IDENT, TOK_CHARCONST, &tok);
++ cases = ALLOC(case_list);
++ cases->case_name = tok.str;
++ scan(TOK_COLON, &tok);
++ /* now peek at next token */
++ if(peekscan(TOK_CASE,&tok))
++ {
++
++ do
++ {
++ scan2(TOK_IDENT, TOK_CHARCONST, &tok);
++ cases->contflag=1; /* continued case statement */
++ *tailp = cases;
++ tailp = &cases->next;
++ cases = ALLOC(case_list);
++ cases->case_name = tok.str;
++ scan(TOK_COLON, &tok);
++
++ }while(peekscan(TOK_CASE,&tok));
++ }
++
++ get_declaration(&dec, DEF_UNION);
++ cases->case_decl = dec;
++ cases->contflag=0; /* no continued case statement */
++ *tailp = cases;
++ tailp = &cases->next;
++ scan(TOK_SEMICOLON, &tok);
++
++ scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok);
++ }
++ *tailp = NULL;
++ if (tok.kind == TOK_DEFAULT) {
++ scan(TOK_COLON, &tok);
++ get_declaration(&dec, DEF_UNION);
++ defp->def.un.default_decl = ALLOC(declaration);
++ *defp->def.un.default_decl = dec;
++ scan(TOK_SEMICOLON, &tok);
++ scan(TOK_RBRACE, &tok);
++ } else {
++ defp->def.un.default_decl = NULL;
++ }
++}
++
++static char* reserved_words[] =
++{
++ "array",
++ "bytes",
++ "destroy",
++ "free",
++ "getpos",
++ "inline",
++ "pointer",
++ "reference",
++ "setpos",
++ "sizeof",
++ "union",
++ "vector",
++ NULL
++ };
++
++static char* reserved_types[] =
++{
++ "opaque",
++ "string",
++ NULL
++ };
++
++/* check that the given name is not one that would eventually result in
++ xdr routines that would conflict with internal XDR routines. */
++static void
++check_type_name(char *name, int new_type)
++{
++ int i;
++ char tmp[100];
++
++ for( i = 0; reserved_words[i] != NULL; i++ ) {
++ if( strcmp( name, reserved_words[i] ) == 0 ) {
++ sprintf(tmp,
++ "illegal (reserved) name :\'%s\' in type definition", name );
++ error(tmp);
++ }
++ }
++ if( new_type ) {
++ for( i = 0; reserved_types[i] != NULL; i++ ) {
++ if( strcmp( name, reserved_types[i] ) == 0 ) {
++ sprintf(tmp,
++ "illegal (reserved) name :\'%s\' in type definition", name );
++ error(tmp);
++ }
++ }
++ }
++}
++
++static void
++def_typedef(definition *defp)
++{
++ declaration dec;
++
++ defp->def_kind = DEF_TYPEDEF;
++ get_declaration(&dec, DEF_TYPEDEF);
++ defp->def_name = dec.name;
++ check_type_name( dec.name, 1 );
++ defp->def.ty.old_prefix = dec.prefix;
++ defp->def.ty.old_type = dec.type;
++ defp->def.ty.rel = dec.rel;
++ defp->def.ty.array_max = dec.array_max;
++}
++
++static void
++get_declaration(declaration *dec, defkind dkind)
++{
++ token tok;
++
++ get_type(&dec->prefix, &dec->type, dkind);
++ dec->rel = REL_ALIAS;
++ if (streq(dec->type, "void")) {
++ return;
++ }
++
++ check_type_name( dec->type, 0 );
++
++ scan2(TOK_STAR, TOK_IDENT, &tok);
++ if (tok.kind == TOK_STAR) {
++ dec->rel = REL_POINTER;
++ scan(TOK_IDENT, &tok);
++ }
++ dec->name = tok.str;
++ if (peekscan(TOK_LBRACKET, &tok)) {
++ if (dec->rel == REL_POINTER) {
++ error("no array-of-pointer declarations -- use typedef");
++ }
++ dec->rel = REL_VECTOR;
++ scan_num(&tok);
++ dec->array_max = tok.str;
++ scan(TOK_RBRACKET, &tok);
++ } else if (peekscan(TOK_LANGLE, &tok)) {
++ if (dec->rel == REL_POINTER) {
++ error("no array-of-pointer declarations -- use typedef");
++ }
++ dec->rel = REL_ARRAY;
++ if (peekscan(TOK_RANGLE, &tok)) {
++ dec->array_max = "~0"; /* unspecified size, use max */
++ } else {
++ scan_num(&tok);
++ dec->array_max = tok.str;
++ scan(TOK_RANGLE, &tok);
++ }
++ }
++ if (streq(dec->type, "opaque")) {
++ if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) {
++ error("array declaration expected");
++ }
++ } else if (streq(dec->type, "string")) {
++ if (dec->rel != REL_ARRAY) {
++ error("variable-length array declaration expected");
++ }
++ }
++}
++
++
++static void
++get_prog_declaration(declaration *dec, defkind dkind, int num)
++{
++ token tok;
++ char name[10]; /* argument name */
++
++ if (dkind == DEF_PROGRAM) {
++ peek(&tok);
++ if (tok.kind == TOK_RPAREN) { /* no arguments */
++ dec->rel = REL_ALIAS;
++ dec->type = "void";
++ dec->prefix = NULL;
++ dec->name = NULL;
++ return;
++ }
++ }
++ get_type(&dec->prefix, &dec->type, dkind);
++ dec->rel = REL_ALIAS;
++ if (peekscan(TOK_IDENT, &tok)) /* optional name of argument */
++ strcpy(name, tok.str);
++ else
++ sprintf(name, "%s%d", ARGNAME, num); /* default name of argument */
++
++ dec->name = (char *) strdup(name);
++
++ if (streq(dec->type, "void")) {
++ return;
++ }
++
++ if (streq(dec->type, "opaque")) {
++ error("opaque -- illegal argument type");
++ }
++ if (peekscan(TOK_STAR, &tok)) {
++ if (streq(dec->type, "string")) {
++ error("pointer to string not allowed in program arguments\n");
++ }
++ dec->rel = REL_POINTER;
++ if (peekscan(TOK_IDENT, &tok)) /* optional name of argument */
++ dec->name = strdup(tok.str);
++ }
++ if (peekscan(TOK_LANGLE, &tok)) {
++ if (!streq(dec->type, "string")) {
++ error("arrays cannot be declared as arguments to procedures -- use typedef");
++ }
++ dec->rel = REL_ARRAY;
++ if (peekscan(TOK_RANGLE, &tok)) {
++ dec->array_max = "~0";/* unspecified size, use max */
++ } else {
++ scan_num(&tok);
++ dec->array_max = tok.str;
++ scan(TOK_RANGLE, &tok);
++ }
++ }
++ if (streq(dec->type, "string")) {
++ if (dec->rel != REL_ARRAY) { /* .x specifies just string as
++ * type of argument
++ * - make it string<>
++ */
++ dec->rel = REL_ARRAY;
++ dec->array_max = "~0";/* unspecified size, use max */
++ }
++ }
++}
++
++
++
++static void
++get_type(char **prefixp, char **typep, defkind dkind)
++{
++ token tok;
++
++ *prefixp = NULL;
++ get_token(&tok);
++ switch (tok.kind) {
++ case TOK_IDENT:
++ *typep = tok.str;
++ break;
++ case TOK_STRUCT:
++ case TOK_ENUM:
++ case TOK_UNION:
++ *prefixp = tok.str;
++ scan(TOK_IDENT, &tok);
++ *typep = tok.str;
++ break;
++ case TOK_UNSIGNED:
++ unsigned_dec(typep);
++ break;
++ case TOK_SHORT:
++ *typep = "short";
++ (void) peekscan(TOK_INT, &tok);
++ break;
++ case TOK_INT32:
++ *typep = "int32_t";
++ (void) peekscan(TOK_INT, &tok);
++ break;
++ case TOK_VOID:
++ if (dkind != DEF_UNION && dkind != DEF_PROGRAM) {
++ error("voids allowed only inside union and program definitions with one argument");
++ }
++ *typep = tok.str;
++ break;
++ case TOK_STRING:
++ case TOK_OPAQUE:
++ case TOK_CHAR:
++ case TOK_INT:
++ case TOK_FLOAT:
++ case TOK_DOUBLE:
++ case TOK_BOOL:
++ *typep = tok.str;
++ break;
++ default:
++ error("expected type specifier");
++ }
++}
++
++static void
++unsigned_dec(char **typep)
++{
++ token tok;
++
++ peek(&tok);
++ switch (tok.kind) {
++ case TOK_CHAR:
++ get_token(&tok);
++ *typep = "u_char";
++ break;
++ case TOK_SHORT:
++ get_token(&tok);
++ *typep = "u_short";
++ (void) peekscan(TOK_INT, &tok);
++ break;
++ case TOK_INT32:
++ get_token(&tok);
++ *typep = "u_int32_";
++ (void) peekscan(TOK_INT, &tok);
++ break;
++ case TOK_INT:
++ get_token(&tok);
++ *typep = "u_int";
++ break;
++ default:
++ *typep = "u_int";
++ break;
++ }
++}
+--- libtirpc-0.2.3/rpcgen/rpc_parse.h.0005~ 2013-02-11 21:47:03.994289281 +0100
++++ libtirpc-0.2.3/rpcgen/rpc_parse.h 2013-02-11 21:47:03.994289281 +0100
+@@ -0,0 +1,166 @@
++/*
++ * Copyright (c) 2009, Sun Microsystems, Inc.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions are met:
++ * - Redistributions of source code must retain the above copyright notice,
++ * this list of conditions and the following disclaimer.
++ * - Redistributions in binary form must reproduce the above copyright notice,
++ * this list of conditions and the following disclaimer in the documentation
++ * and/or other materials provided with the distribution.
++ * - Neither the name of Sun Microsystems, Inc. nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
++ * POSSIBILITY OF SUCH DAMAGE.
++ */
++
++/* @(#)rpc_parse.h 1.3 90/08/29 (C) 1987 SMI */
++
++/*
++ * rpc_parse.h, Definitions for the RPCL parser
++ */
++
++enum defkind {
++ DEF_CONST,
++ DEF_STRUCT,
++ DEF_UNION,
++ DEF_ENUM,
++ DEF_TYPEDEF,
++ DEF_PROGRAM
++};
++typedef enum defkind defkind;
++
++typedef char *const_def;
++
++enum relation {
++ REL_VECTOR, /* fixed length array */
++ REL_ARRAY, /* variable length array */
++ REL_POINTER, /* pointer */
++ REL_ALIAS, /* simple */
++};
++typedef enum relation relation;
++
++struct typedef_def {
++ char *old_prefix;
++ char *old_type;
++ relation rel;
++ char *array_max;
++};
++typedef struct typedef_def typedef_def;
++
++struct enumval_list {
++ char *name;
++ char *assignment;
++ struct enumval_list *next;
++};
++typedef struct enumval_list enumval_list;
++
++struct enum_def {
++ enumval_list *vals;
++};
++typedef struct enum_def enum_def;
++
++struct declaration {
++ char *prefix;
++ char *type;
++ char *name;
++ relation rel;
++ char *array_max;
++};
++typedef struct declaration declaration;
++
++struct decl_list {
++ declaration decl;
++ struct decl_list *next;
++};
++typedef struct decl_list decl_list;
++
++struct struct_def {
++ decl_list *decls;
++};
++typedef struct struct_def struct_def;
++
++struct case_list {
++ char *case_name;
++ int contflag;
++ declaration case_decl;
++ struct case_list *next;
++};
++typedef struct case_list case_list;
++
++struct union_def {
++ declaration enum_decl;
++ case_list *cases;
++ declaration *default_decl;
++};
++typedef struct union_def union_def;
++
++struct arg_list {
++ char *argname; /* name of struct for arg*/
++ decl_list *decls;
++};
++
++typedef struct arg_list arg_list;
++
++struct proc_list {
++ char *proc_name;
++ char *proc_num;
++ arg_list args;
++ int arg_num;
++ char *res_type;
++ char *res_prefix;
++ struct proc_list *next;
++};
++typedef struct proc_list proc_list;
++
++struct version_list {
++ char *vers_name;
++ char *vers_num;
++ proc_list *procs;
++ struct version_list *next;
++};
++typedef struct version_list version_list;
++
++struct program_def {
++ char *prog_num;
++ version_list *versions;
++};
++typedef struct program_def program_def;
++
++struct definition {
++ char *def_name;
++ defkind def_kind;
++ union {
++ const_def co;
++ struct_def st;
++ union_def un;
++ enum_def en;
++ typedef_def ty;
++ program_def pr;
++ } def;
++};
++typedef struct definition definition;
++
++definition *get_definition();
++
++
++struct bas_type
++{
++ char *name;
++ int length;
++ struct bas_type *next;
++};
++
++typedef struct bas_type bas_type;
+--- libtirpc-0.2.3/rpcgen/rpc_sample.c.0005~ 2013-02-11 21:47:03.994289281 +0100
++++ libtirpc-0.2.3/rpcgen/rpc_sample.c 2013-02-11 21:47:03.994289281 +0100
+@@ -0,0 +1,247 @@
++/*
++ * Copyright (c) 2009, Sun Microsystems, Inc.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions are met:
++ * - Redistributions of source code must retain the above copyright notice,
++ * this list of conditions and the following disclaimer.
++ * - Redistributions in binary form must reproduce the above copyright notice,
++ * this list of conditions and the following disclaimer in the documentation
++ * and/or other materials provided with the distribution.
++ * - Neither the name of Sun Microsystems, Inc. nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
++ * POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#if 0
++static char sccsid[] = "@(#)rpc_sample.c 1.1 90/08/30 (C) 1987 SMI";
++
++#endif
++
++/*
++ * rpc_sample.c, Sample client-server code outputter for the RPC protocol compiler
++ */
++
++#include <stdio.h>
++#include <string.h>
++#include "rpc_parse.h"
++#include "rpc_util.h"
++
++
++static char RQSTP[] = "rqstp";
++
++static void write_sample_client(char *program_name, version_list *vp);
++static void write_sample_server(definition * def);
++static void return_type(proc_list *plist);
++
++void
++write_sample_svc(definition *def)
++{
++ if (def->def_kind != DEF_PROGRAM)
++ return;
++ write_sample_server(def);
++}
++
++
++int
++write_sample_clnt(definition *def)
++{
++ version_list *vp;
++ int count = 0;
++
++ if (def->def_kind != DEF_PROGRAM)
++ return (0);
++ /* generate sample code for each version */
++ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
++ write_sample_client(def->def_name, vp);
++ ++count;
++ }
++ return (count);
++}
++
++
++static void
++write_sample_client(char *program_name, version_list *vp)
++{
++ proc_list *proc;
++ int i;
++ decl_list *l;
++
++ f_print(fout, "\n\nvoid\n");
++ pvname(program_name, vp->vers_num);
++ if (Cflag)
++ f_print(fout, "( char* host )\n{\n");
++ else
++ f_print(fout, "(host)\nchar *host;\n{\n");
++ f_print(fout, "\tCLIENT *clnt;\n");
++
++ i = 0;
++ for (proc = vp->procs; proc != NULL; proc = proc->next) {
++ f_print(fout, "\t");
++ ptype(proc->res_prefix, proc->res_type, 1);
++ f_print(fout, " *result_%d;\n", ++i);
++ /* print out declarations for arguments */
++ if (proc->arg_num < 2 && !newstyle) {
++ f_print(fout, "\t");
++ if (!streq(proc->args.decls->decl.type, "void"))
++ ptype(proc->args.decls->decl.prefix, proc->args.decls->decl.type, 1);
++ else
++ f_print(fout, "char* "); /* cannot have "void" type */
++ f_print(fout, " ");
++ pvname(proc->proc_name, vp->vers_num);
++ f_print(fout, "_arg;\n");
++ } else if (!streq(proc->args.decls->decl.type, "void")) {
++ for (l = proc->args.decls; l != NULL; l = l->next) {
++ f_print(fout, "\t");
++ ptype(l->decl.prefix, l->decl.type, 1);
++ f_print(fout, " ");
++ pvname(proc->proc_name, vp->vers_num);
++ f_print(fout, "_%s;\n", l->decl.name);
++ /* pdeclaration(proc->args.argname, &l->decl, 1, ";\n" );*/
++ }
++ }
++ }
++
++ /* generate creation of client handle */
++ f_print(fout, "\tclnt = clnt_create(host, %s, %s, \"%s\");\n",
++ program_name, vp->vers_name, tirpcflag ? "netpath" : "udp");
++ f_print(fout, "\tif (clnt == NULL) {\n");
++ f_print(fout, "\t\tclnt_pcreateerror(host);\n");
++ f_print(fout, "\t\texit(1);\n\t}\n");
++
++ /* generate calls to procedures */
++ i = 0;
++ for (proc = vp->procs; proc != NULL; proc = proc->next) {
++ f_print(fout, "\tresult_%d = ", ++i);
++ pvname(proc->proc_name, vp->vers_num);
++ if (proc->arg_num < 2 && !newstyle) {
++ f_print(fout, "(");
++ if (streq(proc->args.decls->decl.type, "void")) /* cast to void* */
++ f_print(fout, "(void*)");
++ f_print(fout, "&");
++ pvname(proc->proc_name, vp->vers_num);
++ f_print(fout, "_arg, clnt);\n");
++ } else if (streq(proc->args.decls->decl.type, "void")) {
++ f_print(fout, "(clnt);\n");
++ } else {
++ f_print(fout, "(");
++ for (l = proc->args.decls; l != NULL; l = l->next) {
++ pvname(proc->proc_name, vp->vers_num);
++ f_print(fout, "_%s, ", l->decl.name);
++ }
++ f_print(fout, "clnt);\n");
++ }
++ f_print(fout, "\tif (result_%d == NULL) {\n", i);
++ f_print(fout, "\t\tclnt_perror(clnt, \"call failed:\");\n");
++ f_print(fout, "\t}\n");
++ }
++
++ f_print(fout, "\tclnt_destroy( clnt );\n");
++ f_print(fout, "}\n");
++}
++
++static void
++write_sample_server(definition * def)
++{
++ version_list *vp;
++ proc_list *proc;
++
++ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
++ for (proc = vp->procs; proc != NULL; proc = proc->next) {
++ f_print(fout, "\n");
++ /* if( Cflag )
++ f_print( fout, "extern \"C\"{\n");
++*/
++ return_type(proc);
++ f_print(fout, "* \n");
++ if (Cflag)
++ pvname_svc(proc->proc_name, vp->vers_num);
++ else
++ pvname(proc->proc_name, vp->vers_num);
++ printarglist(proc, RQSTP, "struct svc_req *");
++
++ f_print(fout, "{\n");
++ f_print(fout, "\n\tstatic ");
++ if (!streq(proc->res_type, "void"))
++ return_type(proc);
++ else
++ f_print(fout, "char*"); /* cannot have void type */
++ /* f_print(fout, " result;\n", proc->res_type); */
++ f_print(fout, " result;\n");
++ f_print(fout,
++ "\n\t/*\n\t * insert server code here\n\t */\n\n");
++ if (!streq(proc->res_type, "void"))
++ f_print(fout, "\treturn(&result);\n}\n");
++ else /* cast back to void * */
++ f_print(fout, "\treturn((void*) &result);\n}\n");
++ /* if( Cflag)
++ f_print( fout, "};\n");
++*/
++
++ }
++ }
++}
++
++
++
++static void
++return_type(proc_list *plist)
++{
++ ptype( plist->res_prefix, plist->res_type, 1 );
++}
++
++void
++add_sample_msg(void)
++{
++ f_print(fout, "/*\n");
++ f_print(fout, " * This is sample code generated by rpcgen.\n");
++ f_print(fout, " * These are only templates and you can use them\n");
++ f_print(fout, " * as a guideline for developing your own functions.\n");
++ f_print(fout, " */\n\n");
++}
++
++void
++write_sample_clnt_main(void)
++{
++ list *l;
++ definition *def;
++ version_list *vp;
++
++ f_print(fout, "\n\n" );
++ if( Cflag )
++ f_print(fout,"main( int argc, char* argv[] )\n{\n" );
++ else
++ f_print(fout, "main(argc, argv)\nint argc;\nchar *argv[];\n{\n" );
++
++ f_print(fout, "\tchar *host;");
++ f_print(fout, "\n\n\tif(argc < 2) {");
++ f_print(fout, "\n\t\tprintf(\"usage: %%s server_host\\n\", argv[0]);\n" );
++ f_print(fout, "\t\texit(1);\n\t}");
++ f_print(fout, "\n\thost = argv[1];\n");
++
++ for (l = defined; l != NULL; l = l->next) {
++ def = l->val;
++ if (def->def_kind != DEF_PROGRAM) {
++ continue;
++ }
++ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
++ f_print( fout, "\t" );
++ pvname(def->def_name, vp->vers_num);
++ f_print( fout, "( host );\n" );
++ }
++ }
++ f_print(fout, "}\n");
++}
+--- libtirpc-0.2.3/rpcgen/rpc_scan.c.0005~ 2013-02-11 21:47:03.995289293 +0100
++++ libtirpc-0.2.3/rpcgen/rpc_scan.c 2013-02-11 21:47:03.995289293 +0100
+@@ -0,0 +1,474 @@
++/*
++ * Copyright (c) 2009, Sun Microsystems, Inc.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions are met:
++ * - Redistributions of source code must retain the above copyright notice,
++ * this list of conditions and the following disclaimer.
++ * - Redistributions in binary form must reproduce the above copyright notice,
++ * this list of conditions and the following disclaimer in the documentation
++ * and/or other materials provided with the distribution.
++ * - Neither the name of Sun Microsystems, Inc. nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
++ * POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#if 0
++static char sccsid[] = "@(#)rpc_scan.c 1.11 89/02/22 (C) 1987 SMI";
++#endif
++
++/*
++ * rpc_scan.c, Scanner for the RPC protocol compiler
++ * Copyright (C) 1987, Sun Microsystems, Inc.
++ */
++#include <stdio.h>
++#include <ctype.h>
++#include <string.h>
++#include "rpc_scan.h"
++#include "rpc_parse.h"
++#include "rpc_util.h"
++
++static void unget_token(token *tokp);
++static void findstrconst(char **str, char **val);
++static void findchrconst(char **str, char **val);
++static void findconst(char **str, char **val);
++static void findkind(char **mark, token *tokp);
++static int cppline(char *line);
++static int directive(char *line);
++static void printdirective(char *line);
++static void docppline(char *line, int *lineno, char **fname);
++
++#define startcomment(where) (where[0] == '/' && where[1] == '*')
++#define endcomment(where) (where[-1] == '*' && where[0] == '/')
++
++static int pushed = 0; /* is a token pushed */
++static token lasttok; /* last token, if pushed */
++
++/*
++ * scan expecting 1 given token
++ */
++void
++scan(tok_kind expect, token *tokp)
++{
++ get_token(tokp);
++ if (tokp->kind != expect) {
++ expected1(expect);
++ }
++}
++
++/*
++ * scan expecting any of the 2 given tokens
++ */
++void
++scan2(tok_kind expect1, tok_kind expect2, token *tokp)
++{
++ get_token(tokp);
++ if (tokp->kind != expect1 && tokp->kind != expect2) {
++ expected2(expect1, expect2);
++ }
++}
++
++/*
++ * scan expecting any of the 3 given token
++ */
++void
++scan3(tok_kind expect1, tok_kind expect2, tok_kind expect3, token *tokp)
++{
++ get_token(tokp);
++ if (tokp->kind != expect1 && tokp->kind != expect2
++ && tokp->kind != expect3) {
++ expected3(expect1, expect2, expect3);
++ }
++}
++
++/*
++ * scan expecting a constant, possibly symbolic
++ */
++void
++scan_num(token *tokp)
++{
++ get_token(tokp);
++ switch (tokp->kind) {
++ case TOK_IDENT:
++ break;
++ default:
++ error("constant or identifier expected");
++ }
++}
++
++/*
++ * Peek at the next token
++ */
++void
++peek(token *tokp)
++{
++ get_token(tokp);
++ unget_token(tokp);
++}
++
++/*
++ * Peek at the next token and scan it if it matches what you expect
++ */
++int
++peekscan(tok_kind expect, token *tokp)
++{
++ peek(tokp);
++ if (tokp->kind == expect) {
++ get_token(tokp);
++ return (1);
++ }
++ return (0);
++}
++
++/*
++ * Get the next token, printing out any directive that are encountered.
++ */
++void
++get_token(token *tokp)
++{
++ int commenting;
++
++ if (pushed) {
++ pushed = 0;
++ *tokp = lasttok;
++ return;
++ }
++ commenting = 0;
++ for (;;) {
++ if (*where == 0) {
++ for (;;) {
++ if (!fgets(curline, MAXLINESIZE, fin)) {
++ tokp->kind = TOK_EOF;
++ *where = 0;
++ return;
++ }
++ linenum++;
++ if (commenting) {
++ break;
++ } else if (cppline(curline)) {
++ docppline(curline, &linenum,
++ &infilename);
++ } else if (directive(curline)) {
++ printdirective(curline);
++ } else {
++ break;
++ }
++ }
++ where = curline;
++ } else if (isspace(*where)) {
++ while (isspace(*where)) {
++ where++; /* eat */
++ }
++ } else if (commenting) {
++ for (where++; *where; where++) {
++ if (endcomment(where)) {
++ where++;
++ commenting--;
++ break;
++ }
++ }
++ } else if (startcomment(where)) {
++ where += 2;
++ commenting++;
++ } else {
++ break;
++ }
++ }
++
++ /*
++ * 'where' is not whitespace, comment or directive Must be a token!
++ */
++ switch (*where) {
++ case ':':
++ tokp->kind = TOK_COLON;
++ where++;
++ break;
++ case ';':
++ tokp->kind = TOK_SEMICOLON;
++ where++;
++ break;
++ case ',':
++ tokp->kind = TOK_COMMA;
++ where++;
++ break;
++ case '=':
++ tokp->kind = TOK_EQUAL;
++ where++;
++ break;
++ case '*':
++ tokp->kind = TOK_STAR;
++ where++;
++ break;
++ case '[':
++ tokp->kind = TOK_LBRACKET;
++ where++;
++ break;
++ case ']':
++ tokp->kind = TOK_RBRACKET;
++ where++;
++ break;
++ case '{':
++ tokp->kind = TOK_LBRACE;
++ where++;
++ break;
++ case '}':
++ tokp->kind = TOK_RBRACE;
++ where++;
++ break;
++ case '(':
++ tokp->kind = TOK_LPAREN;
++ where++;
++ break;
++ case ')':
++ tokp->kind = TOK_RPAREN;
++ where++;
++ break;
++ case '<':
++ tokp->kind = TOK_LANGLE;
++ where++;
++ break;
++ case '>':
++ tokp->kind = TOK_RANGLE;
++ where++;
++ break;
++
++ case '"':
++ tokp->kind = TOK_STRCONST;
++ findstrconst(&where, &tokp->str);
++ break;
++ case '\'':
++ tokp->kind = TOK_CHARCONST;
++ findchrconst(&where, &tokp->str);
++ break;
++
++ case '-':
++ case '0':
++ case '1':
++ case '2':
++ case '3':
++ case '4':
++ case '5':
++ case '6':
++ case '7':
++ case '8':
++ case '9':
++ tokp->kind = TOK_IDENT;
++ findconst(&where, &tokp->str);
++ break;
++
++ default:
++ if (!(isalpha(*where) || *where == '_')) {
++ char buf[100];
++ char *p;
++
++ s_print(buf, "illegal character in file: ");
++ p = buf + strlen(buf);
++ if (isprint(*where)) {
++ s_print(p, "%c", *where);
++ } else {
++ s_print(p, "%d", *where);
++ }
++ error(buf);
++ }
++ findkind(&where, tokp);
++ break;
++ }
++}
++
++static void
++unget_token(token *tokp)
++{
++ lasttok = *tokp;
++ pushed = 1;
++}
++
++static void
++findstrconst(char **str, char **val)
++{
++ char *p;
++ int size;
++
++ p = *str;
++ do {
++ *p++;
++ } while (*p && *p != '"');
++ if (*p == 0) {
++ error("unterminated string constant");
++ }
++ p++;
++ size = p - *str;
++ *val = alloc(size + 1);
++ (void) strncpy(*val, *str, size);
++ (*val)[size] = 0;
++ *str = p;
++}
++
++static void
++findchrconst(char **str, char **val)
++{
++ char *p;
++ int size;
++
++ p = *str;
++ do {
++ *p++;
++ } while (*p && *p != '\'');
++ if (*p == 0) {
++ error("unterminated string constant");
++ }
++ p++;
++ size = p - *str;
++ if (size != 3) {
++ error("empty char string");
++ }
++ *val = alloc(size + 1);
++ (void) strncpy(*val, *str, size);
++ (*val)[size] = 0;
++ *str = p;
++}
++
++static void
++findconst(char **str, char **val)
++{
++ char *p;
++ int size;
++
++ p = *str;
++ if (*p == '0' && *(p + 1) == 'x') {
++ p++;
++ do {
++ p++;
++ } while (isxdigit(*p));
++ } else {
++ do {
++ p++;
++ } while (isdigit(*p));
++ }
++ size = p - *str;
++ *val = alloc(size + 1);
++ (void) strncpy(*val, *str, size);
++ (*val)[size] = 0;
++ *str = p;
++}
++
++static token symbols[] = {
++ {TOK_CONST, "const"},
++ {TOK_UNION, "union"},
++ {TOK_SWITCH, "switch"},
++ {TOK_CASE, "case"},
++ {TOK_DEFAULT, "default"},
++ {TOK_STRUCT, "struct"},
++ {TOK_TYPEDEF, "typedef"},
++ {TOK_ENUM, "enum"},
++ {TOK_OPAQUE, "opaque"},
++ {TOK_BOOL, "bool"},
++ {TOK_VOID, "void"},
++ {TOK_CHAR, "char"},
++ {TOK_INT, "int"},
++ {TOK_UNSIGNED, "unsigned"},
++ {TOK_SHORT, "short"},
++ {TOK_INT32, "int32"},
++ {TOK_FLOAT, "float"},
++ {TOK_DOUBLE, "double"},
++ {TOK_STRING, "string"},
++ {TOK_PROGRAM, "program"},
++ {TOK_VERSION, "version"},
++ {TOK_EOF, "??????"},
++};
++
++static void
++findkind(char **mark, token *tokp)
++{
++ int len;
++ token *s;
++ char *str;
++
++ str = *mark;
++ for (s = symbols; s->kind != TOK_EOF; s++) {
++ len = strlen(s->str);
++ if (strncmp(str, s->str, len) == 0) {
++ if (!isalnum(str[len]) && str[len] != '_') {
++ tokp->kind = s->kind;
++ tokp->str = s->str;
++ *mark = str + len;
++ return;
++ }
++ }
++ }
++ tokp->kind = TOK_IDENT;
++ for (len = 0; isalnum(str[len]) || str[len] == '_'; len++);
++ tokp->str = alloc(len + 1);
++ (void) strncpy(tokp->str, str, len);
++ tokp->str[len] = 0;
++ *mark = str + len;
++}
++
++static int
++cppline(char *line)
++{
++ return (line == curline && *line == '#');
++}
++
++static int
++directive(char *line)
++{
++ return (line == curline && *line == '%');
++}
++
++static void
++printdirective(char *line)
++{
++ f_print(fout, "%s", line + 1);
++}
++
++static void
++docppline(char *line, int *lineno, char **fname)
++{
++ char *file;
++ int num;
++ char *p;
++
++ line++;
++ while (isspace(*line)) {
++ line++;
++ }
++ num = atoi(line);
++ while (isdigit(*line)) {
++ line++;
++ }
++ while (isspace(*line)) {
++ line++;
++ }
++ if (*line != '"') {
++ error("preprocessor error");
++ }
++ line++;
++ p = file = alloc(strlen(line) + 1);
++ while (*line && *line != '"') {
++ *p++ = *line++;
++ }
++ if (*line == 0) {
++ error("preprocessor error");
++ }
++ *p = 0;
++ if (*file == 0) {
++ *fname = NULL;
++ free(file);
++ } else {
++ *fname = file;
++ }
++ *lineno = num - 1;
++}
+--- libtirpc-0.2.3/rpcgen/rpc_scan.h.0005~ 2013-02-11 21:47:03.995289293 +0100
++++ libtirpc-0.2.3/rpcgen/rpc_scan.h 2013-02-11 21:47:03.995289293 +0100
+@@ -0,0 +1,103 @@
++/*
++ * Copyright (c) 2009, Sun Microsystems, Inc.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions are met:
++ * - Redistributions of source code must retain the above copyright notice,
++ * this list of conditions and the following disclaimer.
++ * - Redistributions in binary form must reproduce the above copyright notice,
++ * this list of conditions and the following disclaimer in the documentation
++ * and/or other materials provided with the distribution.
++ * - Neither the name of Sun Microsystems, Inc. nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
++ * POSSIBILITY OF SUCH DAMAGE.
++ */
++
++/* @(#)rpc_scan.h 1.3 90/08/29 (C) 1987 SMI */
++
++/*
++ * rpc_scan.h, Definitions for the RPCL scanner
++ */
++
++/*
++ * kinds of tokens
++ */
++enum tok_kind {
++ TOK_IDENT,
++ TOK_CHARCONST,
++ TOK_STRCONST,
++ TOK_LPAREN,
++ TOK_RPAREN,
++ TOK_LBRACE,
++ TOK_RBRACE,
++ TOK_LBRACKET,
++ TOK_RBRACKET,
++ TOK_LANGLE,
++ TOK_RANGLE,
++ TOK_STAR,
++ TOK_COMMA,
++ TOK_EQUAL,
++ TOK_COLON,
++ TOK_SEMICOLON,
++ TOK_CONST,
++ TOK_STRUCT,
++ TOK_UNION,
++ TOK_SWITCH,
++ TOK_CASE,
++ TOK_DEFAULT,
++ TOK_ENUM,
++ TOK_TYPEDEF,
++ TOK_INT,
++ TOK_SHORT,
++ TOK_INT32,
++ TOK_UNSIGNED,
++ TOK_FLOAT,
++ TOK_DOUBLE,
++ TOK_OPAQUE,
++ TOK_CHAR,
++ TOK_STRING,
++ TOK_BOOL,
++ TOK_VOID,
++ TOK_PROGRAM,
++ TOK_VERSION,
++ TOK_EOF
++};
++typedef enum tok_kind tok_kind;
++
++/*
++ * a token
++ */
++struct token {
++ tok_kind kind;
++ char *str;
++};
++typedef struct token token;
++
++
++/*
++ * routine interface
++ */
++void scan();
++void scan2();
++void scan3();
++void scan_num();
++void peek();
++int peekscan();
++void get_token();
++void expected1(tok_kind);
++void expected2(tok_kind, tok_kind);
++void expected3(tok_kind, tok_kind, tok_kind);
++
+--- libtirpc-0.2.3/rpcgen/rpc_svcout.c.0005~ 2013-02-11 21:47:03.996289305 +0100
++++ libtirpc-0.2.3/rpcgen/rpc_svcout.c 2013-02-11 21:47:03.996289305 +0100
+@@ -0,0 +1,882 @@
++/*
++ * Copyright (c) 2009, Sun Microsystems, Inc.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions are met:
++ * - Redistributions of source code must retain the above copyright notice,
++ * this list of conditions and the following disclaimer.
++ * - Redistributions in binary form must reproduce the above copyright notice,
++ * this list of conditions and the following disclaimer in the documentation
++ * and/or other materials provided with the distribution.
++ * - Neither the name of Sun Microsystems, Inc. nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
++ * POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#if 0
++ static char sccsid[] = "@(#)rpc_svcout.c 1.29 89/03/30 (C) 1987 SMI";
++#endif
++
++/*
++ * rpc_svcout.c, Server-skeleton outputter for the RPC protocol compiler
++ */
++#include <stdio.h>
++#include <string.h>
++#include "rpc_parse.h"
++#include "rpc_util.h"
++#include "rpc_output.h"
++
++static void write_real_program(definition *def);
++static void write_program(definition *def, char *storage);
++static void printerr(char *err, char *transp);
++static void printif(char *proc, char *transp, char *prefix, char *arg);
++static void write_inetmost(char *infile);
++static void print_return(char *space);
++static void print_pmapunset(char *space);
++static void print_err_message(char *space);
++static void write_timeout_func(void);
++static void write_pm_most(char *infile, int netflag);
++static void write_rpc_svc_fg(char *infile, char *sp);
++static void open_log_file(char *infile, char *sp);
++
++static char RQSTP[] = "rqstp";
++static char TRANSP[] = "transp";
++static char ARG[] = "argument";
++static char RESULT[] = "result";
++static char ROUTINE[] = "local";
++
++char _errbuf[256]; /* For all messages */
++
++static void
++p_xdrfunc(char *rname, char *typename)
++{
++ if (Cflag)
++ f_print(fout, "\t\txdr_%s = (xdrproc_t) xdr_%s;\n", rname,
++ stringfix(typename));
++ else
++ f_print(fout, "\t\txdr_%s = xdr_%s;\n", rname, stringfix(typename));
++}
++
++void
++internal_proctype(proc_list *plist)
++{
++ f_print(fout, "static ");
++ ptype( plist->res_prefix, plist->res_type, 1 );
++ f_print( fout, "*" );
++}
++
++
++/*
++ * write most of the service, that is, everything but the registrations.
++ */
++void
++write_most(char *infile, int netflag, int nomain)
++{
++ if (inetdflag || pmflag) {
++ char* var_type;
++ var_type = (nomain? "extern" : "static");
++ f_print(fout, "%s int _rpcpmstart;", var_type );
++ f_print(fout, "\t\t/* Started by a port monitor ? */\n");
++ f_print(fout, "%s int _rpcfdtype;", var_type );
++ f_print(fout, "\t\t/* Whether Stream or Datagram ? */\n");
++ if (timerflag) {
++ f_print(fout, "%s int _rpcsvcdirty;", var_type );
++ f_print(fout, "\t/* Still serving ? */\n");
++ }
++ write_svc_aux( nomain );
++ }
++ /* write out dispatcher and stubs */
++ write_programs( nomain? (char *)NULL : "static" );
++
++ if( nomain )
++ return;
++
++ f_print(fout, "\nmain()\n");
++ f_print(fout, "{\n");
++ if (inetdflag) {
++ write_inetmost(infile); /* Includes call to write_rpc_svc_fg() */
++ } else {
++ if( tirpcflag ) {
++ if (netflag) {
++ f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP);
++ f_print(fout, "\tstruct netconfig *nconf = NULL;\n");
++ }
++ f_print(fout, "\tpid_t pid;\n");
++ f_print(fout, "\tint i;\n");
++ f_print(fout, "\tchar mname[FMNAMESZ + 1];\n\n");
++ write_pm_most(infile, netflag);
++ f_print(fout, "\telse {\n");
++ write_rpc_svc_fg(infile, "\t\t");
++ f_print(fout, "\t}\n");
++ } else {
++ f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP);
++ f_print(fout, "\n");
++ print_pmapunset("\t");
++ }
++ }
++
++ if (logflag && !inetdflag) {
++ open_log_file(infile, "\t");
++ }
++}
++
++/*
++ * write a registration for the given transport
++ */
++void
++write_netid_register(char *transp)
++{
++ list *l;
++ definition *def;
++ version_list *vp;
++ char *sp;
++ char tmpbuf[32];
++
++ sp = "";
++ f_print(fout, "\n");
++ f_print(fout, "%s\tnconf = getnetconfigent(\"%s\");\n", sp, transp);
++ f_print(fout, "%s\tif (nconf == NULL) {\n", sp);
++ (void) sprintf(_errbuf, "cannot find %s netid.", transp);
++ sprintf(tmpbuf, "%s\t\t", sp);
++ print_err_message(tmpbuf);
++ f_print(fout, "%s\t\texit(1);\n", sp);
++ f_print(fout, "%s\t}\n", sp);
++ f_print(fout, "%s\t%s = svc_tli_create(RPC_ANYFD, nconf, 0, 0, 0);\n",
++ sp, TRANSP);
++ f_print(fout, "%s\tif (%s == NULL) {\n", sp, TRANSP);
++ (void) sprintf(_errbuf, "cannot create %s service.", transp);
++ print_err_message(tmpbuf);
++ f_print(fout, "%s\t\texit(1);\n", sp);
++ f_print(fout, "%s\t}\n", sp);
++
++ for (l = defined; l != NULL; l = l->next) {
++ def = (definition *) l->val;
++ if (def->def_kind != DEF_PROGRAM) {
++ continue;
++ }
++ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
++ f_print(fout,
++ "%s\t(void) rpcb_unset(%s, %s, nconf);\n",
++ sp, def->def_name, vp->vers_name);
++ f_print(fout,
++ "%s\tif (!svc_reg(%s, %s, %s, ",
++ sp, TRANSP, def->def_name, vp->vers_name);
++ pvname(def->def_name, vp->vers_num);
++ f_print(fout, ", nconf)) {\n");
++ (void) sprintf(_errbuf, "unable to register (%s, %s, %s).",
++ def->def_name, vp->vers_name, transp);
++ print_err_message(tmpbuf);
++ f_print(fout, "%s\t\texit(1);\n", sp);
++ f_print(fout, "%s\t}\n", sp);
++ }
++ }
++ f_print(fout, "%s\tfreenetconfigent(nconf);\n", sp);
++}
++
++/*
++ * write a registration for the given transport for TLI
++ */
++void
++write_nettype_register(char *transp)
++{
++ list *l;
++ definition *def;
++ version_list *vp;
++
++ for (l = defined; l != NULL; l = l->next) {
++ def = (definition *) l->val;
++ if (def->def_kind != DEF_PROGRAM) {
++ continue;
++ }
++ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
++ f_print(fout, "\tif (!svc_create(");
++ pvname(def->def_name, vp->vers_num);
++ f_print(fout, ", %s, %s, \"%s\")) {\n ",
++ def->def_name, vp->vers_name, transp);
++ (void) sprintf(_errbuf,
++ "unable to create (%s, %s) for %s.",
++ def->def_name, vp->vers_name, transp);
++ print_err_message("\t\t");
++ f_print(fout, "\t\texit(1);\n");
++ f_print(fout, "\t}\n");
++ }
++ }
++}
++
++/*
++ * write the rest of the service
++ */
++void
++write_rest(void)
++{
++ f_print(fout, "\n");
++ if (inetdflag) {
++ f_print(fout, "\tif (%s == (SVCXPRT *)NULL) {\n", TRANSP);
++ (void) sprintf(_errbuf, "could not create a handle");
++ print_err_message("\t\t");
++ f_print(fout, "\t\texit(1);\n");
++ f_print(fout, "\t}\n");
++ if (timerflag) {
++ f_print(fout, "\tif (_rpcpmstart) {\n");
++ f_print(fout,
++ "\t\t(void) signal(SIGALRM, %s closedown);\n",
++ Cflag? "(SIG_PF)" : "(void(*)())" );
++ f_print(fout, "\t\t(void) alarm(_RPCSVC_CLOSEDOWN);\n");
++ f_print(fout, "\t}\n");
++ }
++ }
++ f_print(fout, "\tsvc_run();\n");
++ (void) sprintf(_errbuf, "svc_run returned");
++ print_err_message("\t");
++ f_print(fout, "\texit(1);\n");
++ f_print(fout, "\t/* NOTREACHED */\n");
++ f_print(fout, "}\n");
++}
++
++void
++write_programs(char *storage)
++{
++ list *l;
++ definition *def;
++
++ /* write out stubs for procedure definitions */
++ for (l = defined; l != NULL; l = l->next) {
++ def = (definition *) l->val;
++ if (def->def_kind == DEF_PROGRAM) {
++ write_real_program(def);
++ }
++ }
++
++ /* write out dispatcher for each program */
++ for (l = defined; l != NULL; l = l->next) {
++ def = (definition *) l->val;
++ if (def->def_kind == DEF_PROGRAM) {
++ write_program(def, storage);
++ }
++ }
++
++
++}
++
++/* write out definition of internal function (e.g. _printmsg_1(...))
++ which calls server's defintion of actual function (e.g. printmsg_1(...)).
++ Unpacks single user argument of printmsg_1 to call-by-value format
++ expected by printmsg_1. */
++static void
++write_real_program(definition *def)
++{
++ version_list *vp;
++ proc_list *proc;
++ decl_list *l;
++
++ if( !newstyle ) return; /* not needed for old style */
++ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
++ for (proc = vp->procs; proc != NULL; proc = proc->next) {
++ f_print(fout, "\n");
++ internal_proctype(proc);
++ f_print(fout, "\n_");
++ pvname(proc->proc_name, vp->vers_num);
++ if( Cflag ) {
++ f_print(fout, "(" );
++ /* arg name */
++ if (proc->arg_num > 1)
++ f_print(fout, proc->args.argname);
++ else
++ ptype(proc->args.decls->decl.prefix,
++ proc->args.decls->decl.type, 0);
++ f_print(fout, " *argp, struct svc_req *%s)\n",
++ RQSTP);
++ } else {
++ f_print(fout, "(argp, %s)\n", RQSTP );
++ /* arg name */
++ if (proc->arg_num > 1)
++ f_print(fout, "\t%s *argp;\n", proc->args.argname);
++ else {
++ f_print(fout, "\t");
++ ptype(proc->args.decls->decl.prefix,
++ proc->args.decls->decl.type, 0);
++ f_print(fout, " *argp;\n");
++ }
++ f_print(fout, " struct svc_req *%s;\n", RQSTP);
++ }
++
++ f_print(fout, "{\n");
++ f_print(fout, "\treturn(");
++ if( Cflag )
++ pvname_svc(proc->proc_name, vp->vers_num);
++ else
++ pvname(proc->proc_name, vp->vers_num);
++ f_print(fout, "(");
++ if (proc->arg_num < 2) { /* single argument */
++ if (!streq( proc->args.decls->decl.type, "void"))
++ f_print(fout, "*argp, "); /* non-void */
++ } else {
++ for (l = proc->args.decls; l != NULL; l = l->next)
++ f_print(fout, "argp->%s, ", l->decl.name);
++ }
++ f_print(fout, "%s));\n}\n", RQSTP);
++ }
++ }
++}
++
++static void
++write_program(definition *def, char *storage)
++{
++ version_list *vp;
++ proc_list *proc;
++ int filled;
++
++ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
++ f_print(fout, "\n");
++ if (storage != NULL) {
++ f_print(fout, "%s ", storage);
++ }
++ f_print(fout, "void\n");
++ pvname(def->def_name, vp->vers_num);
++
++ if (Cflag) {
++ f_print(fout, "(struct svc_req *%s, ", RQSTP);
++ f_print(fout, "register SVCXPRT *%s)\n", TRANSP);
++ } else {
++ f_print(fout, "(%s, %s)\n", RQSTP, TRANSP);
++ f_print(fout, " struct svc_req *%s;\n", RQSTP);
++ f_print(fout, " register SVCXPRT *%s;\n", TRANSP);
++ }
++
++ f_print(fout, "{\n");
++
++ filled = 0;
++ f_print(fout, "\tunion {\n");
++ for (proc = vp->procs; proc != NULL; proc = proc->next) {
++ if (proc->arg_num < 2) { /* single argument */
++ if (streq(proc->args.decls->decl.type,
++ "void")) {
++ continue;
++ }
++ filled = 1;
++ f_print(fout, "\t\t");
++ ptype(proc->args.decls->decl.prefix,
++ proc->args.decls->decl.type, 0);
++ pvname(proc->proc_name, vp->vers_num);
++ f_print(fout, "_arg;\n");
++
++ }
++ else {
++ filled = 1;
++ f_print(fout, "\t\t%s", proc->args.argname);
++ f_print(fout, " ");
++ pvname(proc->proc_name, vp->vers_num);
++ f_print(fout, "_arg;\n");
++ }
++ }
++ if (!filled) {
++ f_print(fout, "\t\tint fill;\n");
++ }
++ f_print(fout, "\t} %s;\n", ARG);
++ f_print(fout, "\tchar *%s;\n", RESULT);
++
++ if (Cflag) {
++ f_print(fout, "\txdrproc_t xdr_%s, xdr_%s;\n", ARG, RESULT);
++ f_print(fout,
++ "\tchar *(*%s)(char *, struct svc_req *);\n",
++ ROUTINE);
++ } else {
++ f_print(fout, "\tbool_t (*xdr_%s)(), (*xdr_%s)();\n", ARG, RESULT);
++ f_print(fout, "\tchar *(*%s)();\n", ROUTINE);
++ }
++
++ f_print(fout, "\n");
++
++ if (timerflag)
++ f_print(fout, "\t_rpcsvcdirty = 1;\n");
++ f_print(fout, "\tswitch (%s->rq_proc) {\n", RQSTP);
++ if (!nullproc(vp->procs)) {
++ f_print(fout, "\tcase NULLPROC:\n");
++ f_print(fout,
++ "\t\t(void) svc_sendreply(%s, (xdrproc_t) xdr_void, (char *)NULL);\n",
++ TRANSP);
++ print_return("\t\t");
++ f_print(fout, "\n");
++ }
++ for (proc = vp->procs; proc != NULL; proc = proc->next) {
++ f_print(fout, "\tcase %s:\n", proc->proc_name);
++ if (proc->arg_num < 2) { /* single argument */
++ p_xdrfunc( ARG, proc->args.decls->decl.type);
++ } else {
++ p_xdrfunc( ARG, proc->args.argname);
++ }
++ p_xdrfunc( RESULT, proc->res_type);
++ if( Cflag )
++ f_print(fout,
++ "\t\t%s = (char *(*)(char *, struct svc_req *)) ",
++ ROUTINE);
++ else
++ f_print(fout, "\t\t%s = (char *(*)()) ", ROUTINE);
++
++ if (newstyle) { /* new style: calls internal routine */
++ f_print(fout,"_");
++ }
++ /* Not sure about the following...
++ * rpc_hout always generates foobar_1_svc for
++ * the service procedure, so why should we use
++ * foobar_1 here?! --okir */
++#if 0
++ if( Cflag && !newstyle )
++ pvname_svc(proc->proc_name, vp->vers_num);
++ else
++ pvname(proc->proc_name, vp->vers_num);
++#else
++ pvname_svc(proc->proc_name, vp->vers_num);
++#endif
++ f_print(fout, ";\n");
++ f_print(fout, "\t\tbreak;\n\n");
++ }
++ f_print(fout, "\tdefault:\n");
++ printerr("noproc", TRANSP);
++ print_return("\t\t");
++ f_print(fout, "\t}\n");
++
++ f_print(fout, "\t(void) memset((char *)&%s, 0, sizeof (%s));\n", ARG, ARG);
++ if (Cflag)
++ printif("getargs", TRANSP, "(caddr_t) &", ARG);
++ else
++ printif("getargs", TRANSP, "&", ARG);
++ printerr("decode", TRANSP);
++ print_return("\t\t");
++ f_print(fout, "\t}\n");
++
++ if (Cflag)
++ f_print(fout, "\t%s = (*%s)((char *)&%s, %s);\n",
++ RESULT, ROUTINE, ARG, RQSTP);
++ else
++ f_print(fout, "\t%s = (*%s)(&%s, %s);\n",
++ RESULT, ROUTINE, ARG, RQSTP);
++ f_print(fout,
++ "\tif (%s != NULL && !svc_sendreply(%s, "
++ "(xdrproc_t) xdr_%s, %s)) {\n",
++ RESULT, TRANSP, RESULT, RESULT);
++ printerr("systemerr", TRANSP);
++ f_print(fout, "\t}\n");
++
++ if (Cflag)
++ printif("freeargs", TRANSP, "(caddr_t) &", ARG);
++ else
++ printif("freeargs", TRANSP, "&", ARG);
++ (void) sprintf(_errbuf, "unable to free arguments");
++ print_err_message("\t\t");
++ f_print(fout, "\t\texit(1);\n");
++ f_print(fout, "\t}\n");
++ print_return("\t");
++ f_print(fout, "}\n");
++ }
++}
++
++static void
++printerr(char *err, char *transp)
++{
++ f_print(fout, "\t\tsvcerr_%s(%s);\n", err, transp);
++}
++
++static void
++printif(char *proc, char *transp, char *prefix, char *arg)
++{
++ f_print(fout, "\tif (!svc_%s(%s, (xdrproc_t) xdr_%s, (caddr_t) %s%s)) {\n",
++ proc, transp, arg, prefix, arg);
++}
++
++int
++nullproc(proc_list *proc)
++{
++ for (; proc != NULL; proc = proc->next) {
++ if (streq(proc->proc_num, "0")) {
++ return (1);
++ }
++ }
++ return (0);
++}
++
++static void
++write_inetmost(char *infile)
++{
++ f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP);
++ f_print(fout, "\tint sock;\n");
++ f_print(fout, "\tint proto;\n");
++ f_print(fout, "\tstruct sockaddr_in saddr;\n");
++ f_print(fout, "\tint asize = sizeof (saddr);\n");
++ f_print(fout, "\n");
++ f_print(fout,
++ "\tif (getsockname(0, (struct sockaddr *)&saddr, &asize) == 0) {\n");
++ f_print(fout, "\t\tint ssize = sizeof (int);\n\n");
++ f_print(fout, "\t\tif (saddr.sin_family != AF_INET)\n");
++ f_print(fout, "\t\t\texit(1);\n");
++ f_print(fout, "\t\tif (getsockopt(0, SOL_SOCKET, SO_TYPE,\n");
++ f_print(fout, "\t\t\t\t(char *)&_rpcfdtype, &ssize) == -1)\n");
++ f_print(fout, "\t\t\texit(1);\n");
++ f_print(fout, "\t\tsock = 0;\n");
++ f_print(fout, "\t\t_rpcpmstart = 1;\n");
++ f_print(fout, "\t\tproto = 0;\n");
++ open_log_file(infile, "\t\t");
++ f_print(fout, "\t} else {\n");
++ write_rpc_svc_fg(infile, "\t\t");
++ f_print(fout, "\t\tsock = RPC_ANYSOCK;\n");
++ print_pmapunset("\t\t");
++ f_print(fout, "\t}\n");
++}
++
++static void
++print_return(char *space)
++{
++ if (exitnow)
++ f_print(fout, "%sexit(0);\n", space);
++ else {
++ if (timerflag)
++ f_print(fout, "%s_rpcsvcdirty = 0;\n", space);
++ f_print(fout, "%sreturn;\n", space);
++ }
++}
++
++static void
++print_pmapunset(char *space)
++{
++ list *l;
++ definition *def;
++ version_list *vp;
++
++ for (l = defined; l != NULL; l = l->next) {
++ def = (definition *) l->val;
++ if (def->def_kind == DEF_PROGRAM) {
++ for (vp = def->def.pr.versions; vp != NULL;
++ vp = vp->next) {
++ f_print(fout, "%s(void) pmap_unset(%s, %s);\n",
++ space, def->def_name, vp->vers_name);
++ }
++ }
++ }
++}
++
++static void
++print_err_message(char *space)
++{
++ if (logflag)
++ f_print(fout, "%ssyslog(LOG_ERR, \"%s\");\n", space, _errbuf);
++ else if (inetdflag || pmflag)
++ f_print(fout, "%s_msgout(\"%s\");\n", space, _errbuf);
++ else
++ f_print(fout, "%sfprintf(stderr, \"%s\");\n", space, _errbuf);
++}
++
++/*
++ * Write the server auxiliary function ( _msgout, timeout)
++ */
++void
++write_svc_aux(int nomain)
++{
++ if (!logflag)
++ write_msg_out();
++ if( !nomain )
++ write_timeout_func();
++}
++
++/*
++ * Write the _msgout function
++ */
++void
++write_msg_out(void)
++{
++ f_print(fout, "\n");
++ f_print(fout, "static\n");
++ if( !Cflag ) {
++ f_print(fout, "void _msgout(msg)\n");
++ f_print(fout, "\tchar *msg;\n");
++ } else {
++ f_print(fout, "void _msgout(char* msg)\n");
++ }
++ f_print(fout, "{\n");
++ f_print(fout, "#ifdef RPC_SVC_FG\n");
++ if (inetdflag || pmflag)
++ f_print(fout, "\tif (_rpcpmstart)\n");
++ f_print(fout, "\t\tsyslog(LOG_ERR, \"%%s\", msg);\n");
++ f_print(fout, "\telse\n");
++ f_print(fout, "\t\t(void) fprintf(stderr, \"%%s\\n\", msg);\n");
++ f_print(fout, "#else\n");
++ f_print(fout, "\tsyslog(LOG_ERR, \"%%s\", msg);\n");
++ f_print(fout, "#endif\n");
++ f_print(fout, "}\n");
++}
++
++/*
++ * Write the timeout function
++ */
++static void
++write_timeout_func(void)
++{
++ if (!timerflag)
++ return;
++ f_print(fout, "\n");
++ f_print(fout, "static void\n");
++ f_print(fout, "closedown()\n");
++ f_print(fout, "{\n");
++ f_print(fout, "\tif (_rpcsvcdirty == 0) {\n");
++ f_print(fout, "\t\tstatic int size;\n");
++ f_print(fout, "\t\tint i, openfd;\n");
++ if (tirpcflag && pmflag) {
++ f_print(fout, "\t\tstruct t_info tinfo;\n\n");
++ f_print(fout, "\t\tif (!t_getinfo(0, &tinfo) && (tinfo.servtype == T_CLTS))\n");
++ } else {
++ f_print(fout, "\n\t\tif (_rpcfdtype == SOCK_DGRAM)\n");
++ }
++ f_print(fout, "\t\t\texit(0);\n");
++ f_print(fout, "\t\tif (size == 0) {\n");
++ if( tirpcflag ) {
++ f_print(fout, "\t\t\tstruct rlimit rl;\n\n");
++ f_print(fout, "\t\t\trl.rlim_max = 0;\n");
++ f_print(fout, "\t\t\tgetrlimit(RLIMIT_NOFILE, &rl);\n");
++ f_print(fout, "\t\t\tif ((size = rl.rlim_max) == 0)\n");
++ f_print(fout, "\t\t\t\treturn;\n");
++ } else {
++ f_print(fout, "\t\t\tsize = getdtablesize();\n");
++ }
++ f_print(fout, "\t\t}\n");
++ f_print(fout, "\t\tfor (i = 0, openfd = 0; i < size && openfd < 2; i++)\n");
++ f_print(fout, "\t\t\tif (FD_ISSET(i, &svc_fdset))\n");
++ f_print(fout, "\t\t\t\topenfd++;\n");
++ f_print(fout, "\t\tif (openfd <= 1)\n");
++ f_print(fout, "\t\t\texit(0);\n");
++ f_print(fout, "\t}\n");
++ f_print(fout, "\t(void) alarm(_RPCSVC_CLOSEDOWN);\n");
++ f_print(fout, "}\n");
++}
++
++/*
++ * Write the most of port monitor support
++ */
++static void
++write_pm_most(char *infile, int netflag)
++{
++ list *l;
++ definition *def;
++ version_list *vp;
++
++ f_print(fout, "\tif (!ioctl(0, I_LOOK, mname) &&\n");
++ f_print(fout, "\t\t(!strcmp(mname, \"sockmod\") ||");
++ f_print(fout, " !strcmp(mname, \"timod\"))) {\n");
++ f_print(fout, "\t\tchar *netid;\n");
++ if (!netflag) { /* Not included by -n option */
++ f_print(fout, "\t\tstruct netconfig *nconf = NULL;\n");
++ f_print(fout, "\t\tSVCXPRT *%s;\n", TRANSP);
++ }
++ if( timerflag )
++ f_print(fout, "\t\tint pmclose;\n");
++/* not necessary, defined in /usr/include/stdlib */
++/* f_print(fout, "\t\textern char *getenv();\n");*/
++ f_print(fout, "\n");
++ f_print(fout, "\t\t_rpcpmstart = 1;\n");
++ if (logflag)
++ open_log_file(infile, "\t\t");
++ f_print(fout, "\t\tif ((netid = getenv(\"NLSPROVIDER\")) == NULL) {\n");
++ sprintf(_errbuf, "cannot get transport name");
++ print_err_message("\t\t\t");
++ f_print(fout, "\t\t} else if ((nconf = getnetconfigent(netid)) == NULL) {\n");
++ sprintf(_errbuf, "cannot get transport info");
++ print_err_message("\t\t\t");
++ f_print(fout, "\t\t}\n");
++ /*
++ * A kludgy support for inetd services. Inetd only works with
++ * sockmod, and RPC works only with timod, hence all this jugglery
++ */
++ f_print(fout, "\t\tif (strcmp(mname, \"sockmod\") == 0) {\n");
++ f_print(fout, "\t\t\tif (ioctl(0, I_POP, 0) || ioctl(0, I_PUSH, \"timod\")) {\n");
++ sprintf(_errbuf, "could not get the right module");
++ print_err_message("\t\t\t\t");
++ f_print(fout, "\t\t\t\texit(1);\n");
++ f_print(fout, "\t\t\t}\n");
++ f_print(fout, "\t\t}\n");
++ if( timerflag )
++ f_print(fout, "\t\tpmclose = (t_getstate(0) != T_DATAXFER);\n");
++ f_print(fout, "\t\tif ((%s = svc_tli_create(0, nconf, NULL, 0, 0)) == NULL) {\n",
++ TRANSP);
++ sprintf(_errbuf, "cannot create server handle");
++ print_err_message("\t\t\t");
++ f_print(fout, "\t\t\texit(1);\n");
++ f_print(fout, "\t\t}\n");
++ f_print(fout, "\t\tif (nconf)\n");
++ f_print(fout, "\t\t\tfreenetconfigent(nconf);\n");
++ for (l = defined; l != NULL; l = l->next) {
++ def = (definition *) l->val;
++ if (def->def_kind != DEF_PROGRAM) {
++ continue;
++ }
++ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
++ f_print(fout,
++ "\t\tif (!svc_reg(%s, %s, %s, ",
++ TRANSP, def->def_name, vp->vers_name);
++ pvname(def->def_name, vp->vers_num);
++ f_print(fout, ", 0)) {\n");
++ (void) sprintf(_errbuf, "unable to register (%s, %s).",
++ def->def_name, vp->vers_name);
++ print_err_message("\t\t\t");
++ f_print(fout, "\t\t\texit(1);\n");
++ f_print(fout, "\t\t}\n");
++ }
++ }
++ if (timerflag) {
++ f_print(fout, "\t\tif (pmclose) {\n");
++ f_print(fout, "\t\t\t(void) signal(SIGALRM, %s closedown);\n",
++ Cflag? "(SIG_PF)" : "(void(*)())" );
++ f_print(fout, "\t\t\t(void) alarm(_RPCSVC_CLOSEDOWN);\n");
++ f_print(fout, "\t\t}\n");
++ }
++ f_print(fout, "\t\tsvc_run();\n");
++ f_print(fout, "\t\texit(1);\n");
++ f_print(fout, "\t\t/* NOTREACHED */\n");
++ f_print(fout, "\t}\n");
++}
++
++/*
++ * Support for backgrounding the server if self started.
++ */
++static void
++write_rpc_svc_fg(char *infile, char *sp)
++{
++ f_print(fout, "#ifndef RPC_SVC_FG\n");
++ f_print(fout, "%sint size;\n", sp);
++ if( tirpcflag )
++ f_print(fout, "%sstruct rlimit rl;\n", sp);
++ if (inetdflag)
++ f_print(fout, "%sint pid, i;\n\n", sp);
++ f_print(fout, "%spid = fork();\n", sp);
++ f_print(fout, "%sif (pid < 0) {\n", sp);
++ f_print(fout, "%s\tperror(\"cannot fork\");\n", sp);
++ f_print(fout, "%s\texit(1);\n", sp);
++ f_print(fout, "%s}\n", sp);
++ f_print(fout, "%sif (pid)\n", sp);
++ f_print(fout, "%s\texit(0);\n", sp);
++ /* get number of file descriptors */
++ if( tirpcflag ) {
++ f_print(fout, "%srl.rlim_max = 0;\n", sp);
++ f_print(fout, "%sgetrlimit(RLIMIT_NOFILE, &rl);\n", sp);
++ f_print(fout, "%sif ((size = rl.rlim_max) == 0)\n", sp);
++ f_print(fout, "%s\texit(1);\n", sp);
++ } else {
++ f_print(fout, "%ssize = getdtablesize();\n", sp);
++ }
++
++ f_print(fout, "%sfor (i = 0; i < size; i++)\n", sp);
++ f_print(fout, "%s\t(void) close(i);\n", sp);
++ /* Redirect stderr and stdout to console */
++ f_print(fout, "%si = open(\"/dev/console\", 2);\n", sp);
++ f_print(fout, "%s(void) dup2(i, 1);\n", sp);
++ f_print(fout, "%s(void) dup2(i, 2);\n", sp);
++ /* This removes control of the controlling terminal */
++ if( tirpcflag )
++ f_print(fout, "%ssetsid();\n", sp);
++ else {
++ f_print(fout, "%si = open(\"/dev/tty\", 2);\n", sp);
++ f_print(fout, "%sif (i >= 0) {\n", sp);
++ f_print(fout, "%s\t(void) ioctl(i, TIOCNOTTY, (char *)NULL);\n", sp);;
++ f_print(fout, "%s\t(void) close(i);\n", sp);
++ f_print(fout, "%s}\n", sp);
++ }
++ if (!logflag)
++ open_log_file(infile, sp);
++ f_print(fout, "#endif\n");
++ if (logflag)
++ open_log_file(infile, sp);
++}
++
++static void
++open_log_file(char *infile, char *sp)
++{
++ char *s;
++
++ s = strrchr(infile, '.');
++ if (s)
++ *s = '\0';
++ f_print(fout,"%sopenlog(\"%s\", LOG_PID, LOG_DAEMON);\n", sp, infile);
++ if (s)
++ *s = '.';
++}
++
++
++
++
++/*
++ * write a registration for the given transport for Inetd
++ */
++void
++write_inetd_register(char *transp)
++{
++ list *l;
++ definition *def;
++ version_list *vp;
++ char *sp;
++ int isudp;
++ char tmpbuf[32];
++
++ if (inetdflag)
++ sp = "\t";
++ else
++ sp = "";
++ if (streq(transp, "udp"))
++ isudp = 1;
++ else
++ isudp = 0;
++ f_print(fout, "\n");
++ if (inetdflag) {
++ f_print(fout, "\tif ((_rpcfdtype == 0) || (_rpcfdtype == %s)) {\n",
++ isudp ? "SOCK_DGRAM" : "SOCK_STREAM");
++ }
++ f_print(fout, "%s\t%s = svc%s_create(%s",
++ sp, TRANSP, transp, inetdflag? "sock": "RPC_ANYSOCK");
++ if (!isudp)
++ f_print(fout, ", 0, 0");
++ f_print(fout, ");\n");
++ f_print(fout, "%s\tif (%s == NULL) {\n", sp, TRANSP);
++ (void) sprintf(_errbuf, "cannot create %s service.", transp);
++ (void) sprintf(tmpbuf, "%s\t\t", sp);
++ print_err_message(tmpbuf);
++ f_print(fout, "%s\t\texit(1);\n", sp);
++ f_print(fout, "%s\t}\n", sp);
++
++ if (inetdflag) {
++ f_print(fout, "%s\tif (!_rpcpmstart)\n\t", sp);
++ f_print(fout, "%s\tproto = IPPROTO_%s;\n",
++ sp, isudp ? "UDP": "TCP");
++ }
++ for (l = defined; l != NULL; l = l->next) {
++ def = (definition *) l->val;
++ if (def->def_kind != DEF_PROGRAM) {
++ continue;
++ }
++ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
++ f_print(fout, "%s\tif (!svc_register(%s, %s, %s, ",
++ sp, TRANSP, def->def_name, vp->vers_name);
++ pvname(def->def_name, vp->vers_num);
++ if (inetdflag)
++ f_print(fout, ", proto)) {\n");
++ else
++ f_print(fout, ", IPPROTO_%s)) {\n",
++ isudp ? "UDP": "TCP");
++ (void) sprintf(_errbuf, "unable to register (%s, %s, %s).",
++ def->def_name, vp->vers_name, transp);
++ print_err_message(tmpbuf);
++ f_print(fout, "%s\t\texit(1);\n", sp);
++ f_print(fout, "%s\t}\n", sp);
++ }
++ }
++ if (inetdflag)
++ f_print(fout, "\t}\n");
++}
+--- libtirpc-0.2.3/rpcgen/rpc_tblout.c.0005~ 2013-02-11 21:47:03.996289305 +0100
++++ libtirpc-0.2.3/rpcgen/rpc_tblout.c 2013-02-11 21:47:03.996289305 +0100
+@@ -0,0 +1,165 @@
++/*
++ * Copyright (c) 2009, Sun Microsystems, Inc.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions are met:
++ * - Redistributions of source code must retain the above copyright notice,
++ * this list of conditions and the following disclaimer.
++ * - Redistributions in binary form must reproduce the above copyright notice,
++ * this list of conditions and the following disclaimer in the documentation
++ * and/or other materials provided with the distribution.
++ * - Neither the name of Sun Microsystems, Inc. nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
++ * POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#if 0
++static char sccsid[] = "@(#)rpc_tblout.c 1.4 89/02/22 (C) 1988 SMI";
++#endif
++
++/*
++ * rpc_tblout.c, Dispatch table outputter for the RPC protocol compiler
++ */
++#include <stdio.h>
++#include <string.h>
++#include "rpc_parse.h"
++#include "rpc_util.h"
++#include "rpc_output.h"
++
++static void write_table(definition *def);
++static void printit(char *prefix, char *type);
++
++#define TABSIZE 8
++#define TABCOUNT 5
++#define TABSTOP (TABSIZE*TABCOUNT)
++
++static char tabstr[TABCOUNT+1] = "\t\t\t\t\t";
++
++static char tbl_hdr[] = "struct rpcgen_table %s_table[] = {\n";
++static char tbl_end[] = "};\n";
++
++static char null_entry[] = "\n\t(char *(*)())0,\n\
++ \t(xdrproc_t) xdr_void,\t\t\t0,\n\
++ \t(xdrproc_t) xdr_void,\t\t\t0,\n";
++
++
++static char tbl_nproc[] = "int %s_nproc =\n\tsizeof(%s_table)/sizeof(%s_table[0]);\n\n";
++
++void
++write_tables(void)
++{
++ list *l;
++ definition *def;
++
++ f_print(fout, "\n");
++ for (l = defined; l != NULL; l = l->next) {
++ def = (definition *) l->val;
++ if (def->def_kind == DEF_PROGRAM) {
++ write_table(def);
++ }
++ }
++}
++
++static void
++write_table(definition *def)
++{
++ version_list *vp;
++ proc_list *proc;
++ int current;
++ int expected;
++ char progvers[100];
++ int warning;
++
++ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
++ warning = 0;
++ s_print(progvers, "%s_%s",
++ locase(def->def_name), vp->vers_num);
++ /* print the table header */
++ f_print(fout, tbl_hdr, progvers);
++
++ if (nullproc(vp->procs)) {
++ expected = 0;
++ } else {
++ expected = 1;
++ f_print(fout, null_entry);
++ }
++ for (proc = vp->procs; proc != NULL; proc = proc->next) {
++ current = atoi(proc->proc_num);
++ if (current != expected++) {
++ f_print(fout,
++ "\n/*\n * WARNING: table out of order\n */\n");
++ if (warning == 0) {
++ f_print(stderr,
++ "WARNING %s table is out of order\n",
++ progvers);
++ warning = 1;
++ nonfatalerrors = 1;
++ }
++ expected = current + 1;
++ }
++ f_print(fout, "\n\t(char *(*)())RPCGEN_ACTION(");
++
++ /* routine to invoke */
++ if( Cflag && !newstyle )
++ pvname_svc(proc->proc_name, vp->vers_num);
++ else {
++ if( newstyle )
++ f_print( fout, "_"); /* calls internal func */
++ pvname(proc->proc_name, vp->vers_num);
++ }
++ f_print(fout, "),\n");
++
++ /* argument info */
++ if( proc->arg_num > 1 )
++ printit((char*) NULL, proc->args.argname );
++ else
++ /* do we have to do something special for newstyle */
++ printit( proc->args.decls->decl.prefix,
++ proc->args.decls->decl.type );
++ /* result info */
++ printit(proc->res_prefix, proc->res_type);
++ }
++
++ /* print the table trailer */
++ f_print(fout, tbl_end);
++ f_print(fout, tbl_nproc, progvers, progvers, progvers);
++ }
++}
++
++static void
++printit(char *prefix, char *type)
++{
++ int len;
++ int tabs;
++
++
++ len = fprintf(fout, "\txdr_%s,", stringfix(type));
++ /* account for leading tab expansion */
++ len += TABSIZE - 1;
++ /* round up to tabs required */
++ tabs = (TABSTOP - len + TABSIZE - 1)/TABSIZE;
++ f_print(fout, "%s", &tabstr[TABCOUNT-tabs]);
++
++ if (streq(type, "void")) {
++ f_print(fout, "0");
++ } else {
++ f_print(fout, "sizeof ( ");
++ /* XXX: should "follow" be 1 ??? */
++ ptype(prefix, type, 0);
++ f_print(fout, ")");
++ }
++ f_print(fout, ",\n");
++}
+--- libtirpc-0.2.3/rpcgen/rpc_util.c.0005~ 2013-02-11 21:47:03.997289317 +0100
++++ libtirpc-0.2.3/rpcgen/rpc_util.c 2013-02-11 21:47:03.997289317 +0100
+@@ -0,0 +1,479 @@
++/*
++ * Copyright (c) 2009, Sun Microsystems, Inc.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions are met:
++ * - Redistributions of source code must retain the above copyright notice,
++ * this list of conditions and the following disclaimer.
++ * - Redistributions in binary form must reproduce the above copyright notice,
++ * this list of conditions and the following disclaimer in the documentation
++ * and/or other materials provided with the distribution.
++ * - Neither the name of Sun Microsystems, Inc. nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
++ * POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#if 0
++static char sccsid[] = "@(#)rpc_util.c 1.11 89/02/22 (C) 1987 SMI";
++#endif
++
++/*
++ * rpc_util.c, Utility routines for the RPC protocol compiler
++ */
++#include <stdio.h>
++#include <memory.h>
++#include <ctype.h>
++#include <unistd.h>
++#include "rpc_scan.h"
++#include "rpc_parse.h"
++#include "rpc_util.h"
++
++static void printwhere(void);
++
++
++#define ARGEXT "argument"
++
++char curline[MAXLINESIZE]; /* current read line */
++char *where = curline; /* current point in line */
++int linenum = 0; /* current line number */
++
++char *infilename; /* input filename */
++
++#define NFILES 7
++char *outfiles[NFILES]; /* output file names */
++int nfiles;
++
++FILE *fout; /* file pointer of current output */
++FILE *fin; /* file pointer of current input */
++
++list *defined; /* list of defined things */
++
++/*
++ * Reinitialize the world
++ */
++void
++reinitialize(void)
++{
++ memset(curline, 0, MAXLINESIZE);
++ where = curline;
++ linenum = 0;
++ defined = NULL;
++}
++
++/*
++ * string equality
++ */
++int
++streq(char *a, char *b)
++{
++ return (strcmp(a, b) == 0);
++}
++
++/*
++ * find a value in a list
++ */
++definition *
++findval(list *lst, char *val, int (*cmp)(definition *, char *))
++{
++
++ for (; lst != NULL; lst = lst->next) {
++ if ((*cmp) (lst->val, val)) {
++ return (lst->val);
++ }
++ }
++ return (NULL);
++}
++
++/*
++ * store a value in a list
++ */
++void
++storeval(lstp, val)
++ list **lstp;
++ definition *val;
++{
++ list **l;
++ list *lst;
++
++
++ for (l = lstp; *l != NULL; l = (list **) & (*l)->next);
++ lst = ALLOC(list);
++ lst->val = val;
++ lst->next = NULL;
++ *l = lst;
++}
++
++static int
++findit(definition *def, char *type)
++{
++ return (streq(def->def_name, type));
++}
++
++static char *
++fixit(char *type, char *orig)
++{
++ definition *def;
++
++ def = (definition *) FINDVAL(defined, type, findit);
++ if (def == NULL || def->def_kind != DEF_TYPEDEF) {
++ return (orig);
++ }
++ switch (def->def.ty.rel) {
++ case REL_VECTOR:
++ return (def->def.ty.old_type);
++ case REL_ALIAS:
++ return (fixit(def->def.ty.old_type, orig));
++ default:
++ return (orig);
++ }
++}
++
++char *
++fixtype(char *type)
++{
++ return (fixit(type, type));
++}
++
++char *
++stringfix(char *type)
++{
++ if (streq(type, "string")) {
++ return ("wrapstring");
++ } else {
++ return (type);
++ }
++}
++
++void
++ptype(char *prefix, char *type, int follow)
++{
++ if (prefix != NULL) {
++ if (streq(prefix, "enum")) {
++ f_print(fout, "enum ");
++ } else {
++ f_print(fout, "struct ");
++ }
++ }
++ if (streq(type, "bool")) {
++ f_print(fout, "bool_t ");
++ } else if (streq(type, "string")) {
++ f_print(fout, "char *");
++ } else {
++ f_print(fout, "%s ", follow ? fixtype(type) : type);
++ }
++}
++
++static int
++typedefed(definition *def, char *type)
++{
++ if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL) {
++ return (0);
++ } else {
++ return (streq(def->def_name, type));
++ }
++}
++
++int
++isvectordef(char *type, relation rel)
++{
++ definition *def;
++
++ for (;;) {
++ switch (rel) {
++ case REL_VECTOR:
++ return (!streq(type, "string"));
++ case REL_ARRAY:
++ return (0);
++ case REL_POINTER:
++ return (0);
++ case REL_ALIAS:
++ def = (definition *) FINDVAL(defined, type, typedefed);
++ if (def == NULL) {
++ return (0);
++ }
++ type = def->def.ty.old_type;
++ rel = def->def.ty.rel;
++ }
++ }
++}
++
++char *
++locase(char *str)
++{
++ char c;
++ static char buf[100];
++ char *p = buf;
++
++ while ((c = *str++) != '\0') {
++ *p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c;
++ }
++ *p = 0;
++ return (buf);
++}
++
++void
++pvname_svc(char *pname, char *vnum)
++{
++ f_print(fout, "%s_%s_svc", locase(pname), vnum);
++}
++
++void
++pvname(char *pname, char *vnum)
++{
++ f_print(fout, "%s_%s", locase(pname), vnum);
++}
++
++/*
++ * print a useful (?) error message, and then die
++ */
++void
++error(char *msg)
++{
++ printwhere();
++ f_print(stderr, "%s, line %d: ", infilename, linenum);
++ f_print(stderr, "%s\n", msg);
++ crash();
++}
++
++/*
++ * Something went wrong, unlink any files that we may have created and then
++ * die.
++ */
++void
++crash(void)
++{
++ int i;
++
++ for (i = 0; i < nfiles; i++) {
++ (void) unlink(outfiles[i]);
++ }
++ exit(1);
++}
++
++void
++record_open(char *file)
++{
++ if (nfiles < NFILES) {
++ outfiles[nfiles++] = file;
++ } else {
++ f_print(stderr, "too many files!\n");
++ crash();
++ }
++}
++
++static char expectbuf[100];
++static char *toktostr();
++
++/*
++ * error, token encountered was not the expected one
++ */
++void
++expected1(exp1)
++ tok_kind exp1;
++{
++ s_print(expectbuf, "expected '%s'",
++ toktostr(exp1));
++ error(expectbuf);
++}
++
++/*
++ * error, token encountered was not one of two expected ones
++ */
++void
++expected2(exp1, exp2)
++ tok_kind exp1, exp2;
++{
++ s_print(expectbuf, "expected '%s' or '%s'",
++ toktostr(exp1),
++ toktostr(exp2));
++ error(expectbuf);
++}
++
++/*
++ * error, token encountered was not one of 3 expected ones
++ */
++void
++expected3(exp1, exp2, exp3)
++ tok_kind exp1, exp2, exp3;
++{
++ s_print(expectbuf, "expected '%s', '%s' or '%s'",
++ toktostr(exp1),
++ toktostr(exp2),
++ toktostr(exp3));
++ error(expectbuf);
++}
++
++void
++tabify(f, tab)
++ FILE *f;
++ int tab;
++{
++ while (tab--) {
++ (void) fputc('\t', f);
++ }
++}
++
++
++static token tokstrings[] = {
++ {TOK_IDENT, "identifier"},
++ {TOK_CONST, "const"},
++ {TOK_RPAREN, ")"},
++ {TOK_LPAREN, "("},
++ {TOK_RBRACE, "}"},
++ {TOK_LBRACE, "{"},
++ {TOK_LBRACKET, "["},
++ {TOK_RBRACKET, "]"},
++ {TOK_STAR, "*"},
++ {TOK_COMMA, ","},
++ {TOK_EQUAL, "="},
++ {TOK_COLON, ":"},
++ {TOK_SEMICOLON, ";"},
++ {TOK_UNION, "union"},
++ {TOK_STRUCT, "struct"},
++ {TOK_SWITCH, "switch"},
++ {TOK_CASE, "case"},
++ {TOK_DEFAULT, "default"},
++ {TOK_ENUM, "enum"},
++ {TOK_TYPEDEF, "typedef"},
++ {TOK_INT, "int"},
++ {TOK_SHORT, "short"},
++ {TOK_INT32, "int32"},
++ {TOK_UNSIGNED, "unsigned"},
++ {TOK_DOUBLE, "double"},
++ {TOK_FLOAT, "float"},
++ {TOK_CHAR, "char"},
++ {TOK_STRING, "string"},
++ {TOK_OPAQUE, "opaque"},
++ {TOK_BOOL, "bool"},
++ {TOK_VOID, "void"},
++ {TOK_PROGRAM, "program"},
++ {TOK_VERSION, "version"},
++ {TOK_EOF, "??????"}
++};
++
++static char *
++toktostr(kind)
++ tok_kind kind;
++{
++ token *sp;
++
++ for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++);
++ return (sp->str);
++}
++
++static void
++printbuf(void)
++{
++ char c;
++ int i;
++ int cnt;
++
++# define TABSIZE 4
++
++ for (i = 0; (c = curline[i]) != '\0'; i++) {
++ if (c == '\t') {
++ cnt = 8 - (i % TABSIZE);
++ c = ' ';
++ } else {
++ cnt = 1;
++ }
++ while (cnt--) {
++ (void) fputc(c, stderr);
++ }
++ }
++}
++
++static void
++printwhere(void)
++{
++ int i;
++ char c;
++ int cnt;
++
++ printbuf();
++ for (i = 0; i < where - curline; i++) {
++ c = curline[i];
++ if (c == '\t') {
++ cnt = 8 - (i % TABSIZE);
++ } else {
++ cnt = 1;
++ }
++ while (cnt--) {
++ (void) fputc('^', stderr);
++ }
++ }
++ (void) fputc('\n', stderr);
++}
++
++char *
++make_argname(char *pname, char *vname)
++{
++ char *name;
++
++ name = malloc(strlen(pname) + strlen(vname) + strlen(ARGEXT) + 3);
++ if (!name) {
++ fprintf(stderr, "failed in malloc");
++ exit(1);
++ }
++ sprintf(name, "%s_%s_%s", locase(pname), vname, ARGEXT);
++ return(name);
++}
++
++bas_type *typ_list_h;
++bas_type *typ_list_t;
++
++void
++add_type(int len, char *type)
++{
++ bas_type *ptr;
++
++
++ if ((ptr = (bas_type *) malloc(sizeof(bas_type))) == (bas_type *) NULL) {
++ fprintf(stderr, "failed in malloc");
++ exit(1);
++ }
++ ptr->name = type;
++ ptr->length = len;
++ ptr->next = NULL;
++ if (typ_list_t == NULL) {
++
++ typ_list_t = ptr;
++ typ_list_h = ptr;
++ } else {
++
++ typ_list_t->next = ptr;
++ typ_list_t = ptr;
++ }
++}
++
++
++bas_type *
++find_type(char *type)
++{
++ bas_type *ptr;
++
++ ptr = typ_list_h;
++
++
++ while (ptr != NULL) {
++ if (strcmp(ptr->name, type) == 0)
++ return (ptr);
++ else
++ ptr = ptr->next;
++ };
++ return (NULL);
++}
++
+--- libtirpc-0.2.3/rpcgen/rpc_util.h.0005~ 2013-02-11 21:47:03.997289317 +0100
++++ libtirpc-0.2.3/rpcgen/rpc_util.h 2013-02-11 21:47:03.997289317 +0100
+@@ -0,0 +1,166 @@
++/*
++ * Copyright (c) 2009, Sun Microsystems, Inc.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions are met:
++ * - Redistributions of source code must retain the above copyright notice,
++ * this list of conditions and the following disclaimer.
++ * - Redistributions in binary form must reproduce the above copyright notice,
++ * this list of conditions and the following disclaimer in the documentation
++ * and/or other materials provided with the distribution.
++ * - Neither the name of Sun Microsystems, Inc. nor the names of its
++ * contributors may be used to endorse or promote products derived
++ * from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
++ * POSSIBILITY OF SUCH DAMAGE.
++ */
++
++/* @(#)rpc_util.h 1.5 90/08/29 (C) 1987 SMI */
++
++/*
++ * rpc_util.h, Useful definitions for the RPC protocol compiler
++ */
++
++#include <stdlib.h>
++
++#define alloc(size) malloc((unsigned)(size))
++#define ALLOC(object) (object *) malloc(sizeof(object))
++
++#define s_print (void) sprintf
++#define f_print (void) fprintf
++
++struct list {
++ definition *val;
++ struct list *next;
++};
++typedef struct list list;
++
++#define PUT 1
++#define GET 2
++
++/*
++ * Global variables
++ */
++#define MAXLINESIZE 1024
++extern char curline[MAXLINESIZE];
++extern char *where;
++extern int linenum;
++
++extern char *infilename;
++extern FILE *fout;
++extern FILE *fin;
++
++extern list *defined;
++
++
++extern bas_type *typ_list_h;
++extern bas_type *typ_list_t;
++
++/*
++ * All the option flags
++ */
++extern int inetdflag;
++extern int pmflag;
++extern int tblflag;
++extern int logflag;
++extern int newstyle;
++extern int Cflag; /* C++ flag */
++extern int tirpcflag; /* flag for generating tirpc code */
++extern int Inline; /* if this is 0, then do not generate inline code */
++
++/*
++ * Other flags related with inetd jumpstart.
++ */
++extern int indefinitewait;
++extern int exitnow;
++extern int timerflag;
++
++extern int nonfatalerrors;
++
++/*
++ * rpc_util routines
++ */
++void storeval();
++
++#define STOREVAL(list,item) \
++ storeval(list,item)
++
++definition *findval();
++
++#define FINDVAL(list,item,finder) \
++ findval(list, item, finder)
++
++
++/*
++ * rpc_cout routines
++ */
++void cprint(void);
++void emit(definition *);
++
++/*
++ * rpc_hout routines
++ */
++void print_datadef(definition *);
++void print_funcdef(definition *);
++
++/*
++ * rpc_svcout routines
++ */
++void write_most(char *, int, int);
++void write_register(void);
++void write_netid_register(char *);
++void write_nettype_register(char *);
++void write_inetd_register(char *);
++void write_rest(void);
++void write_programs(char *);
++void write_svc_aux(int);
++
++/*
++ * rpc_clntout routines
++ */
++void write_stubs(void);
++void printarglist(proc_list *, char *, char *);
++
++/*
++ * rpc_tblout routines
++ */
++void write_tables(void);
++
++/*
++ * rpc_util
++ */
++void pvname_svc(char *, char *);
++void pvname(char *, char *);
++void ptype(char *, char *, int);
++char * make_argname(char *, char *);
++void add_type(int, char *);
++void reinitialize(void);
++void crash(void);
++void error(char *);
++char *fixtype(char *);
++char *stringfix(char *);
++char *locase(char *);
++int isvectordef(char *, relation);
++int streq(char *, char *);
++void tabify(FILE *, int);
++void record_open(char *);
++bas_type *find_type(char *type);
++
++/*
++ * rpc_sample
++ */
++void write_sample_svc(definition *);
++int write_sample_clnt(definition *);
++void write_sample_clnt_main(void);
++void add_sample_msg(void);
diff --git a/meta/recipes-extended/libtirpc/libtirpc-0.2.3/nis.h b/meta/recipes-extended/libtirpc/libtirpc-0.2.3/nis.h
new file mode 100644
index 0000000..5c5c7bb
--- /dev/null
+++ b/meta/recipes-extended/libtirpc/libtirpc-0.2.3/nis.h
@@ -0,0 +1,616 @@
+/*
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RPCSVC_NIS_H
+#define _RPCSVC_NIS_H 1
+
+#include <features.h>
+#include <rpc/rpc.h>
+#include <rpcsvc/nis_tags.h>
+
+__BEGIN_DECLS
+
+/*
+ * nis.h
+ *
+ * This file is the main include file for NIS clients. It contains
+ * both the client library function defines and the various data
+ * structures used by the NIS service. It includes the file nis_tags.h
+ * which defines the tag values. This allows the tags to change without
+ * having to change the nis.x file.
+ *
+ * NOTE : THIS FILE IS NOT GENERATED WITH RPCGEN ! SO YOU HAVE TO
+ * ADD ALL THE CHANGES ON nis_*.x FILES HERE AGAIN !
+ *
+ * I have removed all the Solaris internal structs and variables,
+ * because they are not supported, Sun changed them between various
+ * releases and they shouldn't be used in user programs.
+ * <kukuk@suse.de>
+ */
+
+
+#ifndef __nis_object_h
+#define __nis_object_h
+
+#define NIS_MAXSTRINGLEN 255
+#define NIS_MAXNAMELEN 1024
+#define NIS_MAXATTRNAME 32
+#define NIS_MAXATTRVAL 2048
+#define NIS_MAXCOLUMNS 64
+#define NIS_MAXATTR 16
+#define NIS_MAXPATH 1024
+#define NIS_MAXREPLICAS 128
+#define NIS_MAXLINKS 16
+#define NIS_PK_NONE 0
+#define NIS_PK_DH 1
+#define NIS_PK_RSA 2
+#define NIS_PK_KERB 3
+#define NIS_PK_DHEXT 4
+
+struct nis_attr {
+ char *zattr_ndx;
+ struct {
+ u_int zattr_val_len;
+ char *zattr_val_val;
+ } zattr_val;
+};
+typedef struct nis_attr nis_attr;
+
+typedef char *nis_name;
+
+enum zotypes {
+ BOGUS_OBJ = 0,
+ NO_OBJ = 1,
+ DIRECTORY_OBJ = 2,
+ GROUP_OBJ = 3,
+ TABLE_OBJ = 4,
+ ENTRY_OBJ = 5,
+ LINK_OBJ = 6,
+ PRIVATE_OBJ = 7,
+ NIS_BOGUS_OBJ = 0,
+ NIS_NO_OBJ = 1,
+ NIS_DIRECTORY_OBJ = 2,
+ NIS_GROUP_OBJ = 3,
+ NIS_TABLE_OBJ = 4,
+ NIS_ENTRY_OBJ = 5,
+ NIS_LINK_OBJ = 6,
+ NIS_PRIVATE_OBJ = 7
+};
+typedef enum zotypes zotypes;
+
+enum nstype {
+ UNKNOWN = 0,
+ NIS = 1,
+ SUNYP = 2,
+ IVY = 3,
+ DNS = 4,
+ X500 = 5,
+ DNANS = 6,
+ XCHS = 7,
+ CDS = 8,
+};
+typedef enum nstype nstype;
+
+struct oar_mask {
+ uint32_t oa_rights;
+ zotypes oa_otype;
+};
+typedef struct oar_mask oar_mask;
+
+struct endpoint {
+ char *uaddr;
+ char *family;
+ char *proto;
+};
+typedef struct endpoint endpoint;
+
+struct nis_server {
+ nis_name name;
+ struct {
+ u_int ep_len;
+ endpoint *ep_val;
+ } ep;
+ uint32_t key_type;
+ netobj pkey;
+};
+typedef struct nis_server nis_server;
+
+struct directory_obj {
+ nis_name do_name;
+ nstype do_type;
+ struct {
+ u_int do_servers_len;
+ nis_server *do_servers_val;
+ } do_servers;
+ uint32_t do_ttl;
+ struct {
+ u_int do_armask_len;
+ oar_mask *do_armask_val;
+ } do_armask;
+};
+typedef struct directory_obj directory_obj;
+
+#define EN_BINARY 1
+#define EN_CRYPT 2
+#define EN_XDR 4
+#define EN_MODIFIED 8
+#define EN_ASN1 64
+
+struct entry_col {
+ uint32_t ec_flags;
+ struct {
+ u_int ec_value_len;
+ char *ec_value_val;
+ } ec_value;
+};
+typedef struct entry_col entry_col;
+
+struct entry_obj {
+ char *en_type;
+ struct {
+ u_int en_cols_len;
+ entry_col *en_cols_val;
+ } en_cols;
+};
+typedef struct entry_obj entry_obj;
+
+struct group_obj {
+ uint32_t gr_flags;
+ struct {
+ u_int gr_members_len;
+ nis_name *gr_members_val;
+ } gr_members;
+};
+typedef struct group_obj group_obj;
+
+struct link_obj {
+ zotypes li_rtype;
+ struct {
+ u_int li_attrs_len;
+ nis_attr *li_attrs_val;
+ } li_attrs;
+ nis_name li_name;
+};
+typedef struct link_obj link_obj;
+
+#define TA_BINARY 1
+#define TA_CRYPT 2
+#define TA_XDR 4
+#define TA_SEARCHABLE 8
+#define TA_CASE 16
+#define TA_MODIFIED 32
+#define TA_ASN1 64
+
+struct table_col {
+ char *tc_name;
+ uint32_t tc_flags;
+ uint32_t tc_rights;
+};
+typedef struct table_col table_col;
+
+struct table_obj {
+ char *ta_type;
+ int ta_maxcol;
+ u_char ta_sep;
+ struct {
+ u_int ta_cols_len;
+ table_col *ta_cols_val;
+ } ta_cols;
+ char *ta_path;
+};
+typedef struct table_obj table_obj;
+
+struct objdata {
+ zotypes zo_type;
+ union {
+ struct directory_obj di_data;
+ struct group_obj gr_data;
+ struct table_obj ta_data;
+ struct entry_obj en_data;
+ struct link_obj li_data;
+ struct {
+ u_int po_data_len;
+ char *po_data_val;
+ } po_data;
+ } objdata_u;
+};
+typedef struct objdata objdata;
+
+struct nis_oid {
+ uint32_t ctime;
+ uint32_t mtime;
+};
+typedef struct nis_oid nis_oid;
+
+struct nis_object {
+ nis_oid zo_oid;
+ nis_name zo_name;
+ nis_name zo_owner;
+ nis_name zo_group;
+ nis_name zo_domain;
+ uint32_t zo_access;
+ uint32_t zo_ttl;
+ objdata zo_data;
+};
+typedef struct nis_object nis_object;
+
+#endif /* if __nis_object_h */
+
+enum nis_error {
+ NIS_SUCCESS = 0,
+ NIS_S_SUCCESS = 1,
+ NIS_NOTFOUND = 2,
+ NIS_S_NOTFOUND = 3,
+ NIS_CACHEEXPIRED = 4,
+ NIS_NAMEUNREACHABLE = 5,
+ NIS_UNKNOWNOBJ = 6,
+ NIS_TRYAGAIN = 7,
+ NIS_SYSTEMERROR = 8,
+ NIS_CHAINBROKEN = 9,
+ NIS_PERMISSION = 10,
+ NIS_NOTOWNER = 11,
+ NIS_NOT_ME = 12,
+ NIS_NOMEMORY = 13,
+ NIS_NAMEEXISTS = 14,
+ NIS_NOTMASTER = 15,
+ NIS_INVALIDOBJ = 16,
+ NIS_BADNAME = 17,
+ NIS_NOCALLBACK = 18,
+ NIS_CBRESULTS = 19,
+ NIS_NOSUCHNAME = 20,
+ NIS_NOTUNIQUE = 21,
+ NIS_IBMODERROR = 22,
+ NIS_NOSUCHTABLE = 23,
+ NIS_TYPEMISMATCH = 24,
+ NIS_LINKNAMEERROR = 25,
+ NIS_PARTIAL = 26,
+ NIS_TOOMANYATTRS = 27,
+ NIS_RPCERROR = 28,
+ NIS_BADATTRIBUTE = 29,
+ NIS_NOTSEARCHABLE = 30,
+ NIS_CBERROR = 31,
+ NIS_FOREIGNNS = 32,
+ NIS_BADOBJECT = 33,
+ NIS_NOTSAMEOBJ = 34,
+ NIS_MODFAIL = 35,
+ NIS_BADREQUEST = 36,
+ NIS_NOTEMPTY = 37,
+ NIS_COLDSTART_ERR = 38,
+ NIS_RESYNC = 39,
+ NIS_FAIL = 40,
+ NIS_UNAVAIL = 41,
+ NIS_RES2BIG = 42,
+ NIS_SRVAUTH = 43,
+ NIS_CLNTAUTH = 44,
+ NIS_NOFILESPACE = 45,
+ NIS_NOPROC = 46,
+ NIS_DUMPLATER = 47,
+};
+typedef enum nis_error nis_error;
+
+struct nis_result {
+ nis_error status;
+ struct {
+ u_int objects_len;
+ nis_object *objects_val;
+ } objects;
+ netobj cookie;
+ uint32_t zticks;
+ uint32_t dticks;
+ uint32_t aticks;
+ uint32_t cticks;
+};
+typedef struct nis_result nis_result;
+
+struct ns_request {
+ nis_name ns_name;
+ struct {
+ u_int ns_object_len;
+ nis_object *ns_object_val;
+ } ns_object;
+};
+typedef struct ns_request ns_request;
+
+struct ib_request {
+ nis_name ibr_name;
+ struct {
+ u_int ibr_srch_len;
+ nis_attr *ibr_srch_val;
+ } ibr_srch;
+ uint32_t ibr_flags;
+ struct {
+ u_int ibr_obj_len;
+ nis_object *ibr_obj_val;
+ } ibr_obj;
+ struct {
+ u_int ibr_cbhost_len;
+ nis_server *ibr_cbhost_val;
+ } ibr_cbhost;
+ u_int ibr_bufsize;
+ netobj ibr_cookie;
+};
+typedef struct ib_request ib_request;
+
+struct ping_args {
+ nis_name dir;
+ uint32_t stamp;
+};
+typedef struct ping_args ping_args;
+
+enum log_entry_t {
+ LOG_NOP = 0,
+ ADD_NAME = 1,
+ REM_NAME = 2,
+ MOD_NAME_OLD = 3,
+ MOD_NAME_NEW = 4,
+ ADD_IBASE = 5,
+ REM_IBASE = 6,
+ MOD_IBASE = 7,
+ UPD_STAMP = 8,
+};
+typedef enum log_entry_t log_entry_t;
+
+struct log_entry {
+ uint32_t le_time;
+ log_entry_t le_type;
+ nis_name le_princp;
+ nis_name le_name;
+ struct {
+ u_int le_attrs_len;
+ nis_attr *le_attrs_val;
+ } le_attrs;
+ nis_object le_object;
+};
+typedef struct log_entry log_entry;
+
+struct log_result {
+ nis_error lr_status;
+ netobj lr_cookie;
+ struct {
+ u_int lr_entries_len;
+ log_entry *lr_entries_val;
+ } lr_entries;
+};
+typedef struct log_result log_result;
+
+struct cp_result {
+ nis_error cp_status;
+ uint32_t cp_zticks;
+ uint32_t cp_dticks;
+};
+typedef struct cp_result cp_result;
+
+struct nis_tag {
+ uint32_t tag_type;
+ char *tag_val;
+};
+typedef struct nis_tag nis_tag;
+
+struct nis_taglist {
+ struct {
+ u_int tags_len;
+ nis_tag *tags_val;
+ } tags;
+};
+typedef struct nis_taglist nis_taglist;
+
+struct dump_args {
+ nis_name da_dir;
+ uint32_t da_time;
+ struct {
+ u_int da_cbhost_len;
+ nis_server *da_cbhost_val;
+ } da_cbhost;
+};
+typedef struct dump_args dump_args;
+
+struct fd_args {
+ nis_name dir_name;
+ nis_name requester;
+};
+typedef struct fd_args fd_args;
+
+struct fd_result {
+ nis_error status;
+ nis_name source;
+ struct {
+ u_int dir_data_len;
+ char *dir_data_val;
+ } dir_data;
+ struct {
+ u_int signature_len;
+ char *signature_val;
+ } signature;
+};
+typedef struct fd_result fd_result;
+
+/* Generic client creating flags */
+#define ZMH_VC 1
+#define ZMH_DG 2
+#define ZMH_AUTH 4
+
+/* Testing Access rights for objects */
+
+#define NIS_READ_ACC 1
+#define NIS_MODIFY_ACC 2
+#define NIS_CREATE_ACC 4
+#define NIS_DESTROY_ACC 8
+/* Test macros. a == access rights, m == desired rights. */
+#define NIS_WORLD(a, m) (((a) & (m)) != 0)
+#define NIS_GROUP(a, m) (((a) & ((m) << 8)) != 0)
+#define NIS_OWNER(a, m) (((a) & ((m) << 16)) != 0)
+#define NIS_NOBODY(a, m) (((a) & ((m) << 24)) != 0)
+/*
+ * EOL Alert - The following non-prefixed test macros are
+ * here for backward compatability, and will be not be present
+ * in future releases - use the NIS_*() macros above.
+ */
+#define WORLD(a, m) (((a) & (m)) != 0)
+#define GROUP(a, m) (((a) & ((m) << 8)) != 0)
+#define OWNER(a, m) (((a) & ((m) << 16)) != 0)
+#define NOBODY(a, m) (((a) & ((m) << 24)) != 0)
+
+#define OATYPE(d, n) (((d)->do_armask.do_armask_val+n)->oa_otype)
+#define OARIGHTS(d, n) (((d)->do_armask.do_armask_val+n)->oa_rights)
+#define WORLD_DEFAULT (NIS_READ_ACC)
+#define GROUP_DEFAULT (NIS_READ_ACC << 8)
+#define OWNER_DEFAULT ((NIS_READ_ACC + NIS_MODIFY_ACC + NIS_CREATE_ACC +\
+ NIS_DESTROY_ACC) << 16)
+#define DEFAULT_RIGHTS (WORLD_DEFAULT | GROUP_DEFAULT | OWNER_DEFAULT)
+
+/* Result manipulation defines ... */
+#define NIS_RES_NUMOBJ(x) ((x)->objects.objects_len)
+#define NIS_RES_OBJECT(x) ((x)->objects.objects_val)
+#define NIS_RES_COOKIE(x) ((x)->cookie)
+#define NIS_RES_STATUS(x) ((x)->status)
+
+/* These defines make getting at the variant part of the object easier. */
+#define TA_data zo_data.objdata_u.ta_data
+#define EN_data zo_data.objdata_u.en_data
+#define DI_data zo_data.objdata_u.di_data
+#define LI_data zo_data.objdata_u.li_data
+#define GR_data zo_data.objdata_u.gr_data
+
+#define __type_of(o) ((o)->zo_data.zo_type)
+
+/* Declarations for the internal subroutines in nislib.c */
+enum name_pos {SAME_NAME, HIGHER_NAME, LOWER_NAME, NOT_SEQUENTIAL, BAD_NAME};
+typedef enum name_pos name_pos;
+
+/*
+ * Defines for getting at column data in entry objects. Because RPCGEN
+ * generates some rather wordy structures, we create some defines that
+ * collapse the needed keystrokes to access a particular value using
+ * these definitions they take an nis_object *, and an int and return
+ * a u_char * for Value, and an int for length.
+ */
+#define ENTRY_VAL(obj, col) (obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val
+#define ENTRY_LEN(obj, col) (obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len
+
+
+/* Prototypes, and extern declarations for the NIS library functions. */
+#include <rpcsvc/nislib.h>
+#endif
+
+/*
+ * nis_3.h
+ *
+ * This file contains definitions that are only of interest to the actual
+ * service daemon and client stubs. Normal users of NIS will not include
+ * this file.
+ *
+ * NOTE : This include file is automatically created by a combination
+ * of rpcgen and sed. DO NOT EDIT IT, change the nis.x file instead
+ * and then remake this file.
+ */
+#ifndef __nis_3_h
+#define __nis_3_h
+
+#define NIS_PROG 100300
+#define NIS_VERSION 3
+
+#define NIS_LOOKUP 1
+extern nis_result * nis_lookup_3 (ns_request *, CLIENT *) __THROW;
+extern nis_result * nis_lookup_3_svc (ns_request *, struct svc_req *) __THROW;
+#define NIS_ADD 2
+extern nis_result * nis_add_3 (ns_request *, CLIENT *) __THROW;
+extern nis_result * nis_add_3_svc (ns_request *, struct svc_req *) __THROW;
+#define NIS_MODIFY 3
+extern nis_result * nis_modify_3 (ns_request *, CLIENT *) __THROW;
+extern nis_result * nis_modify_3_svc (ns_request *, struct svc_req *) __THROW;
+#define NIS_REMOVE 4
+extern nis_result * nis_remove_3 (ns_request *, CLIENT *) __THROW;
+extern nis_result * nis_remove_3_svc (ns_request *, struct svc_req *) __THROW;
+#define NIS_IBLIST 5
+extern nis_result * nis_iblist_3 (ib_request *, CLIENT *) __THROW;
+extern nis_result * nis_iblist_3_svc (ib_request *, struct svc_req *) __THROW;
+#define NIS_IBADD 6
+extern nis_result * nis_ibadd_3 (ib_request *, CLIENT *) __THROW;
+extern nis_result * nis_ibadd_3_svc (ib_request *, struct svc_req *) __THROW;
+#define NIS_IBMODIFY 7
+extern nis_result * nis_ibmodify_3 (ib_request *, CLIENT *) __THROW;
+extern nis_result * nis_ibmodify_3_svc (ib_request *, struct svc_req *)
+ __THROW;
+#define NIS_IBREMOVE 8
+extern nis_result * nis_ibremove_3 (ib_request *, CLIENT *) __THROW;
+extern nis_result * nis_ibremove_3_svc (ib_request *, struct svc_req *)
+ __THROW;
+#define NIS_IBFIRST 9
+extern nis_result * nis_ibfirst_3 (ib_request *, CLIENT *) __THROW;
+extern nis_result * nis_ibfirst_3_svc (ib_request *, struct svc_req *)
+ __THROW;
+#define NIS_IBNEXT 10
+extern nis_result * nis_ibnext_3 (ib_request *, CLIENT *) __THROW;
+extern nis_result * nis_ibnext_3_svc (ib_request *, struct svc_req *) __THROW;
+#define NIS_FINDDIRECTORY 12
+extern fd_result * nis_finddirectory_3 (fd_args *, CLIENT *) __THROW;
+extern fd_result * nis_finddirectory_3_svc (fd_args *,
+ struct svc_req *) __THROW;
+#define NIS_STATUS 14
+extern nis_taglist * nis_status_3 (nis_taglist *, CLIENT *) __THROW;
+extern nis_taglist * nis_status_3_svc (nis_taglist *, struct svc_req *)
+ __THROW;
+#define NIS_DUMPLOG 15
+extern log_result * nis_dumplog_3 (dump_args *, CLIENT *) __THROW;
+extern log_result * nis_dumplog_3_svc (dump_args *, struct svc_req *) __THROW;
+#define NIS_DUMP 16
+extern log_result * nis_dump_3 (dump_args *, CLIENT *) __THROW;
+extern log_result * nis_dump_3_svc (dump_args *, struct svc_req *) __THROW;
+#define NIS_CALLBACK 17
+extern bool_t * nis_callback_3 (netobj *, CLIENT *) __THROW;
+extern bool_t * nis_callback_3_svc (netobj *, struct svc_req *) __THROW;
+#define NIS_CPTIME 18
+extern uint32_t * nis_cptime_3 (nis_name *, CLIENT *) __THROW;
+extern uint32_t * nis_cptime_3_svc (nis_name *, struct svc_req *) __THROW;
+#define NIS_CHECKPOINT 19
+extern cp_result * nis_checkpoint_3 (nis_name *, CLIENT *) __THROW;
+extern cp_result * nis_checkpoint_3_svc (nis_name *, struct svc_req *)
+ __THROW;
+#define NIS_PING 20
+extern void * nis_ping_3 (ping_args *, CLIENT *) __THROW;
+extern void * nis_ping_3_svc (ping_args *, struct svc_req *) __THROW;
+#define NIS_SERVSTATE 21
+extern nis_taglist * nis_servstate_3 (nis_taglist *, CLIENT *) __THROW;
+extern nis_taglist * nis_servstate_3_svc (nis_taglist *,
+ struct svc_req *) __THROW;
+#define NIS_MKDIR 22
+extern nis_error * nis_mkdir_3 (nis_name *, CLIENT *) __THROW;
+extern nis_error * nis_mkdir_3_svc (nis_name *, struct svc_req *) __THROW;
+#define NIS_RMDIR 23
+extern nis_error * nis_rmdir_3 (nis_name *, CLIENT *) __THROW;
+extern nis_error * nis_rmdir_3_svc (nis_name *, struct svc_req *) __THROW;
+#define NIS_UPDKEYS 24
+extern nis_error * nis_updkeys_3 (nis_name *, CLIENT *) __THROW;
+extern nis_error * nis_updkeys_3_svc (nis_name *, struct svc_req *) __THROW;
+
+__END_DECLS
+
+#endif /* ! _RPCSVC_NIS_H */
diff --git a/meta/recipes-extended/libtirpc/libtirpc-0.2.3/nis_tags.h b/meta/recipes-extended/libtirpc/libtirpc-0.2.3/nis_tags.h
new file mode 100644
index 0000000..c2dc7fd
--- /dev/null
+++ b/meta/recipes-extended/libtirpc/libtirpc-0.2.3/nis_tags.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * nis_tags.h
+ *
+ * This file contains the tags and statistics definitions. It is
+ * automatically included by nis.h
+ */
+
+#ifndef _RPCSVC_NIS_TAGS_H
+#define _RPCSVC_NIS_TAGS_H
+
+#if 0
+#pragma ident "@(#)nis_tags.h 1.16 96/10/25"
+#endif
+/* from file: zns_tags.h 1.7 */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define NIS_DIR "data"
+
+/* Lookup and List function flags */
+#define FOLLOW_LINKS (1<<0) /* Follow link objects */
+#define FOLLOW_PATH (1<<1) /* Follow the path in a table */
+#define HARD_LOOKUP (1<<2) /* Block until successful */
+#define ALL_RESULTS (1<<3) /* Retrieve all results */
+#define NO_CACHE (1<<4) /* Do not return 'cached' results */
+#define MASTER_ONLY (1<<5) /* Get value only from master server */
+#define EXPAND_NAME (1<<6) /* Expand partitially qualified names */
+
+/* Semantic modification for table operations flags */
+#define RETURN_RESULT (1<<7) /* Return resulting object to client */
+#define ADD_OVERWRITE (1<<8) /* Allow overwrites on ADD */
+#define REM_MULTIPLE (1<<9) /* Allow wildcard deletes */
+#define MOD_SAMEOBJ (1<<10) /* Check modified object before write */
+#define ADD_RESERVED (1<<11) /* Spare ADD semantic */
+#define REM_RESERVED (1<<12) /* Spare REM semantic */
+#define MOD_EXCLUSIVE (1<<13) /* Modify no overwrite on modified keys */
+
+/* Lookup and List function flags (continued) */
+#define SOFT_LOOKUP (1<<14) /* The "old default" return on failure */
+
+/* Transport specific modifications to the operation */
+#define USE_DGRAM (1<<16) /* Use a datagram transport */
+#define NO_AUTHINFO (1<<17) /* Don't bother attaching auth info */
+
+/*
+ * Declarations for "standard" NIS+ tags
+ * State variable tags have values 0 - 2047
+ * Statistic tags have values 2048 - 65535
+ * User Tags have values >2^16
+ */
+#define TAG_DEBUG 1 /* set debug level */
+#define TAG_STATS 2 /* Enable/disable statistics */
+#define TAG_GCACHE 3 /* Flush the Group Cache */
+#define TAG_GCACHE_ALL TAG_GCACHE
+#define TAG_DCACHE 4 /* Flush the directory cache */
+#define TAG_DCACHE_ONE TAG_DCACHE
+#define TAG_OCACHE 5 /* Flush the Object Cache */
+#define TAG_SECURE 6 /* Set the security level */
+#define TAG_TCACHE_ONE 7 /* Flush the table cache */
+#define TAG_DCACHE_ALL 8 /* Flush entire directory cache */
+#define TAG_TCACHE_ALL 9 /* Flush entire table cache */
+#define TAG_GCACHE_ONE 10 /* Flush one group object */
+#define TAG_DCACHE_ONE_REFRESH 11 /* Flush and refresh one DO */
+#define TAG_READONLY 12 /* Set read only mode */
+#define TAG_READWRITE 14 /* Reset read-write mode */
+
+#define TAG_OPSTATS 2048 /* NIS+ operations statistics */
+#define TAG_THREADS 2049 /* Child process/thread status */
+#define TAG_HEAP 2050 /* Heap usage statistics */
+#define TAG_UPDATES 2051 /* Updates to this service */
+#define TAG_VISIBLE 2052 /* First update that isn't replicated */
+#define TAG_S_DCACHE 2053 /* Directory cache statistics */
+#define TAG_S_OCACHE 2054 /* Object cache statistics */
+#define TAG_S_GCACHE 2055 /* Group cache statistics */
+#define TAG_S_STORAGE 2056 /* Group cache statistics */
+#define TAG_UPTIME 2057 /* Time that server has been up */
+#define TAG_DIRLIST 2058 /* Dir served by this server */
+#define TAG_NISCOMPAT 2059 /* Whether supports NIS compat mode */
+#define TAG_DNSFORWARDING 2060 /* Whether DNS forwarding supported */
+#define TAG_SECURITY_LEVEL 2061 /* Security level of the server */
+#define TAG_ROOTSERVER 2062 /* Whether root server */
+
+/*
+ * Declarations for the Group object flags. Currently
+ * there are only 3.
+ */
+#define IMPMEM_GROUPS 1 /* Implicit Membership allowed */
+#define RECURS_GROUPS 2 /* Recursive Groups allowed */
+#define NEGMEM_GROUPS 4 /* Negative Groups allowed */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RPCSVC_NIS_TAGS_H */
diff --git a/meta/recipes-extended/libtirpc/libtirpc-0.2.3/nislib.h b/meta/recipes-extended/libtirpc/libtirpc-0.2.3/nislib.h
new file mode 100644
index 0000000..f3cc2c4
--- /dev/null
+++ b/meta/recipes-extended/libtirpc/libtirpc-0.2.3/nislib.h
@@ -0,0 +1,288 @@
+/* Copyright (C) 1997, 1998, 1999, 2006, 2007, 2009
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@suse.de>, 1997.
+
+ The GNU C 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.1 of the License, or (at your option) any later version.
+
+ The GNU C 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 the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef __RPCSVC_NISLIB_H__
+#define __RPCSVC_NISLIB_H__
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+typedef const char *const_nis_name;
+
+/* nis_names: These functions are used to locate and manipulate all NIS+
+ * objects except the NIS+ entry objects.
+ *
+ * nis_lookup (name, flags) resolves a NIS+ name and returns a copy of
+ * that object from a NIS+ server.
+ * const nis_name name: name of the object to be resolved
+ * unsigned int flags: logically ORing zero or more flags (FOLLOW_LINKS,
+ * HARD_LOOKUP, [NO_CACHE], MASTER_ONLY, EXPAND_NAME)
+ *
+ * nis_add (name, obj) adds objects to the NIS+ namespace.
+ * const nis_name name: fully qualified NIS+ name.
+ * const nis_object *obj: object members zo_name and zo_domain will be
+ * constructed from name.
+ *
+ * nis_remove (name, obj) removes objects from the NIS+ namespace.
+ * const nis_name name: fully qualified NIS+ name.
+ * const nis_object *obj: if not NULL, it is assumed to point to a copy
+ * of the object being removed. In this case, if
+ * the object on the server does not have the same
+ * object identifier as the object being passed,
+ * the operation will fail with the NIS_NOTSAMEOBJ
+ * error.
+ *
+ * nis_modify (name, obj) can change specific attributes of an object
+ * that already exists in the namespace.
+ */
+extern nis_result *nis_lookup (const_nis_name name, unsigned int flags)
+ __THROW;
+extern nis_result *nis_add (const_nis_name name, const nis_object *obj)
+ __THROW;
+extern nis_result *nis_remove (const_nis_name name,
+ const nis_object *obj) __THROW;
+extern nis_result *nis_modify (const_nis_name name,
+ const nis_object *obj) __THROW;
+
+/* nis_tables: These functions are used to search and modify NIS+ tables.
+ *
+ * nis_list (table_name, flags, callback(table_name, obj, userdata), userdata)
+ * search a table in the NIS+ namespace.
+ * const nis_name table_name: indexed name ([xx=yy],table.dir)
+ * unsigned int flags: logically ORing one or more flags (FOLLOW_LINKS,
+ * [FOLLOW_PATH], HARD_LOOKUP, [ALL_RESULTS], [NO_CACHE],
+ * MASTER_ONLY, EXPAND_NAME, RETURN_RESULT)
+ * callback(): callback is an optional pointer to a function that will
+ * process the ENTRY type objects that are returned from the
+ * search. If this pointer is NULL, then all entries that match
+ * the search criteria are returned in the nis_result structure,
+ * otherwise this function will be called once for each
+ * entry returned.
+ * void *userdata: passed to callback function along with the returned
+ * entry object.
+ *
+ * nis_add_entry (table_name, obj, flags) will add the NIS+ object to the
+ * NIS+ table_name.
+ * const nis_name table_name
+ * const nis_object *obj
+ * unsigned int flags: 0, ADD_OVERWRITE, RETURN_RESULT
+ *
+ * nis_modify_entry (name, obj, flags) modifies an object identified by name.
+ * const nis_name name: object identifier
+ * const nis_object *obj: should point to an entry with the EN_MODIFIED
+ * flag set in each column that contains new
+ * information.
+ * unsigned int flags: 0, MOD_SAMEOBJ, RETURN_RESULT
+ *
+ * nis_remove_entry (table_name, obj, flags) removes a set of entries
+ * identified by table_name from the table.
+ * const nis_name table_name: indexed NIS+ name
+ * const nis_object *obj: if obj is non-null, it is presumed to point to
+ * a cached copy of the entry. When the removal is
+ * attempted, and the object that would be removed
+ * is not the same as the cached object pointed to
+ * by object then the operation will fail with an
+ * NIS_NOTSAMEOBJ error
+ * unsigned int flags: 0, REM_MULTIPLE
+ *
+ * nis_first_entry (table_name) fetches entries from a table one at a time.
+ * const nis_name table_name
+ *
+ * nis_next_entry (table_name, cookie) retrieves the "next" entry from a
+ * table specified by table_name.
+ * const nis_name table_name:
+ * const netobj *cookie: The value of cookie from the nis_result structure
+ * form the previous call.
+ */
+extern nis_result *nis_list (const_nis_name __name, unsigned int __flags,
+ int (*__callback)(const_nis_name __table_name,
+ const nis_object *__obj,
+ const void *__userdata),
+ const void *__userdata) __THROW;
+extern nis_result *nis_add_entry (const_nis_name __table_name,
+ const nis_object *__obj,
+ unsigned int __flags) __THROW;
+extern nis_result *nis_modify_entry (const_nis_name __name,
+ const nis_object *__obj,
+ unsigned int __flags) __THROW;
+extern nis_result *nis_remove_entry (const_nis_name __table_name,
+ const nis_object *__obj,
+ unsigned int __flags) __THROW;
+extern nis_result *nis_first_entry (const_nis_name __table_name) __THROW;
+extern nis_result *nis_next_entry (const_nis_name __table_name,
+ const netobj *__cookie) __THROW;
+/*
+** nis_server
+*/
+extern nis_error nis_mkdir (const_nis_name __dirname,
+ const nis_server *__machine) __THROW;
+extern nis_error nis_rmdir (const_nis_name __dirname,
+ const nis_server *__machine) __THROW;
+extern nis_error nis_servstate (const nis_server *__machine,
+ const nis_tag *__tags, int __numtags,
+ nis_tag **__result) __THROW;
+extern nis_error nis_stats (const nis_server *__machine,
+ const nis_tag *__tags, int __numtags,
+ nis_tag **__result) __THROW;
+extern void nis_freetags (nis_tag *__tags, int __numtags) __THROW;
+extern nis_server **nis_getservlist (const_nis_name __dirname) __THROW;
+extern void nis_freeservlist (nis_server **__machines) __THROW;
+
+/*
+** nis_subr
+*/
+extern nis_name nis_leaf_of (const_nis_name __name) __THROW;
+extern nis_name nis_leaf_of_r (const_nis_name __name, char *__buffer,
+ size_t __buflen) __THROW;
+extern nis_name nis_name_of (const_nis_name __name) __THROW;
+extern nis_name nis_name_of_r (const_nis_name __name, char *__buffer,
+ size_t __buflen) __THROW;
+extern nis_name nis_domain_of (const_nis_name __name) __THROW;
+extern nis_name nis_domain_of_r (const_nis_name __name, char *__buffer,
+ size_t __buflen) __THROW;
+extern nis_name *nis_getnames (const_nis_name __name) __THROW;
+extern void nis_freenames (nis_name *__namelist) __THROW;
+extern name_pos nis_dir_cmp (const_nis_name __n1, const_nis_name __n2) __THROW;
+extern nis_object *nis_clone_object (const nis_object *__src,
+ nis_object *__dest) __THROW;
+extern void nis_destroy_object (nis_object *__obj) __THROW;
+extern void nis_print_object (const nis_object *__obj) __THROW;
+
+/*
+** nis_local_names
+*/
+extern nis_name nis_local_group (void) __THROW;
+extern nis_name nis_local_directory (void) __THROW;
+extern nis_name nis_local_principal (void) __THROW;
+extern nis_name nis_local_host (void) __THROW;
+
+/*
+** nis_error
+*/
+extern const char *nis_sperrno (const nis_error __status) __THROW;
+extern void nis_perror (const nis_error __status, const char *__label) __THROW;
+extern void nis_lerror (const nis_error __status, const char *__label) __THROW;
+extern char *nis_sperror (const nis_error status, const char *__label) __THROW;
+extern char *nis_sperror_r (const nis_error __status, const char *__label,
+ char *__buffer, size_t __buflen) __THROW;
+/*
+** nis_groups
+*/
+extern bool_t nis_ismember (const_nis_name __principal,
+ const_nis_name __group) __THROW;
+extern nis_error nis_addmember (const_nis_name __member,
+ const_nis_name __group) __THROW;
+extern nis_error nis_removemember (const_nis_name __member,
+ const_nis_name __group) __THROW;
+extern nis_error nis_creategroup (const_nis_name __group,
+ unsigned int __flags) __THROW;
+extern nis_error nis_destroygroup (const_nis_name __group) __THROW;
+extern void nis_print_group_entry (const_nis_name __group) __THROW;
+extern nis_error nis_verifygroup (const_nis_name __group) __THROW;
+
+/*
+** nis_ping
+*/
+extern void nis_ping (const_nis_name __dirname, uint32_t __utime,
+ const nis_object *__dirobj) __THROW;
+extern nis_result *nis_checkpoint (const_nis_name __dirname) __THROW;
+
+/*
+** nis_print (XXX INTERNAL FUNCTIONS, SHOULD NOT BE USED !!)
+*/
+extern void nis_print_result (const nis_result *__result) __THROW;
+extern void nis_print_rights (unsigned int __rights) __THROW;
+extern void nis_print_directory (const directory_obj *__dirobj) __THROW;
+extern void nis_print_group (const group_obj *__grpobj) __THROW;
+extern void nis_print_table (const table_obj *__tblobj) __THROW;
+extern void nis_print_link (const link_obj *__lnkobj) __THROW;
+extern void nis_print_entry (const entry_obj *__enobj) __THROW;
+
+/*
+** nis_file (XXX INTERNAL FUNCTIONS, SHOULD NOT BE USED !!)
+*/
+extern directory_obj *readColdStartFile (void) __THROW;
+extern bool_t writeColdStartFile (const directory_obj *__dirobj) __THROW;
+extern nis_object *nis_read_obj (const char *__obj) __THROW;
+extern bool_t nis_write_obj (const char *__file, const nis_object *__obj) __THROW;
+
+/*
+** nis_clone - (XXX INTERNAL FUNCTIONS, SHOULD NOT BE USED !!)
+*/
+extern directory_obj *nis_clone_directory (const directory_obj *__src,
+ directory_obj *__dest) __THROW;
+extern nis_result *nis_clone_result (const nis_result *__src,
+ nis_result *__dest) __THROW;
+
+/* nis_free - nis_freeresult */
+extern void nis_freeresult (nis_result *__result) __THROW;
+/* (XXX THE FOLLOWING ARE INTERNAL FUNCTIONS, SHOULD NOT BE USED !!) */
+extern void nis_free_request (ib_request *__req) __THROW;
+extern void nis_free_directory (directory_obj *__dirobj) __THROW;
+extern void nis_free_object (nis_object *__obj) __THROW;
+
+/* (XXX INTERNAL FUNCTIONS, SHOULD NOT BE USED !!) */
+extern nis_name __nis_default_owner (char *) __THROW;
+extern nis_name __nis_default_group (char *) __THROW;
+extern uint32_t __nis_default_ttl (char *) __THROW;
+extern unsigned int __nis_default_access (char *, unsigned int) __THROW;
+extern fd_result *__nis_finddirectory (directory_obj *, const_nis_name) __THROW;
+extern void __free_fdresult (fd_result *) __THROW;
+extern uint32_t __nis_hash (const void *__keyarg, size_t __len) __THROW;
+
+/* NIS+ cache locking */
+extern int __nis_lock_cache (void) __THROW;
+extern int __nis_unlock_cache (void) __THROW;
+
+/* (XXX INTERNAL FUNCTIONS, ONLY FOR rpc.nisd AND glibc !!) */
+#if defined (NIS_INTERNAL) || defined (_LIBC)
+
+struct dir_binding
+{
+ CLIENT *clnt; /* RPC CLIENT handle */
+ nis_server *server_val; /* List of servers */
+ unsigned int server_len; /* # of servers */
+ unsigned int server_used; /* Which server we are bind in the moment ? */
+ unsigned int current_ep; /* Which endpoint of the server are in use? */
+ unsigned int trys; /* How many server have we tried ? */
+ unsigned int class; /* From which class is server_val ? */
+ bool_t master_only; /* Is only binded to the master */
+ bool_t use_auth; /* Do we use AUTH ? */
+ bool_t use_udp; /* Do we use UDP ? */
+ struct sockaddr_in addr; /* Server's IP address */
+ int socket; /* Server's local socket */
+};
+typedef struct dir_binding dir_binding;
+
+extern nis_error __nisbind_create (dir_binding *, const nis_server *,
+ unsigned int, unsigned int, unsigned int,
+ unsigned int) __THROW;
+extern nis_error __nisbind_connect (dir_binding *) __THROW;
+extern nis_error __nisbind_next (dir_binding *) __THROW;
+extern void __nisbind_destroy (dir_binding *) __THROW;
+extern nis_error __nisfind_server (const_nis_name, int, directory_obj **,
+ dir_binding *, unsigned int) __THROW;
+
+#endif
+
+__END_DECLS
+
+#endif /* __RPCSVC_NISLIB_H__ */
diff --git a/meta/recipes-extended/libtirpc/libtirpc-0.2.3/rpc_des.h b/meta/recipes-extended/libtirpc/libtirpc-0.2.3/rpc_des.h
new file mode 100644
index 0000000..4b3c426
--- /dev/null
+++ b/meta/recipes-extended/libtirpc/libtirpc-0.2.3/rpc_des.h
@@ -0,0 +1,71 @@
+/*
+ * Generic DES driver interface
+ * Keep this file hardware independent!
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DES_H
+#define _DES_H
+
+#include <sys/types.h>
+
+#define DES_MAXLEN 65536 /* maximum # of bytes to encrypt */
+#define DES_QUICKLEN 16 /* maximum # of bytes to encrypt quickly */
+
+enum desdir
+ {
+ ENCRYPT, DECRYPT
+ };
+enum desmode
+ {
+ CBC, ECB
+ };
+
+/*
+ * parameters to ioctl call
+ */
+struct desparams
+ {
+ u_char des_key[8]; /* key (with low bit parity) */
+ enum desdir des_dir; /* direction */
+ enum desmode des_mode; /* mode */
+ u_char des_ivec[8]; /* input vector */
+ unsigned des_len; /* number of bytes to crypt */
+ union
+ {
+ u_char UDES_data[DES_QUICKLEN];
+ u_char *UDES_buf;
+ }
+ UDES;
+#define des_data UDES.UDES_data /* direct data here if quick */
+#define des_buf UDES.UDES_buf /* otherwise, pointer to data */
+ };
+
+#endif
diff --git a/meta/recipes-extended/libtirpc/libtirpc-0.2.3/yp_prot.h b/meta/recipes-extended/libtirpc/libtirpc-0.2.3/yp_prot.h
new file mode 100644
index 0000000..ae0db36
--- /dev/null
+++ b/meta/recipes-extended/libtirpc/libtirpc-0.2.3/yp_prot.h
@@ -0,0 +1,366 @@
+/*
+ * This file contains symbols and structures defining the rpc protocol
+ * between the NIS clients and the NIS servers. The servers
+ * are the NIS database servers, and the NIS binders.
+ */
+
+#ifndef _RPCSVC_YP_PROT_H
+#define _RPCSVC_YP_PROT_H
+
+#include <features.h>
+
+#include <rpc/rpc.h>
+#include <rpcsvc/ypclnt.h>
+
+__BEGIN_DECLS
+
+/*
+ * The following procedures are supported by the protocol:
+ *
+ * YPPROC_NULL() returns () takes nothing, returns nothing. This indicates
+ * that the NIS server is alive.
+ *
+ * YPPROC_DOMAIN (char *) returns (bool_t) TRUE. Indicates that the
+ * responding NIS server does serve the named domain; FALSE indicates no
+ * support.
+ *
+ * YPPROC_DOMAIN_NONACK (char *) returns (TRUE) if the NIS server does serve
+ * the named domain, otherwise does not return. Used in the broadcast case.
+ *
+ * YPPROC_MATCH (struct ypreq_key) returns (struct ypresp_val). Returns the
+ * right-hand value for a passed left-hand key, within a named map and
+ * domain.
+ *
+ * YPPROC_FIRST (struct ypreq_nokey) returns (struct ypresp_key_val).
+ * Returns the first key-value pair from a named domain and map.
+ *
+ * YPPROC_NEXT (struct ypreq_key) returns (struct ypresp_key_val). Returns
+ * the key-value pair following a passed key-value pair within a named
+ * domain and map.
+ *
+ * YPPROC_XFR (struct ypreq_xfr) returns nothing. Indicates to a server that
+ * a map should be updated.
+ *
+ * YPPROC_CLEAR takes nothing, returns nothing. Instructs a NIS server to
+ * close the current map, so that old versions of the disk file don't get
+ * held open.
+ *
+ * YPPROC_ALL (struct ypreq_nokey), returns
+ * union switch (bool_t more) {
+ * TRUE: (struct ypresp_key_val);
+ * FALSE: (struct) {};
+ * }
+ *
+ * YPPROC_MASTER (struct ypreq_nokey), returns (ypresp_master)
+ *
+ * YPPROC_ORDER (struct ypreq_nokey), returns (ypresp_order)
+ *
+ * YPPROC_MAPLIST (char *), returns (struct ypmaplist *)
+ */
+
+/* Program and version symbols, magic numbers */
+
+#define YPPROG 100004
+#define YPVERS 2
+#define YPVERS_ORIG 1
+#define YPMAXRECORD 1024
+#define YPMAXDOMAIN 64 /* XXX orig. yp_prot.h defines 256 */
+#define YPMAXMAP 64
+#define YPMAXPEER 64 /* XXX orig. yp_prot.h defines 256 */
+
+/* byte size of a large NIS packet */
+#define YPMSGSZ 1600
+
+typedef struct {
+ u_int keydat_len;
+ char *keydat_val;
+} keydat_t;
+
+typedef struct {
+ u_int valdat_len;
+ char *valdat_val;
+} valdat_t;
+
+struct ypmap_parms {
+ char *domain; /* Null string means not available */
+ char *map; /* Null string means not available */
+ unsigned int ordernum; /* 0 means not available */
+ char *owner; /* Null string means not available */
+};
+
+/*
+ * Request parameter structures
+ */
+
+struct ypreq_key {
+ const char *domain;
+ const char *map;
+ keydat_t keydat;
+};
+
+struct ypreq_nokey {
+ char *domain;
+ char *map;
+};
+
+struct ypreq_xfr {
+ struct ypmap_parms map_parms;
+ u_int transid;
+ u_int proto;
+ u_int port;
+};
+
+#define ypxfr_domain map_parms.domain
+#define ypxfr_map map_parms.map
+#define ypxfr_ordernum map_parms.ordernum
+#define ypxfr_owner map_parms.owner
+
+/* Return status values */
+
+enum ypstat {
+ YP_TRUE = 1, /* General purpose success code */
+#define YP_TRUE YP_TRUE
+ YP_NOMORE = 2, /* No more entries in map */
+#define YP_NOMORE YP_NOMORE
+ YP_FALSE = 0, /* General purpose failure code */
+#define YP_FALSE YP_FALSE
+ YP_NOMAP = -1, /* No such map in domain */
+#define YP_NOMAP YP_NOMAP
+ YP_NODOM = -2, /* Domain not supported */
+#define YP_NODOM YP_NODOM
+ YP_NOKEY = -3, /* No such key in map */
+#define YP_NOKEY YP_NOKEY
+ YP_BADOP = -4, /* Invalid operation */
+#define YP_BADOP YP_BADOP
+ YP_BADDB = -5, /* Server data base is bad */
+#define YP_BADDB YP_BADDB
+ YP_YPERR = -6, /* NIS server error */
+#define YP_YPERR YP_YPERR
+ YP_BADARGS = -7, /* Request arguments bad */
+#define YP_BADARGS YP_BADARGS
+ YP_VERS = -8, /* NIS server version mismatch - server can't supply
+ requested service. */
+#define YP_VERS YP_VERS
+};
+
+/*
+ * Response parameter structures
+ */
+
+typedef enum ypstat ypstat;
+
+struct ypresp_val {
+ ypstat status;
+ valdat_t valdat;
+};
+
+struct ypresp_key_val {
+ ypstat status;
+#ifdef STUPID_SUN_BUG
+ /* This is the form as distributed by Sun. But even the Sun NIS
+ servers expect the values in the other order. So their
+ implementation somehow must change the order internally. We
+ don't want to follow this bad example since the user should be
+ able to use rpcgen on this file. */
+ keydat_t keydat;
+ valdat_t valdat;
+#else
+ valdat_t valdat;
+ keydat_t keydat;
+#endif
+};
+
+struct ypresp_master {
+ ypstat status;
+ char *master;
+};
+
+struct ypresp_order {
+ ypstat status;
+ u_int ordernum;
+};
+
+struct ypmaplist {
+ char *map;
+#define ypml_name map
+ struct ypmaplist *next;
+#define ypml_next next
+};
+
+struct ypresp_maplist {
+ ypstat status;
+ struct ypmaplist *list;
+};
+
+/*
+ * Procedure symbols. YPPROC_NULL, YPPROC_DOMAIN, and YPPROC_DOMAIN_NONACK
+ * must keep the same values (0, 1, and 2) that they had in the first version
+ * of the protocol.
+ */
+
+#define YPPROC_NULL 0
+#define YPPROC_DOMAIN 1
+#define YPPROC_DOMAIN_NONACK 2
+#define YPPROC_MATCH 3
+#define YPPROC_FIRST 4
+#define YPPROC_NEXT 5
+#define YPPROC_XFR 6
+#define YPPROC_CLEAR 7
+#define YPPROC_ALL 8
+#define YPPROC_MASTER 9
+#define YPPROC_ORDER 10
+#define YPPROC_MAPLIST 11
+#define YPPROC_NEWXFR 12
+
+/*
+ * Protocol between clients and NIS binder servers
+ */
+
+/*
+ * The following procedures are supported by the protocol:
+ *
+ * YPBINDPROC_NULL() returns ()
+ * takes nothing, returns nothing
+ *
+ * YPBINDPROC_DOMAIN takes (char *) returns (struct ypbind_resp)
+ *
+ * YPBINDPROC_SETDOM takes (struct ypbind_setdom) returns nothing
+ */
+
+/* Program and version symbols, magic numbers */
+
+#define YPBINDPROG 100007
+#define YPBINDVERS 2
+#define YPBINDVERS_ORIG 1
+
+/* Procedure symbols */
+
+#define YPBINDPROC_NULL 0
+#define YPBINDPROC_DOMAIN 1
+#define YPBINDPROC_SETDOM 2
+/*
+ * Response structure and overall result status codes. Success and failure
+ * represent two separate response message types.
+ */
+
+enum ypbind_resptype {YPBIND_SUCC_VAL = 1, YPBIND_FAIL_VAL = 2};
+
+struct ypbind_binding {
+ struct in_addr ypbind_binding_addr; /* In network order */
+ unsigned short int ypbind_binding_port; /* In network order */
+};
+
+struct ypbind_resp {
+ enum ypbind_resptype ypbind_status;
+ union {
+ u_int ypbind_error;
+ struct ypbind_binding ypbind_bindinfo;
+ } ypbind_respbody;
+};
+
+
+/* Detailed failure reason codes for response field ypbind_error*/
+
+#define YPBIND_ERR_ERR 1 /* Internal error */
+#define YPBIND_ERR_NOSERV 2 /* No bound server for passed domain */
+#define YPBIND_ERR_RESC 3 /* System resource allocation failure */
+
+/*
+ * Request data structure for ypbind "Set domain" procedure.
+ */
+struct ypbind_setdom {
+ char *ypsetdom_domain;
+ struct ypbind_binding ypsetdom_binding;
+ u_int ypsetdom_vers;
+};
+#define ypsetdom_addr ypsetdom_binding.ypbind_binding_addr
+#define ypsetdom_port ypsetdom_binding.ypbind_binding_port
+
+/*
+ * Protocol between clients (ypxfr, only) and yppush
+ * yppush speaks a protocol in the transient range, which
+ * is supplied to ypxfr as a command-line parameter when it
+ * is activated by ypserv.
+ */
+#define YPPUSHVERS 1
+#define YPPUSHVERS_ORIG 1
+
+/* Procedure symbols */
+
+#define YPPUSHPROC_NULL 0
+#define YPPUSHPROC_XFRRESP 1
+
+/* Status values for yppushresp_xfr.status */
+
+enum yppush_status {
+ YPPUSH_SUCC = 1, /* Success */
+#define YPPUSH_SUCC YPPUSH_SUCC
+ YPPUSH_AGE = 2, /* Master's version not newer */
+#define YPPUSH_AGE YPPUSH_AGE
+ YPPUSH_NOMAP = -1, /* Can't find server for map */
+#define YPPUSH_NOMAP YPPUSH_NOMAP
+ YPPUSH_NODOM = -2, /* Domain not supported */
+#define YPPUSH_NODOM YPPUSH_NODOM
+ YPPUSH_RSRC = -3, /* Local resouce alloc failure */
+#define YPPUSH_RSRC YPPUSH_RSRC
+ YPPUSH_RPC = -4, /* RPC failure talking to server */
+#define YPPUSH_RPC YPPUSH_RPC
+ YPPUSH_MADDR = -5, /* Can't get master address */
+#define YPPUSH_MADDR YPPUSH_MADDR
+ YPPUSH_YPERR = -6, /* NIS server/map db error */
+#define YPPUSH_YPERR YPPUSH_YPERR
+ YPPUSH_BADARGS = -7, /* Request arguments bad */
+#define YPPUSH_BADARGS YPPUSH_BADARGS
+ YPPUSH_DBM = -8, /* Local dbm operation failed */
+#define YPPUSH_DBM YPPUSH_DBM
+ YPPUSH_FILE = -9, /* Local file I/O operation failed */
+#define YPPUSH_FILE YPPUSH_FILE
+ YPPUSH_SKEW = -10, /* Map version skew during transfer */
+#define YPPUSH_SKEW YPPUSH_SKEW
+ YPPUSH_CLEAR = -11, /* Can't send "Clear" req to local ypserv */
+#define YPPUSH_CLEAR YPPUSH_CLEAR
+ YPPUSH_FORCE = -12, /* No local order number in map - use -f flag*/
+#define YPPUSH_FORCE YPPUSH_FORCE
+ YPPUSH_XFRERR = -13, /* ypxfr error */
+#define YPPUSH_XFRERR YPPUSH_XFRERR
+ YPPUSH_REFUSED = -14, /* Transfer request refused by ypserv */
+#define YPPUSH_REFUSED YPPUSH_REFUSED
+ YPPUSH_NOALIAS = -15 /* Alias not found for map or domain */
+#define YPPUSH_NOALIAS YPPUSH_NOALIAS
+};
+typedef enum yppush_status yppush_status;
+
+struct yppushresp_xfr {
+ u_int transid;
+ yppush_status status;
+};
+
+struct ypresp_all {
+ bool_t more;
+ union {
+ struct ypresp_key_val val;
+ } ypresp_all_u;
+};
+
+extern bool_t xdr_ypreq_key (XDR *__xdrs, struct ypreq_key * __objp);
+extern bool_t xdr_ypreq_nokey (XDR *__xdrs, struct ypreq_nokey * __objp);
+extern bool_t xdr_ypreq_xfr (XDR *__xdrs, struct ypreq_xfr * __objp);
+extern bool_t xdr_ypresp_val (XDR *__xdrs, struct ypresp_val * __objp);
+extern bool_t xdr_ypresp_key_val (XDR *__xdrs, struct ypresp_key_val * __objp);
+extern bool_t xdr_ypbind_resp (XDR *__xdrs, struct ypbind_resp * __objp);
+extern bool_t xdr_ypbind_setdom (XDR *__xdrs, struct ypbind_setdom * __objp);
+extern bool_t xdr_ypmap_parms (XDR *__xdrs, struct ypmap_parms * __objp);
+extern bool_t xdr_yppushresp_xfr (XDR *__xdrs, struct yppushresp_xfr * __objp);
+extern bool_t xdr_ypresp_order (XDR *__xdrs, struct ypresp_order * __objp);
+extern bool_t xdr_ypresp_master (XDR *__xdrs, struct ypresp_master * __objp);
+extern bool_t xdr_ypall (XDR *__xdrs, struct ypall_callback * __objp);
+extern bool_t xdr_ypresp_maplist (XDR *__xdrs, struct ypresp_maplist * __objp);
+extern bool_t xdr_ypbind_binding (XDR *__xdrs, struct ypbind_binding * __objp);
+extern bool_t xdr_ypbind_resptype (XDR *__xdrs, enum ypbind_resptype * __objp);
+extern bool_t xdr_ypstat (XDR *__xdrs, enum ypbind_resptype * __objp);
+extern bool_t xdr_ypresp_all (XDR *__xdrs, struct ypresp_all * __objp);
+extern bool_t xdr_domainname (XDR *__xdrs, char ** __objp);
+
+__END_DECLS
+
+#endif /* _RPCSVC_YP_PROT_H */
diff --git a/meta/recipes-extended/libtirpc/libtirpc-0.2.3/ypclnt.h b/meta/recipes-extended/libtirpc/libtirpc-0.2.3/ypclnt.h
new file mode 100644
index 0000000..aa37a29
--- /dev/null
+++ b/meta/recipes-extended/libtirpc/libtirpc-0.2.3/ypclnt.h
@@ -0,0 +1,89 @@
+/* Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996.
+
+ The GNU C 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.1 of the License, or (at your option) any later version.
+
+ The GNU C 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 the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+
+#ifndef __RPCSVC_YPCLNT_H__
+#define __RPCSVC_YPCLNT_H__
+
+#include <features.h>
+
+/* Some defines */
+#define YPERR_SUCCESS 0 /* There is no error */
+#define YPERR_BADARGS 1 /* Args to function are bad */
+#define YPERR_RPC 2 /* RPC failure */
+#define YPERR_DOMAIN 3 /* Can't bind to a server with this domain */
+#define YPERR_MAP 4 /* No such map in server's domain */
+#define YPERR_KEY 5 /* No such key in map */
+#define YPERR_YPERR 6 /* Internal yp server or client error */
+#define YPERR_RESRC 7 /* Local resource allocation failure */
+#define YPERR_NOMORE 8 /* No more records in map database */
+#define YPERR_PMAP 9 /* Can't communicate with portmapper */
+#define YPERR_YPBIND 10 /* Can't communicate with ypbind */
+#define YPERR_YPSERV 11 /* Can't communicate with ypserv */
+#define YPERR_NODOM 12 /* Local domain name not set */
+#define YPERR_BADDB 13 /* yp data base is bad */
+#define YPERR_VERS 14 /* YP version mismatch */
+#define YPERR_ACCESS 15 /* Access violation */
+#define YPERR_BUSY 16 /* Database is busy */
+
+/* Types of update operations */
+#define YPOP_CHANGE 1 /* Change, do not add */
+#define YPOP_INSERT 2 /* Add, do not change */
+#define YPOP_DELETE 3 /* Delete this entry */
+#define YPOP_STORE 4 /* Add, or change */
+
+__BEGIN_DECLS
+
+/* struct ypall_callback * is the arg which must be passed to yp_all. */
+struct ypall_callback
+ {
+ int (*foreach) (int __status, char *__key, int __keylen,
+ char *__val, int __vallen, char *__data);
+ char *data;
+ };
+
+/* External NIS client function references. */
+extern int yp_bind (__const char *) __THROW;
+extern void yp_unbind (__const char *) __THROW;
+extern int yp_get_default_domain (char **) __THROW;
+extern int yp_match (__const char *, __const char *, __const char *,
+ __const int, char **, int *) __THROW;
+extern int yp_first (__const char *, __const char *, char **,
+ int *, char **, int *) __THROW;
+extern int yp_next (__const char *, __const char *, __const char *,
+ __const int, char **, int *, char **, int *) __THROW;
+extern int yp_master (__const char *, __const char *, char **) __THROW;
+extern int yp_order (__const char *, __const char *, unsigned int *) __THROW;
+extern int yp_all (__const char *, __const char *,
+ __const struct ypall_callback *) __THROW;
+extern __const char *yperr_string (__const int) __THROW;
+extern __const char *ypbinderr_string (__const int) __THROW;
+extern int ypprot_err (__const int) __THROW;
+extern int yp_update (char *, char *, unsigned int, char *,
+ int, char *, int) __THROW;
+#if 0
+extern int yp_maplist (__const char *, struct ypmaplist **) __THROW;
+#endif
+
+/* This functions exists only under BSD and Linux systems. */
+extern int __yp_check (char **) __THROW;
+
+__END_DECLS
+
+#endif /* __RPCSVC_YPCLNT_H__ */
diff --git a/meta/recipes-extended/libtirpc/libtirpc_0.2.3.bb b/meta/recipes-extended/libtirpc/libtirpc_0.2.3.bb
index ed838b7..dda9e05 100644
--- a/meta/recipes-extended/libtirpc/libtirpc_0.2.3.bb
+++ b/meta/recipes-extended/libtirpc/libtirpc_0.2.3.bb
@@ -12,23 +12,50 @@ DEPENDS += "xz-native"
PROVIDES = "virtual/librpc"
SRC_URI = "${SOURCEFORGE_MIRROR}/${BPN}/${BPN}-${PV}.tar.bz2;name=libtirpc \
- ${GENTOO_MIRROR}/${BPN}-glibc-nfs.tar.xz;name=glibc-nfs \
file://libtirpc-0.2.1-fortify.patch \
file://obsolete_automake_macros.patch \
+ file://libtirpc-0.2.3-add-missing-bits-from-glibc.patch \
+ file://libtirpc-0.2.3-types.h.patch \
+ file://libtirpc-0008-Add-rpcgen-program-from-nfs-utils-sources.patch \
+ file://key_prot.h \
+ file://nis.h \
+ file://nislib.h \
+ file://nis_tags.h \
+ file://rpc_des.h \
+ file://ypclnt.h \
+ file://yp_prot.h \
"
SRC_URI_append_libc-uclibc = " file://remove-des-uclibc.patch"
SRC_URI[libtirpc.md5sum] = "b70e6c12a369a91e69fcc3b9feb23d61"
SRC_URI[libtirpc.sha256sum] = "4f29ea0491b4ca4c29f95f3c34191b857757873bbbf4b069f9dd4da01a6a923c"
-SRC_URI[glibc-nfs.md5sum] = "5ae500b9d0b6b72cb875bc04944b9445"
-SRC_URI[glibc-nfs.sha256sum] = "2677cfedf626f3f5a8f6e507aed5bb8f79a7453b589d684dbbc086e755170d83"
+
inherit autotools pkgconfig
+CFLAGS += "-I${S}/glibc-headers"
+EXTRA_OECONF = "--disable-gss"
+
do_configure_prepend () {
- cp -r ${S}/../tirpc ${S}
+ install -d ${S}/glibc-headers/rpc/
+ install -d ${S}/glibc-headers/rpcsvc/
+
+ install -m 0644 ${WORKDIR}/key_prot.h ${S}/glibc-headers/rpc
+ install -m 0644 ${WORKDIR}/rpc_des.h ${S}/glibc-headers/rpc
+
+ install -m 0644 ${WORKDIR}/nis.h ${S}/glibc-headers/rpcsvc
+ install -m 0644 ${WORKDIR}/nislib.h ${S}/glibc-headers/rpcsvc
+ install -m 0644 ${WORKDIR}/nis_tags.h ${S}/glibc-headers/rpcsvc
+ install -m 0644 ${WORKDIR}/ypclnt.h ${S}/glibc-headers/rpcsvc
+ install -m 0644 ${WORKDIR}/yp_prot.h ${S}/glibc-headers/rpcsvc
}
do_install_append() {
chown root:root ${D}${sysconfdir}/netconfig
+
+ install -d ${D}/${includedir}/rpc/
+ install -d ${D}/${includedir}/rpcsvc/
+
+ install -m 0644 ${S}/glibc-headers/rpc/*.h ${D}/${includedir}/rpc/
+ install -m 0644 ${S}/glibc-headers/rpcsvc/*.h ${D}/${includedir}/rpcsvc/
}
--
1.8.1.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 3/6] busybox: disable MOUNT_NFS option - not needed on 2.6.23+ kernels
2013-03-20 9:37 [RFC] Switching from glibc RPC to TI RPC Marcin Juszkiewicz
2013-03-20 9:37 ` [PATCH 1/6] eglibc: disable RPC in favour of libtirpc Marcin Juszkiewicz
2013-03-20 9:37 ` [PATCH 2/6] libtirpc: add RPC parts from glibc - patches from OpenMandriva Marcin Juszkiewicz
@ 2013-03-20 9:37 ` Marcin Juszkiewicz
2013-03-20 9:37 ` [PATCH 4/6] quota: switch to libtirpc Marcin Juszkiewicz
` (3 subsequent siblings)
6 siblings, 0 replies; 14+ messages in thread
From: Marcin Juszkiewicz @ 2013-03-20 9:37 UTC (permalink / raw)
To: openembedded-core
Without this option we do not need RPC support from glibc.
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
---
meta/recipes-core/busybox/busybox-1.20.2/defconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/meta/recipes-core/busybox/busybox-1.20.2/defconfig b/meta/recipes-core/busybox/busybox-1.20.2/defconfig
index bdfdadf..cfcbcae 100644
--- a/meta/recipes-core/busybox/busybox-1.20.2/defconfig
+++ b/meta/recipes-core/busybox/busybox-1.20.2/defconfig
@@ -583,7 +583,7 @@ CONFIG_MOUNT=y
# CONFIG_FEATURE_MOUNT_VERBOSE is not set
# CONFIG_FEATURE_MOUNT_HELPERS is not set
# CONFIG_FEATURE_MOUNT_LABEL is not set
-CONFIG_FEATURE_MOUNT_NFS=y
+# CONFIG_FEATURE_MOUNT_NFS is not set
# CONFIG_FEATURE_MOUNT_CIFS is not set
CONFIG_FEATURE_MOUNT_FLAGS=y
CONFIG_FEATURE_MOUNT_FSTAB=y
--
1.8.1.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 4/6] quota: switch to libtirpc
2013-03-20 9:37 [RFC] Switching from glibc RPC to TI RPC Marcin Juszkiewicz
` (2 preceding siblings ...)
2013-03-20 9:37 ` [PATCH 3/6] busybox: disable MOUNT_NFS option - not needed on 2.6.23+ kernels Marcin Juszkiewicz
@ 2013-03-20 9:37 ` Marcin Juszkiewicz
2013-03-20 9:37 ` [PATCH 5/6] rpcbind: disable yellow pages support Marcin Juszkiewicz
` (2 subsequent siblings)
6 siblings, 0 replies; 14+ messages in thread
From: Marcin Juszkiewicz @ 2013-03-20 9:37 UTC (permalink / raw)
To: openembedded-core
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
---
meta/recipes-extended/quota/quota_4.01.bb | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/meta/recipes-extended/quota/quota_4.01.bb b/meta/recipes-extended/quota/quota_4.01.bb
index 80159a9..e171160 100644
--- a/meta/recipes-extended/quota/quota_4.01.bb
+++ b/meta/recipes-extended/quota/quota_4.01.bb
@@ -15,12 +15,17 @@ SRC_URI[sha256sum] = "a36300bbc126b79b745bf937245092808b4585aa3309ef3335d4ab9d87
S = "${WORKDIR}/quota-tools"
-DEPENDS = "gettext-native e2fsprogs"
+DEPENDS = "gettext-native e2fsprogs libtirpc"
inherit autotools gettext
EXTRA_OEMAKE += 'STRIP=""'
+do_configure_prepend() {
+ export CFLAGS="${CFLAGS} -I${STAGING_INCDIR}/tirpc"
+ export LDFLAGS="-ltirpc ${LDFLAGS} "
+}
+
do_install() {
oe_runmake prefix=${D}${prefix} install
}
--
1.8.1.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 5/6] rpcbind: disable yellow pages support
2013-03-20 9:37 [RFC] Switching from glibc RPC to TI RPC Marcin Juszkiewicz
` (3 preceding siblings ...)
2013-03-20 9:37 ` [PATCH 4/6] quota: switch to libtirpc Marcin Juszkiewicz
@ 2013-03-20 9:37 ` Marcin Juszkiewicz
2013-03-20 9:37 ` [PATCH 6/6] nfs-utils: switch to libtirpc Marcin Juszkiewicz
2013-03-20 10:27 ` [RFC] Switching from glibc RPC to TI RPC Paul Eggleton
6 siblings, 0 replies; 14+ messages in thread
From: Marcin Juszkiewicz @ 2013-03-20 9:37 UTC (permalink / raw)
To: openembedded-core
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
---
.../rpcbind/rpcbind/rpcbind-01-no-yp-support.patch | 49 ++++++++++++++++++++++
meta/recipes-extended/rpcbind/rpcbind_0.2.0.bb | 1 +
2 files changed, 50 insertions(+)
create mode 100644 meta/recipes-extended/rpcbind/rpcbind/rpcbind-01-no-yp-support.patch
diff --git a/meta/recipes-extended/rpcbind/rpcbind/rpcbind-01-no-yp-support.patch b/meta/recipes-extended/rpcbind/rpcbind/rpcbind-01-no-yp-support.patch
new file mode 100644
index 0000000..db26214
--- /dev/null
+++ b/meta/recipes-extended/rpcbind/rpcbind/rpcbind-01-no-yp-support.patch
@@ -0,0 +1,49 @@
+Remove yellow pages support
+
+This support requires yellow pages support in libtirpc, which isn't
+available. As most Buildroot users are most likely never going to need
+such feature, get rid of it.
+
+Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+
+Upstream-Status: inappropriate [embedded specific]
+
+Index: b/src/security.c
+===================================================================
+--- a/src/security.c
++++ b/src/security.c
+@@ -23,9 +23,6 @@
+ #include <rpcsvc/mount.h>
+ #include <rpcsvc/rquota.h>
+ #include <rpcsvc/nfs_prot.h>
+-#include <rpcsvc/yp.h>
+-#include <rpcsvc/ypclnt.h>
+-#include <rpcsvc/yppasswd.h>
+
+ #include "rpcbind.h"
+
+@@ -322,24 +319,9 @@
+ args->rmt_proc != MOUNTPROC_UMNT)
+ break;
+ goto deny;
+- case YPBINDPROG:
+- if (args->rmt_proc != YPBINDPROC_SETDOM)
+- break;
+- /* FALLTHROUGH */
+- case YPPASSWDPROG:
+ case NFS_PROGRAM:
+ case RQUOTAPROG:
+ goto deny;
+- case YPPROG:
+- switch (args->rmt_proc) {
+- case YPPROC_ALL:
+- case YPPROC_MATCH:
+- case YPPROC_FIRST:
+- case YPPROC_NEXT:
+- goto deny;
+- default:
+- break;
+- }
+ default:
+ break;
+ }
diff --git a/meta/recipes-extended/rpcbind/rpcbind_0.2.0.bb b/meta/recipes-extended/rpcbind/rpcbind_0.2.0.bb
index 1007613..0a1b2d9 100644
--- a/meta/recipes-extended/rpcbind/rpcbind_0.2.0.bb
+++ b/meta/recipes-extended/rpcbind/rpcbind_0.2.0.bb
@@ -14,6 +14,7 @@ SRC_URI = "${SOURCEFORGE_MIRROR}/rpcbind/rpcbind-${PV}.tar.bz2 \
file://init.d \
file://fix_host_path.patch \
file://obsolete_automake_macros.patch \
+ file://rpcbind-01-no-yp-support.patch \
${UCLIBCPATCHES} \
"
--
1.8.1.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 6/6] nfs-utils: switch to libtirpc
2013-03-20 9:37 [RFC] Switching from glibc RPC to TI RPC Marcin Juszkiewicz
` (4 preceding siblings ...)
2013-03-20 9:37 ` [PATCH 5/6] rpcbind: disable yellow pages support Marcin Juszkiewicz
@ 2013-03-20 9:37 ` Marcin Juszkiewicz
2013-03-20 10:27 ` [RFC] Switching from glibc RPC to TI RPC Paul Eggleton
6 siblings, 0 replies; 14+ messages in thread
From: Marcin Juszkiewicz @ 2013-03-20 9:37 UTC (permalink / raw)
To: openembedded-core
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
---
meta/recipes-connectivity/nfs-utils/nfs-utils_1.2.7.bb | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/meta/recipes-connectivity/nfs-utils/nfs-utils_1.2.7.bb b/meta/recipes-connectivity/nfs-utils/nfs-utils_1.2.7.bb
index cd97810..2a12a34 100644
--- a/meta/recipes-connectivity/nfs-utils/nfs-utils_1.2.7.bb
+++ b/meta/recipes-connectivity/nfs-utils/nfs-utils_1.2.7.bb
@@ -8,7 +8,7 @@ LICENSE = "MIT & GPLv2+ & BSD"
LIC_FILES_CHKSUM = "file://COPYING;md5=95f3a93a5c3c7888de623b46ea085a84"
# util-linux for libblkid
-DEPENDS = "libcap libnfsidmap libevent util-linux tcp-wrappers sqlite3"
+DEPENDS = "libcap libnfsidmap libevent util-linux tcp-wrappers sqlite3 libtirpc"
RDEPENDS_${PN} = "rpcbind"
RRECOMMENDS_${PN} = "kernel-module-nfsd"
@@ -42,9 +42,10 @@ EXTRA_OECONF = "--with-statduser=nobody \
--disable-nfsv41 \
--enable-uuid \
--disable-gss \
- --disable-tirpc \
+ --enable-tirpc \
--disable-nfsdcltrack \
--with-statdpath=/var/lib/nfs/statd \
+ --with-tirpcinclude=${STAGING_INCDIR}/tirpc/ \
"
INHIBIT_AUTO_STAGE = "1"
--
1.8.1.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [RFC] Switching from glibc RPC to TI RPC
2013-03-20 9:37 [RFC] Switching from glibc RPC to TI RPC Marcin Juszkiewicz
` (5 preceding siblings ...)
2013-03-20 9:37 ` [PATCH 6/6] nfs-utils: switch to libtirpc Marcin Juszkiewicz
@ 2013-03-20 10:27 ` Paul Eggleton
2013-03-20 10:41 ` Marcin Juszkiewicz
6 siblings, 1 reply; 14+ messages in thread
From: Paul Eggleton @ 2013-03-20 10:27 UTC (permalink / raw)
To: Marcin Juszkiewicz; +Cc: openembedded-core
On Wednesday 20 March 2013 10:37:17 Marcin Juszkiewicz wrote:
> rpcbind needed removal of yellow pages support (whatever it is).
Isn't that NIS? Will that affect the ypbind-mt / yp-tools recipes recently
added back into meta-networking?
Cheers,
Paul
--
Paul Eggleton
Intel Open Source Technology Centre
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC] Switching from glibc RPC to TI RPC
2013-03-20 10:27 ` [RFC] Switching from glibc RPC to TI RPC Paul Eggleton
@ 2013-03-20 10:41 ` Marcin Juszkiewicz
2013-03-20 12:50 ` Mark Hatle
0 siblings, 1 reply; 14+ messages in thread
From: Marcin Juszkiewicz @ 2013-03-20 10:41 UTC (permalink / raw)
To: openembedded-core
W dniu 20.03.2013 11:27, Paul Eggleton pisze:
> On Wednesday 20 March 2013 10:37:17 Marcin Juszkiewicz wrote:
>> rpcbind needed removal of yellow pages support (whatever it is).
>
> Isn't that NIS? Will that affect the ypbind-mt / yp-tools recipes recently
> added back into meta-networking?
Good point. YP-tools are not buildable with my changeset due to lack of
YP support in libtirpc.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC] Switching from glibc RPC to TI RPC
2013-03-20 10:41 ` Marcin Juszkiewicz
@ 2013-03-20 12:50 ` Mark Hatle
2013-03-20 14:09 ` Marcin Juszkiewicz
0 siblings, 1 reply; 14+ messages in thread
From: Mark Hatle @ 2013-03-20 12:50 UTC (permalink / raw)
To: openembedded-core
On 3/20/13 5:41 AM, Marcin Juszkiewicz wrote:
> W dniu 20.03.2013 11:27, Paul Eggleton pisze:
>> On Wednesday 20 March 2013 10:37:17 Marcin Juszkiewicz wrote:
>>> rpcbind needed removal of yellow pages support (whatever it is).
>>
>> Isn't that NIS? Will that affect the ypbind-mt / yp-tools recipes recently
>> added back into meta-networking?
>
> Good point. YP-tools are not buildable with my changeset due to lack of
> YP support in libtirpc.
>
There is definitely a class of user (networking devices) where nis/yp are still
being used. I would love to see NIS support be a distro feature or similar
configure time element.
-after- the upcoming release, I think we should pursue these patches, assuming
we can get the NIS support enabled in some way.
BTW my only other question was the busybox side. I'm a bit confused by the
comment. I thought the mount_nfs was still required because it enabled the
proper binding argument for the mount syscall. While I don't believe we need to
still support the older kernel(s), we definitely need NFS mounts to work in busybox.
--Mark
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/6] eglibc: disable RPC in favour of libtirpc
2013-03-20 9:37 ` [PATCH 1/6] eglibc: disable RPC in favour of libtirpc Marcin Juszkiewicz
@ 2013-03-20 14:05 ` Khem Raj
2013-03-20 14:15 ` Marcin Juszkiewicz
0 siblings, 1 reply; 14+ messages in thread
From: Khem Raj @ 2013-03-20 14:05 UTC (permalink / raw)
To: Marcin Juszkiewicz; +Cc: openembedded-core
NACK. tirpc is not at a point where it can replace the glibc provided rpc. There is too much software that depends on it.
We have tried it in past 2.14 time frame and reverted back.
On Mar 20, 2013, at 2:37 AM, Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org> wrote:
> Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
> ---
> meta/recipes-core/eglibc/eglibc_2.17.bb | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/meta/recipes-core/eglibc/eglibc_2.17.bb b/meta/recipes-core/eglibc/eglibc_2.17.bb
> index 22129e6..0853c08 100644
> --- a/meta/recipes-core/eglibc/eglibc_2.17.bb
> +++ b/meta/recipes-core/eglibc/eglibc_2.17.bb
> @@ -85,7 +85,7 @@ EXTRA_OECONF = "--enable-kernel=${OLDEST_KERNEL} \
> --enable-add-ons \
> --with-headers=${STAGING_INCDIR} \
> --without-selinux \
> - --enable-obsolete-rpc \
> + --disable-obsolete-rpc \
> --with-kconfig=${STAGING_BINDIR_NATIVE} \
> ${GLIBC_EXTRA_OECONF}"
>
> --
> 1.8.1.2
>
>
> _______________________________________________
> Openembedded-core mailing list
> Openembedded-core@lists.openembedded.org
> http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/openembedded-core
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC] Switching from glibc RPC to TI RPC
2013-03-20 12:50 ` Mark Hatle
@ 2013-03-20 14:09 ` Marcin Juszkiewicz
2013-03-20 14:13 ` Phil Blundell
0 siblings, 1 reply; 14+ messages in thread
From: Marcin Juszkiewicz @ 2013-03-20 14:09 UTC (permalink / raw)
To: openembedded-core
W dniu 20.03.2013 13:50, Mark Hatle pisze:
> On 3/20/13 5:41 AM, Marcin Juszkiewicz wrote:
>> Good point. YP-tools are not buildable with my changeset due to lack of
>> YP support in libtirpc.
> There is definitely a class of user (networking devices) where nis/yp
> are still being used. I would love to see NIS support be a distro
> feature or similar configure time element.
Good idea.
> -after- the upcoming release, I think we should pursue these patches,
> assuming we can get the NIS support enabled in some way.
Looks like we have to wait for TI RPC to mature more.
> BTW my only other question was the busybox side. I'm a bit confused by
> the comment. I thought the mount_nfs was still required because it
> enabled the proper binding argument for the mount syscall. While I
> don't believe we need to still support the older kernel(s), we
> definitely need NFS mounts to work in busybox.
Since
http://git.busybox.net/busybox/commit/?id=a86e02492d7700ce8cb4108f53646dfb025c2dff
change (2011-11-10) this option is not needed to mount NFS with 2.6.23+
kernel:
config FEATURE_MOUNT_NFS
bool "Support mounting NFS file systems on Linux < 2.6.23"
default n
depends on MOUNT
select FEATURE_HAVE_RPC
select FEATURE_SYSLOG
help
Enable mounting of NFS file systems on Linux kernels prior
to version 2.6.23. Note that in this case mounting of NFS
over IPv6 will not be possible.
Note that this option links in RPC support from libc,
which is rather large (~10 kbytes on uclibc).
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC] Switching from glibc RPC to TI RPC
2013-03-20 14:09 ` Marcin Juszkiewicz
@ 2013-03-20 14:13 ` Phil Blundell
0 siblings, 0 replies; 14+ messages in thread
From: Phil Blundell @ 2013-03-20 14:13 UTC (permalink / raw)
To: Marcin Juszkiewicz; +Cc: openembedded-core
On Wed, 2013-03-20 at 15:09 +0100, Marcin Juszkiewicz wrote:
> W dniu 20.03.2013 13:50, Mark Hatle pisze:
> > On 3/20/13 5:41 AM, Marcin Juszkiewicz wrote:
>
> >> Good point. YP-tools are not buildable with my changeset due to lack of
> >> YP support in libtirpc.
>
> > There is definitely a class of user (networking devices) where nis/yp
> > are still being used. I would love to see NIS support be a distro
> > feature or similar configure time element.
>
> Good idea.
It's not totally obvious to me that having NIS itself be a
DISTRO_FEATURE would buy much. Are there any packages whose
configuration actually changes as a result?
Having tirpc vs legacy rpc selectable through DISTRO_FEATURES sounds
like a fine plan though.
p.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/6] eglibc: disable RPC in favour of libtirpc
2013-03-20 14:05 ` Khem Raj
@ 2013-03-20 14:15 ` Marcin Juszkiewicz
0 siblings, 0 replies; 14+ messages in thread
From: Marcin Juszkiewicz @ 2013-03-20 14:15 UTC (permalink / raw)
To: openembedded-core
W dniu 20.03.2013 15:05, Khem Raj pisze:
> NACK. tirpc is not at a point where it can replace the glibc provided
> rpc. There is too much software that depends on it. We have tried it
> in past 2.14 time frame and reverted back.
Thanks. We will go with other option and re-enable RPC in eglibc part of
binary cross toolchain.
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2013-03-20 14:32 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-03-20 9:37 [RFC] Switching from glibc RPC to TI RPC Marcin Juszkiewicz
2013-03-20 9:37 ` [PATCH 1/6] eglibc: disable RPC in favour of libtirpc Marcin Juszkiewicz
2013-03-20 14:05 ` Khem Raj
2013-03-20 14:15 ` Marcin Juszkiewicz
2013-03-20 9:37 ` [PATCH 2/6] libtirpc: add RPC parts from glibc - patches from OpenMandriva Marcin Juszkiewicz
2013-03-20 9:37 ` [PATCH 3/6] busybox: disable MOUNT_NFS option - not needed on 2.6.23+ kernels Marcin Juszkiewicz
2013-03-20 9:37 ` [PATCH 4/6] quota: switch to libtirpc Marcin Juszkiewicz
2013-03-20 9:37 ` [PATCH 5/6] rpcbind: disable yellow pages support Marcin Juszkiewicz
2013-03-20 9:37 ` [PATCH 6/6] nfs-utils: switch to libtirpc Marcin Juszkiewicz
2013-03-20 10:27 ` [RFC] Switching from glibc RPC to TI RPC Paul Eggleton
2013-03-20 10:41 ` Marcin Juszkiewicz
2013-03-20 12:50 ` Mark Hatle
2013-03-20 14:09 ` Marcin Juszkiewicz
2013-03-20 14:13 ` Phil Blundell
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.