summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVijay Kumar Banerjee <vijay@rtems.org>2021-02-11 22:13:34 -0700
committerVijay Kumar Banerjee <vijay@rtems.org>2021-03-02 14:29:29 -0700
commitaf6b0e296605c82d710385f41117396a54d4d625 (patch)
treeb1398a475df9d9f593eea523711f916424b14c27
parent4e49c230d470b0aeb4d40453becd17b58677e05d (diff)
Add libmisc and librpc from RTEMS cpukit
-rw-r--r--libmisc/dummy-networking.c42
-rw-r--r--libmisc/err.c64
-rw-r--r--libmisc/err.h85
-rw-r--r--libmisc/internal.h36
-rw-r--r--libmisc/main_ifconfig.c275
-rw-r--r--libmisc/main_netstats.c137
-rw-r--r--libmisc/main_ping.c1982
-rw-r--r--libmisc/main_route.c151
-rw-r--r--libmisc/mon-network.c342
-rw-r--r--libmisc/sysexits.h116
-rw-r--r--librpc/README_RTEMS64
-rw-r--r--librpc/include/rpcsvc/bootparam_prot.x103
-rw-r--r--librpc/include/rpcsvc/crypt.x91
-rw-r--r--librpc/include/rpcsvc/key_prot.x282
-rw-r--r--librpc/include/rpcsvc/klm_prot.x139
-rw-r--r--librpc/include/rpcsvc/mount.x257
-rw-r--r--librpc/include/rpcsvc/nfs_prot.x1265
-rw-r--r--librpc/include/rpcsvc/nis.x466
-rw-r--r--librpc/include/rpcsvc/nis_cache.x87
-rw-r--r--librpc/include/rpcsvc/nis_callback.x76
-rw-r--r--librpc/include/rpcsvc/nis_db.h164
-rw-r--r--librpc/include/rpcsvc/nis_object.x317
-rw-r--r--librpc/include/rpcsvc/nis_tags.h137
-rw-r--r--librpc/include/rpcsvc/nislib.h317
-rw-r--r--librpc/include/rpcsvc/nlm_prot.x183
-rw-r--r--librpc/include/rpcsvc/pmap_prot.x284
-rw-r--r--librpc/include/rpcsvc/rex.x235
-rw-r--r--librpc/include/rpcsvc/rnusers.x122
-rw-r--r--librpc/include/rpcsvc/rquota.x67
-rw-r--r--librpc/include/rpcsvc/rstat.x151
-rw-r--r--librpc/include/rpcsvc/rwall.x57
-rw-r--r--librpc/include/rpcsvc/sm_inter.x122
-rw-r--r--librpc/include/rpcsvc/spray.x90
-rw-r--r--librpc/include/rpcsvc/yp.x379
-rw-r--r--librpc/include/rpcsvc/yp_prot.h330
-rw-r--r--librpc/include/rpcsvc/ypclnt.h93
-rw-r--r--librpc/include/rpcsvc/yppasswd.x75
-rw-r--r--librpc/include/rpcsvc/ypupdate_prot.x88
-rw-r--r--librpc/include/rpcsvc/ypxfrd.x173
-rw-r--r--librpc/src/rpc/DISCLAIMER28
-rw-r--r--librpc/src/rpc/README233
-rw-r--r--librpc/src/rpc/auth_none.c140
-rw-r--r--librpc/src/rpc/auth_unix.c347
-rw-r--r--librpc/src/rpc/authunix_prot.c73
-rw-r--r--librpc/src/rpc/bindresvport.3106
-rw-r--r--librpc/src/rpc/bindresvport.c162
-rw-r--r--librpc/src/rpc/clnt_generic.c147
-rw-r--r--librpc/src/rpc/clnt_perror.c261
-rw-r--r--librpc/src/rpc/clnt_raw.c250
-rw-r--r--librpc/src/rpc/clnt_simple.c129
-rw-r--r--librpc/src/rpc/clnt_tcp.c608
-rw-r--r--librpc/src/rpc/clnt_udp.c582
-rw-r--r--librpc/src/rpc/des_crypt.3130
-rw-r--r--librpc/src/rpc/get_myaddress.c143
-rw-r--r--librpc/src/rpc/getrpcent.398
-rw-r--r--librpc/src/rpc/getrpcent.c303
-rw-r--r--librpc/src/rpc/getrpcport.331
-rw-r--r--librpc/src/rpc/getrpcport.c71
-rw-r--r--librpc/src/rpc/netname.c141
-rw-r--r--librpc/src/rpc/netnamer.c333
-rw-r--r--librpc/src/rpc/pmap_clnt.c153
-rw-r--r--librpc/src/rpc/pmap_getmaps.c93
-rw-r--r--librpc/src/rpc/pmap_getport.c99
-rw-r--r--librpc/src/rpc/pmap_prot.c65
-rw-r--r--librpc/src/rpc/pmap_prot2.c124
-rw-r--r--librpc/src/rpc/pmap_rmt.c444
-rw-r--r--librpc/src/rpc/publickey.347
-rw-r--r--librpc/src/rpc/publickey.538
-rw-r--r--librpc/src/rpc/rpc.31767
-rw-r--r--librpc/src/rpc/rpc.535
-rw-r--r--librpc/src/rpc/rpc_callmsg.c198
-rw-r--r--librpc/src/rpc/rpc_commondata.c47
-rw-r--r--librpc/src/rpc/rpc_dtablesize.c67
-rw-r--r--librpc/src/rpc/rpc_prot.c338
-rw-r--r--librpc/src/rpc/rpc_secure.3254
-rw-r--r--librpc/src/rpc/rpcdname.c86
-rw-r--r--librpc/src/rpc/rstat.158
-rw-r--r--librpc/src/rpc/rstat_svc.822
-rw-r--r--librpc/src/rpc/rtems-rpc-config.h40
-rw-r--r--librpc/src/rpc/rtems_portmapper.c502
-rw-r--r--librpc/src/rpc/rtems_rpc.c127
-rw-r--r--librpc/src/rpc/rtime.347
-rw-r--r--librpc/src/rpc/rtime.c165
-rw-r--r--librpc/src/rpc/svc.c502
-rw-r--r--librpc/src/rpc/svc_auth.c222
-rw-r--r--librpc/src/rpc/svc_auth_unix.c154
-rw-r--r--librpc/src/rpc/svc_raw.c175
-rw-r--r--librpc/src/rpc/svc_run.c91
-rw-r--r--librpc/src/rpc/svc_simple.c163
-rw-r--r--librpc/src/rpc/svc_tcp.c491
-rw-r--r--librpc/src/rpc/svc_udp.c486
-rw-r--r--librpc/src/xdr/xdr.3837
-rw-r--r--librpc/src/xdr/xdr.c858
-rw-r--r--librpc/src/xdr/xdr_array.c160
-rw-r--r--librpc/src/xdr/xdr_float.c344
-rw-r--r--librpc/src/xdr/xdr_mem.c245
-rw-r--r--librpc/src/xdr/xdr_rec.c608
-rw-r--r--librpc/src/xdr/xdr_reference.c142
-rw-r--r--librpc/src/xdr/xdr_sizeof.c167
-rw-r--r--librpc/src/xdr/xdr_stdio.c194
-rw-r--r--lnetworking.py2
101 files changed, 24416 insertions, 1 deletions
diff --git a/libmisc/dummy-networking.c b/libmisc/dummy-networking.c
new file mode 100644
index 0000000..379e23e
--- /dev/null
+++ b/libmisc/dummy-networking.c
@@ -0,0 +1,42 @@
+/*
+ * Dummy configuration file
+ *
+ * COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+/* Loopback Network Configuration */
+#if defined(RTEMS_NETWORKING)
+ #include <rtems/rtems_bsdnet.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+
+ struct rtems_bsdnet_config rtems_bsdnet_config = {
+ NULL, /* Network interface */
+ NULL, /* Use fixed network configuration */
+ 0, /* Default network task priority */
+ 0, /* Default mbuf capacity */
+ 0, /* Default mbuf cluster capacity */
+ "testSystem", /* Host name */
+ "nowhere.com", /* Domain name */
+ "127.0.0.1", /* Gateway */
+ "127.0.0.1", /* Log host */
+ {"127.0.0.1" }, /* Name server(s) */
+ {"127.0.0.1" }, /* NTP server(s) */
+ 1, /* sb_efficiency */
+ 0, /* udp_tx_buf_size */
+ 0, /* udp_rx_buf_size */
+ 0, /* tcp_tx_buf_size */
+ 0 /* tcp_rx_buf_size */
+ };
+#endif
diff --git a/libmisc/err.c b/libmisc/err.c
new file mode 100644
index 0000000..fff022a
--- /dev/null
+++ b/libmisc/err.c
@@ -0,0 +1,64 @@
+/* $NetBSD: err.c,v 1.25 2005/09/13 13:51:50 christos Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#if HAVE_NBTOOL_CONFIG_H
+#include "nbtool_config.h"
+#endif
+
+#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)err.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: err.c,v 1.25 2005/09/13 13:51:50 christos Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include "err.h"
+#include <stdarg.h>
+
+#ifdef __weak_alias
+__weak_alias(err, _err)
+#endif
+
+__dead void
+err(jmp_buf* exit_jmp, int eval, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ verr(exit_jmp, eval, fmt, ap);
+ va_end(ap);
+}
diff --git a/libmisc/err.h b/libmisc/err.h
new file mode 100644
index 0000000..6e64e8d
--- /dev/null
+++ b/libmisc/err.h
@@ -0,0 +1,85 @@
+/* $NetBSD: err.h,v 1.14 2005/02/03 04:39:32 perry Exp $ */
+
+/*-
+ * Copyright (c) 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)err.h 8.1 (Berkeley) 6/2/93
+ */
+
+#ifndef _ERR_H_
+#define _ERR_H_
+
+/*
+ * Don't use va_list in the err/warn prototypes. Va_list is typedef'd in two
+ * places (<machine/varargs.h> and <machine/stdarg.h>), so if we include one
+ * of them here we may collide with the utility's includes. It's unreasonable
+ * for utilities to have to include one of them to include err.h, so we get
+ * _BSD_VA_LIST_ from <machine/ansi.h> and use it.
+ */
+#include <machine/ansi.h>
+#include <sys/cdefs.h>
+
+#include <stdarg.h>
+#define _BSD_VA_LIST_ va_list
+
+#define __dead
+
+#define err rtems_shell_err
+#define verr rtems_shell_verr
+#define errx rtems_shell_errx
+#define verrx rtems_shell_verrx
+#define warn rtems_shell_warn
+#define vwarn rtems_shell_vwarn
+#define warnx rtems_shell_warnx
+#define vwarnx rtems_shell_vwarnx
+
+#include <setjmp.h>
+#include <rtems.h>
+
+extern jmp_buf rtems_shell_bsd_exit_recover;
+
+__BEGIN_DECLS
+__dead void err(jmp_buf*, int, const char *, ...)
+ __attribute__((__noreturn__, __format__(__printf__, 3, 4)));
+__dead void verr(jmp_buf*, int, const char *, _BSD_VA_LIST_)
+ __attribute__((__noreturn__, __format__(__printf__, 3, 0)));
+__dead void errx(jmp_buf*, int, const char *, ...)
+ __attribute__((__noreturn__, __format__(__printf__, 3, 4)));
+__dead void verrx(jmp_buf*, int, const char *, _BSD_VA_LIST_)
+ __attribute__((__noreturn__, __format__(__printf__, 3, 0)));
+void warn(const char *, ...)
+ __attribute__((__format__(__printf__, 1, 2)));
+void vwarn(const char *, _BSD_VA_LIST_)
+ __attribute__((__format__(__printf__, 1, 0)));
+void warnx(const char *, ...)
+ __attribute__((__format__(__printf__, 1, 2)));
+void vwarnx(const char *, _BSD_VA_LIST_)
+ __attribute__((__format__(__printf__, 1, 0)));
+__END_DECLS
+
+#endif /* !_ERR_H_ */
diff --git a/libmisc/internal.h b/libmisc/internal.h
new file mode 100644
index 0000000..2d042ae
--- /dev/null
+++ b/libmisc/internal.h
@@ -0,0 +1,36 @@
+/*
+ * Shell Internal Information
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef _RTEMS_SHELL_INTERNAL_H
+#define _RTEMS_SHELL_INTERNAL_H
+
+#include <rtems/shell.h>
+
+extern rtems_shell_cmd_t * rtems_shell_first_cmd;
+extern rtems_shell_topic_t * rtems_shell_first_topic;
+
+extern void rtems_shell_register_monitor_commands(void);
+
+extern void rtems_shell_print_heap_info(
+ const char *c,
+ const Heap_Information *h
+);
+
+extern void rtems_shell_print_heap_stats(
+ const Heap_Statistics *s
+);
+
+extern void rtems_shell_print_unified_work_area_message(void);
+
+#include <sys/types.h>
+
+extern void strmode(mode_t mode, char *p);
+extern const char *user_from_uid(uid_t uid, int nouser);
+extern char *group_from_gid(gid_t gid, int nogroup);
+
+#endif
diff --git a/libmisc/main_ifconfig.c b/libmisc/main_ifconfig.c
new file mode 100644
index 0000000..c19048f
--- /dev/null
+++ b/libmisc/main_ifconfig.c
@@ -0,0 +1,275 @@
+/*
+ * IFCONFIG Command Implmentation
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include <netinet/in.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+
+
+#include <rtems.h>
+#include <rtems/rtems_bsdnet.h>
+#include <rtems/shell.h>
+#include "internal.h"
+
+
+static const char IFCONFIG_USAGE[] =
+ "ifconfig [iface]\n"
+ "ifconfig iface options | addr\n"
+ " iface: name of the interface\n"
+ " options: iface \n"
+ " up: bring the interface up\n"
+ " down: take the interface down\n"
+ " netmask addr: network mask\n"
+ " broadcast addr: boardcast address\n"
+ " pointopoint addr: destination address for a PTP link\n"
+ "\n"
+ " addr: IP address";
+
+
+static int rtems_shell_main_ifconfig(
+ int argc,
+ char *argv[]
+)
+{
+ struct sockaddr_in ipaddr;
+ struct sockaddr_in dstaddr;
+ struct sockaddr_in netmask;
+ struct sockaddr_in broadcast;
+ char *iface = NULL;
+ int f_ip = 0;
+ int f_ptp = 0;
+ int f_netmask = 0;
+ int f_up = 0;
+ int f_down = 0;
+ int f_bcast = 0;
+ int f_usage = 0;
+ int cur_idx;
+ int rc;
+ int flags;
+
+ memset(&ipaddr, 0, sizeof(ipaddr));
+ memset(&dstaddr, 0, sizeof(dstaddr));
+ memset(&netmask, 0, sizeof(netmask));
+ memset(&broadcast, 0, sizeof(broadcast));
+
+ ipaddr.sin_len = sizeof(ipaddr);
+ ipaddr.sin_family = AF_INET;
+
+ dstaddr.sin_len = sizeof(dstaddr);
+ dstaddr.sin_family = AF_INET;
+
+ netmask.sin_len = sizeof(netmask);
+ netmask.sin_family = AF_INET;
+
+ broadcast.sin_len = sizeof(broadcast);
+ broadcast.sin_family = AF_INET;
+
+ cur_idx = 0;
+ if (argc <= 1) {
+ /* display all interfaces */
+ iface = NULL;
+ cur_idx += 1;
+ } else {
+ if ( 0 == strcmp( "--help", argv[1] ) ) {
+ f_usage = 1;
+ cur_idx += 2;
+ } else if ( 0 == strcmp( "-help", argv[1] ) ) {
+ f_usage = 1;
+ cur_idx += 2;
+ } else {
+ iface = argv[1];
+ if ( argc >= 3 ) {
+ if (isdigit((unsigned char)*argv[2])) {
+ if (inet_pton(AF_INET, argv[2], &ipaddr.sin_addr) < 0) {
+ printf("bad ip address: %s\n", argv[2]);
+ return 0;
+ }
+ f_ip = 1;
+ cur_idx += 3;
+ } else {
+ cur_idx += 2;
+ }
+ } else {
+ cur_idx += 2;
+ }
+ }
+ }
+
+ if ((f_down !=0) && (f_ip != 0)) {
+ f_up = 1;
+ }
+
+ while(argc > cur_idx) {
+ if (strcmp(argv[cur_idx], "up") == 0) {
+ f_up = 1;
+ if (f_down != 0) {
+ printf("Can't make interface up and down\n");
+ return -1;
+ }
+ } else if(strcmp(argv[cur_idx], "down") == 0) {
+ f_down = 1;
+ if (f_up != 0) {
+ printf("Can't make interface up and down\n");
+ return -1;
+ }
+ } else if(strcmp(argv[cur_idx], "netmask") == 0) {
+ if ((cur_idx + 1) >= argc) {
+ printf("No netmask address\n");
+ return -1;
+ }
+ if (inet_pton(AF_INET, argv[cur_idx+1], &netmask.sin_addr) < 0) {
+ printf("bad netmask: %s\n", argv[cur_idx]);
+ return -1;
+ }
+ f_netmask = 1;
+ cur_idx += 1;
+ } else if(strcmp(argv[cur_idx], "broadcast") == 0) {
+ if ((cur_idx + 1) >= argc) {
+ printf("No broadcast address\n");
+ return -1;
+ }
+ if (inet_pton(AF_INET, argv[cur_idx+1], &broadcast.sin_addr) < 0) {
+ printf("bad broadcast: %s\n", argv[cur_idx]);
+ return -1;
+ }
+ f_bcast = 1;
+ cur_idx += 1;
+ } else if(strcmp(argv[cur_idx], "pointopoint") == 0) {
+ if ((cur_idx + 1) >= argc) {
+ printf("No pointopoint address\n");
+ return -1;
+ }
+ if (inet_pton(AF_INET, argv[cur_idx+1], &dstaddr.sin_addr) < 0) {
+ printf("bad pointopoint: %s\n", argv[cur_idx]);
+ return -1;
+ }
+ f_ptp = 1;
+ cur_idx += 1;
+ } else {
+ printf("Bad parameter: %s\n", argv[cur_idx]);
+ return -1;
+ }
+ cur_idx += 1;
+ }
+
+ printf("ifconfig ");
+ if (iface != NULL) {
+ printf("%s ", iface);
+ if (f_ip != 0) {
+ char str[256];
+ inet_ntop(AF_INET, &ipaddr.sin_addr, str, 256);
+ printf("%s ", str);
+ }
+
+ if (f_netmask != 0) {
+ char str[256];
+ inet_ntop(AF_INET, &netmask.sin_addr, str, 256);
+ printf("netmask %s ", str);
+ }
+
+ if (f_bcast != 0) {
+ char str[256];
+ inet_ntop(AF_INET, &broadcast.sin_addr, str, 256);
+ printf("broadcast %s ", str);
+ }
+
+ if (f_ptp != 0) {
+ char str[256];
+ inet_ntop(AF_INET, &dstaddr.sin_addr, str, 256);
+ printf("pointopoint %s ", str);
+ }
+
+ if (f_up != 0) {
+ printf("up\n");
+ } else if (f_down != 0) {
+ printf("down\n");
+ } else {
+ printf("\n");
+ }
+ } else if (f_usage != 0) {
+ printf ( "\n" );
+ printf ( IFCONFIG_USAGE );
+ }
+
+ if ( ! f_usage ) {
+ if ((iface == NULL) || ((f_ip == 0) && (f_down == 0) && (f_up == 0))) {
+ rtems_bsdnet_show_if_stats();
+ return 0;
+ }
+ }
+
+ flags = 0;
+ if (f_netmask) {
+ rc = rtems_bsdnet_ifconfig(iface, SIOCSIFNETMASK, &netmask);
+ if (rc < 0) {
+ printf("Could not set netmask: %s\n", strerror(errno));
+ return -1;
+ }
+ }
+
+ if (f_bcast) {
+ rc = rtems_bsdnet_ifconfig(iface, SIOCSIFBRDADDR, &broadcast);
+ if (rc < 0) {
+ printf("Could not set broadcast: %s\n", strerror(errno));
+ return -1;
+ }
+ }
+
+ if (f_ptp) {
+ rc = rtems_bsdnet_ifconfig(iface, SIOCSIFDSTADDR, &dstaddr);
+ if (rc < 0) {
+ printf("Could not set destination address: %s\n", strerror(errno));
+ return -1;
+ }
+ flags |= IFF_POINTOPOINT;
+ }
+
+ /* This must come _after_ setting the netmask, broadcast addresses */
+ if (f_ip) {
+ rc = rtems_bsdnet_ifconfig(iface, SIOCSIFADDR, &ipaddr);
+ if (rc < 0) {
+ printf("Could not set IP address: %s\n", strerror(errno));
+ return -1;
+ }
+ }
+
+ if (f_up != 0) {
+ flags |= IFF_UP;
+ }
+
+ if ( ! f_usage ) {
+ rc = rtems_bsdnet_ifconfig(iface, SIOCSIFFLAGS, &flags);
+ if (rc < 0) {
+ printf("Could not set interface flags: %s\n", strerror(errno));
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+rtems_shell_cmd_t rtems_shell_IFCONFIG_Command = {
+ "ifconfig", /* name */
+ IFCONFIG_USAGE, /* usage */
+ "network", /* topic */
+ rtems_shell_main_ifconfig, /* command */
+ NULL, /* alias */
+ NULL /* next */
+};
diff --git a/libmisc/main_netstats.c b/libmisc/main_netstats.c
new file mode 100644
index 0000000..30007a6
--- /dev/null
+++ b/libmisc/main_netstats.c
@@ -0,0 +1,137 @@
+/*
+ * Network Statistics Shell Command Implmentation
+ *
+ * COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#define __need_getopt_newlib
+#include <getopt.h>
+
+#include <rtems.h>
+#include <rtems/rtems_bsdnet.h>
+#include <rtems/shell.h>
+#include "internal.h"
+
+static void netstats_usage(void)
+{
+ printf(
+ "netstats [-vAimfpcut] where:\n"
+ " -A print All statistics\n"
+ " -i print Inet Routes\n"
+ " -m print MBUF Statistics\n"
+ " -f print IF Statistics\n"
+ " -p print IP Statistics\n"
+ " -c print ICMP Statistics\n"
+ " -u print UDP Statistics\n"
+ " -t print TCP Statistics\n"
+ );
+}
+
+static int rtems_shell_main_netstats( /* command */
+ int argc,
+ char *argv[]
+)
+{
+ int option;
+ int doAll = 0;
+ int doInetRoutes = 0;
+ int doMBUFStats = 0;
+ int doIFStats = 0;
+ int doIPStats = 0;
+ int doICMPStats = 0;
+ int doUDPStats = 0;
+ int doTCPStats = 0;
+ int verbose = 0;
+ struct getopt_data getopt_reent;
+
+ memset(&getopt_reent, 0, sizeof(getopt_data));
+ while ( (option = getopt_r( argc, argv, "Aimfpcutv", &getopt_reent)) != -1 ) {
+
+ switch ((char)option) {
+ case 'A': doAll = 1; break;
+ case 'i': doInetRoutes = 1; break;
+ case 'm': doMBUFStats = 1; break;
+ case 'f': doIFStats = 1; break;
+ case 'p': doIPStats = 1; break;
+ case 'c': doICMPStats = 1; break;
+ case 'u': doUDPStats = 1; break;
+ case 't': doTCPStats = 1; break;
+ case 'v': verbose = 1; break;
+ case '?':
+ default:
+ netstats_usage();
+ return -1;
+ }
+ }
+
+ if ( verbose ) {
+ printf(
+ "doAll=%d\n"
+ "doInetRoutes=%d\n"
+ "doMBUFStats=%d\n"
+ "doIFStats=%d\n"
+ "doIPStats=%d\n"
+ "doICMPStats=%d\n"
+ "doUDPStats=%d\n"
+ "doTCPStats=%d\n",
+ doAll,
+ doInetRoutes,
+ doMBUFStats,
+ doIFStats,
+ doIPStats,
+ doICMPStats,
+ doUDPStats,
+ doTCPStats
+ );
+ }
+
+ if ( doInetRoutes == 1 || doAll == 1 ) {
+ rtems_bsdnet_show_inet_routes();
+ }
+
+ if ( doMBUFStats == 1 || doAll == 1 ) {
+ rtems_bsdnet_show_mbuf_stats();
+ }
+
+ if ( doIFStats == 1 || doAll == 1 ) {
+ rtems_bsdnet_show_if_stats();
+ }
+
+ if ( doIPStats == 1 || doAll == 1 ) {
+ rtems_bsdnet_show_ip_stats();
+ }
+
+ if ( doICMPStats == 1 || doAll == 1 ) {
+ rtems_bsdnet_show_icmp_stats();
+ }
+
+ if ( doUDPStats == 1 || doAll == 1 ) {
+ rtems_bsdnet_show_udp_stats();
+ }
+
+ if ( doTCPStats == 1 || doAll == 1 ) {
+ rtems_bsdnet_show_tcp_stats();
+ }
+
+ return 0;
+}
+
+rtems_shell_cmd_t rtems_shell_NETSTATS_Command = {
+ "netstats", /* name */
+ "netstats [-Aimfpcutv]", /* usage */
+ "network", /* topic */
+ rtems_shell_main_netstats, /* command */
+ NULL, /* alias */
+ NULL /* next */
+};
diff --git a/libmisc/main_ping.c b/libmisc/main_ping.c
new file mode 100644
index 0000000..05dee34
--- /dev/null
+++ b/libmisc/main_ping.c
@@ -0,0 +1,1982 @@
+#ifdef __rtems__
+#define __need_getopt_newlib
+#include <getopt.h>
+#endif
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Mike Muuss.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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 !__rtems__
+#ifndef lint
+static const char copyright[] =
+"@(#) Copyright (c) 1989, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)ping.c 8.1 (Berkeley) 6/5/93";
+#endif /* not lint */
+#endif
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * P I N G . C
+ *
+ * Using the Internet Control Message Protocol (ICMP) "ECHO" facility,
+ * measure round-trip-delays and packet loss across network paths.
+ *
+ * Author -
+ * Mike Muuss
+ * U. S. Army Ballistic Research Laboratory
+ * December, 1983
+ *
+ * Status -
+ * Public Domain. Distribution Unlimited.
+ * Bugs -
+ * More statistics could always be gathered.
+ * This program has to run SUID to ROOT to access the ICMP socket.
+ */
+
+#include <sys/param.h> /* NB: we rely on this for <sys/types.h> */
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+#include <sys/time.h>
+#include <sys/uio.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/ip_var.h>
+#include <arpa/inet.h>
+
+#ifdef IPSEC
+#include <netipsec/ipsec.h>
+#endif /*IPSEC*/
+
+#include <ctype.h>
+//#include "err.h"
+#include <errno.h>
+#if !defined(__rtems__)
+#include <math.h>
+#endif
+#include <netdb.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+//#include <sysexits.h>
+#include <unistd.h>
+
+#include "err.h"
+#include "sysexits.h"
+#include <sys/select.h>
+#ifdef __rtems__
+#include <rtems/shell.h>
+#endif /* __rtems__ */
+
+#define INADDR_LEN ((int)sizeof(in_addr_t))
+#define TIMEVAL_LEN ((int)sizeof(struct tv32))
+#define MASK_LEN (ICMP_MASKLEN - ICMP_MINLEN)
+#define TS_LEN (ICMP_TSLEN - ICMP_MINLEN)
+#define DEFDATALEN 56 /* default data length */
+#define FLOOD_BACKOFF 20000 /* usecs to back off if F_FLOOD mode */
+ /* runs out of buffer space */
+#define MAXIPLEN (sizeof(struct ip) + MAX_IPOPTLEN)
+#define MAXICMPLEN (ICMP_ADVLENMIN + MAX_IPOPTLEN)
+#define MAXWAIT 10000 /* max ms to wait for response */
+#define MAXALARM (60 * 60) /* max seconds for alarm timeout */
+#define MAXTOS 255
+
+#define A(bit) rcvd_tbl[(bit)>>3] /* identify byte in array */
+#define B(bit) (1 << ((bit) & 0x07)) /* identify bit in byte */
+#define SET(bit) (A(bit) |= B(bit))
+#define CLR(bit) (A(bit) &= (~B(bit)))
+#define TST(bit) (A(bit) & B(bit))
+
+struct tv32 {
+ int32_t tv32_sec;
+ int32_t tv32_usec;
+};
+
+/* various options */
+#if !__rtems__
+int options;
+#endif
+#define F_FLOOD 0x0001
+#define F_INTERVAL 0x0002
+#define F_NUMERIC 0x0004
+#define F_PINGFILLED 0x0008
+#define F_QUIET 0x0010
+#define F_RROUTE 0x0020
+#define F_SO_DEBUG 0x0040
+#define F_SO_DONTROUTE 0x0080
+#define F_VERBOSE 0x0100
+#define F_QUIET2 0x0200
+#define F_NOLOOP 0x0400
+#define F_MTTL 0x0800
+#define F_MIF 0x1000
+#define F_AUDIBLE 0x2000
+#ifdef IPSEC
+#ifdef IPSEC_POLICY_IPSEC
+#define F_POLICY 0x4000
+#endif /*IPSEC_POLICY_IPSEC*/
+#endif /*IPSEC*/
+#define F_TTL 0x8000
+#define F_MISSED 0x10000
+#define F_ONCE 0x20000
+#define F_HDRINCL 0x40000
+#define F_MASK 0x80000
+#define F_TIME 0x100000
+#define F_SWEEP 0x200000
+#define F_WAITTIME 0x400000
+
+/*
+ * MAX_DUP_CHK is the number of bits in received table, i.e. the maximum
+ * number of received sequence numbers we can keep track of. Change 128
+ * to 8192 for complete accuracy...
+ */
+#define MAX_DUP_CHK (8 * 128)
+#if !__rtems__
+int mx_dup_ck = MAX_DUP_CHK;
+char rcvd_tbl[MAX_DUP_CHK / 8];
+
+struct sockaddr_in whereto; /* who to ping */
+int datalen = DEFDATALEN;
+int maxpayload;
+int s; /* socket file descriptor */
+u_char outpackhdr[IP_MAXPACKET], *outpack;
+#endif
+char BBELL = '\a'; /* characters written for MISSED and AUDIBLE */
+char BSPACE = '\b'; /* characters written for flood */
+char DOT = '.';
+#if !__rtems__
+char *hostname;
+char *shostname;
+int ident; /* process id to identify our packets */
+int uid; /* cached uid for micro-optimization */
+u_char icmp_type = ICMP_ECHO;
+u_char icmp_type_rsp = ICMP_ECHOREPLY;
+int phdr_len = 0;
+int send_len;
+
+/* counters */
+long nmissedmax; /* max value of ntransmitted - nreceived - 1 */
+long npackets; /* max packets to transmit */
+long nreceived; /* # of packets we got back */
+long nrepeats; /* number of duplicates */
+long ntransmitted; /* sequence # for outbound packets = #sent */
+long snpackets; /* max packets to transmit in one sweep */
+long snreceived; /* # of packets we got back in this sweep */
+long sntransmitted; /* # of packets we sent in this sweep */
+int sweepmax; /* max value of payload in sweep */
+int sweepmin = 0; /* start value of payload in sweep */
+int sweepincr = 1; /* payload increment in sweep */
+int interval = 1000; /* interval between packets, ms */
+int waittime = MAXWAIT; /* timeout for each packet */
+long nrcvtimeout = 0; /* # of packets we got back after waittime */
+
+/* timing */
+int timing; /* flag to do timing */
+double tmin = 999999999.0; /* minimum round trip time */
+double tmax = 0.0; /* maximum round trip time */
+double tsum = 0.0; /* sum of all times, for doing average */
+double tsumsq = 0.0; /* sum of all times squared, for std. dev. */
+
+volatile sig_atomic_t finish_up; /* nonzero if we've been told to finish up */
+volatile sig_atomic_t siginfo_p;
+
+static void fill(char *, char *);
+static u_short in_cksum(u_short *, int);
+static void check_status(void);
+static void finish(void) __dead2;
+static void pinger(void);
+static char *pr_addr(struct in_addr);
+static char *pr_ntime(n_time);
+static void pr_icmph(struct icmp *);
+static void pr_iph(struct ip *);
+static void pr_pack(char *, int, struct sockaddr_in *, struct timeval *);
+static void pr_retip(struct ip *);
+static void status(int);
+static void stopit(int);
+static void tvsub(struct timeval *, struct timeval *);
+static void usage(void) __dead2;
+#endif
+
+#if __rtems__
+#define CMSG_SPACE(l) (_ALIGN(sizeof(struct cmsghdr)) + _ALIGN(l))
+#define CMSG_LEN(l) (_ALIGN(sizeof(struct cmsghdr)) + (l))
+typedef struct
+{
+ int options;
+ int mx_dup_ck;
+ char rcvd_tbl[MAX_DUP_CHK / 8];
+ struct sockaddr_in whereto;
+ int datalen;
+ int maxpayload;
+ int s;
+ u_char outpackhdr[IP_MAXPACKET];
+ u_char *outpack;
+ char *hostname;
+ char *shostname;
+ int ident;
+ int uid;
+ u_char icmp_type;
+ u_char icmp_type_rsp;
+ int phdr_len;
+ int send_len;
+ long nmissedmax;
+ long npackets;
+ long nreceived;
+ long nrepeats;
+ long ntransmitted;
+ long snpackets;
+ long snreceived;
+ long sntransmitted;
+ int sweepmax;
+ int sweepmin;
+ int sweepincr;
+ int interval;
+ int waittime;
+ long nrcvtimeout;
+ int timing;
+ double tmin;
+ double tmax;
+ double tsum;
+ double tsumsq;
+ volatile sig_atomic_t finish_up;
+ volatile sig_atomic_t siginfo_p;
+
+ /* main */
+ u_char packet[IP_MAXPACKET] __aligned(4);
+
+ /* pr_pack */
+ int old_rrlen;
+ char old_rr[MAX_IPOPTLEN];
+
+ int exit_code;
+ jmp_buf exit_jmp;
+} rtems_shell_globals_t;
+
+#define options_ globals->options
+#define mx_dup_ck globals->mx_dup_ck
+#define rcvd_tbl globals->rcvd_tbl
+#define whereto globals->whereto
+#define datalen globals->datalen
+#define maxpayload globals->maxpayload
+#define s globals->s
+#define outpackhdr globals->outpackhdr
+#define outpack globals->outpack
+#define hostname globals->hostname
+#define shostname globals->shostname
+#define ident globals->ident
+#define uid globals->uid
+#define icmp_type_ globals->icmp_type
+#define icmp_type_rsp globals->icmp_type_rsp
+#define phdr_len globals->phdr_len
+#define send_len globals->send_len
+#define nmissedmax globals->nmissedmax
+#define npackets globals->npackets
+#define nreceived globals->nreceived
+#define nrepeats globals->nrepeats
+#define ntransmitted globals->ntransmitted
+#define snpackets globals->snpackets
+#define snreceived globals->snreceived
+#define sntransmitted globals->sntransmitted
+#define sweepmax globals->sweepmax
+#define sweepmin globals->sweepmin
+#define sweepincr globals->sweepincr
+#define interval globals->interval
+#define waittime globals->waittime
+#define nrcvtimeout globals->nrcvtimeout
+#define timing globals->timing
+#define tmin globals->tmin
+#define tmax globals->tmax
+#define tsum globals->tsum
+#define tsumsq globals->tsumsq
+#define finish_up globals->finish_up
+#define siginfo_p globals->siginfo_p
+
+#define old_rrlen globals->old_rrlen
+#define old_rr globals->old_rr
+
+#define packet_ globals->packet
+
+static u_short in_cksum(u_short *, int);
+static char *pr_ntime(n_time);
+static void pr_icmph(struct icmp *);
+static void pr_iph(struct ip *);
+static void pr_retip(struct ip *);
+static void stopit(int);
+static void tvsub(struct timeval *, struct timeval *);
+
+#define fill(_a1, _a2) g_fill(_a1, _a2, globals)
+static void g_fill(char *_a1, char *_a2, rtems_shell_globals_t* globals);
+
+#define check_status() g_check_status(globals)
+static void g_check_status(rtems_shell_globals_t* globals);
+
+#define finish() g_finish(globals)
+static void g_finish(rtems_shell_globals_t* globals) __dead2;
+
+#define pinger() g_pinger(globals)
+static void g_pinger(rtems_shell_globals_t* globals);
+
+#define pr_addr(_a1) g_pr_addr(_a1, globals)
+static char *g_pr_addr(struct in_addr, rtems_shell_globals_t* globals);
+
+#define pr_pack(_a1, _a2, _a3, _a4) g_pr_pack(_a1, _a2, _a3, _a4, globals)
+static void g_pr_pack(char *, int, struct sockaddr_in *, struct timeval *, rtems_shell_globals_t* globals);
+
+#define usage() g_usage(globals)
+static void g_usage(rtems_shell_globals_t* globals) __dead2;
+
+static void
+rtems_shell_ping_exit (rtems_shell_globals_t* globals, int code)
+{
+ globals->exit_code = code;
+ longjmp (globals->exit_jmp, 1);
+}
+
+#define exit(_c) rtems_shell_ping_exit (globals, _c)
+#define _exit(_c) exit(_c)
+
+static int main_ping(int argc, char *const *argv, rtems_shell_globals_t* globals);
+static int rtems_shell_main_ping(int argc, char *argv[])
+{
+ rtems_shell_globals_t* globals = malloc(sizeof(rtems_shell_globals_t));
+ if (!globals)
+ {
+ printf("error: no memory\n");
+ return 1;
+ }
+ memset (globals, 0, sizeof (rtems_shell_globals_t));
+ npackets = 5;
+ datalen = DEFDATALEN;
+ icmp_type_ = ICMP_ECHO;
+ icmp_type_rsp = ICMP_ECHOREPLY;
+ phdr_len = 0;
+ sweepmin = 0;
+ sweepincr = 1;
+ interval = 1000;
+ waittime = MAXWAIT;
+ nrcvtimeout = 0;
+ tmin = 999999999.0;
+ tmax = 0.0;
+ tsum = 0.0;
+ tsumsq = 0.0;
+ globals->exit_code = 1;
+ if (setjmp (globals->exit_jmp) == 0)
+ return main_ping (argc, argv, globals);
+ return globals->exit_code;
+}
+#endif
+
+
+
+int
+#ifdef __rtems__
+main_ping(argc, argv, globals)
+#else
+main(argc, argv)
+#endif
+ int argc;
+ char *const *argv;
+ rtems_shell_globals_t* globals;
+{
+ struct sockaddr_in from, sock_in;
+ struct in_addr ifaddr;
+ struct timeval last, intvl;
+ struct iovec iov;
+ struct ip *ip;
+ struct msghdr msg;
+ struct sigaction si_sa;
+ size_t sz;
+#if !__rtems__
+ u_char *datap, packet[IP_MAXPACKET] __aligned(4);
+#else
+ u_char *datap;
+#endif
+ char *ep, *source, *target, *payload;
+ struct hostent *hp;
+#ifdef IPSEC_POLICY_IPSEC
+ char *policy_in, *policy_out;
+#endif
+ struct sockaddr_in *to;
+ double t;
+ u_long alarmtimeout, ultmp;
+ int almost_done, ch, df, hold, i, icmp_len, mib[4], preload, sockerrno,
+ tos, ttl;
+ char ctrl[CMSG_SPACE(sizeof(struct timeval))];
+ char hnamebuf[MAXHOSTNAMELEN], snamebuf[MAXHOSTNAMELEN];
+#ifdef IP_OPTIONS
+ char rspace[MAX_IPOPTLEN]; /* record route space */
+#endif
+ unsigned char loop, mttl;
+#ifdef __rtems__
+ struct getopt_data getopt_reent;
+#define optarg getopt_reent.optarg
+#define optind getopt_reent.optind
+#define opterr getopt.reent.opterr
+#define optopt getopt.reent.optopt
+#endif
+
+ payload = source = NULL;
+#ifdef IPSEC_POLICY_IPSEC
+ policy_in = policy_out = NULL;
+#endif
+
+ /*
+ * Do the stuff that we need root priv's for *first*, and
+ * then drop our setuid bit. Save error reporting for
+ * after arg parsing.
+ */
+ s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
+ sockerrno = errno;
+
+ setuid(getuid());
+ uid = getuid();
+
+ alarmtimeout = df = preload = tos = 0;
+
+ outpack = outpackhdr + sizeof(struct ip);
+#ifdef __rtems__
+ memset(&getopt_reent, 0, sizeof(getopt_data));
+ while ((ch = getopt_r(argc, argv,
+#else
+ while ((ch = getopt(argc, argv,
+#endif
+ "Aac:DdfG:g:h:I:i:Ll:M:m:nop:QqRrS:s:T:t:vW:z:"
+#ifdef IPSEC
+#ifdef IPSEC_POLICY_IPSEC
+ "P:"
+#endif /*IPSEC_POLICY_IPSEC*/
+#endif /*IPSEC*/
+#ifdef __rtems__
+ , &getopt_reent
+#endif
+ )) != -1)
+ {
+ switch(ch) {
+ case 'A':
+ options_ |= F_MISSED;
+ break;
+ case 'a':
+ options_ |= F_AUDIBLE;
+ break;
+ case 'c':
+ ultmp = strtoul(optarg, &ep, 0);
+ if (*ep || ep == optarg || ultmp > LONG_MAX || !ultmp)
+ errx(&globals->exit_jmp, EX_USAGE,
+ "invalid count of packets to transmit: `%s'",
+ optarg);
+ npackets = ultmp;
+ break;
+ case 'D':
+ options_ |= F_HDRINCL;
+ df = 1;
+ break;
+ case 'd':
+ options_ |= F_SO_DEBUG;
+ break;
+ case 'f':
+ if (uid) {
+ errno = EPERM;
+ err(&globals->exit_jmp, EX_NOPERM, "-f flag");
+ }
+ options_ |= F_FLOOD;
+ setbuf(stdout, (char *)NULL);
+ break;
+ case 'G': /* Maximum packet size for ping sweep */
+ ultmp = strtoul(optarg, &ep, 0);
+ if (*ep || ep == optarg)
+ errx(&globals->exit_jmp, EX_USAGE, "invalid packet size: `%s'",
+ optarg);
+ if (uid != 0 && ultmp > DEFDATALEN) {
+ errno = EPERM;
+ err(&globals->exit_jmp, EX_NOPERM,
+ "packet size too large: %lu > %u",
+ ultmp, DEFDATALEN);
+ }
+ options_ |= F_SWEEP;
+ sweepmax = ultmp;
+ break;
+ case 'g': /* Minimum packet size for ping sweep */
+ ultmp = strtoul(optarg, &ep, 0);
+ if (*ep || ep == optarg)
+ errx(&globals->exit_jmp, EX_USAGE, "invalid packet size: `%s'",
+ optarg);
+ if (uid != 0 && ultmp > DEFDATALEN) {
+ errno = EPERM;
+ err(&globals->exit_jmp, EX_NOPERM,
+ "packet size too large: %lu > %u",
+ ultmp, DEFDATALEN);
+ }
+ options_ |= F_SWEEP;
+ sweepmin = ultmp;
+ break;
+ case 'h': /* Packet size increment for ping sweep */
+ ultmp = strtoul(optarg, &ep, 0);
+ if (*ep || ep == optarg || ultmp < 1)
+ errx(&globals->exit_jmp, EX_USAGE, "invalid increment size: `%s'",
+ optarg);
+ if (uid != 0 && ultmp > DEFDATALEN) {
+ errno = EPERM;
+ err(&globals->exit_jmp, EX_NOPERM,
+ "packet size too large: %lu > %u",
+ ultmp, DEFDATALEN);
+ }
+ options_ |= F_SWEEP;
+ sweepincr = ultmp;
+ break;
+ case 'I': /* multicast interface */
+ if (inet_aton(optarg, &ifaddr) == 0)
+ errx(&globals->exit_jmp, EX_USAGE,
+ "invalid multicast interface: `%s'",
+ optarg);
+ options_ |= F_MIF;
+ break;
+ case 'i': /* wait between sending packets */
+ t = strtod(optarg, &ep) * 1000.0;
+ if (*ep || ep == optarg || t > (double)INT_MAX)
+ errx(&globals->exit_jmp, EX_USAGE, "invalid timing interval: `%s'",
+ optarg);
+ options_ |= F_INTERVAL;
+ interval = (int)t;
+ if (uid && interval < 1000) {
+ errno = EPERM;
+ err(&globals->exit_jmp, EX_NOPERM, "-i interval too short");
+ }
+ break;
+ case 'L':
+ options_ |= F_NOLOOP;
+ loop = 0;
+ break;
+ case 'l':
+ ultmp = strtoul(optarg, &ep, 0);
+ if (*ep || ep == optarg || ultmp > INT_MAX)
+ errx(&globals->exit_jmp, EX_USAGE,
+ "invalid preload value: `%s'", optarg);
+ if (uid) {
+ errno = EPERM;
+ err(&globals->exit_jmp, EX_NOPERM, "-l flag");
+ }
+ preload = ultmp;
+ break;
+ case 'M':
+ switch(optarg[0]) {
+ case 'M':
+ case 'm':
+ options_ |= F_MASK;
+ break;
+ case 'T':
+ case 't':
+ options_ |= F_TIME;
+ break;
+ default:
+ errx(&globals->exit_jmp, EX_USAGE, "invalid message: `%c'", optarg[0]);
+ break;
+ }
+ break;
+ case 'm': /* TTL */
+ ultmp = strtoul(optarg, &ep, 0);
+ if (*ep || ep == optarg || ultmp > MAXTTL)
+ errx(&globals->exit_jmp, EX_USAGE, "invalid TTL: `%s'", optarg);
+ ttl = ultmp;
+ options_ |= F_TTL;
+ break;
+ case 'n':
+ options_ |= F_NUMERIC;
+ break;
+ case 'o':
+ options_ |= F_ONCE;
+ break;
+#ifdef IPSEC
+#ifdef IPSEC_POLICY_IPSEC
+ case 'P':
+ options_ |= F_POLICY;
+ if (!strncmp("in", optarg, 2))
+ policy_in = strdup(optarg);
+ else if (!strncmp("out", optarg, 3))
+ policy_out = strdup(optarg);
+ else
+ errx(&globals->exit_jmp, 1, "invalid security policy");
+ break;
+#endif /*IPSEC_POLICY_IPSEC*/
+#endif /*IPSEC*/
+ case 'p': /* fill buffer with user pattern */
+ options_ |= F_PINGFILLED;
+ payload = optarg;
+ break;
+ case 'Q':
+ options_ |= F_QUIET2;
+ break;
+ case 'q':
+ options_ |= F_QUIET;
+ break;
+ case 'R':
+ options_ |= F_RROUTE;
+ break;
+ case 'r':
+ options_ |= F_SO_DONTROUTE;
+ break;
+ case 'S':
+ source = optarg;
+ break;
+ case 's': /* size of packet to send */
+ ultmp = strtoul(optarg, &ep, 0);
+ if (*ep || ep == optarg)
+ errx(&globals->exit_jmp, EX_USAGE, "invalid packet size: `%s'",
+ optarg);
+ if (uid != 0 && ultmp > DEFDATALEN) {
+ errno = EPERM;
+ err(&globals->exit_jmp, EX_NOPERM,
+ "packet size too large: %lu > %u",
+ ultmp, DEFDATALEN);
+ }
+ datalen = ultmp;
+ break;
+ case 'T': /* multicast TTL */
+ ultmp = strtoul(optarg, &ep, 0);
+ if (*ep || ep == optarg || ultmp > MAXTTL)
+ errx(&globals->exit_jmp, EX_USAGE, "invalid multicast TTL: `%s'",
+ optarg);
+ mttl = ultmp;
+ options_ |= F_MTTL;
+ break;
+ case 't':
+ alarmtimeout = strtoul(optarg, &ep, 0);
+ if ((alarmtimeout < 1) || (alarmtimeout == ULONG_MAX))
+ errx(&globals->exit_jmp, EX_USAGE, "invalid timeout: `%s'",
+ optarg);
+ if (alarmtimeout > MAXALARM)
+ errx(&globals->exit_jmp, EX_USAGE, "invalid timeout: `%s' > %d",
+ optarg, MAXALARM);
+ alarm((int)alarmtimeout);
+ break;
+ case 'v':
+ options_ |= F_VERBOSE;
+ break;
+ case 'W': /* wait ms for answer */
+ t = strtod(optarg, &ep);
+ if (*ep || ep == optarg || t > (double)INT_MAX)
+ errx(&globals->exit_jmp, EX_USAGE, "invalid timing interval: `%s'",
+ optarg);
+ options_ |= F_WAITTIME;
+ waittime = (int)t;
+ break;
+ case 'z':
+ options_ |= F_HDRINCL;
+ ultmp = strtoul(optarg, &ep, 0);
+ if (*ep || ep == optarg || ultmp > MAXTOS)
+ errx(&globals->exit_jmp, EX_USAGE, "invalid TOS: `%s'", optarg);
+ tos = ultmp;
+ break;
+ default:
+ usage();
+
+ }
+ }
+
+ if (argc - optind != 1)
+ usage();
+
+ target = argv[optind];
+
+ switch (options_ & (F_MASK|F_TIME)) {
+ case 0: break;
+ case F_MASK:
+ icmp_type_ = ICMP_MASKREQ;
+ icmp_type_rsp = ICMP_MASKREPLY;
+ phdr_len = MASK_LEN;
+ if (!(options_ & F_QUIET))
+ (void)printf("ICMP_MASKREQ\n");
+ break;
+ case F_TIME:
+ icmp_type_ = ICMP_TSTAMP;
+ icmp_type_rsp = ICMP_TSTAMPREPLY;
+ phdr_len = TS_LEN;
+ if (!(options_ & F_QUIET))
+ (void)printf("ICMP_TSTAMP\n");
+ break;
+ default:
+ errx(&globals->exit_jmp, EX_USAGE, "ICMP_TSTAMP and ICMP_MASKREQ are exclusive.");
+ break;
+ }
+ icmp_len = sizeof(struct ip) + ICMP_MINLEN + phdr_len;
+ if (options_ & F_RROUTE)
+ icmp_len += MAX_IPOPTLEN;
+ maxpayload = IP_MAXPACKET - icmp_len;
+ if (datalen > maxpayload)
+ errx(&globals->exit_jmp, EX_USAGE, "packet size too large: %d > %d", datalen,
+ maxpayload);
+ send_len = icmp_len + datalen;
+ datap = &outpack[ICMP_MINLEN + phdr_len + TIMEVAL_LEN];
+ if (options_ & F_PINGFILLED) {
+ fill((char *)datap, payload);
+ }
+ if (source) {
+ bzero((char *)&sock_in, sizeof(sock_in));
+ sock_in.sin_family = AF_INET;
+ if (inet_aton(source, &sock_in.sin_addr) != 0) {
+ shostname = source;
+ } else {
+ hp = gethostbyname2(source, AF_INET);
+ if (!hp)
+ errx(&globals->exit_jmp, EX_NOHOST, "cannot resolve %s: %s",
+ source, hstrerror(h_errno));
+
+ sock_in.sin_len = sizeof sock_in;
+ if ((unsigned)hp->h_length > sizeof(sock_in.sin_addr) ||
+ hp->h_length < 0)
+ errx(&globals->exit_jmp, 1, "gethostbyname2: illegal address");
+ memcpy(&sock_in.sin_addr, hp->h_addr_list[0],
+ sizeof(sock_in.sin_addr));
+ (void)strncpy(snamebuf, hp->h_name,
+ sizeof(snamebuf) - 1);
+ snamebuf[sizeof(snamebuf) - 1] = '\0';
+ shostname = snamebuf;
+ }
+ if (bind(s, (struct sockaddr *)&sock_in, sizeof sock_in) == -1)
+ err(&globals->exit_jmp, 1, "bind");
+ }
+
+ bzero(&whereto, sizeof(whereto));
+ to = &whereto;
+ to->sin_family = AF_INET;
+ to->sin_len = sizeof *to;
+ if (inet_aton(target, &to->sin_addr) != 0) {
+ hostname = target;
+ } else {
+ hp = gethostbyname2(target, AF_INET);
+ if (!hp)
+ errx(&globals->exit_jmp, EX_NOHOST, "cannot resolve %s: %s",
+ target, hstrerror(h_errno));
+
+ if ((unsigned)hp->h_length > sizeof(to->sin_addr))
+ errx(&globals->exit_jmp, 1, "gethostbyname2 returned an illegal address");
+ memcpy(&to->sin_addr, hp->h_addr_list[0], sizeof to->sin_addr);
+ (void)strncpy(hnamebuf, hp->h_name, sizeof(hnamebuf) - 1);
+ hnamebuf[sizeof(hnamebuf) - 1] = '\0';
+ hostname = hnamebuf;
+ }
+
+ if (options_ & F_FLOOD && options_ & F_INTERVAL)
+ errx(&globals->exit_jmp, EX_USAGE, "-f and -i: incompatible options");
+
+ if (options_ & F_FLOOD && IN_MULTICAST(ntohl(to->sin_addr.s_addr)))
+ errx(&globals->exit_jmp, EX_USAGE,
+ "-f flag cannot be used with multicast destination");
+ if (options_ & (F_MIF | F_NOLOOP | F_MTTL)
+ && !IN_MULTICAST(ntohl(to->sin_addr.s_addr)))
+ errx(&globals->exit_jmp, EX_USAGE,
+ "-I, -L, -T flags cannot be used with unicast destination");
+
+ if (datalen >= TIMEVAL_LEN) /* can we time transfer */
+ timing = 1;
+
+ if (!(options_ & F_PINGFILLED))
+ for (i = TIMEVAL_LEN; i < datalen; ++i)
+ *datap++ = i;
+
+ ident = getpid() & 0xFFFF;
+
+ if (s < 0) {
+ errno = sockerrno;
+ err(&globals->exit_jmp, EX_OSERR, "socket");
+ }
+ hold = 1;
+ if (options_ & F_SO_DEBUG)
+ (void)setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&hold,
+ sizeof(hold));
+ if (options_ & F_SO_DONTROUTE)
+ (void)setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *)&hold,
+ sizeof(hold));
+#ifdef IPSEC
+#ifdef IPSEC_POLICY_IPSEC
+ if (options_ & F_POLICY) {
+ char *buf;
+ if (policy_in != NULL) {
+ buf = ipsec_set_policy(policy_in, strlen(policy_in));
+ if (buf == NULL)
+ errx(&globals->exit_jmp, EX_CONFIG, "%s", ipsec_strerror());
+ if (setsockopt(s, IPPROTO_IP, IP_IPSEC_POLICY,
+ buf, ipsec_get_policylen(buf)) < 0)
+ err(EX_CONFIG,
+ "ipsec policy cannot be configured");
+ free(buf);
+ }
+
+ if (policy_out != NULL) {
+ buf = ipsec_set_policy(policy_out, strlen(policy_out));
+ if (buf == NULL)
+ errx(&globals->exit_jmp, EX_CONFIG, "%s", ipsec_strerror());
+ if (setsockopt(s, IPPROTO_IP, IP_IPSEC_POLICY,
+ buf, ipsec_get_policylen(buf)) < 0)
+ err(EX_CONFIG,
+ "ipsec policy cannot be configured");
+ free(buf);
+ }
+ }
+#endif /*IPSEC_POLICY_IPSEC*/
+#endif /*IPSEC*/
+
+ if (options_ & F_HDRINCL) {
+ ip = (struct ip*)outpackhdr;
+ if (!(options_ & (F_TTL | F_MTTL))) {
+ mib[0] = CTL_NET;
+ mib[1] = PF_INET;
+ mib[2] = IPPROTO_IP;
+ mib[3] = IPCTL_DEFTTL;
+ sz = sizeof(ttl);
+ if (sysctl(mib, 4, &ttl, &sz, NULL, 0) == -1)
+ err(&globals->exit_jmp, 1, "sysctl(net.inet.ip.ttl)");
+ }
+ setsockopt(s, IPPROTO_IP, IP_HDRINCL, &hold, sizeof(hold));
+ ip->ip_v = IPVERSION;
+ ip->ip_hl = sizeof(struct ip) >> 2;
+ ip->ip_tos = tos;
+ ip->ip_id = 0;
+ ip->ip_off = df ? IP_DF : 0;
+ ip->ip_ttl = ttl;
+ ip->ip_p = IPPROTO_ICMP;
+ ip->ip_src.s_addr = source ? sock_in.sin_addr.s_addr : INADDR_ANY;
+ ip->ip_dst = to->sin_addr;
+ }
+ /* record route option */
+ if (options_ & F_RROUTE) {
+#ifdef IP_OPTIONS
+ bzero(rspace, sizeof(rspace));
+ rspace[IPOPT_OPTVAL] = IPOPT_RR;
+ rspace[IPOPT_OLEN] = sizeof(rspace) - 1;
+ rspace[IPOPT_OFFSET] = IPOPT_MINOFF;
+ rspace[sizeof(rspace) - 1] = IPOPT_EOL;
+ if (setsockopt(s, IPPROTO_IP, IP_OPTIONS, rspace,
+ sizeof(rspace)) < 0)
+ err(&globals->exit_jmp, EX_OSERR, "setsockopt IP_OPTIONS");
+#else
+ errx(&globals->exit_jmp, EX_UNAVAILABLE,
+ "record route not available in this implementation");
+#endif /* IP_OPTIONS */
+ }
+
+ if (options_ & F_TTL) {
+ if (setsockopt(s, IPPROTO_IP, IP_TTL, &ttl,
+ sizeof(ttl)) < 0) {
+ err(&globals->exit_jmp, EX_OSERR, "setsockopt IP_TTL");
+ }
+ }
+ if (options_ & F_NOLOOP) {
+ if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, &loop,
+ sizeof(loop)) < 0) {
+ err(&globals->exit_jmp, EX_OSERR, "setsockopt IP_MULTICAST_LOOP");
+ }
+ }
+ if (options_ & F_MTTL) {
+ if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, &mttl,
+ sizeof(mttl)) < 0) {
+ err(&globals->exit_jmp, EX_OSERR, "setsockopt IP_MULTICAST_TTL");
+ }
+ }
+ if (options_ & F_MIF) {
+ if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, &ifaddr,
+ sizeof(ifaddr)) < 0) {
+ err(&globals->exit_jmp, EX_OSERR, "setsockopt IP_MULTICAST_IF");
+ }
+ }
+#ifdef SO_TIMESTAMP
+ { int on = 1;
+ if (setsockopt(s, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on)) < 0)
+ err(&globals->exit_jmp, EX_OSERR, "setsockopt SO_TIMESTAMP");
+ }
+#endif
+ if (sweepmax) {
+ if (sweepmin >= sweepmax)
+ errx(&globals->exit_jmp, EX_USAGE, "Maximum packet size must be greater than the minimum packet size");
+
+ if (datalen != DEFDATALEN)
+ errx(&globals->exit_jmp, EX_USAGE, "Packet size and ping sweep are mutually exclusive");
+
+ if (npackets > 0) {
+ snpackets = npackets;
+ npackets = 0;
+ } else
+ snpackets = 1;
+ datalen = sweepmin;
+ send_len = icmp_len + sweepmin;
+ }
+ if (options_ & F_SWEEP && !sweepmax)
+ errx(&globals->exit_jmp, EX_USAGE, "Maximum sweep size must be specified");
+
+ /*
+ * When pinging the broadcast address, you can get a lot of answers.
+ * Doing something so evil is useful if you are trying to stress the
+ * ethernet, or just want to fill the arp cache to get some stuff for
+ * /etc/ethers. But beware: RFC 1122 allows hosts to ignore broadcast
+ * or multicast pings if they wish.
+ */
+
+ /*
+ * XXX receive buffer needs undetermined space for mbuf overhead
+ * as well.
+ */
+ hold = IP_MAXPACKET + 128;
+ (void)setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&hold,
+ sizeof(hold));
+ if (uid == 0)
+ (void)setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&hold,
+ sizeof(hold));
+
+ if (to->sin_family == AF_INET) {
+ (void)printf("PING %s (%s)", hostname,
+ inet_ntoa(to->sin_addr));
+ if (source)
+ (void)printf(" from %s", shostname);
+ if (sweepmax)
+ (void)printf(": (%d ... %d) data bytes\n",
+ sweepmin, sweepmax);
+ else
+ (void)printf(": %d data bytes\n", datalen);
+
+ } else {
+ if (sweepmax)
+ (void)printf("PING %s: (%d ... %d) data bytes\n",
+ hostname, sweepmin, sweepmax);
+ else
+ (void)printf("PING %s: %d data bytes\n", hostname, datalen);
+ }
+
+ /*
+ * Use sigaction() instead of signal() to get unambiguous semantics,
+ * in particular with SA_RESTART not set.
+ */
+
+ sigemptyset(&si_sa.sa_mask);
+ si_sa.sa_flags = 0;
+
+ si_sa.sa_handler = stopit;
+ if (sigaction(SIGINT, &si_sa, 0) == -1) {
+ err(&globals->exit_jmp, EX_OSERR, "sigaction SIGINT");
+ }
+
+#ifdef SIGINFO
+ si_sa.sa_handler = status;
+ if (sigaction(SIGINFO, &si_sa, 0) == -1) {
+ err(EX_OSERR, "sigaction");
+ }
+#endif
+
+ if (alarmtimeout > 0) {
+ si_sa.sa_handler = stopit;
+ if (sigaction(SIGALRM, &si_sa, 0) == -1)
+ err(&globals->exit_jmp, EX_OSERR, "sigaction SIGALRM");
+ }
+
+ bzero(&msg, sizeof(msg));
+ msg.msg_name = (caddr_t)&from;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+#ifdef SO_TIMESTAMP
+ msg.msg_control = (caddr_t)ctrl;
+#endif
+ iov.iov_base = packet_;
+ iov.iov_len = IP_MAXPACKET;
+
+ if (preload == 0)
+ pinger(); /* send the first ping */
+ else {
+ if (npackets != 0 && preload > npackets)
+ preload = npackets;
+ while (preload--) /* fire off them quickies */
+ pinger();
+ }
+ (void)gettimeofday(&last, NULL);
+
+ if (options_ & F_FLOOD) {
+ intvl.tv_sec = 0;
+ intvl.tv_usec = 10000;
+ } else {
+ intvl.tv_sec = interval / 1000;
+ intvl.tv_usec = interval % 1000 * 1000;
+ }
+
+ almost_done = 0;
+ while (!finish_up) {
+ struct timeval now, timeout;
+ fd_set rfds;
+ int cc, n;
+
+ check_status();
+ if ((unsigned)s >= FD_SETSIZE)
+ errx(&globals->exit_jmp, EX_OSERR, "descriptor too large");
+ FD_ZERO(&rfds);
+ FD_SET(s, &rfds);
+ (void)gettimeofday(&now, NULL);
+ timeout.tv_sec = last.tv_sec + intvl.tv_sec - now.tv_sec;
+ timeout.tv_usec = last.tv_usec + intvl.tv_usec - now.tv_usec;
+ while (timeout.tv_usec < 0) {
+ timeout.tv_usec += 1000000;
+ timeout.tv_sec--;
+ }
+ while (timeout.tv_usec >= 1000000) {
+ timeout.tv_usec -= 1000000;
+ timeout.tv_sec++;
+ }
+ if (timeout.tv_sec < 0)
+ timeout.tv_sec = timeout.tv_usec = 0;
+ n = select(s + 1, &rfds, NULL, NULL, &timeout);
+ if (n < 0)
+ continue; /* Must be EINTR. */
+ if (n == 1) {
+ struct timeval *tv = NULL;
+#ifdef SO_TIMESTAMP
+ struct cmsghdr *cmsg = (struct cmsghdr *)&ctrl;
+
+ msg.msg_controllen = sizeof(ctrl);
+#endif
+
+ bzero(&msg, sizeof(msg));
+ msg.msg_name = (caddr_t)&from;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+#ifdef SO_TIMESTAMP
+ msg.msg_control = (caddr_t)ctrl;
+#endif
+ iov.iov_base = packet_;
+ iov.iov_len = IP_MAXPACKET;
+
+ msg.msg_namelen = sizeof(from);
+ if ((cc = recvmsg(s, &msg, 0)) < 0) {
+ if (errno == EINTR)
+ continue;
+ warn("recvmsg");
+ continue;
+ }
+#ifdef SO_TIMESTAMP
+ if (cmsg->cmsg_level == SOL_SOCKET &&
+ cmsg->cmsg_type == SCM_TIMESTAMP &&
+ cmsg->cmsg_len == CMSG_LEN(sizeof *tv)) {
+ /* Copy to avoid alignment problems: */
+ memcpy(&now, CMSG_DATA(cmsg), sizeof(now));
+ tv = &now;
+ }
+#endif
+ if (tv == NULL) {
+ (void)gettimeofday(&now, NULL);
+ tv = &now;
+ }
+ pr_pack((char *)packet_, cc, &from, tv);
+ if ((options_ & F_ONCE && nreceived) ||
+ (npackets && nreceived >= npackets))
+ break;
+ }
+ if (n == 0 || options_ & F_FLOOD) {
+ if (sweepmax && sntransmitted == snpackets) {
+ for (i = 0; i < sweepincr ; ++i)
+ *datap++ = i;
+ datalen += sweepincr;
+ if (datalen > sweepmax)
+ break;
+ send_len = icmp_len + datalen;
+ sntransmitted = 0;
+ }
+ if (!npackets || ntransmitted < npackets)
+ pinger();
+ else {
+ if (almost_done)
+ break;
+ almost_done = 1;
+ intvl.tv_usec = 0;
+ if (nreceived) {
+ intvl.tv_sec = 2 * tmax / 1000;
+ if (!intvl.tv_sec)
+ intvl.tv_sec = 1;
+ } else {
+ intvl.tv_sec = waittime / 1000;
+ intvl.tv_usec = waittime % 1000 * 1000;
+ }
+ }
+ (void)gettimeofday(&last, NULL);
+ if (ntransmitted - nreceived - 1 > nmissedmax) {
+ nmissedmax = ntransmitted - nreceived - 1;
+ if (options_ & F_MISSED)
+ (void)write(STDOUT_FILENO, &BBELL, 1);
+ }
+ }
+ }
+ finish();
+#ifdef __rtems__
+ /* RTEMS shell programs return -- they do not exit */
+ if (nreceived)
+ return(0);
+ else
+ return(2);
+#endif
+ /* NOTREACHED */
+ exit(0); /* Make the compiler happy */
+}
+
+/*
+ * stopit --
+ * Set the global bit that causes the main loop to quit.
+ * Do NOT call finish() from here, since finish() does far too much
+ * to be called from a signal handler.
+ */
+void
+stopit(sig)
+ int sig __unused;
+{
+#if !__rtems__
+ /*
+ * When doing reverse DNS lookups, the finish_up flag might not
+ * be noticed for a while. Just exit if we get a second SIGINT.
+ */
+ if (!(options_ & F_NUMERIC) && finish_up)
+ _exit(nreceived ? 0 : 2);
+ finish_up = 1;
+#endif
+}
+
+/*
+ * pinger --
+ * Compose and transmit an ICMP ECHO REQUEST packet. The IP packet
+ * will be added on by the kernel. The ID field is our UNIX process ID,
+ * and the sequence number is an ascending integer. The first TIMEVAL_LEN
+ * bytes of the data portion are used to hold a UNIX "timeval" struct in
+ * host byte-order, to compute the round-trip time.
+ */
+static void
+g_pinger(globals)
+ rtems_shell_globals_t* globals;
+{
+ struct timeval now;
+ struct tv32 tv32;
+ struct ip *ip;
+ struct icmp *icp;
+ int cc, i;
+ u_char *packet;
+
+ packet = outpack;
+ icp = (struct icmp *)outpack;
+ icp->icmp_type = icmp_type_;
+ icp->icmp_code = 0;
+ icp->icmp_cksum = 0;
+ icp->icmp_seq = htons(ntransmitted);
+ icp->icmp_id = ident; /* ID */
+
+ CLR(ntransmitted % mx_dup_ck);
+
+ if ((options_ & F_TIME) || timing) {
+ (void)gettimeofday(&now, NULL);
+
+ tv32.tv32_sec = htonl(now.tv_sec);
+ tv32.tv32_usec = htonl(now.tv_usec);
+ if (options_ & F_TIME)
+ icp->icmp_otime = htonl((now.tv_sec % (24*60*60))
+ * 1000 + now.tv_usec / 1000);
+ if (timing)
+ bcopy((void *)&tv32,
+ (void *)&outpack[ICMP_MINLEN + phdr_len],
+ sizeof(tv32));
+ }
+
+ cc = ICMP_MINLEN + phdr_len + datalen;
+
+ /* compute ICMP checksum here */
+ icp->icmp_cksum = in_cksum((u_short *)icp, cc);
+
+ if (options_ & F_HDRINCL) {
+ cc += sizeof(struct ip);
+ ip = (struct ip *)outpackhdr;
+ ip->ip_len = cc;
+ ip->ip_sum = in_cksum((u_short *)outpackhdr, cc);
+ packet = outpackhdr;
+ }
+ i = sendto(s, (char *)packet, cc, 0, (struct sockaddr *)&whereto,
+ sizeof(whereto));
+
+ if (i < 0 || i != cc) {
+ if (i < 0) {
+ if (options_ & F_FLOOD && errno == ENOBUFS) {
+ usleep(FLOOD_BACKOFF);
+ return;
+ }
+ warn("sendto");
+ } else {
+ warn("%s: partial write: %d of %d bytes",
+ hostname, i, cc);
+ }
+ }
+ ntransmitted++;
+ sntransmitted++;
+ if (!(options_ & F_QUIET) && options_ & F_FLOOD)
+ (void)write(STDOUT_FILENO, &DOT, 1);
+}
+
+/*
+ * pr_pack --
+ * Print out the packet, if it came from us. This logic is necessary
+ * because ALL readers of the ICMP socket get a copy of ALL ICMP packets
+ * which arrive ('tis only fair). This permits multiple copies of this
+ * program to be run without having intermingled output (or statistics!).
+ */
+static void
+g_pr_pack(buf, cc, from, tv, globals)
+ char *buf;
+ int cc;
+ struct sockaddr_in *from;
+ struct timeval *tv;
+ rtems_shell_globals_t* globals;
+{
+ struct in_addr ina;
+ u_char *cp, *dp;
+ struct icmp *icp;
+ struct ip *ip;
+ const void *tp;
+ double triptime;
+ int dupflag, hlen, i, j, recv_len, seq;
+#if !__rtems__
+ static int old_rrlen;
+ static char old_rr[MAX_IPOPTLEN];
+#endif
+
+ /* Check the IP header */
+ ip = (struct ip *)buf;
+ hlen = ip->ip_hl << 2;
+ recv_len = cc;
+ if (cc < hlen + ICMP_MINLEN) {
+ if (options_ & F_VERBOSE)
+ warn("packet too short (%d bytes) from %s", cc,
+ inet_ntoa(from->sin_addr));
+ return;
+ }
+
+ /* Now the ICMP part */
+ cc -= hlen;
+ icp = (struct icmp *)(buf + hlen);
+ if (icp->icmp_type == icmp_type_rsp) {
+ if (icp->icmp_id != ident)
+ return; /* 'Twas not our ECHO */
+ ++nreceived;
+ triptime = 0.0;
+ if (timing) {
+ struct timeval tv1;
+ struct tv32 tv32;
+#ifndef icmp_data
+ tp = &icp->icmp_ip;
+#else
+ tp = icp->icmp_data;
+#endif
+ tp = (const char *)tp + phdr_len;
+
+ if (cc - ICMP_MINLEN - phdr_len >= (int) sizeof(tv1)) {
+ /* Copy to avoid alignment problems: */
+ memcpy(&tv32, tp, sizeof(tv32));
+ tv1.tv_sec = ntohl(tv32.tv32_sec);
+ tv1.tv_usec = ntohl(tv32.tv32_usec);
+ tvsub(tv, &tv1);
+ triptime = ((double)tv->tv_sec) * 1000.0 +
+ ((double)tv->tv_usec) / 1000.0;
+ tsum += triptime;
+ tsumsq += triptime * triptime;
+ if (triptime < tmin)
+ tmin = triptime;
+ if (triptime > tmax)
+ tmax = triptime;
+ } else
+ timing = 0;
+ }
+
+ seq = ntohs(icp->icmp_seq);
+
+ if (TST(seq % mx_dup_ck)) {
+ ++nrepeats;
+ --nreceived;
+ dupflag = 1;
+ } else {
+ SET(seq % mx_dup_ck);
+ dupflag = 0;
+ }
+
+ if (options_ & F_QUIET)
+ return;
+
+ if (options_ & F_WAITTIME && triptime > waittime) {
+ ++nrcvtimeout;
+ return;
+ }
+
+ if (options_ & F_FLOOD)
+ (void)write(STDOUT_FILENO, &BSPACE, 1);
+ else {
+ (void)printf("%d bytes from %s: icmp_seq=%u", cc,
+ inet_ntoa(*(struct in_addr *)&from->sin_addr.s_addr),
+ seq);
+ (void)printf(" ttl=%d", ip->ip_ttl);
+ if (timing)
+ (void)printf(" time=%.3f ms", triptime);
+ if (dupflag)
+ (void)printf(" (DUP!)");
+ if (options_ & F_AUDIBLE)
+ (void)write(STDOUT_FILENO, &BBELL, 1);
+ if (options_ & F_MASK) {
+ /* Just prentend this cast isn't ugly */
+ (void)printf(" mask=%s",
+ pr_addr(*(struct in_addr *)&(icp->icmp_mask)));
+ }
+ if (options_ & F_TIME) {
+ (void)printf(" tso=%s", pr_ntime(icp->icmp_otime));
+ (void)printf(" tsr=%s", pr_ntime(icp->icmp_rtime));
+ (void)printf(" tst=%s", pr_ntime(icp->icmp_ttime));
+ }
+ if (recv_len != send_len) {
+ (void)printf(
+ "\nwrong total length %d instead of %d",
+ recv_len, send_len);
+ }
+ /* check the data */
+ cp = (u_char*)&icp->icmp_data[phdr_len];
+ dp = &outpack[ICMP_MINLEN + phdr_len];
+ cc -= ICMP_MINLEN + phdr_len;
+ i = 0;
+ if (timing) { /* don't check variable timestamp */
+ cp += TIMEVAL_LEN;
+ dp += TIMEVAL_LEN;
+ cc -= TIMEVAL_LEN;
+ i += TIMEVAL_LEN;
+ }
+ for (; i < datalen && cc > 0; ++i, ++cp, ++dp, --cc) {
+ if (*cp != *dp) {
+ (void)printf("\nwrong data byte #%d should be 0x%x but was 0x%x",
+ i, *dp, *cp);
+ (void)printf("\ncp:");
+ cp = (u_char*)&icp->icmp_data[0];
+ for (i = 0; i < datalen; ++i, ++cp) {
+ if ((i % 16) == 8)
+ (void)printf("\n\t");
+ (void)printf("%2x ", *cp);
+ }
+ (void)printf("\ndp:");
+ cp = &outpack[ICMP_MINLEN];
+ for (i = 0; i < datalen; ++i, ++cp) {
+ if ((i % 16) == 8)
+ (void)printf("\n\t");
+ (void)printf("%2x ", *cp);
+ }
+ break;
+ }
+ }
+ }
+ } else {
+ /*
+ * We've got something other than an ECHOREPLY.
+ * See if it's a reply to something that we sent.
+ * We can compare IP destination, protocol,
+ * and ICMP type and ID.
+ *
+ * Only print all the error messages if we are running
+ * as root to avoid leaking information not normally
+ * available to those not running as root.
+ */
+#ifndef icmp_data
+ struct ip *oip = &icp->icmp_ip;
+#else
+ struct ip *oip = (struct ip *)icp->icmp_data;
+#endif
+ struct icmp *oicmp = (struct icmp *)(oip + 1);
+
+ if (((options_ & F_VERBOSE) && uid == 0) ||
+ (!(options_ & F_QUIET2) &&
+ (oip->ip_dst.s_addr == whereto.sin_addr.s_addr) &&
+ (oip->ip_p == IPPROTO_ICMP) &&
+ (oicmp->icmp_type == ICMP_ECHO) &&
+ (oicmp->icmp_id == ident))) {
+ (void)printf("%d bytes from %s: ", cc,
+ pr_addr(from->sin_addr));
+ pr_icmph(icp);
+ } else
+ return;
+ }
+
+ /* Display any IP options */
+ cp = (u_char *)buf + sizeof(struct ip);
+
+ for (; hlen > (int)sizeof(struct ip); --hlen, ++cp)
+ switch (*cp) {
+ case IPOPT_EOL:
+ hlen = 0;
+ break;
+ case IPOPT_LSRR:
+ case IPOPT_SSRR:
+ (void)printf(*cp == IPOPT_LSRR ?
+ "\nLSRR: " : "\nSSRR: ");
+ j = cp[IPOPT_OLEN] - IPOPT_MINOFF + 1;
+ hlen -= 2;
+ cp += 2;
+ if (j >= INADDR_LEN &&
+ j <= hlen - (int)sizeof(struct ip)) {
+ for (;;) {
+ bcopy(++cp, &ina.s_addr, INADDR_LEN);
+ if (ina.s_addr == 0)
+ (void)printf("\t0.0.0.0");
+ else
+ (void)printf("\t%s",
+ pr_addr(ina));
+ hlen -= INADDR_LEN;
+ cp += INADDR_LEN - 1;
+ j -= INADDR_LEN;
+ if (j < INADDR_LEN)
+ break;
+ (void)putchar('\n');
+ }
+ } else
+ (void)printf("\t(truncated route)\n");
+ break;
+ case IPOPT_RR:
+ j = cp[IPOPT_OLEN]; /* get length */
+ i = cp[IPOPT_OFFSET]; /* and pointer */
+ hlen -= 2;
+ cp += 2;
+ if (i > j)
+ i = j;
+ i = i - IPOPT_MINOFF + 1;
+ if (i < 0 || i > (hlen - (int)sizeof(struct ip))) {
+ old_rrlen = 0;
+ continue;
+ }
+ if (i == old_rrlen
+ && !bcmp((char *)cp, old_rr, i)
+ && !(options_ & F_FLOOD)) {
+ (void)printf("\t(same route)");
+ hlen -= i;
+ cp += i;
+ break;
+ }
+ old_rrlen = i;
+ bcopy((char *)cp, old_rr, i);
+ (void)printf("\nRR: ");
+ if (i >= INADDR_LEN &&
+ i <= hlen - (int)sizeof(struct ip)) {
+ for (;;) {
+ bcopy(++cp, &ina.s_addr, INADDR_LEN);
+ if (ina.s_addr == 0)
+ (void)printf("\t0.0.0.0");
+ else
+ (void)printf("\t%s",
+ pr_addr(ina));
+ hlen -= INADDR_LEN;
+ cp += INADDR_LEN - 1;
+ i -= INADDR_LEN;
+ if (i < INADDR_LEN)
+ break;
+ (void)putchar('\n');
+ }
+ } else
+ (void)printf("\t(truncated route)");
+ break;
+ case IPOPT_NOP:
+ (void)printf("\nNOP");
+ break;
+ default:
+ (void)printf("\nunknown option %x", *cp);
+ break;
+ }
+ if (!(options_ & F_FLOOD)) {
+ (void)putchar('\n');
+ (void)fflush(stdout);
+ }
+}
+
+/*
+ * in_cksum --
+ * Checksum routine for Internet Protocol family headers (C Version)
+ */
+u_short
+in_cksum(addr, len)
+ u_short *addr;
+ int len;
+{
+ int nleft, sum;
+ u_short *w;
+ union {
+ u_short us;
+ u_char uc[2];
+ } last;
+ u_short answer;
+
+ nleft = len;
+ sum = 0;
+ w = addr;
+
+ /*
+ * Our algorithm is simple, using a 32 bit accumulator (sum), we add
+ * sequential 16 bit words to it, and at the end, fold back all the
+ * carry bits from the top 16 bits into the lower 16 bits.
+ */
+ while (nleft > 1) {
+ sum += *w++;
+ nleft -= 2;
+ }
+
+ /* mop up an odd byte, if necessary */
+ if (nleft == 1) {
+ last.uc[0] = *(u_char *)w;
+ last.uc[1] = 0;
+ sum += last.us;
+ }
+
+ /* add back carry outs from top 16 bits to low 16 bits */
+ sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
+ sum += (sum >> 16); /* add carry */
+ answer = ~sum; /* truncate to 16 bits */
+ return(answer);
+}
+
+/*
+ * tvsub --
+ * Subtract 2 timeval structs: out = out - in. Out is assumed to
+ * be >= in.
+ */
+static void
+tvsub(out, in)
+ struct timeval *out, *in;
+{
+
+ if ((out->tv_usec -= in->tv_usec) < 0) {
+ --out->tv_sec;
+ out->tv_usec += 1000000;
+ }
+ out->tv_sec -= in->tv_sec;
+}
+
+/*
+ * status --
+ * Print out statistics when SIGINFO is received.
+ */
+
+#if !defined(__rtems__)
+static void
+status(sig)
+ int sig __unused;
+{
+ siginfo_p = 1;
+}
+#endif
+
+static void
+g_check_status(globals)
+ rtems_shell_globals_t* globals;
+{
+ if (siginfo_p) {
+ siginfo_p = 0;
+ (void)fprintf(stderr, "\r%ld/%ld packets received (%.1f%%)",
+ nreceived, ntransmitted,
+ ntransmitted ? nreceived * 100.0 / ntransmitted : 0.0);
+ if (nreceived && timing)
+ (void)fprintf(stderr, " %.3f min / %.3f avg / %.3f max",
+ tmin, tsum / (nreceived + nrepeats), tmax);
+ (void)fprintf(stderr, "\n");
+ }
+}
+
+/*
+ * finish --
+ * Print out statistics, and give up.
+ */
+static void
+g_finish(globals)
+ rtems_shell_globals_t* globals;
+{
+
+ (void)signal(SIGINT, SIG_IGN);
+ (void)signal(SIGALRM, SIG_IGN);
+ (void)putchar('\n');
+ (void)fflush(stdout);
+ (void)printf("--- %s ping statistics ---\n", hostname);
+ (void)printf("%ld packets transmitted, ", ntransmitted);
+ (void)printf("%ld packets received, ", nreceived);
+ if (nrepeats)
+ (void)printf("+%ld duplicates, ", nrepeats);
+ if (ntransmitted) {
+ if (nreceived > ntransmitted)
+ (void)printf("-- somebody's printing up packets!");
+ else
+ (void)printf("%.1f%% packet loss",
+ ((ntransmitted - nreceived) * 100.0) /
+ ntransmitted);
+ }
+ if (nrcvtimeout)
+ (void)printf(", %ld packets out of wait time", nrcvtimeout);
+ (void)putchar('\n');
+ if (nreceived && timing) {
+ double n = nreceived + nrepeats;
+ double avg = tsum / n;
+#if defined(__rtems__)
+ (void) printf(
+ "round-trip min/avg/max/stddev = %.3f/%.3f/%.3f ms\n",
+ tmin, avg, tmax);
+#else
+ double vari = tsumsq / n - avg * avg;
+ (void)printf(
+ "round-trip min/avg/max/stddev = %.3f/%.3f/%.3f/%.3f ms\n",
+ tmin, avg, tmax, sqrt(vari));
+#endif
+ }
+ if (nreceived)
+ exit(0);
+ else
+ exit(2);
+ while (1);
+}
+
+#ifdef notdef
+static char *ttab[] = {
+ "Echo Reply", /* ip + seq + udata */
+ "Dest Unreachable", /* net, host, proto, port, frag, sr + IP */
+ "Source Quench", /* IP */
+ "Redirect", /* redirect type, gateway, + IP */
+ "Echo",
+ "Time Exceeded", /* transit, frag reassem + IP */
+ "Parameter Problem", /* pointer + IP */
+ "Timestamp", /* id + seq + three timestamps */
+ "Timestamp Reply", /* " */
+ "Info Request", /* id + sq */
+ "Info Reply" /* " */
+};
+#endif
+
+/*
+ * pr_icmph --
+ * Print a descriptive string about an ICMP header.
+ */
+static void
+pr_icmph(icp)
+ struct icmp *icp;
+{
+
+ switch(icp->icmp_type) {
+ case ICMP_ECHOREPLY:
+ (void)printf("Echo Reply\n");
+ /* XXX ID + Seq + Data */
+ break;
+ case ICMP_UNREACH:
+ switch(icp->icmp_code) {
+ case ICMP_UNREACH_NET:
+ (void)printf("Destination Net Unreachable\n");
+ break;
+ case ICMP_UNREACH_HOST:
+ (void)printf("Destination Host Unreachable\n");
+ break;
+ case ICMP_UNREACH_PROTOCOL:
+ (void)printf("Destination Protocol Unreachable\n");
+ break;
+ case ICMP_UNREACH_PORT:
+ (void)printf("Destination Port Unreachable\n");
+ break;
+ case ICMP_UNREACH_NEEDFRAG:
+ (void)printf("frag needed and DF set (MTU %d)\n",
+ ntohs(icp->icmp_nextmtu));
+ break;
+ case ICMP_UNREACH_SRCFAIL:
+ (void)printf("Source Route Failed\n");
+ break;
+ case ICMP_UNREACH_FILTER_PROHIB:
+ (void)printf("Communication prohibited by filter\n");
+ break;
+ default:
+ (void)printf("Dest Unreachable, Bad Code: %d\n",
+ icp->icmp_code);
+ break;
+ }
+ /* Print returned IP header information */
+#ifndef icmp_data
+ pr_retip(&icp->icmp_ip);
+#else
+ pr_retip((struct ip *)icp->icmp_data);
+#endif
+ break;
+ case ICMP_SOURCEQUENCH:
+ (void)printf("Source Quench\n");
+#ifndef icmp_data
+ pr_retip(&icp->icmp_ip);
+#else
+ pr_retip((struct ip *)icp->icmp_data);
+#endif
+ break;
+ case ICMP_REDIRECT:
+ switch(icp->icmp_code) {
+ case ICMP_REDIRECT_NET:
+ (void)printf("Redirect Network");
+ break;
+ case ICMP_REDIRECT_HOST:
+ (void)printf("Redirect Host");
+ break;
+ case ICMP_REDIRECT_TOSNET:
+ (void)printf("Redirect Type of Service and Network");
+ break;
+ case ICMP_REDIRECT_TOSHOST:
+ (void)printf("Redirect Type of Service and Host");
+ break;
+ default:
+ (void)printf("Redirect, Bad Code: %d", icp->icmp_code);
+ break;
+ }
+ (void)printf("(New addr: %s)\n", inet_ntoa(icp->icmp_gwaddr));
+#ifndef icmp_data
+ pr_retip(&icp->icmp_ip);
+#else
+ pr_retip((struct ip *)icp->icmp_data);
+#endif
+ break;
+ case ICMP_ECHO:
+ (void)printf("Echo Request\n");
+ /* XXX ID + Seq + Data */
+ break;
+ case ICMP_TIMXCEED:
+ switch(icp->icmp_code) {
+ case ICMP_TIMXCEED_INTRANS:
+ (void)printf("Time to live exceeded\n");
+ break;
+ case ICMP_TIMXCEED_REASS:
+ (void)printf("Frag reassembly time exceeded\n");
+ break;
+ default:
+ (void)printf("Time exceeded, Bad Code: %d\n",
+ icp->icmp_code);
+ break;
+ }
+#ifndef icmp_data
+ pr_retip(&icp->icmp_ip);
+#else
+ pr_retip((struct ip *)icp->icmp_data);
+#endif
+ break;
+ case ICMP_PARAMPROB:
+ (void)printf("Parameter problem: pointer = 0x%02x\n",
+ icp->icmp_hun.ih_pptr);
+#ifndef icmp_data
+ pr_retip(&icp->icmp_ip);
+#else
+ pr_retip((struct ip *)icp->icmp_data);
+#endif
+ break;
+ case ICMP_TSTAMP:
+ (void)printf("Timestamp\n");
+ /* XXX ID + Seq + 3 timestamps */
+ break;
+ case ICMP_TSTAMPREPLY:
+ (void)printf("Timestamp Reply\n");
+ /* XXX ID + Seq + 3 timestamps */
+ break;
+ case ICMP_IREQ:
+ (void)printf("Information Request\n");
+ /* XXX ID + Seq */
+ break;
+ case ICMP_IREQREPLY:
+ (void)printf("Information Reply\n");
+ /* XXX ID + Seq */
+ break;
+ case ICMP_MASKREQ:
+ (void)printf("Address Mask Request\n");
+ break;
+ case ICMP_MASKREPLY:
+ (void)printf("Address Mask Reply\n");
+ break;
+ case ICMP_ROUTERADVERT:
+ (void)printf("Router Advertisement\n");
+ break;
+ case ICMP_ROUTERSOLICIT:
+ (void)printf("Router Solicitation\n");
+ break;
+ default:
+ (void)printf("Bad ICMP type: %d\n", icp->icmp_type);
+ }
+}
+
+/*
+ * pr_iph --
+ * Print an IP header with options.
+ */
+static void
+pr_iph(ip)
+ struct ip *ip;
+{
+ u_char *cp;
+ int hlen;
+
+ hlen = ip->ip_hl << 2;
+ cp = (u_char *)ip + 20; /* point to options */
+
+ (void)printf("Vr HL TOS Len ID Flg off TTL Pro cks Src Dst\n");
+ (void)printf(" %1x %1x %02x %04x %04x",
+ ip->ip_v, ip->ip_hl, ip->ip_tos, ntohs(ip->ip_len),
+ ntohs(ip->ip_id));
+ (void)printf(" %1lx %04lx",
+ (u_long) (ntohl(ip->ip_off) & 0xe000) >> 13,
+ (u_long) ntohl(ip->ip_off) & 0x1fff);
+ (void)printf(" %02x %02x %04x", ip->ip_ttl, ip->ip_p,
+ ntohs(ip->ip_sum));
+ (void)printf(" %s ", inet_ntoa(*(struct in_addr *)&ip->ip_src.s_addr));
+ (void)printf(" %s ", inet_ntoa(*(struct in_addr *)&ip->ip_dst.s_addr));
+ /* dump any option bytes */
+ while (hlen-- > 20) {
+ (void)printf("%02x", *cp++);
+ }
+ (void)putchar('\n');
+}
+
+/*
+ * pr_addr --
+ * Return an ascii host address as a dotted quad and optionally with
+ * a hostname.
+ */
+static char *
+g_pr_addr(ina, globals)
+ struct in_addr ina;
+ rtems_shell_globals_t* globals;
+{
+ struct hostent *hp;
+ static char buf[16 + 3 + MAXHOSTNAMELEN];
+
+ if ((options_ & F_NUMERIC) ||
+ !(hp = gethostbyaddr((char *)&ina, 4, AF_INET)))
+ return inet_ntoa(ina);
+ else
+ (void)snprintf(buf, sizeof(buf), "%s (%s)", hp->h_name,
+ inet_ntoa(ina));
+ return(buf);
+}
+
+/*
+ * pr_retip --
+ * Dump some info on a returned (via ICMP) IP packet.
+ */
+static void
+pr_retip(ip)
+ struct ip *ip;
+{
+ u_char *cp;
+ int hlen;
+
+ pr_iph(ip);
+ hlen = ip->ip_hl << 2;
+ cp = (u_char *)ip + hlen;
+
+ if (ip->ip_p == 6)
+ (void)printf("TCP: from port %u, to port %u (decimal)\n",
+ (*cp * 256 + *(cp + 1)), (*(cp + 2) * 256 + *(cp + 3)));
+ else if (ip->ip_p == 17)
+ (void)printf("UDP: from port %u, to port %u (decimal)\n",
+ (*cp * 256 + *(cp + 1)), (*(cp + 2) * 256 + *(cp + 3)));
+}
+
+static char *
+pr_ntime (n_time timestamp)
+{
+ static char buf[10];
+ int hour, min, sec;
+
+ sec = ntohl(timestamp) / 1000;
+ hour = sec / 60 / 60;
+ min = (sec % (60 * 60)) / 60;
+ sec = (sec % (60 * 60)) % 60;
+
+ (void)snprintf(buf, sizeof(buf), "%02d:%02d:%02d", hour, min, sec);
+
+ return (buf);
+}
+
+static void
+g_fill(bp, patp, globals)
+ char *bp, *patp;
+ rtems_shell_globals_t* globals;
+{
+ char *cp;
+ int pat[16];
+ u_int ii, jj, kk;
+
+ for (cp = patp; *cp; cp++) {
+ if (!isxdigit((int)*cp))
+ errx(&globals->exit_jmp, EX_USAGE,
+ "patterns must be specified as hex digits");
+
+ }
+ ii = sscanf(patp,
+ "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
+ &pat[0], &pat[1], &pat[2], &pat[3], &pat[4], &pat[5], &pat[6],
+ &pat[7], &pat[8], &pat[9], &pat[10], &pat[11], &pat[12],
+ &pat[13], &pat[14], &pat[15]);
+
+ if (ii > 0)
+ for (kk = 0; kk <= maxpayload - (TIMEVAL_LEN + ii); kk += ii)
+ for (jj = 0; jj < ii; ++jj)
+ bp[jj + kk] = pat[jj];
+ if (!(options_ & F_QUIET)) {
+ (void)printf("PATTERN: 0x");
+ for (jj = 0; jj < ii; ++jj)
+ (void)printf("%02x", bp[jj] & 0xFF);
+ (void)printf("\n");
+ }
+}
+
+#if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
+#define SECOPT " [-P policy]"
+#else
+#define SECOPT ""
+#endif
+static void
+g_usage(globals)
+ rtems_shell_globals_t* globals;
+{
+ (void)fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
+"usage: ping [-AaDdfnoQqRrv] [-c count] [-G sweepmaxsize] [-g sweepminsize]",
+" [-h sweepincrsize] [-i wait] [-l preload] [-M mask | time] [-m ttl]",
+" " SECOPT " [-p pattern] [-S src_addr] [-s packetsize] [-t timeout]",
+" [-W waittime] [-z tos] host",
+" ping [-AaDdfLnoQqRrv] [-c count] [-I iface] [-i wait] [-l preload]",
+" [-M mask | time] [-m ttl]" SECOPT " [-p pattern] [-S src_addr]",
+" [-s packetsize] [-T ttl] [-t timeout] [-W waittime]",
+" [-z tos] mcast-group");
+ exit(EX_USAGE);
+ while (1);
+}
+
+#if __rtems__
+ rtems_shell_cmd_t rtems_shell_PING_Command = {
+ "ping", /* name */
+ "ping [args]", /* usage */
+ "network", /* topic */
+ rtems_shell_main_ping, /* command */
+ NULL, /* alias */
+ NULL /* next */
+ };
+#endif
diff --git a/libmisc/main_route.c b/libmisc/main_route.c
new file mode 100644
index 0000000..3b322ca
--- /dev/null
+++ b/libmisc/main_route.c
@@ -0,0 +1,151 @@
+/*
+ * ROUTE Command Implmentation
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#include <netinet/in.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <net/route.h>
+
+#include <rtems.h>
+#include <rtems/rtems_bsdnet.h>
+#include <rtems/shell.h>
+#include "internal.h"
+
+static int rtems_shell_main_route(
+ int argc,
+ char *argv[]
+)
+{
+ int cmd;
+ struct sockaddr_in dst;
+ struct sockaddr_in gw;
+ struct sockaddr_in netmask;
+ int f_host;
+ int f_gw = 0;
+ int cur_idx;
+ int flags;
+ int rc;
+
+ memset(&dst, 0, sizeof(dst));
+ memset(&gw, 0, sizeof(gw));
+ memset(&netmask, 0, sizeof(netmask));
+
+ dst.sin_len = sizeof(dst);
+ dst.sin_family = AF_INET;
+ dst.sin_addr.s_addr = inet_addr("0.0.0.0");
+
+ gw.sin_len = sizeof(gw);
+ gw.sin_family = AF_INET;
+ gw.sin_addr.s_addr = inet_addr("0.0.0.0");
+
+ netmask.sin_len = sizeof(netmask);
+ netmask.sin_family = AF_INET;
+ netmask.sin_addr.s_addr = inet_addr("255.255.255.0");
+
+ if (argc < 2) {
+ rtems_bsdnet_show_inet_routes();
+ return 0;
+ }
+
+ if (strcmp(argv[1], "add") == 0) {
+ cmd = RTM_ADD;
+ } else if (strcmp(argv[1], "del") == 0) {
+ cmd = RTM_DELETE;
+ } else {
+ printf("invalid command: %s\n", argv[1]);
+ printf("\tit should be 'add' or 'del'\n");
+ return -1;
+ }
+
+ if (argc < 3) {
+ printf("not enough arguments\n");
+ return -1;
+ }
+
+ if (strcmp(argv[2], "-host") == 0) {
+ f_host = 1;
+ } else if (strcmp(argv[2], "-net") == 0) {
+ f_host = 0;
+ } else {
+ printf("Invalid type: %s\n", argv[1]);
+ printf("\tit should be '-host' or '-net'\n");
+ return -1;
+ }
+
+ if (argc < 4) {
+ printf("not enough arguments\n");
+ return -1;
+ }
+
+ inet_pton(AF_INET, argv[3], &dst.sin_addr);
+
+ cur_idx = 4;
+ while(cur_idx < argc) {
+ if (strcmp(argv[cur_idx], "gw") == 0) {
+ if ((cur_idx +1) >= argc) {
+ printf("no gateway address\n");
+ return -1;
+ }
+ f_gw = 1;
+ inet_pton(AF_INET, argv[cur_idx + 1], &gw.sin_addr);
+ cur_idx += 1;
+ } else if(strcmp(argv[cur_idx], "netmask") == 0) {
+ if ((cur_idx +1) >= argc) {
+ printf("no netmask address\n");
+ return -1;
+ }
+ f_gw = 1;
+ inet_pton(AF_INET, argv[cur_idx + 1], &netmask.sin_addr);
+ cur_idx += 1;
+ } else {
+ printf("Unknown argument\n");
+ return -1;
+ }
+ cur_idx += 1;
+ }
+
+ flags = RTF_STATIC;
+ if (f_gw != 0) {
+ flags |= RTF_GATEWAY;
+ }
+ if (f_host != 0) {
+ flags |= RTF_HOST;
+ }
+
+ rc = rtems_bsdnet_rtrequest(
+ cmd,
+ (struct sockaddr *)&dst,
+ (struct sockaddr *)&gw,
+ (struct sockaddr *)&netmask,
+ flags,
+ NULL
+ );
+ if (rc < 0) {
+ printf("Error adding route\n");
+ }
+
+ return 0;
+}
+
+rtems_shell_cmd_t rtems_shell_ROUTE_Command = {
+ "route", /* name */
+ "TBD", /* usage */
+ "network", /* topic */
+ rtems_shell_main_route, /* command */
+ NULL, /* alias */
+ NULL /* next */
+};
diff --git a/libmisc/mon-network.c b/libmisc/mon-network.c
new file mode 100644
index 0000000..2140044
--- /dev/null
+++ b/libmisc/mon-network.c
@@ -0,0 +1,342 @@
+/*
+ * COPYRIGHT (c) 1989-2007.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include <rtems/rtems_bsdnet.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/sockio.h>
+#include <net/route.h>
+
+#include <rtems/monitor.h>
+
+void mon_ifconfig(int argc, char *argv[],
+ uint32_t command_arg RTEMS_UNUSED,
+ bool verbose RTEMS_UNUSED)
+{
+ struct sockaddr_in ipaddr;
+ struct sockaddr_in dstaddr;
+ struct sockaddr_in netmask;
+ struct sockaddr_in broadcast;
+ char *iface;
+ int f_ip = 0;
+ int f_ptp = 0;
+ int f_netmask = 0;
+ int f_up = 0;
+ int f_down = 0;
+ int f_bcast = 0;
+ int cur_idx;
+ int rc;
+ int flags;
+
+ memset(&ipaddr, 0, sizeof(ipaddr));
+ memset(&dstaddr, 0, sizeof(dstaddr));
+ memset(&netmask, 0, sizeof(netmask));
+ memset(&broadcast, 0, sizeof(broadcast));
+
+ ipaddr.sin_len = sizeof(ipaddr);
+ ipaddr.sin_family = AF_INET;
+
+ dstaddr.sin_len = sizeof(dstaddr);
+ dstaddr.sin_family = AF_INET;
+
+ netmask.sin_len = sizeof(netmask);
+ netmask.sin_family = AF_INET;
+
+ broadcast.sin_len = sizeof(broadcast);
+ broadcast.sin_family = AF_INET;
+
+ cur_idx = 0;
+ if (argc <= 1) {
+ /* display all interfaces */
+ iface = NULL;
+ cur_idx += 1;
+ } else {
+ iface = argv[1];
+ if (isdigit((unsigned char)*argv[2])) {
+ if (inet_pton(AF_INET, argv[2], &ipaddr.sin_addr) < 0) {
+ printf("bad ip address: %s\n", argv[2]);
+ return;
+ }
+ f_ip = 1;
+ cur_idx += 3;
+ } else {
+ cur_idx += 2;
+ }
+ }
+
+ if ((f_down !=0) && (f_ip != 0)) {
+ f_up = 1;
+ }
+
+ while(argc > cur_idx) {
+ if (strcmp(argv[cur_idx], "up") == 0) {
+ f_up = 1;
+ if (f_down != 0) {
+ printf("Can't make interface up and down\n");
+ }
+ } else if(strcmp(argv[cur_idx], "down") == 0) {
+ f_down = 1;
+ if (f_up != 0) {
+ printf("Can't make interface up and down\n");
+ }
+ } else if(strcmp(argv[cur_idx], "netmask") == 0) {
+ if ((cur_idx + 1) >= argc) {
+ printf("No netmask address\n");
+ return;
+ }
+ if (inet_pton(AF_INET, argv[cur_idx+1], &netmask.sin_addr) < 0) {
+ printf("bad netmask: %s\n", argv[cur_idx]);
+ return;
+ }
+ f_netmask = 1;
+ cur_idx += 1;
+ } else if(strcmp(argv[cur_idx], "broadcast") == 0) {
+ if ((cur_idx + 1) >= argc) {
+ printf("No broadcast address\n");
+ return;
+ }
+ if (inet_pton(AF_INET, argv[cur_idx+1], &broadcast.sin_addr) < 0) {
+ printf("bad broadcast: %s\n", argv[cur_idx]);
+ return;
+ }
+ f_bcast = 1;
+ cur_idx += 1;
+ } else if(strcmp(argv[cur_idx], "pointopoint") == 0) {
+ if ((cur_idx + 1) >= argc) {
+ printf("No pointopoint address\n");
+ return;
+ }
+ if (inet_pton(AF_INET, argv[cur_idx+1], &dstaddr.sin_addr) < 0) {
+ printf("bad pointopoint: %s\n", argv[cur_idx]);
+ return;
+ }
+
+ f_ptp = 1;
+ cur_idx += 1;
+ } else {
+ printf("Bad parameter: %s\n", argv[cur_idx]);
+ return;
+ }
+
+ cur_idx += 1;
+ }
+
+ printf("ifconfig ");
+ if (iface != NULL) {
+ printf("%s ", iface);
+ if (f_ip != 0) {
+ char str[256];
+ inet_ntop(AF_INET, &ipaddr.sin_addr, str, 256);
+ printf("%s ", str);
+ }
+
+ if (f_netmask != 0) {
+ char str[256];
+ inet_ntop(AF_INET, &netmask.sin_addr, str, 256);
+ printf("netmask %s ", str);
+ }
+
+ if (f_bcast != 0) {
+ char str[256];
+ inet_ntop(AF_INET, &broadcast.sin_addr, str, 256);
+ printf("broadcast %s ", str);
+ }
+
+ if (f_ptp != 0) {
+ char str[256];
+ inet_ntop(AF_INET, &dstaddr.sin_addr, str, 256);
+ printf("pointopoint %s ", str);
+ }
+
+ if (f_up != 0) {
+ printf("up\n");
+ } else if (f_down != 0) {
+ printf("down\n");
+ } else {
+ printf("\n");
+ }
+ }
+
+ if ((iface == NULL) || ((f_ip == 0) && (f_down == 0) && (f_up == 0))) {
+ rtems_bsdnet_show_if_stats();
+ return;
+ }
+
+ flags = 0;
+ if (f_netmask) {
+ rc = rtems_bsdnet_ifconfig(iface, SIOCSIFNETMASK, &netmask);
+ if (rc < 0) {
+ printf("Could not set netmask: %s\n", strerror(errno));
+ return;
+ }
+ }
+
+ if (f_bcast) {
+ rc = rtems_bsdnet_ifconfig(iface, SIOCSIFBRDADDR, &broadcast);
+ if (rc < 0) {
+ printf("Could not set broadcast: %s\n", strerror(errno));
+ return;
+ }
+ }
+
+ if (f_ptp) {
+ rc = rtems_bsdnet_ifconfig(iface, SIOCSIFDSTADDR, &dstaddr);
+ if (rc < 0) {
+ printf("Could not set destination address: %s\n", strerror(errno));
+ return;
+ }
+ flags |= IFF_POINTOPOINT;
+ }
+
+ /* This must come _after_ setting the netmask, broadcast addresses */
+ if (f_ip) {
+ rc = rtems_bsdnet_ifconfig(iface, SIOCSIFADDR, &ipaddr);
+ if (rc < 0) {
+ printf("Could not set IP address: %s\n", strerror(errno));
+ return;
+ }
+ }
+
+ if (f_up != 0) {
+ flags |= IFF_UP;
+ }
+
+ if (f_down != 0) {
+ printf("Warning: taking interfaces down is not supported\n");
+ }
+
+ rc = rtems_bsdnet_ifconfig(iface, SIOCSIFFLAGS, &flags);
+ if (rc < 0) {
+ printf("Could not set interface flags: %s\n", strerror(errno));
+ return;
+ }
+}
+
+
+
+void mon_route(int argc, char *argv[],
+ uint32_t command_arg RTEMS_UNUSED,
+ bool verbose RTEMS_UNUSED)
+{
+ int cmd;
+ struct sockaddr_in dst;
+ struct sockaddr_in gw;
+ struct sockaddr_in netmask;
+ int f_host;
+ int f_gw = 0;
+ int cur_idx;
+ int flags;
+ int rc;
+
+ memset(&dst, 0, sizeof(dst));
+ memset(&gw, 0, sizeof(gw));
+ memset(&netmask, 0, sizeof(netmask));
+
+ dst.sin_len = sizeof(dst);
+ dst.sin_family = AF_INET;
+ dst.sin_addr.s_addr = inet_addr("0.0.0.0");
+
+ gw.sin_len = sizeof(gw);
+ gw.sin_family = AF_INET;
+ gw.sin_addr.s_addr = inet_addr("0.0.0.0");
+
+ netmask.sin_len = sizeof(netmask);
+ netmask.sin_family = AF_INET;
+ netmask.sin_addr.s_addr = inet_addr("255.255.255.0");
+
+ if (argc < 2) {
+ rtems_bsdnet_show_inet_routes();
+ return;
+ }
+
+ if (strcmp(argv[1], "add") == 0) {
+ cmd = RTM_ADD;
+ } else if (strcmp(argv[1], "del") == 0) {
+ cmd = RTM_DELETE;
+ } else {
+ printf("invalid command: %s\n", argv[1]);
+ printf("\tit should be 'add' or 'del'\n");
+ return;
+ }
+
+ if (argc < 3) {
+ printf("not enough arguments\n");
+ return;
+ }
+
+ if (strcmp(argv[2], "-host") == 0) {
+ f_host = 1;
+ } else if (strcmp(argv[2], "-net") == 0) {
+ f_host = 0;
+ } else {
+ printf("Invalid type: %s\n", argv[1]);
+ printf("\tit should be '-host' or '-net'\n");
+ return;
+ }
+
+ if (argc < 4) {
+ printf("not enough arguments\n");
+ return;
+ }
+
+ inet_pton(AF_INET, argv[3], &dst.sin_addr);
+
+ cur_idx = 4;
+ while(cur_idx < argc) {
+ if (strcmp(argv[cur_idx], "gw") == 0) {
+ if ((cur_idx +1) >= argc) {
+ printf("no gateway address\n");
+ return;
+ }
+ f_gw = 1;
+ inet_pton(AF_INET, argv[cur_idx + 1], &gw.sin_addr);
+ cur_idx += 1;
+ } else if(strcmp(argv[cur_idx], "netmask") == 0) {
+ if ((cur_idx +1) >= argc) {
+ printf("no netmask address\n");
+ return;
+ }
+ f_gw = 1;
+ inet_pton(AF_INET, argv[cur_idx + 1], &netmask.sin_addr);
+ cur_idx += 1;
+ } else {
+ printf("Unknown argument: %s\n", argv[cur_idx]);
+ return;
+ }
+ cur_idx += 1;
+ }
+
+ flags = RTF_STATIC;
+ if (f_gw != 0) {
+ flags |= RTF_GATEWAY;
+ }
+ if (f_host != 0) {
+ flags |= RTF_HOST;
+ }
+
+ rc = rtems_bsdnet_rtrequest(cmd,
+ (struct sockaddr*) &dst,
+ (struct sockaddr*) &gw,
+ (struct sockaddr*) &netmask, flags, NULL);
+ if (rc < 0) {
+ printf("Error adding route\n");
+ }
+}
diff --git a/libmisc/sysexits.h b/libmisc/sysexits.h
new file mode 100644
index 0000000..50827f1
--- /dev/null
+++ b/libmisc/sysexits.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)sysexits.h 8.1 (Berkeley) 6/2/93
+ *
+ * $FreeBSD: release/9.1.0/include/sysexits.h 203964 2010-02-16 19:39:50Z imp $
+ */
+
+#ifndef _SYSEXITS_H_
+#define _SYSEXITS_H_
+
+/*
+ * SYSEXITS.H -- Exit status codes for system programs.
+ *
+ * This include file attempts to categorize possible error
+ * exit statuses for system programs, notably delivermail
+ * and the Berkeley network.
+ *
+ * Error numbers begin at EX__BASE to reduce the possibility of
+ * clashing with other exit statuses that random programs may
+ * already return. The meaning of the codes is approximately
+ * as follows:
+ *
+ * EX_USAGE -- The command was used incorrectly, e.g., with
+ * the wrong number of arguments, a bad flag, a bad
+ * syntax in a parameter, or whatever.
+ * EX_DATAERR -- The input data was incorrect in some way.
+ * This should only be used for user's data & not
+ * system files.
+ * EX_NOINPUT -- An input file (not a system file) did not
+ * exist or was not readable. This could also include
+ * errors like "No message" to a mailer (if it cared
+ * to catch it).
+ * EX_NOUSER -- The user specified did not exist. This might
+ * be used for mail addresses or remote logins.
+ * EX_NOHOST -- The host specified did not exist. This is used
+ * in mail addresses or network requests.
+ * EX_UNAVAILABLE -- A service is unavailable. This can occur
+ * if a support program or file does not exist. This
+ * can also be used as a catchall message when something
+ * you wanted to do doesn't work, but you don't know
+ * why.
+ * EX_SOFTWARE -- An internal software error has been detected.
+ * This should be limited to non-operating system related
+ * errors as possible.
+ * EX_OSERR -- An operating system error has been detected.
+ * This is intended to be used for such things as "cannot
+ * fork", "cannot create pipe", or the like. It includes
+ * things like getuid returning a user that does not
+ * exist in the passwd file.
+ * EX_OSFILE -- Some system file (e.g., /etc/passwd, /etc/utmp,
+ * etc.) does not exist, cannot be opened, or has some
+ * sort of error (e.g., syntax error).
+ * EX_CANTCREAT -- A (user specified) output file cannot be
+ * created.
+ * EX_IOERR -- An error occurred while doing I/O on some file.
+ * EX_TEMPFAIL -- temporary failure, indicating something that
+ * is not really an error. In sendmail, this means
+ * that a mailer (e.g.) could not create a connection,
+ * and the request should be reattempted later.
+ * EX_PROTOCOL -- the remote system returned something that
+ * was "not possible" during a protocol exchange.
+ * EX_NOPERM -- You did not have sufficient permission to
+ * perform the operation. This is not intended for
+ * file system problems, which should use NOINPUT or
+ * CANTCREAT, but rather for higher level permissions.
+ */
+
+#define EX_OK 0 /* successful termination */
+
+#define EX__BASE 64 /* base value for error messages */
+
+#define EX_USAGE 64 /* command line usage error */
+#define EX_DATAERR 65 /* data format error */
+#define EX_NOINPUT 66 /* cannot open input */
+#define EX_NOUSER 67 /* addressee unknown */
+#define EX_NOHOST 68 /* host name unknown */
+#define EX_UNAVAILABLE 69 /* service unavailable */
+#define EX_SOFTWARE 70 /* internal software error */
+#define EX_OSERR 71 /* system error (e.g., can't fork) */
+#define EX_OSFILE 72 /* critical OS file missing */
+#define EX_CANTCREAT 73 /* can't create (user) output file */
+#define EX_IOERR 74 /* input/output error */
+#define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */
+#define EX_PROTOCOL 76 /* remote error in protocol */
+#define EX_NOPERM 77 /* permission denied */
+#define EX_CONFIG 78 /* configuration error */
+
+#define EX__MAX 78 /* maximum listed value */
+
+#endif /* !_SYSEXITS_H_ */
diff --git a/librpc/README_RTEMS b/librpc/README_RTEMS
new file mode 100644
index 0000000..e60f879
--- /dev/null
+++ b/librpc/README_RTEMS
@@ -0,0 +1,64 @@
+USING RPC/XDR ON RTEMS
+======================
+For the most part, programmers using RPC/XDR routines on RTEMS
+can proceed as if they were to be using a POSIX/UNIX system.
+The only significant changes are those to start the portmapper
+and to allow use of RPC/XDR by multiple threads.
+
+Starting the portmapper
+=======================
+The SUN portmapper program has been modified to run as an RTEMS
+task. Applications which need the portmapper can start this
+task by calling:
+ int rtems_rpc_start_portmapper (int priority);
+The return value is an RTEMS status code.
+
+Multi-threaded operation
+========================
+The RPC/XDR package has been modified to allow for multiple RTEMS
+tasks to use RPC/XDR routines. If more than one task is to call
+an RPC/XDR routine, the additional tasks must call:
+ int rtems_rpc_task_init(void);
+before calling any RPC/XDR routines. For example, the portmapper
+calls this routine since the portmapper uses RPC/XDR routines in
+a separate thread.
+The return value is an RTEMS status code.
+
+
+Porting Notes
+=============
+Most of the FreeBSD rpc library ports to RTEMS with little
+or no modification beyond that required to provide for operation
+in a multitasking environment. Multitasking operation was
+provided by moving all `static persistence' variables into
+a single structure and using an RTEMS task variable to point
+to that structure.
+
+Some of the library, however, has not made it into the RTEMS
+implementation. FreeBSD source files which have been left out include:
+- Files which provide RPC to the AF_UNIX address family:
+ clnt_unix.c
+ svc_unix.c
+ An `ifndef __rtems__' was added to clnt_generic.c because clnt_unix.c
+ was omitted.
+- Files which need NIS:
+ auth_time.c
+- Files which provide DES authentication:
+ auth_des.c
+ authdes_prot.c
+ crypt_client.c
+ des_crypt.c
+ des_soft.c
+ getpublickey.c
+ key_call.c
+ key_prot_xdr.c
+ svc_auth_des.c
+
+The FreeBSD xdr source compiles and runs on RTEMS without modification.
+
+The original source was obtained from:
+ ftp://ftp.FreeBSD.org/pub/FreeBSD/
+ branches/4.0-stable/src/lib/libc/rpc
+ branches/4.0-stable/src/lib/libc/xdr
+ branches/4.0-stable/src/include/rpc
+ branches/4.0-stable/src/include/rpcsvc
diff --git a/librpc/include/rpcsvc/bootparam_prot.x b/librpc/include/rpcsvc/bootparam_prot.x
new file mode 100644
index 0000000..0f74c8f
--- /dev/null
+++ b/librpc/include/rpcsvc/bootparam_prot.x
@@ -0,0 +1,103 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * RPC for bootparms service.
+ * There are two procedures:
+ * WHOAMI takes a net address and returns a client name and also a
+ * likely net address for routing
+ * GETFILE takes a client name and file identifier and returns the
+ * server name, server net address and pathname for the file.
+ * file identifiers typically include root, swap, pub and dump
+ */
+
+#ifdef RPC_HDR
+%#include <rpc/types.h>
+%#include <sys/time.h>
+%#include <sys/errno.h>
+%#include <sys/param.h>
+%#include <sys/syslimits.h>
+%#include <sys/ucred.h>
+#else
+%#ifndef lint
+%/*static char sccsid[] = "from: @(#)bootparam_prot.x 1.2 87/06/24 Copyr 1987 Sun Micro";*/
+%/*static char sccsid[] = "from: @(#)bootparam_prot.x 2.1 88/08/01 4.0 RPCSRC";*/
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/bootparam_prot.x,v 1.5 1999/08/27 23:45:07 peter Exp $";
+%#endif /* not lint */
+#endif
+
+const MAX_MACHINE_NAME = 255;
+const MAX_PATH_LEN = 1024;
+const MAX_FILEID = 32;
+const IP_ADDR_TYPE = 1;
+
+typedef string bp_machine_name_t<MAX_MACHINE_NAME>;
+typedef string bp_path_t<MAX_PATH_LEN>;
+typedef string bp_fileid_t<MAX_FILEID>;
+
+struct ip_addr_t {
+ char net;
+ char host;
+ char lh;
+ char impno;
+};
+
+union bp_address switch (int address_type) {
+ case IP_ADDR_TYPE:
+ ip_addr_t ip_addr;
+};
+
+struct bp_whoami_arg {
+ bp_address client_address;
+};
+
+struct bp_whoami_res {
+ bp_machine_name_t client_name;
+ bp_machine_name_t domain_name;
+ bp_address router_address;
+};
+
+struct bp_getfile_arg {
+ bp_machine_name_t client_name;
+ bp_fileid_t file_id;
+};
+
+struct bp_getfile_res {
+ bp_machine_name_t server_name;
+ bp_address server_address;
+ bp_path_t server_path;
+};
+
+program BOOTPARAMPROG {
+ version BOOTPARAMVERS {
+ bp_whoami_res BOOTPARAMPROC_WHOAMI(bp_whoami_arg) = 1;
+ bp_getfile_res BOOTPARAMPROC_GETFILE(bp_getfile_arg) = 2;
+ } = 1;
+} = 100026;
diff --git a/librpc/include/rpcsvc/crypt.x b/librpc/include/rpcsvc/crypt.x
new file mode 100644
index 0000000..8df1654
--- /dev/null
+++ b/librpc/include/rpcsvc/crypt.x
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 1996
+ * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Bill Paul.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bill Paul 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 Bill Paul 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.
+ *
+ * $FreeBSD: src/include/rpcsvc/crypt.x,v 1.3 1999/08/27 23:45:08 peter Exp $
+ */
+
+#ifndef RPC_HDR
+%#ifndef lint
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/crypt.x,v 1.3 1999/08/27 23:45:08 peter Exp $";
+%#endif
+#endif
+
+/*
+ * This protocol definition exists because of the U.S. government and
+ * its stupid export laws. We can't export DES code from the United
+ * States to other countries (even though the code already exists
+ * outside the U.S. -- go figure that one out) but we need to make
+ * Secure RPC work. The normal way around this is to break the DES
+ * code out into a shared library; we can then provide a dummy lib
+ * in the base OS and provide the real lib in the secure dist, which
+ * the user can install later. But we need Secure RPC for NIS+, and
+ * there are several system programs that use NIS+ which are statically
+ * linked. We would have to provide replacements for these programs
+ * in the secure dist, but there are a lot, and this is a pain. The
+ * shared lib trick won't work for these programs, and we can't change
+ * them once they're compiled.
+ *
+ * One solution for this problem is to do the DES encryption as a system
+ * call; no programs need to be changed and we can even supply the DES
+ * support as an LKM. But this bloats the kernel. Maybe if we have
+ * Secure NFS one day this will be worth it, but for now we should keep
+ * this mess in user space.
+ *
+ * So we have this second solution: we provide a server that does the
+ * DES encryption for us. In this case, the server is keyserv (we need
+ * it to make Secure RPC work anyway) and we use this protocol to ship
+ * the data back and forth between keyserv and the application.
+ */
+
+enum des_dir { ENCRYPT_DES, DECRYPT_DES };
+enum des_mode { CBC_DES, ECB_DES };
+
+struct desargs {
+ u_char des_key[8]; /* key (with low bit parity) */
+ des_dir des_dir; /* direction */
+ des_mode des_mode; /* mode */
+ u_char des_ivec[8]; /* input vector */
+ opaque desbuf<>;
+};
+
+struct desresp {
+ opaque desbuf<>;
+ u_char des_ivec[8];
+ int stat;
+};
+
+program CRYPT_PROG {
+ version CRYPT_VERS {
+ desresp
+ DES_CRYPT(desargs) = 1;
+ } = 1;
+} = 600100029;
diff --git a/librpc/include/rpcsvc/key_prot.x b/librpc/include/rpcsvc/key_prot.x
new file mode 100644
index 0000000..f545569
--- /dev/null
+++ b/librpc/include/rpcsvc/key_prot.x
@@ -0,0 +1,282 @@
+%/*
+% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+% * unrestricted use provided that this legend is included on all tape
+% * media and as a part of the software program in whole or part. Users
+% * may copy or modify Sun RPC without charge, but are not authorized
+% * to license or distribute it to anyone else except as part of a product or
+% * program developed by the user.
+% *
+% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+% *
+% * Sun RPC is provided with no support and without any obligation on the
+% * part of Sun Microsystems, Inc. to assist in its use, correction,
+% * modification or enhancement.
+% *
+% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+% * OR ANY PART THEREOF.
+% *
+% * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+% * or profits or other special, indirect and consequential damages, even if
+% * Sun has been advised of the possibility of such damages.
+% *
+% * Sun Microsystems, Inc.
+% * 2550 Garcia Avenue
+% * Mountain View, California 94043
+% */
+/*
+ * Key server protocol definition
+ * Copyright (C) 1990, 1991 Sun Microsystems, Inc.
+ *
+ * The keyserver is a public key storage/encryption/decryption service
+ * The encryption method used is based on the Diffie-Hellman exponential
+ * key exchange technology.
+ *
+ * The key server is local to each machine, akin to the portmapper.
+ * Under TI-RPC, communication with the keyserver is through the
+ * loopback transport.
+ *
+ * NOTE: This .x file generates the USER level headers for the keyserver.
+ * the KERNEL level headers are created by hand as they kernel has special
+ * requirements.
+ */
+
+%/* From: #pragma ident "@(#)key_prot.x 1.7 94/04/29 SMI" */
+%
+%/* Copyright (c) 1990, 1991 Sun Microsystems, Inc. */
+%
+%/*
+% * Compiled from key_prot.x using rpcgen.
+% * DO NOT EDIT THIS FILE!
+% * This is NOT source code!
+% */
+
+/*
+ * PROOT and MODULUS define the way the Diffie-Hellman key is generated.
+ *
+ * MODULUS should be chosen as a prime of the form: MODULUS == 2*p + 1,
+ * where p is also prime.
+ *
+ * PROOT satisfies the following two conditions:
+ * (1) (PROOT ** 2) % MODULUS != 1
+ * (2) (PROOT ** p) % MODULUS != 1
+ *
+ */
+
+const PROOT = 3;
+const HEXMODULUS = "d4a0ba0250b6fd2ec626e7efd637df76c716e22d0944b88b";
+
+const HEXKEYBYTES = 48; /* HEXKEYBYTES == strlen(HEXMODULUS) */
+const KEYSIZE = 192; /* KEYSIZE == bit length of key */
+const KEYBYTES = 24; /* byte length of key */
+
+/*
+ * The first 16 hex digits of the encrypted secret key are used as
+ * a checksum in the database.
+ */
+const KEYCHECKSUMSIZE = 16;
+
+/*
+ * status of operation
+ */
+enum keystatus {
+ KEY_SUCCESS, /* no problems */
+ KEY_NOSECRET, /* no secret key stored */
+ KEY_UNKNOWN, /* unknown netname */
+ KEY_SYSTEMERR /* system error (out of memory, encryption failure) */
+};
+
+typedef opaque keybuf[HEXKEYBYTES]; /* store key in hex */
+
+typedef string netnamestr<MAXNETNAMELEN>;
+
+/*
+ * Argument to ENCRYPT or DECRYPT
+ */
+struct cryptkeyarg {
+ netnamestr remotename;
+ des_block deskey;
+};
+
+/*
+ * Argument to ENCRYPT_PK or DECRYPT_PK
+ */
+struct cryptkeyarg2 {
+ netnamestr remotename;
+ netobj remotekey; /* Contains a length up to 1024 bytes */
+ des_block deskey;
+};
+
+
+/*
+ * Result of ENCRYPT, DECRYPT, ENCRYPT_PK, and DECRYPT_PK
+ */
+union cryptkeyres switch (keystatus status) {
+case KEY_SUCCESS:
+ des_block deskey;
+default:
+ void;
+};
+
+const MAXGIDS = 16; /* max number of gids in gid list */
+
+/*
+ * Unix credential
+ */
+struct unixcred {
+ u_int uid;
+ u_int gid;
+ u_int gids<MAXGIDS>;
+};
+
+/*
+ * Result returned from GETCRED
+ */
+union getcredres switch (keystatus status) {
+case KEY_SUCCESS:
+ unixcred cred;
+default:
+ void;
+};
+/*
+ * key_netstarg;
+ */
+
+struct key_netstarg {
+ keybuf st_priv_key;
+ keybuf st_pub_key;
+ netnamestr st_netname;
+};
+
+union key_netstres switch (keystatus status){
+case KEY_SUCCESS:
+ key_netstarg knet;
+default:
+ void;
+};
+
+#ifdef RPC_HDR
+%
+%#ifndef opaque
+%#define opaque char
+%#endif
+%
+#endif
+program KEY_PROG {
+ version KEY_VERS {
+
+ /*
+ * This is my secret key.
+ * Store it for me.
+ */
+ keystatus
+ KEY_SET(keybuf) = 1;
+
+ /*
+ * I want to talk to X.
+ * Encrypt a conversation key for me.
+ */
+ cryptkeyres
+ KEY_ENCRYPT(cryptkeyarg) = 2;
+
+ /*
+ * X just sent me a message.
+ * Decrypt the conversation key for me.
+ */
+ cryptkeyres
+ KEY_DECRYPT(cryptkeyarg) = 3;
+
+ /*
+ * Generate a secure conversation key for me
+ */
+ des_block
+ KEY_GEN(void) = 4;
+
+ /*
+ * Get me the uid, gid and group-access-list associated
+ * with this netname (for kernel which cannot use NIS)
+ */
+ getcredres
+ KEY_GETCRED(netnamestr) = 5;
+ } = 1;
+ version KEY_VERS2 {
+
+ /*
+ * #######
+ * Procedures 1-5 are identical to version 1
+ * #######
+ */
+
+ /*
+ * This is my secret key.
+ * Store it for me.
+ */
+ keystatus
+ KEY_SET(keybuf) = 1;
+
+ /*
+ * I want to talk to X.
+ * Encrypt a conversation key for me.
+ */
+ cryptkeyres
+ KEY_ENCRYPT(cryptkeyarg) = 2;
+
+ /*
+ * X just sent me a message.
+ * Decrypt the conversation key for me.
+ */
+ cryptkeyres
+ KEY_DECRYPT(cryptkeyarg) = 3;
+
+ /*
+ * Generate a secure conversation key for me
+ */
+ des_block
+ KEY_GEN(void) = 4;
+
+ /*
+ * Get me the uid, gid and group-access-list associated
+ * with this netname (for kernel which cannot use NIS)
+ */
+ getcredres
+ KEY_GETCRED(netnamestr) = 5;
+
+ /*
+ * I want to talk to X. and I know X's public key
+ * Encrypt a conversation key for me.
+ */
+ cryptkeyres
+ KEY_ENCRYPT_PK(cryptkeyarg2) = 6;
+
+ /*
+ * X just sent me a message. and I know X's public key
+ * Decrypt the conversation key for me.
+ */
+ cryptkeyres
+ KEY_DECRYPT_PK(cryptkeyarg2) = 7;
+
+ /*
+ * Store my public key, netname and private key.
+ */
+ keystatus
+ KEY_NET_PUT(key_netstarg) = 8;
+
+ /*
+ * Retrieve my public key, netname and private key.
+ */
+ key_netstres
+ KEY_NET_GET(void) = 9;
+
+ /*
+ * Return me the conversation key that is constructed
+ * from my secret key and this publickey.
+ */
+
+ cryptkeyres
+ KEY_GET_CONV(keybuf) = 10;
+
+
+ } = 2;
+} = 100029;
diff --git a/librpc/include/rpcsvc/klm_prot.x b/librpc/include/rpcsvc/klm_prot.x
new file mode 100644
index 0000000..c4cfe36
--- /dev/null
+++ b/librpc/include/rpcsvc/klm_prot.x
@@ -0,0 +1,139 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * Kernel/lock manager protocol definition
+ * Copyright (C) 1986 Sun Microsystems, Inc.
+ *
+ * protocol used between the UNIX kernel (the "client") and the
+ * local lock manager. The local lock manager is a deamon running
+ * above the kernel.
+ */
+
+#ifndef RPC_HDR
+%#ifndef lint
+%/*static char sccsid[] = "from: @(#)klm_prot.x 1.7 87/07/08 Copyr 1987 Sun Micro";*/
+%/*static char sccsid[] = "from: @(#)klm_prot.x 2.1 88/08/01 4.0 RPCSRC";*/
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/klm_prot.x,v 1.6 1999/08/27 23:45:08 peter Exp $";
+%#endif /* not lint */
+#endif
+
+const LM_MAXSTRLEN = 1024;
+
+/*
+ * lock manager status returns
+ */
+enum klm_stats {
+ klm_granted = 0, /* lock is granted */
+ klm_denied = 1, /* lock is denied */
+ klm_denied_nolocks = 2, /* no lock entry available */
+ klm_working = 3 /* lock is being processed */
+};
+
+/*
+ * lock manager lock identifier
+ */
+struct klm_lock {
+ string server_name<LM_MAXSTRLEN>;
+ netobj fh; /* a counted file handle */
+ int pid; /* holder of the lock */
+ unsigned l_offset; /* beginning offset of the lock */
+ unsigned l_len; /* byte length of the lock;
+ * zero means through end of file */
+};
+
+/*
+ * lock holder identifier
+ */
+struct klm_holder {
+ bool exclusive; /* FALSE if shared lock */
+ int svid; /* holder of the lock (pid) */
+ unsigned l_offset; /* beginning offset of the lock */
+ unsigned l_len; /* byte length of the lock;
+ * zero means through end of file */
+};
+
+/*
+ * reply to KLM_LOCK / KLM_UNLOCK / KLM_CANCEL
+ */
+struct klm_stat {
+ klm_stats stat;
+};
+
+/*
+ * reply to a KLM_TEST call
+ */
+union klm_testrply switch (klm_stats stat) {
+ case klm_denied:
+ struct klm_holder holder;
+ default: /* All other cases return no arguments */
+ void;
+};
+
+
+/*
+ * arguments to KLM_LOCK
+ */
+struct klm_lockargs {
+ bool block;
+ bool exclusive;
+ struct klm_lock alock;
+};
+
+/*
+ * arguments to KLM_TEST
+ */
+struct klm_testargs {
+ bool exclusive;
+ struct klm_lock alock;
+};
+
+/*
+ * arguments to KLM_UNLOCK
+ */
+struct klm_unlockargs {
+ struct klm_lock alock;
+};
+
+program KLM_PROG {
+ version KLM_VERS {
+
+ klm_testrply KLM_TEST (struct klm_testargs) = 1;
+
+ klm_stat KLM_LOCK (struct klm_lockargs) = 2;
+
+ klm_stat KLM_CANCEL (struct klm_lockargs) = 3;
+ /* klm_granted=> the cancel request fails due to lock is already granted */
+ /* klm_denied=> the cancel request successfully aborts
+lock request */
+
+ klm_stat KLM_UNLOCK (struct klm_unlockargs) = 4;
+ } = 1;
+} = 100020;
diff --git a/librpc/include/rpcsvc/mount.x b/librpc/include/rpcsvc/mount.x
new file mode 100644
index 0000000..f68a06f
--- /dev/null
+++ b/librpc/include/rpcsvc/mount.x
@@ -0,0 +1,257 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * Protocol description for the mount program
+ */
+
+#ifndef RPC_HDR
+%#ifndef lint
+%/*static char sccsid[] = "from: @(#)mount.x 1.2 87/09/18 Copyr 1987 Sun Micro";*/
+%/*static char sccsid[] = "from: @(#)mount.x 2.1 88/08/01 4.0 RPCSRC";*/
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/mount.x,v 1.6 1999/08/27 23:45:08 peter Exp $";
+%#endif /* not lint */
+#endif
+
+const MNTPATHLEN = 1024; /* maximum bytes in a pathname argument */
+const MNTNAMLEN = 255; /* maximum bytes in a name argument */
+const FHSIZE = 32; /* size in bytes of a file handle */
+#ifdef WANT_NFS3
+const FHSIZE3 = 64; /* size in bytes of a file handle (v3) */
+#endif
+
+/*
+ * The fhandle is the file handle that the server passes to the client.
+ * All file operations are done using the file handles to refer to a file
+ * or a directory. The file handle can contain whatever information the
+ * server needs to distinguish an individual file.
+ */
+typedef opaque fhandle[FHSIZE];
+#ifdef WANT_NFS3
+typedef opaque fhandle3<FHSIZE3>;
+#endif
+
+/*
+ * If a status of zero is returned, the call completed successfully, and
+ * a file handle for the directory follows. A non-zero status indicates
+ * some sort of error. The status corresponds with UNIX error numbers.
+ */
+union fhstatus switch (unsigned fhs_status) {
+case 0:
+ fhandle fhs_fhandle;
+default:
+ void;
+};
+
+#ifdef WANT_NFS3
+/*
+ * Status codes returned by the version 3 mount call.
+ */
+enum mountstat3 {
+ MNT3_OK = 0, /* no error */
+ MNT3ERR_PERM = 1, /* Not owner */
+ MNT3ERR_NOENT = 2, /* No such file or directory */
+ MNT3ERR_IO = 5, /* I/O error */
+ MNT3ERR_ACCES = 13, /* Permission denied */
+ MNT3ERR_NOTDIR = 20, /* Not a directory */
+ MNT3ERR_INVAL = 22, /* Invalid argument */
+ MNT3ERR_NAMETOOLONG = 63, /* Filename too long */
+ MNT3ERR_NOTSUPP = 10004, /* Operation not supported */
+ MNT3ERR_SERVERFAULT = 10006 /* A failure on the server */
+};
+
+struct mountres3_ok {
+ fhandle3 fhandle;
+ int auth_flavors<>;
+};
+
+union mountres3 switch (mountstat3 fhs_status) {
+case 0:
+ mountres3_ok mountinfo;
+default:
+ void;
+};
+#endif
+
+/*
+ * The type dirpath is the pathname of a directory
+ */
+typedef string dirpath<MNTPATHLEN>;
+
+/*
+ * The type name is used for arbitrary names (hostnames, groupnames)
+ */
+typedef string name<MNTNAMLEN>;
+
+/*
+ * A list of who has what mounted
+ */
+typedef struct mountbody *mountlist;
+struct mountbody {
+ name ml_hostname;
+ dirpath ml_directory;
+ mountlist ml_next;
+};
+
+/*
+ * A list of netgroups
+ */
+typedef struct groupnode *groups;
+struct groupnode {
+ name gr_name;
+ groups gr_next;
+};
+
+/*
+ * A list of what is exported and to whom
+ */
+typedef struct exportnode *exports;
+struct exportnode {
+ dirpath ex_dir;
+ groups ex_groups;
+ exports ex_next;
+};
+
+program MOUNTPROG {
+ /*
+ * Version one of the mount protocol communicates with version two
+ * of the NFS protocol. Version three communicates with
+ * version three of the NFS protocol. The only connecting
+ * point is the fhandle structure, which is the same for both
+ * protocols.
+ */
+ version MOUNTVERS {
+ /*
+ * Does no work. It is made available in all RPC services
+ * to allow server reponse testing and timing
+ */
+ void
+ MOUNTPROC_NULL(void) = 0;
+
+ /*
+ * If fhs_status is 0, then fhs_fhandle contains the
+ * file handle for the directory. This file handle may
+ * be used in the NFS protocol. This procedure also adds
+ * a new entry to the mount list for this client mounting
+ * the directory.
+ * Unix authentication required.
+ */
+ fhstatus
+ MOUNTPROC_MNT(dirpath) = 1;
+
+ /*
+ * Returns the list of remotely mounted filesystems. The
+ * mountlist contains one entry for each hostname and
+ * directory pair.
+ */
+ mountlist
+ MOUNTPROC_DUMP(void) = 2;
+
+ /*
+ * Removes the mount list entry for the directory
+ * Unix authentication required.
+ */
+ void
+ MOUNTPROC_UMNT(dirpath) = 3;
+
+ /*
+ * Removes all of the mount list entries for this client
+ * Unix authentication required.
+ */
+ void
+ MOUNTPROC_UMNTALL(void) = 4;
+
+ /*
+ * Returns a list of all the exported filesystems, and which
+ * machines are allowed to import it.
+ */
+ exports
+ MOUNTPROC_EXPORT(void) = 5;
+
+ /*
+ * Identical to MOUNTPROC_EXPORT above
+ */
+ exports
+ MOUNTPROC_EXPORTALL(void) = 6;
+ } = 1;
+#ifdef WANT_NFS3
+ version MOUNTVERS3 {
+ /*
+ * Does no work. It is made available in all RPC services
+ * to allow server reponse testing and timing
+ */
+ void
+ MOUNTPROC_NULL(void) = 0;
+
+ /*
+ * If mountres3.fhs_status is MNT3_OK, then
+ * mountres3.mountinfo contains the file handle for
+ * the directory and a list of acceptable
+ * authentication flavors. This file handle may only
+ * be used in the NFS version 3 protocol. This
+ * procedure also results in the server adding a new
+ * entry to its mount list recording that this client
+ * has mounted the directory. AUTH_UNIX authentication
+ * or better is required.
+ */
+ mountres3
+ MOUNTPROC_MNT(dirpath) = 1;
+
+ /*
+ * Returns the list of remotely mounted filesystems. The
+ * mountlist contains one entry for each hostname and
+ * directory pair.
+ */
+ mountlist
+ MOUNTPROC_DUMP(void) = 2;
+
+ /*
+ * Removes the mount list entry for the directory
+ * Unix authentication required.
+ */
+ void
+ MOUNTPROC_UMNT(dirpath) = 3;
+
+ /*
+ * Removes all of the mount list entries for this client
+ * Unix authentication required.
+ */
+ void
+ MOUNTPROC_UMNTALL(void) = 4;
+
+ /*
+ * Returns a list of all the exported filesystems, and which
+ * machines are allowed to import it.
+ */
+ exports
+ MOUNTPROC_EXPORT(void) = 5;
+ } = 3;
+#endif
+} = 100005;
diff --git a/librpc/include/rpcsvc/nfs_prot.x b/librpc/include/rpcsvc/nfs_prot.x
new file mode 100644
index 0000000..c1e592c
--- /dev/null
+++ b/librpc/include/rpcsvc/nfs_prot.x
@@ -0,0 +1,1265 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#ifndef RPC_HDR
+%#ifndef lint
+%/*static char sccsid[] = "from: @(#)nfs_prot.x 1.2 87/10/12 Copyr 1987 Sun Micro";*/
+%/*static char sccsid[] = "from: @(#)nfs_prot.x 2.1 88/08/01 4.0 RPCSRC";*/
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/nfs_prot.x,v 1.7 1999/08/27 23:45:08 peter Exp $";
+%#endif /* not lint */
+#endif
+
+const NFS_PORT = 2049;
+const NFS_MAXDATA = 8192;
+const NFS_MAXPATHLEN = 1024;
+const NFS_MAXNAMLEN = 255;
+const NFS_FHSIZE = 32;
+const NFS_COOKIESIZE = 4;
+const NFS_FIFO_DEV = -1; /* size kludge for named pipes */
+
+/*
+ * File types
+ */
+const NFSMODE_FMT = 0170000; /* type of file */
+const NFSMODE_DIR = 0040000; /* directory */
+const NFSMODE_CHR = 0020000; /* character special */
+const NFSMODE_BLK = 0060000; /* block special */
+const NFSMODE_REG = 0100000; /* regular */
+const NFSMODE_LNK = 0120000; /* symbolic link */
+const NFSMODE_SOCK = 0140000; /* socket */
+const NFSMODE_FIFO = 0010000; /* fifo */
+
+/*
+ * Error status
+ */
+enum nfsstat {
+ NFS_OK= 0, /* no error */
+ NFSERR_PERM=1, /* Not owner */
+ NFSERR_NOENT=2, /* No such file or directory */
+ NFSERR_IO=5, /* I/O error */
+ NFSERR_NXIO=6, /* No such device or address */
+ NFSERR_ACCES=13, /* Permission denied */
+ NFSERR_EXIST=17, /* File exists */
+ NFSERR_NODEV=19, /* No such device */
+ NFSERR_NOTDIR=20, /* Not a directory*/
+ NFSERR_ISDIR=21, /* Is a directory */
+ NFSERR_FBIG=27, /* File too large */
+ NFSERR_NOSPC=28, /* No space left on device */
+ NFSERR_ROFS=30, /* Read-only file system */
+ NFSERR_NAMETOOLONG=63, /* File name too long */
+ NFSERR_NOTEMPTY=66, /* Directory not empty */
+ NFSERR_DQUOT=69, /* Disc quota exceeded */
+ NFSERR_STALE=70, /* Stale NFS file handle */
+ NFSERR_WFLUSH=99 /* write cache flushed */
+};
+
+/*
+ * File types
+ */
+enum ftype {
+ NFNON = 0, /* non-file */
+ NFREG = 1, /* regular file */
+ NFDIR = 2, /* directory */
+ NFBLK = 3, /* block special */
+ NFCHR = 4, /* character special */
+ NFLNK = 5, /* symbolic link */
+ NFSOCK = 6, /* unix domain sockets */
+ NFBAD = 7, /* unused */
+ NFFIFO = 8 /* named pipe */
+};
+
+/*
+ * File access handle
+ */
+struct nfs_fh {
+ opaque data[NFS_FHSIZE];
+};
+
+/*
+ * Timeval
+ */
+struct nfstime {
+ unsigned seconds;
+ unsigned useconds;
+};
+
+
+/*
+ * File attributes
+ */
+struct fattr {
+ ftype type; /* file type */
+ unsigned mode; /* protection mode bits */
+ unsigned nlink; /* # hard links */
+ unsigned uid; /* owner user id */
+ unsigned gid; /* owner group id */
+ unsigned size; /* file size in bytes */
+ unsigned blocksize; /* prefered block size */
+ unsigned rdev; /* special device # */
+ unsigned blocks; /* Kb of disk used by file */
+ unsigned fsid; /* device # */
+ unsigned fileid; /* inode # */
+ nfstime atime; /* time of last access */
+ nfstime mtime; /* time of last modification */
+ nfstime ctime; /* time of last change */
+};
+
+/*
+ * File attributes which can be set
+ */
+struct sattr {
+ unsigned mode; /* protection mode bits */
+ unsigned uid; /* owner user id */
+ unsigned gid; /* owner group id */
+ unsigned size; /* file size in bytes */
+ nfstime atime; /* time of last access */
+ nfstime mtime; /* time of last modification */
+};
+
+
+typedef string filename<NFS_MAXNAMLEN>;
+typedef string nfspath<NFS_MAXPATHLEN>;
+
+/*
+ * Reply status with file attributes
+ */
+union attrstat switch (nfsstat status) {
+case NFS_OK:
+ fattr attributes;
+default:
+ void;
+};
+
+struct sattrargs {
+ nfs_fh file;
+ sattr attributes;
+};
+
+/*
+ * Arguments for directory operations
+ */
+struct diropargs {
+ nfs_fh dir; /* directory file handle */
+ filename name; /* name (up to NFS_MAXNAMLEN bytes) */
+};
+
+struct diropokres {
+ nfs_fh file;
+ fattr attributes;
+};
+
+/*
+ * Results from directory operation
+ */
+union diropres switch (nfsstat status) {
+case NFS_OK:
+ diropokres diropres;
+default:
+ void;
+};
+
+union readlinkres switch (nfsstat status) {
+case NFS_OK:
+ nfspath data;
+default:
+ void;
+};
+
+/*
+ * Arguments to remote read
+ */
+struct readargs {
+ nfs_fh file; /* handle for file */
+ unsigned offset; /* byte offset in file */
+ unsigned count; /* immediate read count */
+ unsigned totalcount; /* total read count (from this offset)*/
+};
+
+/*
+ * Status OK portion of remote read reply
+ */
+struct readokres {
+ fattr attributes; /* attributes, need for pagin*/
+ opaque data<NFS_MAXDATA>;
+};
+
+union readres switch (nfsstat status) {
+case NFS_OK:
+ readokres reply;
+default:
+ void;
+};
+
+/*
+ * Arguments to remote write
+ */
+struct writeargs {
+ nfs_fh file; /* handle for file */
+ unsigned beginoffset; /* beginning byte offset in file */
+ unsigned offset; /* current byte offset in file */
+ unsigned totalcount; /* total write count (to this offset)*/
+ opaque data<NFS_MAXDATA>;
+};
+
+struct createargs {
+ diropargs where;
+ sattr attributes;
+};
+
+struct renameargs {
+ diropargs from;
+ diropargs to;
+};
+
+struct linkargs {
+ nfs_fh from;
+ diropargs to;
+};
+
+struct symlinkargs {
+ diropargs from;
+ nfspath to;
+ sattr attributes;
+};
+
+
+typedef opaque nfscookie[NFS_COOKIESIZE];
+
+/*
+ * Arguments to readdir
+ */
+struct readdirargs {
+ nfs_fh dir; /* directory handle */
+ nfscookie cookie;
+ unsigned count; /* number of directory bytes to read */
+};
+
+struct entry {
+ unsigned fileid;
+ filename name;
+ nfscookie cookie;
+ entry *nextentry;
+};
+
+struct dirlist {
+ entry *entries;
+ bool eof;
+};
+
+union readdirres switch (nfsstat status) {
+case NFS_OK:
+ dirlist reply;
+default:
+ void;
+};
+
+struct statfsokres {
+ unsigned tsize; /* preferred transfer size in bytes */
+ unsigned bsize; /* fundamental file system block size */
+ unsigned blocks; /* total blocks in file system */
+ unsigned bfree; /* free blocks in fs */
+ unsigned bavail; /* free blocks avail to non-superuser */
+};
+
+union statfsres switch (nfsstat status) {
+case NFS_OK:
+ statfsokres reply;
+default:
+ void;
+};
+
+#ifdef WANT_NFS3
+
+/*
+ * NFSv3 constants and types
+ */
+const NFS3_FHSIZE = 64; /* maximum size in bytes of a file handle */
+const NFS3_COOKIEVERFSIZE = 8; /* size of a cookie verifier for READDIR */
+const NFS3_CREATEVERFSIZE = 8; /* size of the verifier used for CREATE */
+const NFS3_WRITEVERFSIZE = 8; /* size of the verifier used for WRITE */
+
+typedef unsigned hyper uint64;
+typedef hyper int64;
+typedef unsigned long uint32;
+typedef long int32;
+typedef string filename3<>;
+typedef string nfspath3<>;
+typedef uint64 fileid3;
+typedef uint64 cookie3;
+typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE];
+typedef opaque createverf3[NFS3_CREATEVERFSIZE];
+typedef opaque writeverf3[NFS3_WRITEVERFSIZE];
+typedef uint32 uid3;
+typedef uint32 gid3;
+typedef uint64 size3;
+typedef uint64 offset3;
+typedef uint32 mode3;
+typedef uint32 count3;
+
+/*
+ * Error status (v3)
+ */
+enum nfsstat3 {
+ NFS3_OK = 0,
+ NFS3ERR_PERM = 1,
+ NFS3ERR_NOENT = 2,
+ NFS3ERR_IO = 5,
+ NFS3ERR_NXIO = 6,
+ NFS3ERR_ACCES = 13,
+ NFS3ERR_EXIST = 17,
+ NFS3ERR_XDEV = 18,
+ NFS3ERR_NODEV = 19,
+ NFS3ERR_NOTDIR = 20,
+ NFS3ERR_ISDIR = 21,
+ NFS3ERR_INVAL = 22,
+ NFS3ERR_FBIG = 27,
+ NFS3ERR_NOSPC = 28,
+ NFS3ERR_ROFS = 30,
+ NFS3ERR_MLINK = 31,
+ NFS3ERR_NAMETOOLONG = 63,
+ NFS3ERR_NOTEMPTY = 66,
+ NFS3ERR_DQUOT = 69,
+ NFS3ERR_STALE = 70,
+ NFS3ERR_REMOTE = 71,
+ NFS3ERR_BADHANDLE = 10001,
+ NFS3ERR_NOT_SYNC = 10002,
+ NFS3ERR_BAD_COOKIE = 10003,
+ NFS3ERR_NOTSUPP = 10004,
+ NFS3ERR_TOOSMALL = 10005,
+ NFS3ERR_SERVERFAULT = 10006,
+ NFS3ERR_BADTYPE = 10007,
+ NFS3ERR_JUKEBOX = 10008
+};
+
+/*
+ * File types (v3)
+ */
+enum ftype3 {
+ NF3REG = 1, /* regular file */
+ NF3DIR = 2, /* directory */
+ NF3BLK = 3, /* block special */
+ NF3CHR = 4, /* character special */
+ NF3LNK = 5, /* symbolic link */
+ NF3SOCK = 6, /* unix domain sockets */
+ NF3FIFO = 7 /* named pipe */
+};
+
+struct specdata3 {
+ uint32 specdata1;
+ uint32 specdata2;
+};
+
+/*
+ * File access handle (v3)
+ */
+struct nfs_fh3 {
+ opaque data<NFS3_FHSIZE>;
+};
+
+/*
+ * Timeval (v3)
+ */
+struct nfstime3 {
+ uint32 seconds;
+ uint32 nseconds;
+};
+
+
+/*
+ * File attributes (v3)
+ */
+struct fattr3 {
+ ftype3 type; /* file type */
+ mode3 mode; /* protection mode bits */
+ uint32 nlink; /* # hard links */
+ uid3 uid; /* owner user id */
+ gid3 gid; /* owner group id */
+ size3 size; /* file size in bytes */
+ size3 used; /* prefered block size */
+ specdata3 rdev; /* special device # */
+ uint64 fsid; /* device # */
+ fileid3 fileid; /* inode # */
+ nfstime3 atime; /* time of last access */
+ nfstime3 mtime; /* time of last modification */
+ nfstime3 ctime; /* time of last change */
+};
+
+union post_op_attr switch (bool attributes_follow) {
+case TRUE:
+ fattr3 attributes;
+case FALSE:
+ void;
+};
+
+struct wcc_attr {
+ size3 size;
+ nfstime3 mtime;
+ nfstime3 ctime;
+};
+
+union pre_op_attr switch (bool attributes_follow) {
+case TRUE:
+ wcc_attr attributes;
+case FALSE:
+ void;
+};
+
+struct wcc_data {
+ pre_op_attr before;
+ post_op_attr after;
+};
+
+union post_op_fh3 switch (bool handle_follows) {
+case TRUE:
+ nfs_fh3 handle;
+case FALSE:
+ void;
+};
+
+/*
+ * File attributes which can be set (v3)
+ */
+enum time_how {
+ DONT_CHANGE = 0,
+ SET_TO_SERVER_TIME = 1,
+ SET_TO_CLIENT_TIME = 2
+};
+
+union set_mode3 switch (bool set_it) {
+case TRUE:
+ mode3 mode;
+default:
+ void;
+};
+
+union set_uid3 switch (bool set_it) {
+case TRUE:
+ uid3 uid;
+default:
+ void;
+};
+
+union set_gid3 switch (bool set_it) {
+case TRUE:
+ gid3 gid;
+default:
+ void;
+};
+
+union set_size3 switch (bool set_it) {
+case TRUE:
+ size3 size;
+default:
+ void;
+};
+
+union set_atime switch (time_how set_it) {
+case SET_TO_CLIENT_TIME:
+ nfstime3 atime;
+default:
+ void;
+};
+
+union set_mtime switch (time_how set_it) {
+case SET_TO_CLIENT_TIME:
+ nfstime3 mtime;
+default:
+ void;
+};
+
+struct sattr3 {
+ set_mode3 mode;
+ set_uid3 uid;
+ set_gid3 gid;
+ set_size3 size;
+ set_atime atime;
+ set_mtime mtime;
+};
+
+/*
+ * Arguments for directory operations (v3)
+ */
+struct diropargs3 {
+ nfs_fh3 dir; /* directory file handle */
+ filename3 name; /* name (up to NFS_MAXNAMLEN bytes) */
+};
+
+/*
+ * Arguments to getattr (v3).
+ */
+struct GETATTR3args {
+ nfs_fh3 object;
+};
+
+struct GETATTR3resok {
+ fattr3 obj_attributes;
+};
+
+union GETATTR3res switch (nfsstat3 status) {
+case NFS3_OK:
+ GETATTR3resok resok;
+default:
+ void;
+};
+
+/*
+ * Arguments to setattr (v3).
+ */
+union sattrguard3 switch (bool check) {
+case TRUE:
+ nfstime3 obj_ctime;
+case FALSE:
+ void;
+};
+
+struct SETATTR3args {
+ nfs_fh3 object;
+ sattr3 new_attributes;
+ sattrguard3 guard;
+};
+
+struct SETATTR3resok {
+ wcc_data obj_wcc;
+};
+
+struct SETATTR3resfail {
+ wcc_data obj_wcc;
+};
+
+union SETATTR3res switch (nfsstat3 status) {
+case NFS3_OK:
+ SETATTR3resok resok;
+default:
+ SETATTR3resfail resfail;
+};
+
+/*
+ * Arguments to lookup (v3).
+ */
+struct LOOKUP3args {
+ diropargs3 what;
+};
+
+struct LOOKUP3resok {
+ nfs_fh3 object;
+ post_op_attr obj_attributes;
+ post_op_attr dir_attributes;
+};
+
+struct LOOKUP3resfail {
+ post_op_attr dir_attributes;
+};
+
+union LOOKUP3res switch (nfsstat3 status) {
+case NFS3_OK:
+ LOOKUP3resok resok;
+default:
+ LOOKUP3resfail resfail;
+};
+
+/*
+ * Arguments to access (v3).
+ */
+const ACCESS3_READ = 0x0001;
+const ACCESS3_LOOKUP = 0x0002;
+const ACCESS3_MODIFY = 0x0004;
+const ACCESS3_EXTEND = 0x0008;
+const ACCESS3_DELETE = 0x0010;
+const ACCESS3_EXECUTE = 0x0020;
+
+struct ACCESS3args {
+ nfs_fh3 object;
+ uint32 access;
+};
+
+struct ACCESS3resok {
+ post_op_attr obj_attributes;
+ uint32 access;
+};
+
+struct ACCESS3resfail {
+ post_op_attr obj_attributes;
+};
+
+union ACCESS3res switch (nfsstat3 status) {
+case NFS3_OK:
+ ACCESS3resok resok;
+default:
+ ACCESS3resfail resfail;
+};
+
+/*
+ * Arguments to readlink (v3).
+ */
+struct READLINK3args {
+ nfs_fh3 symlink;
+};
+
+struct READLINK3resok {
+ post_op_attr symlink_attributes;
+ nfspath3 data;
+};
+
+struct READLINK3resfail {
+ post_op_attr symlink_attributes;
+};
+
+union READLINK3res switch (nfsstat3 status) {
+case NFS3_OK:
+ READLINK3resok resok;
+default:
+ READLINK3resfail resfail;
+};
+
+/*
+ * Arguments to read (v3).
+ */
+struct READ3args {
+ nfs_fh3 file;
+ offset3 offset;
+ count3 count;
+};
+
+struct READ3resok {
+ post_op_attr file_attributes;
+ count3 count;
+ bool eof;
+ opaque data<>;
+};
+
+struct READ3resfail {
+ post_op_attr file_attributes;
+};
+
+/* XXX: solaris 2.6 uses ``nfsstat'' here */
+union READ3res switch (nfsstat3 status) {
+case NFS3_OK:
+ READ3resok resok;
+default:
+ READ3resfail resfail;
+};
+
+/*
+ * Arguments to write (v3).
+ */
+enum stable_how {
+ UNSTABLE = 0,
+ DATA_SYNC = 1,
+ FILE_SYNC = 2
+};
+
+struct WRITE3args {
+ nfs_fh3 file;
+ offset3 offset;
+ count3 count;
+ stable_how stable;
+ opaque data<>;
+};
+
+struct WRITE3resok {
+ wcc_data file_wcc;
+ count3 count;
+ stable_how committed;
+ writeverf3 verf;
+};
+
+struct WRITE3resfail {
+ wcc_data file_wcc;
+};
+
+union WRITE3res switch (nfsstat3 status) {
+case NFS3_OK:
+ WRITE3resok resok;
+default:
+ WRITE3resfail resfail;
+};
+
+/*
+ * Arguments to create (v3).
+ */
+enum createmode3 {
+ UNCHECKED = 0,
+ GUARDED = 1,
+ EXCLUSIVE = 2
+};
+
+union createhow3 switch (createmode3 mode) {
+case UNCHECKED:
+case GUARDED:
+ sattr3 obj_attributes;
+case EXCLUSIVE:
+ createverf3 verf;
+};
+
+struct CREATE3args {
+ diropargs3 where;
+ createhow3 how;
+};
+
+struct CREATE3resok {
+ post_op_fh3 obj;
+ post_op_attr obj_attributes;
+ wcc_data dir_wcc;
+};
+
+struct CREATE3resfail {
+ wcc_data dir_wcc;
+};
+
+union CREATE3res switch (nfsstat3 status) {
+case NFS3_OK:
+ CREATE3resok resok;
+default:
+ CREATE3resfail resfail;
+};
+
+/*
+ * Arguments to mkdir (v3).
+ */
+struct MKDIR3args {
+ diropargs3 where;
+ sattr3 attributes;
+};
+
+struct MKDIR3resok {
+ post_op_fh3 obj;
+ post_op_attr obj_attributes;
+ wcc_data dir_wcc;
+};
+
+struct MKDIR3resfail {
+ wcc_data dir_wcc;
+};
+
+union MKDIR3res switch (nfsstat3 status) {
+case NFS3_OK:
+ MKDIR3resok resok;
+default:
+ MKDIR3resfail resfail;
+};
+
+/*
+ * Arguments to symlink (v3).
+ */
+struct symlinkdata3 {
+ sattr3 symlink_attributes;
+ nfspath3 symlink_data;
+};
+
+struct SYMLINK3args {
+ diropargs3 where;
+ symlinkdata3 symlink;
+};
+
+struct SYMLINK3resok {
+ post_op_fh3 obj;
+ post_op_attr obj_attributes;
+ wcc_data dir_wcc;
+};
+
+struct SYMLINK3resfail {
+ wcc_data dir_wcc;
+};
+
+union SYMLINK3res switch (nfsstat3 status) {
+case NFS3_OK:
+ SYMLINK3resok resok;
+default:
+ SYMLINK3resfail resfail;
+};
+
+/*
+ * Arguments to mknod (v3).
+ */
+struct devicedata3 {
+ sattr3 dev_attributes;
+ specdata3 spec;
+};
+
+union mknoddata3 switch (ftype3 type) {
+case NF3CHR:
+case NF3BLK:
+ devicedata3 device;
+case NF3SOCK:
+case NF3FIFO:
+ sattr3 pipe_attributes;
+default:
+ void;
+};
+
+struct MKNOD3args {
+ diropargs3 where;
+ mknoddata3 what;
+};
+
+struct MKNOD3resok {
+ post_op_fh3 obj;
+ post_op_attr obj_attributes;
+ wcc_data dir_wcc;
+};
+
+struct MKNOD3resfail {
+ wcc_data dir_wcc;
+};
+
+union MKNOD3res switch (nfsstat3 status) {
+case NFS3_OK:
+ MKNOD3resok resok;
+default:
+ MKNOD3resfail resfail;
+};
+
+/*
+ * Arguments to remove (v3).
+ */
+struct REMOVE3args {
+ diropargs3 object;
+};
+
+struct REMOVE3resok {
+ wcc_data dir_wcc;
+};
+
+struct REMOVE3resfail {
+ wcc_data dir_wcc;
+};
+
+union REMOVE3res switch (nfsstat3 status) {
+case NFS3_OK:
+ REMOVE3resok resok;
+default:
+ REMOVE3resfail resfail;
+};
+
+/*
+ * Arguments to rmdir (v3).
+ */
+struct RMDIR3args {
+ diropargs3 object;
+};
+
+struct RMDIR3resok {
+ wcc_data dir_wcc;
+};
+
+struct RMDIR3resfail {
+ wcc_data dir_wcc;
+};
+
+union RMDIR3res switch (nfsstat3 status) {
+case NFS3_OK:
+ RMDIR3resok resok;
+default:
+ RMDIR3resfail resfail;
+};
+
+/*
+ * Arguments to rename (v3).
+ */
+struct RENAME3args {
+ diropargs3 from;
+ diropargs3 to;
+};
+
+struct RENAME3resok {
+ wcc_data fromdir_wcc;
+ wcc_data todir_wcc;
+};
+
+struct RENAME3resfail {
+ wcc_data fromdir_wcc;
+ wcc_data todir_wcc;
+};
+
+union RENAME3res switch (nfsstat3 status) {
+case NFS3_OK:
+ RENAME3resok resok;
+default:
+ RENAME3resfail resfail;
+};
+
+/*
+ * Arguments to link (v3).
+ */
+struct LINK3args {
+ nfs_fh3 file;
+ diropargs3 link;
+};
+
+struct LINK3resok {
+ post_op_attr file_attributes;
+ wcc_data linkdir_wcc;
+};
+
+struct LINK3resfail {
+ post_op_attr file_attributes;
+ wcc_data linkdir_wcc;
+};
+
+union LINK3res switch (nfsstat3 status) {
+case NFS3_OK:
+ LINK3resok resok;
+default:
+ LINK3resfail resfail;
+};
+
+/*
+ * Arguments to readdir (v3).
+ */
+struct READDIR3args {
+ nfs_fh3 dir;
+ cookie3 cookie;
+ cookieverf3 cookieverf;
+ count3 count;
+};
+
+struct entry3 {
+ fileid3 fileid;
+ filename3 name;
+ cookie3 cookie;
+ entry3 *nextentry;
+};
+
+struct dirlist3 {
+ entry3 *entries;
+ bool eof;
+};
+
+struct READDIR3resok {
+ post_op_attr dir_attributes;
+ cookieverf3 cookieverf;
+ dirlist3 reply;
+};
+
+struct READDIR3resfail {
+ post_op_attr dir_attributes;
+};
+
+union READDIR3res switch (nfsstat3 status) {
+case NFS3_OK:
+ READDIR3resok resok;
+default:
+ READDIR3resfail resfail;
+};
+
+/*
+ * Arguments to readdirplus (v3).
+ */
+struct READDIRPLUS3args {
+ nfs_fh3 dir;
+ cookie3 cookie;
+ cookieverf3 cookieverf;
+ count3 dircount;
+ count3 maxcount;
+};
+
+struct entryplus3 {
+ fileid3 fileid;
+ filename3 name;
+ cookie3 cookie;
+ post_op_attr name_attributes;
+ post_op_fh3 name_handle;
+ entryplus3 *nextentry;
+};
+
+struct dirlistplus3 {
+ entryplus3 *entries;
+ bool eof;
+};
+
+struct READDIRPLUS3resok {
+ post_op_attr dir_attributes;
+ cookieverf3 cookieverf;
+ dirlistplus3 reply;
+};
+
+struct READDIRPLUS3resfail {
+ post_op_attr dir_attributes;
+};
+
+union READDIRPLUS3res switch (nfsstat3 status) {
+case NFS3_OK:
+ READDIRPLUS3resok resok;
+default:
+ READDIRPLUS3resfail resfail;
+};
+
+/*
+ * Arguments to fsstat (v3).
+ */
+struct FSSTAT3args {
+ nfs_fh3 fsroot;
+};
+
+struct FSSTAT3resok {
+ post_op_attr obj_attributes;
+ size3 tbytes;
+ size3 fbytes;
+ size3 abytes;
+ size3 tfiles;
+ size3 ffiles;
+ size3 afiles;
+ uint32 invarsec;
+};
+
+struct FSSTAT3resfail {
+ post_op_attr obj_attributes;
+};
+
+union FSSTAT3res switch (nfsstat3 status) {
+case NFS3_OK:
+ FSSTAT3resok resok;
+default:
+ FSSTAT3resfail resfail;
+};
+
+/*
+ * Arguments to fsinfo (v3).
+ */
+const FSF3_LINK = 0x0001;
+const FSF3_SYMLINK = 0x0002;
+const FSF3_HOMOGENEOUS = 0x0008;
+const FSF3_CANSETTIME = 0x0010;
+
+struct FSINFO3args {
+ nfs_fh3 fsroot;
+};
+
+struct FSINFO3resok {
+ post_op_attr obj_attributes;
+ uint32 rtmax;
+ uint32 rtpref;
+ uint32 rtmult;
+ uint32 wtmax;
+ uint32 wtpref;
+ uint32 wtmult;
+ uint32 dtpref;
+ size3 maxfilesize;
+ nfstime3 time_delta;
+ uint32 properties;
+};
+
+struct FSINFO3resfail {
+ post_op_attr obj_attributes;
+};
+
+union FSINFO3res switch (nfsstat3 status) {
+case NFS3_OK:
+ FSINFO3resok resok;
+default:
+ FSINFO3resfail resfail;
+};
+
+/*
+ * Arguments to pathconf (v3).
+ */
+struct PATHCONF3args {
+ nfs_fh3 object;
+};
+
+struct PATHCONF3resok {
+ post_op_attr obj_attributes;
+ uint32 linkmax;
+ uint32 name_max;
+ bool no_trunc;
+ bool chown_restricted;
+ bool case_insensitive;
+ bool case_preserving;
+};
+
+struct PATHCONF3resfail {
+ post_op_attr obj_attributes;
+};
+
+union PATHCONF3res switch (nfsstat3 status) {
+case NFS3_OK:
+ PATHCONF3resok resok;
+default:
+ PATHCONF3resfail resfail;
+};
+
+/*
+ * Arguments to commit (v3).
+ */
+struct COMMIT3args {
+ nfs_fh3 file;
+ offset3 offset;
+ count3 count;
+};
+
+struct COMMIT3resok {
+ wcc_data file_wcc;
+ writeverf3 verf;
+};
+
+struct COMMIT3resfail {
+ wcc_data file_wcc;
+};
+
+union COMMIT3res switch (nfsstat3 status) {
+case NFS3_OK:
+ COMMIT3resok resok;
+default:
+ COMMIT3resfail resfail;
+};
+
+#endif /* WANT_NFS3 */
+
+/*
+ * Remote file service routines
+ */
+program NFS_PROGRAM {
+ version NFS_VERSION {
+ void
+ NFSPROC_NULL(void) = 0;
+
+ attrstat
+ NFSPROC_GETATTR(nfs_fh) = 1;
+
+ attrstat
+ NFSPROC_SETATTR(sattrargs) = 2;
+
+ void
+ NFSPROC_ROOT(void) = 3;
+
+ diropres
+ NFSPROC_LOOKUP(diropargs) = 4;
+
+ readlinkres
+ NFSPROC_READLINK(nfs_fh) = 5;
+
+ readres
+ NFSPROC_READ(readargs) = 6;
+
+ void
+ NFSPROC_WRITECACHE(void) = 7;
+
+ attrstat
+ NFSPROC_WRITE(writeargs) = 8;
+
+ diropres
+ NFSPROC_CREATE(createargs) = 9;
+
+ nfsstat
+ NFSPROC_REMOVE(diropargs) = 10;
+
+ nfsstat
+ NFSPROC_RENAME(renameargs) = 11;
+
+ nfsstat
+ NFSPROC_LINK(linkargs) = 12;
+
+ nfsstat
+ NFSPROC_SYMLINK(symlinkargs) = 13;
+
+ diropres
+ NFSPROC_MKDIR(createargs) = 14;
+
+ nfsstat
+ NFSPROC_RMDIR(diropargs) = 15;
+
+ readdirres
+ NFSPROC_READDIR(readdirargs) = 16;
+
+ statfsres
+ NFSPROC_STATFS(nfs_fh) = 17;
+ } = 2;
+} = 100003;
+#ifdef WANT_NFS3
+program NFS3_PROGRAM {
+ version NFS_V3 {
+ void
+ NFSPROC3_NULL(void) = 0;
+
+ GETATTR3res
+ NFSPROC3_GETATTR(GETATTR3args) = 1;
+
+ SETATTR3res
+ NFSPROC3_SETATTR(SETATTR3args) = 2;
+
+ LOOKUP3res
+ NFSPROC3_LOOKUP(LOOKUP3args) = 3;
+
+ ACCESS3res
+ NFSPROC3_ACCESS(ACCESS3args) = 4;
+
+ READLINK3res
+ NFSPROC3_READLINK(READLINK3args) = 5;
+
+ READ3res
+ NFSPROC3_READ(READ3args) = 6;
+
+ WRITE3res
+ NFSPROC3_WRITE(WRITE3args) = 7;
+
+ CREATE3res
+ NFSPROC3_CREATE(CREATE3args) = 8;
+
+ MKDIR3res
+ NFSPROC3_MKDIR(MKDIR3args) = 9;
+
+ SYMLINK3res
+ NFSPROC3_SYMLINK(SYMLINK3args) = 10;
+
+ MKNOD3res
+ NFSPROC3_MKNOD(MKNOD3args) = 11;
+
+ REMOVE3res
+ NFSPROC3_REMOVE(REMOVE3args) = 12;
+
+ RMDIR3res
+ NFSPROC3_RMDIR(RMDIR3args) = 13;
+
+ RENAME3res
+ NFSPROC3_RENAME(RENAME3args) = 14;
+
+ LINK3res
+ NFSPROC3_LINK(LINK3args) = 15;
+
+ READDIR3res
+ NFSPROC3_READDIR(READDIR3args) = 16;
+
+ READDIRPLUS3res
+ NFSPROC3_READDIRPLUS(READDIRPLUS3args) = 17;
+
+ FSSTAT3res
+ NFSPROC3_FSSTAT(FSSTAT3args) = 18;
+
+ FSINFO3res
+ NFSPROC3_FSINFO(FSINFO3args) = 19;
+
+ PATHCONF3res
+ NFSPROC3_PATHCONF(PATHCONF3args) = 20;
+
+ COMMIT3res
+ NFSPROC3_COMMIT(COMMIT3args) = 21;
+ } = 3;
+} = 100003;
+#endif
diff --git a/librpc/include/rpcsvc/nis.x b/librpc/include/rpcsvc/nis.x
new file mode 100644
index 0000000..ba6c6d1
--- /dev/null
+++ b/librpc/include/rpcsvc/nis.x
@@ -0,0 +1,466 @@
+%/*
+% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+% * unrestricted use provided that this legend is included on all tape
+% * media and as a part of the software program in whole or part. Users
+% * may copy or modify Sun RPC without charge, but are not authorized
+% * to license or distribute it to anyone else except as part of a product or
+% * program developed by the user or with the express written consent of
+% * Sun Microsystems, Inc.
+% *
+% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+% *
+% * Sun RPC is provided with no support and without any obligation on the
+% * part of Sun Microsystems, Inc. to assist in its use, correction,
+% * modification or enhancement.
+% *
+% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+% * OR ANY PART THEREOF.
+% *
+% * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+% * or profits or other special, indirect and consequential damages, even if
+% * Sun has been advised of the possibility of such damages.
+% *
+% * Sun Microsystems, Inc.
+% * 2550 Garcia Avenue
+% * Mountain View, California 94043
+% */
+
+#ifndef RPC_HDR
+%#ifndef lint
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/nis.x,v 1.3 1999/08/27 23:45:09 peter Exp $";
+%#endif /* not lint */
+#endif
+
+/*
+ * From 4.1 : @(#)nis.x 1.61 Copyright 1989 Sun Microsystems
+ *
+ * RPC Language Protocol description file for NIS Plus
+ * This version : 1.61
+ * Last Modified : 3/19/91
+ */
+#ifdef RPC_HDR
+%/*
+% * 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 : DO NOT EDIT THIS FILE! It is automatically generated when
+% * rpcgen is run on the nis.x file. Note that there is a
+% * simple sed script to remove some unneeded lines. (See the
+% * Makefile target nis.h)
+% *
+% */
+%#include <rpcsvc/nis_tags.h>
+#endif
+
+/* This gets stuffed into the source files. */
+#if RPC_HDR
+%#include <rpc/xdr.h>
+#endif
+/*
+ * This is just pointless.
+ */
+#ifdef SUN_STUPIDITY
+#if RPC_SVC
+%#include "nis_svc.h"
+#endif
+#endif
+
+/* Include the RPC Language description of NIS objects */
+#include "nis_object.x"
+
+/* Errors that can be returned by the service */
+enum nis_error {
+ NIS_SUCCESS = 0, /* A-ok, let's rock n roll */
+ NIS_S_SUCCESS = 1, /* Name found (maybe) */
+ NIS_NOTFOUND = 2, /* Name definitely not found */
+ NIS_S_NOTFOUND = 3, /* Name maybe not found */
+ NIS_CACHEEXPIRED = 4, /* Name exists but cache out of date */
+ NIS_NAMEUNREACHABLE = 5, /* Can't get there from here */
+ NIS_UNKNOWNOBJ = 6, /* Object type is bogus */
+ NIS_TRYAGAIN = 7, /* I'm busy, call back */
+ NIS_SYSTEMERROR = 8, /* Out of band failure */
+ NIS_CHAINBROKEN = 9, /* First/Next warning */
+ NIS_PERMISSION = 10, /* Not enough permission to access */
+ NIS_NOTOWNER = 11, /* You don't own it, sorry */
+ NIS_NOT_ME = 12, /* I don't serve this name */
+ NIS_NOMEMORY = 13, /* Outta VM! Help! */
+ NIS_NAMEEXISTS = 14, /* Can't create over another name */
+ NIS_NOTMASTER = 15, /* I'm justa secondaray, don't ask me */
+ NIS_INVALIDOBJ = 16, /* Object is broken somehow */
+ NIS_BADNAME = 17, /* Unparsable name */
+ NIS_NOCALLBACK = 18, /* Couldn't talk to call back proc */
+ NIS_CBRESULTS = 19, /* Results being called back to you */
+ NIS_NOSUCHNAME = 20, /* Name unknown */
+ NIS_NOTUNIQUE = 21, /* Value is not uniques (entry) */
+ NIS_IBMODERROR = 22, /* Inf. Base. Modify error. */
+ NIS_NOSUCHTABLE = 23, /* Name for table was wrong */
+ NIS_TYPEMISMATCH = 24, /* Entry and table type mismatch */
+ NIS_LINKNAMEERROR = 25, /* Link points to bogus name */
+ NIS_PARTIAL = 26, /* Partial success, found table */
+ NIS_TOOMANYATTRS = 27, /* Too many attributes */
+ NIS_RPCERROR = 28, /* RPC error encountered */
+ NIS_BADATTRIBUTE = 29, /* Bad or invalid attribute */
+ NIS_NOTSEARCHABLE = 30, /* Non-searchable object searched */
+ NIS_CBERROR = 31, /* Error during callback (svc crash) */
+ NIS_FOREIGNNS = 32, /* Foreign Namespace */
+ NIS_BADOBJECT = 33, /* Malformed object structure */
+ NIS_NOTSAMEOBJ = 34, /* Object swapped during deletion */
+ NIS_MODFAIL = 35, /* Failure during a Modify. */
+ NIS_BADREQUEST = 36, /* Illegal query for table */
+ NIS_NOTEMPTY = 37, /* Attempt to remove a non-empty tbl */
+ NIS_COLDSTART_ERR = 38, /* Error accesing the cold start file */
+ NIS_RESYNC = 39, /* Transaction log too far out of date */
+ NIS_FAIL = 40, /* NIS operation failed. */
+ NIS_UNAVAIL = 41, /* NIS+ service is unavailable (client) */
+ NIS_RES2BIG = 42, /* NIS+ result too big for datagram */
+ NIS_SRVAUTH = 43, /* NIS+ server wasn't authenticated. */
+ NIS_CLNTAUTH = 44, /* NIS+ Client wasn't authenticated. */
+ NIS_NOFILESPACE = 45, /* NIS+ server ran out of disk space */
+ NIS_NOPROC = 46, /* NIS+ server couldn't create new proc */
+ NIS_DUMPLATER = 47 /* NIS+ server already has dump child */
+};
+
+
+/*
+ * Structure definitions for the parameters and results of the actual
+ * NIS RPC calls.
+ *
+ * This is the standard result (in the protocol) of most of the nis
+ * requests.
+ */
+
+struct nis_result {
+ nis_error status; /* Status of the response */
+ nis_object objects<>; /* objects found */
+ netobj cookie; /* Cookie Data */
+ u_long zticks; /* server ticks */
+ u_long dticks; /* DBM ticks. */
+ u_long aticks; /* Cache (accel) ticks */
+ u_long cticks; /* Client ticks */
+};
+
+/*
+ * A Name Service request
+ * This request is used to access the name space, ns_name is the name
+ * of the object within the namespace and the object is it's value, for
+ * add/modify, a copy of the original for remove.
+ */
+
+struct ns_request {
+ nis_name ns_name; /* Name in the NIS name space */
+ nis_object ns_object<1>; /* Optional Object (add/remove) */
+};
+
+/*
+ * An information base request
+ * This request includes the NIS name of the table we wish to search, the
+ * search criteria in the form of attribute/value pairs and an optional
+ * callback program number. If the callback program number is provided
+ * the server will send back objects one at a time, otherwise it will
+ * return them all in the response.
+ */
+
+struct ib_request {
+ nis_name ibr_name; /* The name of the Table */
+ nis_attr ibr_srch<>; /* The search critereia */
+ u_long ibr_flags; /* Optional flags */
+ nis_object ibr_obj<1>; /* optional object (add/modify) */
+ nis_server ibr_cbhost<1>; /* Optional callback info */
+ u_long ibr_bufsize; /* Optional first/next bufsize */
+ netobj ibr_cookie; /* The first/next cookie */
+};
+
+/*
+ * This argument to the PING call notifies the replicas that something in
+ * a directory has changed and this is it's timestamp. The replica will use
+ * the timestamp to determine if its resync operation was successful.
+ */
+struct ping_args {
+ nis_name dir; /* Directory that had the change */
+ u_long stamp; /* timestamp of the transaction */
+};
+
+/*
+ * These are the type of entries that are stored in the transaction log,
+ * note that modifications will appear as two entries, for names, they have
+ * a "OLD" entry followed by a "NEW" entry. For entries in tables, there
+ * is a remove followed by an add. It is done this way so that we can read
+ * the log backwards to back out transactions and forwards to propogate
+ * updated.
+ */
+enum log_entry_t {
+ LOG_NOP = 0,
+ ADD_NAME = 1, /* Name Added to name space */
+ REM_NAME = 2, /* Name removed from name space */
+ MOD_NAME_OLD = 3, /* Name was modified in the name space */
+ MOD_NAME_NEW = 4, /* Name was modified in the name space */
+ ADD_IBASE = 5, /* Entry added to information base */
+ REM_IBASE = 6, /* Entry removed from information base */
+ MOD_IBASE = 7, /* Entry was modified in information base */
+ UPD_STAMP = 8 /* Update timestamp (used as fenceposts) */
+};
+
+/*
+ * This result is returned from the name service when it is requested to
+ * dump logged entries from its transaction log. Information base updates
+ * will have the name of the information base in the le_name field and
+ * a canonical set of attribute/value pairs to fully specify the entry's
+ * 'name'.
+ */
+struct log_entry {
+ u_long le_time; /* Time in seconds */
+ log_entry_t le_type; /* Type of log entry */
+ nis_name le_princp; /* Principal making the change */
+ nis_name le_name; /* Name of table/dir involved */
+ nis_attr le_attrs<>; /* List of AV pairs. */
+ nis_object le_object; /* Actual object value */
+};
+
+struct log_result {
+ nis_error lr_status; /* The status itself */
+ netobj lr_cookie; /* Used by the dump callback */
+ log_entry lr_entries<>; /* zero or more entries */
+};
+
+struct cp_result {
+ nis_error cp_status; /* Status of the checkpoint */
+ u_long cp_zticks; /* Service 'ticks' */
+ u_long cp_dticks; /* Database 'ticks' */
+};
+
+/*
+ * This structure defines a generic NIS tag list. The taglist contains
+ * zero or tags, each of which is a type and a value. (u_long).
+ * These are used to report statistics (see tag definitions below)
+ * and to set or reset state variables.
+ */
+struct nis_tag {
+ u_long tag_type; /* Statistic tag (may vary) */
+ string tag_val<1024>; /* Statistic value may also vary */
+};
+
+struct nis_taglist {
+ nis_tag tags<>; /* List of tags */
+};
+
+struct dump_args {
+ nis_name da_dir; /* Directory to dump */
+ u_long da_time; /* From this timestamp */
+ nis_server da_cbhost<1>; /* Callback to use. */
+};
+
+struct fd_args {
+ nis_name dir_name; /* The directory we're looking for */
+ nis_name requester; /* Host principal name for signature */
+};
+
+struct fd_result {
+ nis_error status; /* Status returned by function */
+ nis_name source; /* Source of this answer */
+ opaque dir_data<>; /* Directory Data (XDR'ed) */
+ opaque signature<>; /* Signature of the source */
+};
+
+
+/*
+ * What's going on here? Well, it's like this. When the service
+ * is being compiled it wants to have the service definition specific
+ * info included, and when the client is being compiled it wants that
+ * info. This includes the appropriate file which was generated by
+ * make in the protocols directory (probably /usr/include/rpcsvc).
+ *
+ * Uhm... guys? With RPC, you aren't supposed to have seperate
+ * server-specific and client-specific header files. You have one header
+ * file that's suitable for both. If your code doesn't work using just
+ * the one header file, I submit to you that it's broken.
+ * -Bill
+ */
+#ifdef SUN_STUPIDITY
+#ifdef RPC_SVC
+%#include "nis_svc.h"
+#endif
+#ifdef RPC_CLNT
+%#include "nis_clnt.h"
+#endif
+#endif
+
+program NIS_PROG {
+
+ /* RPC Language description of the NIS+ protocol */
+ version NIS_VERSION {
+ /* The name service functions */
+ nis_result NIS_LOOKUP(ns_request) = 1;
+ nis_result NIS_ADD(ns_request) = 2;
+ nis_result NIS_MODIFY(ns_request) = 3;
+ nis_result NIS_REMOVE(ns_request) = 4;
+
+ /* The information base functions */
+ nis_result NIS_IBLIST(ib_request) = 5;
+ nis_result NIS_IBADD(ib_request) = 6;
+ nis_result NIS_IBMODIFY(ib_request) = 7;
+ nis_result NIS_IBREMOVE(ib_request) = 8;
+ nis_result NIS_IBFIRST(ib_request) = 9;
+ nis_result NIS_IBNEXT(ib_request) = 10;
+
+ /* NIS Administrative functions */
+ fd_result NIS_FINDDIRECTORY(fd_args) = 12;
+
+ /* If fetch and optionally reset statistics */
+ nis_taglist NIS_STATUS(nis_taglist) = 14;
+
+ /* Dump changes to directory since time in da_time */
+ log_result NIS_DUMPLOG(dump_args) = 15;
+
+ /* Dump contents of directory named */
+ log_result NIS_DUMP(dump_args) = 16;
+
+ /* Check status of callback thread */
+ bool NIS_CALLBACK(netobj) = 17;
+
+ /* Return last update time for named dir */
+ u_long NIS_CPTIME(nis_name) = 18;
+
+ /* Checkpoint directory or table named */
+ cp_result NIS_CHECKPOINT(nis_name) = 19;
+
+ /* Send 'status changed' ping to replicates */
+ void NIS_PING(ping_args) = 20;
+
+ /* Modify server behaviour (such as debugging) */
+ nis_taglist NIS_SERVSTATE(nis_taglist) = 21;
+
+ /* Create a Directory */
+ nis_error NIS_MKDIR(nis_name) = 22;
+
+ /* Remove a Directory */
+ nis_error NIS_RMDIR(nis_name) = 23;
+
+ /* Update public keys of a directory object */
+ nis_error NIS_UPDKEYS(nis_name) = 24;
+ } = 3;
+} = 100300;
+
+/*
+ * Included below are the defines that become part of nis.h,
+ * they are technically not part of the protocol, but do define
+ * key aspects of the implementation and are therefore useful
+ * in building a conforming server or client.
+ */
+#if RPC_HDR
+%/*
+% * Generic "hash" datastructures, used by all types of hashed data.
+% */
+%struct nis_hash_data {
+% nis_name name; /* NIS name of hashed item */
+% int keychain; /* It's hash key (for pop) */
+% struct nis_hash_data *next; /* Hash collision pointer */
+% struct nis_hash_data *prv_item; /* A serial, doubly linked list */
+% struct nis_hash_data *nxt_item; /* of items in the hash table */
+%};
+%typedef struct nis_hash_data NIS_HASH_ITEM;
+%
+%struct nis_hash_table {
+% NIS_HASH_ITEM *keys[64]; /* A hash table of items */
+% NIS_HASH_ITEM *first; /* The first "item" in serial list */
+%};
+%typedef struct nis_hash_table NIS_HASH_TABLE;
+%
+%/* Structure for storing dynamically allocated static data */
+%struct nis_sdata {
+% void *buf; /* Memory allocation pointer */
+% u_long size; /* Buffer size */
+%};
+%
+%/* 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 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
+%
+%#ifdef __cplusplus
+%}
+%#endif
+%
+%/* Prototypes, and extern declarations for the NIS library functions. */
+%#include <rpcsvc/nislib.h>
+%#endif /* __NIS_RPCGEN_H */
+%/* EDIT_START */
+%
+%/*
+% * 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
+%#ifdef __cplusplus
+%extern "C" {
+%#endif
+#endif
diff --git a/librpc/include/rpcsvc/nis_cache.x b/librpc/include/rpcsvc/nis_cache.x
new file mode 100644
index 0000000..8343cfd
--- /dev/null
+++ b/librpc/include/rpcsvc/nis_cache.x
@@ -0,0 +1,87 @@
+%/*
+% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+% * unrestricted use provided that this legend is included on all tape
+% * media and as a part of the software program in whole or part. Users
+% * may copy or modify Sun RPC without charge, but are not authorized
+% * to license or distribute it to anyone else except as part of a product or
+% * program developed by the user or with the express written consent of
+% * Sun Microsystems, Inc.
+% *
+% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+% *
+% * Sun RPC is provided with no support and without any obligation on the
+% * part of Sun Microsystems, Inc. to assist in its use, correction,
+% * modification or enhancement.
+% *
+% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+% * OR ANY PART THEREOF.
+% *
+% * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+% * or profits or other special, indirect and consequential damages, even if
+% * Sun has been advised of the possibility of such damages.
+% *
+% * Sun Microsystems, Inc.
+% * 2550 Garcia Avenue
+% * Mountain View, California 94043
+% */
+
+/*
+ * nis_cache.x
+ *
+ * Copyright (c) 1988-1992 Sun Microsystems Inc
+ * All Rights Reserved.
+ */
+
+/* From: %#pragma ident "@(#)nis_cache.x 1.11 94/05/03 SMI" */
+
+#ifndef RPC_HDR
+%#ifndef lint
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/nis_cache.x,v 1.3 1999/08/27 23:45:09 peter Exp $";
+%#endif /* not lint */
+#endif
+
+#ifdef RPC_HDR
+%#include <rpc/types.h>
+%#include <rpcsvc/nis.h>
+%
+%/* default cache file */
+%#define CACHEFILE "/var/nis/NIS_SHARED_DIRCACHE"
+%
+%/* clients have to read-lock the cache file, and SVR4 locking requires that */
+%/* the file be writable, but we don't want a world-writable cache file. */
+%/* So... everyone agrees to use a different, world-writable file for the */
+%/* locking operations, but the data is in CACHEFILE. */
+%#define CACHELOCK "/usr/tmp/.NIS_DIR_CACHELOCK"
+%
+%/* the file containing one trusted XDR'ed directory object.
+% * This has to be present for the system to work.
+% */
+%#define COLD_START_FILE "/var/nis/NIS_COLD_START"
+%
+%enum pc_status {HIT, MISS, NEAR_MISS};
+%
+%extern int __nis_debuglevel;
+%
+%
+#endif
+
+#ifdef RPC_CLNT
+#ifdef SOLARIS
+%#include "../gen/nis_clnt.h"
+#else
+%#include "nis.h"
+#endif
+#endif
+
+program CACHEPROG {
+ version CACHE_VER_1 {
+ void NIS_CACHE_ADD_ENTRY(fd_result) = 1;
+ void NIS_CACHE_REMOVE_ENTRY(directory_obj) = 2;
+ void NIS_CACHE_READ_COLDSTART(void) = 3;
+ void NIS_CACHE_REFRESH_ENTRY(string<>) = 4;
+ } = 1;
+} = 100301;
diff --git a/librpc/include/rpcsvc/nis_callback.x b/librpc/include/rpcsvc/nis_callback.x
new file mode 100644
index 0000000..4e74aa0
--- /dev/null
+++ b/librpc/include/rpcsvc/nis_callback.x
@@ -0,0 +1,76 @@
+%/*
+% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+% * unrestricted use provided that this legend is included on all tape
+% * media and as a part of the software program in whole or part. Users
+% * may copy or modify Sun RPC without charge, but are not authorized
+% * to license or distribute it to anyone else except as part of a product or
+% * program developed by the user or with the express written consent of
+% * Sun Microsystems, Inc.
+% *
+% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+% *
+% * Sun RPC is provided with no support and without any obligation on the
+% * part of Sun Microsystems, Inc. to assist in its use, correction,
+% * modification or enhancement.
+% *
+% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+% * OR ANY PART THEREOF.
+% *
+% * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+% * or profits or other special, indirect and consequential damages, even if
+% * Sun has been advised of the possibility of such damages.
+% *
+% * Sun Microsystems, Inc.
+% * 2550 Garcia Avenue
+% * Mountain View, California 94043
+% */
+
+/*
+ * nis_callback.x
+ *
+ * Copyright (c) 1988-1992 Sun Microsystems Inc
+ * All Rights Reserved.
+ */
+
+/* From: %#pragma ident "@(#)nis_callback.x 1.7 94/05/03 SMI" */
+
+#ifndef RPC_HDR
+%#ifndef lint
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/nis_callback.x,v 1.3 1999/08/27 23:45:09 peter Exp $";
+%#endif /* not lint */
+#endif
+
+/*
+ * "@(#)zns_cback.x 1.2 90/09/10 Copyr 1990 Sun Micro"
+ *
+ * RPCL description of the Callback Service.
+ */
+
+#ifdef RPC_HDR
+%#include <rpcsvc/nis.h>
+#endif
+#ifdef RPC_XDR
+#ifdef SOLARIS
+%#include "nis_clnt.h"
+#else
+%#include "nis.h"
+#endif
+#endif
+
+typedef nis_object *obj_p;
+
+struct cback_data {
+ obj_p entries<>; /* List of objects */
+};
+
+program CB_PROG {
+ version CB_VERS {
+ bool CBPROC_RECEIVE(cback_data) = 1;
+ void CBPROC_FINISH(void) = 2;
+ void CBPROC_ERROR(nis_error) = 3;
+ } = 1;
+} = 100302;
diff --git a/librpc/include/rpcsvc/nis_db.h b/librpc/include/rpcsvc/nis_db.h
new file mode 100644
index 0000000..71785b0
--- /dev/null
+++ b/librpc/include/rpcsvc/nis_db.h
@@ -0,0 +1,164 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ *
+ * $FreeBSD: src/include/rpcsvc/nis_db.h,v 1.5 1999/08/27 23:45:09 peter Exp $
+ */
+
+/*
+ * Copyright (c) 1991, by Sun Microsystems Inc.
+ */
+
+/*
+ * This header file defines the interface to the NIS database. All
+ * implementations of the database must export at least these routines.
+ * They must also follow the conventions set herein. See the implementors
+ * guide for specific semantics that are required.
+ */
+
+#ifndef _RPCSVC_NIS_DB_H
+#define _RPCSVC_NIS_DB_H
+
+
+/* From: #pragma ident "@(#)nis_db.h 1.8 94/05/03 SMI" */
+
+/*
+ * Note: although the version of <rpcsvc/nis_db.h> shipped with Solaris
+ * 2.5/2.5.x is actually older than this one (according to the ident
+ * string), it contains changes and a few added functions. Those changes
+ * have been hand merged into this file to bring it up to date.
+ */
+
+#include <rpc/rpc.h>
+#include <rpcsvc/nis.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum db_status {
+ DB_SUCCESS = 0,
+ DB_NOTFOUND = 1,
+ DB_NOTUNIQUE = 2,
+ DB_BADTABLE = 3,
+ DB_BADQUERY = 4,
+ DB_BADOBJECT = 5,
+ DB_MEMORY_LIMIT = 6,
+ DB_STORAGE_LIMIT = 7,
+ DB_INTERNAL_ERROR = 8,
+ _DB_STATUS = 0xffffffff
+};
+typedef enum db_status db_status;
+
+enum db_action {
+ DB_LOOKUP = 0,
+ DB_REMOVE = 1,
+ DB_ADD = 2,
+ DB_FIRST = 3,
+ DB_NEXT = 4,
+ DB_ALL = 5,
+ DB_RESET_NEXT = 6,
+ _DB_ACTION = 0xffffffff
+};
+typedef enum db_action db_action;
+
+typedef entry_obj *entry_object_p;
+
+typedef struct {
+ u_int db_next_desc_len;
+ char *db_next_desc_val;
+} db_next_desc;
+
+struct db_result {
+ db_status status;
+ db_next_desc nextinfo;
+ struct {
+ u_int objects_len;
+ entry_object_p *objects_val;
+ } objects;
+ long ticks;
+};
+typedef struct db_result db_result;
+
+/*
+ * Prototypes for the database functions.
+ */
+
+#if (__STDC__)
+
+extern bool_t db_initialize(char *);
+#ifdef ORIGINAL_DECLS
+extern bool_t db_create_table(char *, table_obj *);
+extern bool_t db_destroy_table(char *);
+#else
+extern db_status db_create_table(char *, table_obj *);
+extern db_status db_destroy_table(char *);
+#endif
+extern db_result *db_first_entry(char *, int, nis_attr *);
+extern db_result *db_next_entry(char *, db_next_desc *);
+extern db_result *db_reset_next_entry(char *, db_next_desc *);
+extern db_result *db_list_entries(char *, int, nis_attr *);
+extern db_result *db_add_entry(char *, int, nis_attr *, entry_obj *);
+extern db_result *db_remove_entry(char *, int, nis_attr *);
+extern db_status db_checkpoint(char *);
+extern db_status db_standby(char *);
+#ifndef ORIGINAL_DECLS
+extern db_status db_table_exists(char *);
+extern db_status db_unload_table(char *);
+extern void db_free_result(db_result *);
+#endif
+
+#else /* Non-prototype definitions */
+
+extern bool_t db_initialize();
+#ifdef ORIGINAL_DECLS
+extern bool_t db_create_table();
+extern bool_t db_destroy_table();
+#else
+extern db_status db_create_table();
+extern db_status db_destroy_table();
+#endif
+extern db_result *db_first_entry();
+extern db_result *db_next_entry();
+extern db_result *db_reset_next_entry();
+extern db_result *db_list_entries();
+extern db_result *db_add_entry();
+extern db_result *db_remove_entry();
+extern db_status db_checkpoint();
+extern db_status db_standby();
+#ifndef ORIGINAL_DECLS
+extern db_status db_table_exists();
+extern db_status db_unload_table();
+extern void db_free_result();
+#endif
+#endif /* __STDC__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RPCSVC_NIS_DB_H */
diff --git a/librpc/include/rpcsvc/nis_object.x b/librpc/include/rpcsvc/nis_object.x
new file mode 100644
index 0000000..3156724
--- /dev/null
+++ b/librpc/include/rpcsvc/nis_object.x
@@ -0,0 +1,317 @@
+%/*
+% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+% * unrestricted use provided that this legend is included on all tape
+% * media and as a part of the software program in whole or part. Users
+% * may copy or modify Sun RPC without charge, but are not authorized
+% * to license or distribute it to anyone else except as part of a product or
+% * program developed by the user or with the express written consent of
+% * Sun Microsystems, Inc.
+% *
+% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+% *
+% * Sun RPC is provided with no support and without any obligation on the
+% * part of Sun Microsystems, Inc. to assist in its use, correction,
+% * modification or enhancement.
+% *
+% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+% * OR ANY PART THEREOF.
+% *
+% * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+% * or profits or other special, indirect and consequential damages, even if
+% * Sun has been advised of the possibility of such damages.
+% *
+% * Sun Microsystems, Inc.
+% * 2550 Garcia Avenue
+% * Mountain View, California 94043
+% */
+
+/*
+ * nis_object.x
+ *
+ * Copyright (c) 1988-1992 Sun Microsystems Inc
+ * All Rights Reserved.
+ */
+
+/* From: %#pragma ident "@(#)nis_object.x 1.10 94/05/03 SMI" */
+
+#if RPC_HDR
+%
+%#ifndef __nis_object_h
+%#define __nis_object_h
+%
+#endif
+/*
+ * This file defines the format for a NIS object in RPC language.
+ * It is included by the main .x file and the database access protocol
+ * file. It is common because both of them need to deal with the same
+ * type of object. Generating the actual code though is a bit messy because
+ * the nis.x file and the nis_dba.x file will generate xdr routines to
+ * encode/decode objects when only one set is needed. Such is life when
+ * one is using rpcgen.
+ *
+ * Note, the protocol doesn't specify any limits on such things as
+ * maximum name length, number of attributes, etc. These are enforced
+ * by the database backend. When you hit them you will no. Also see
+ * the db_getlimits() function for fetching the limit values.
+ *
+ */
+
+/* Some manifest constants, chosen to maximize flexibility without
+ * plugging the wire full of data.
+ */
+const NIS_MAXSTRINGLEN = 255;
+const NIS_MAXNAMELEN = 1024;
+const NIS_MAXATTRNAME = 32;
+const NIS_MAXATTRVAL = 2048;
+const NIS_MAXCOLUMNS = 64;
+const NIS_MAXATTR = 16;
+const NIS_MAXPATH = 1024;
+const NIS_MAXREPLICAS = 128;
+const NIS_MAXLINKS = 16;
+
+const NIS_PK_NONE = 0; /* no public key (unix/sys auth) */
+const NIS_PK_DH = 1; /* Public key is Diffie-Hellman type */
+const NIS_PK_RSA = 2; /* Public key if RSA type */
+const NIS_PK_KERB = 3; /* Use kerberos style authentication */
+
+/*
+ * The fundamental name type of NIS. The name may consist of two parts,
+ * the first being the fully qualified name, and the second being an
+ * optional set of attribute/value pairs.
+ */
+struct nis_attr {
+ string zattr_ndx<>; /* name of the index */
+ opaque zattr_val<>; /* Value for the attribute. */
+};
+
+typedef string nis_name<>; /* The NIS name itself. */
+
+/* NIS object types are defined by the following enumeration. The numbers
+ * they use are based on the following scheme :
+ * 0 - 1023 are reserved for Sun,
+ * 1024 - 2047 are defined to be private to a particular tree.
+ * 2048 - 4095 are defined to be user defined.
+ * 4096 - ... are reserved for future use.
+ */
+
+enum zotypes {
+ BOGUS_OBJ = 0, /* Uninitialized object structure */
+ NO_OBJ = 1, /* NULL object (no data) */
+ DIRECTORY_OBJ = 2, /* Directory object describing domain */
+ GROUP_OBJ = 3, /* Group object (a list of names) */
+ TABLE_OBJ = 4, /* Table object (a database schema) */
+ ENTRY_OBJ = 5, /* Entry object (a database record) */
+ LINK_OBJ = 6, /* A name link. */
+ PRIVATE_OBJ = 7 /* Private object (all opaque data) */
+};
+
+/*
+ * The types of Name services NIS knows about. They are enumerated
+ * here. The Binder code will use this type to determine if it has
+ * a set of library routines that will access the indicated name service.
+ */
+enum nstype {
+ UNKNOWN = 0,
+ NIS = 1, /* Nis Plus Service */
+ SUNYP = 2, /* Old NIS Service */
+ IVY = 3, /* Nis Plus Plus Service */
+ DNS = 4, /* Domain Name Service */
+ X500 = 5, /* ISO/CCCIT X.500 Service */
+ DNANS = 6, /* Digital DECNet Name Service */
+ XCHS = 7, /* Xerox ClearingHouse Service */
+ CDS= 8
+};
+
+/*
+ * DIRECTORY - The name service object. These objects identify other name
+ * servers that are serving some portion of the name space. Each has a
+ * type associated with it. The resolver library will note whether or not
+ * is has the needed routines to access that type of service.
+ * The oarmask structure defines an access rights mask on a per object
+ * type basis for the name spaces. The only bits currently used are
+ * create and destroy. By enabling or disabling these access rights for
+ * a specific object type for a one of the accessor entities (owner,
+ * group, world) the administrator can control what types of objects
+ * may be freely added to the name space and which require the
+ * administrator's approval.
+ */
+struct oar_mask {
+ u_long oa_rights; /* Access rights mask */
+ zotypes oa_otype; /* Object type */
+};
+
+struct endpoint {
+ string uaddr<>;
+ string family<>; /* Transport family (INET, OSI, etc) */
+ string proto<>; /* Protocol (TCP, UDP, CLNP, etc) */
+};
+
+/*
+ * Note: pkey is a netobj which is limited to 1024 bytes which limits the
+ * keysize to 8192 bits. This is consider to be a reasonable limit for
+ * the expected lifetime of this service.
+ */
+struct nis_server {
+ nis_name name; /* Principal name of the server */
+ endpoint ep<>; /* Universal addr(s) for server */
+ u_long key_type; /* Public key type */
+ netobj pkey; /* server's public key */
+};
+
+struct directory_obj {
+ nis_name do_name; /* Name of the directory being served */
+ nstype do_type; /* one of NIS, DNS, IVY, YP, or X.500 */
+ nis_server do_servers<>; /* <0> == Primary name server */
+ u_long do_ttl; /* Time To Live (for caches) */
+ oar_mask do_armask<>; /* Create/Destroy rights by object type */
+};
+
+/*
+ * ENTRY - This is one row of data from an information base.
+ * The type value is used by the client library to convert the entry to
+ * it's internal structure representation. The Table name is a back pointer
+ * to the table where the entry is stored. This allows the client library
+ * to determine where to send a request if the client wishes to change this
+ * entry but got to it through a LINK rather than directly.
+ * If the entry is a "standalone" entry then this field is void.
+ */
+const EN_BINARY = 1; /* Indicates value is binary data */
+const EN_CRYPT = 2; /* Indicates the value is encrypted */
+const EN_XDR = 4; /* Indicates the value is XDR encoded */
+const EN_MODIFIED = 8; /* Indicates entry is modified. */
+const EN_ASN1 = 64; /* Means contents use ASN.1 encoding */
+
+struct entry_col {
+ u_long ec_flags; /* Flags for this value */
+ opaque ec_value<>; /* It's textual value */
+};
+
+struct entry_obj {
+ string en_type<>; /* Type of entry such as "passwd" */
+ entry_col en_cols<>; /* Value for the entry */
+};
+
+/*
+ * GROUP - The group object contains a list of NIS principal names. Groups
+ * are used to authorize principals. Each object has a set of access rights
+ * for members of its group. Principal names in groups are in the form
+ * name.directory and recursive groups are expressed as @groupname.directory
+ */
+struct group_obj {
+ u_long gr_flags; /* Flags controlling group */
+ nis_name gr_members<>; /* List of names in group */
+};
+
+/*
+ * LINK - This is the LINK object. It is quite similar to a symbolic link
+ * in the UNIX filesystem. The attributes in the main object structure are
+ * relative to the LINK data and not what it points to (like the file system)
+ * "modify" privleges here indicate the right to modify what the link points
+ * at and not to modify that actual object pointed to by the link.
+ */
+struct link_obj {
+ zotypes li_rtype; /* Real type of the object */
+ nis_attr li_attrs<>; /* Attribute/Values for tables */
+ nis_name li_name; /* The object's real NIS name */
+};
+
+/*
+ * TABLE - This is the table object. It implements a simple
+ * data base that applications and use for configuration or
+ * administration purposes. The role of the table is to group together
+ * a set of related entries. Tables are the simple database component
+ * of NIS. Like many databases, tables are logically divided into columns
+ * and rows. The columns are labeled with indexes and each ENTRY makes
+ * up a row. Rows may be addressed within the table by selecting one
+ * or more indexes, and values for those indexes. Each row which has
+ * a value for the given index that matches the desired value is returned.
+ * Within the definition of each column there is a flags variable, this
+ * variable contains flags which determine whether or not the column is
+ * searchable, contains binary data, and access rights for the entry objects
+ * column value.
+ */
+
+const TA_BINARY = 1; /* Means table data is binary */
+const TA_CRYPT = 2; /* Means value should be encrypted */
+const TA_XDR = 4; /* Means value is XDR encoded */
+const TA_SEARCHABLE = 8; /* Means this column is searchable */
+const TA_CASE = 16; /* Means this column is Case Sensitive */
+const TA_MODIFIED = 32; /* Means this columns attrs are modified*/
+const TA_ASN1 = 64; /* Means contents use ASN.1 encoding */
+
+struct table_col {
+ string tc_name<64>; /* Column Name */
+ u_long tc_flags; /* control flags */
+ u_long tc_rights; /* Access rights mask */
+};
+
+struct table_obj {
+ string ta_type<64>; /* Table type such as "passwd" */
+ int ta_maxcol; /* Total number of columns */
+ u_char ta_sep; /* Separator character */
+ table_col ta_cols<>; /* The number of table indexes */
+ string ta_path<>; /* A search path for this table */
+};
+
+/*
+ * This union joins together all of the currently known objects.
+ */
+union objdata switch (zotypes zo_type) {
+ case DIRECTORY_OBJ :
+ struct directory_obj di_data;
+ case GROUP_OBJ :
+ struct group_obj gr_data;
+ case TABLE_OBJ :
+ struct table_obj ta_data;
+ case ENTRY_OBJ:
+ struct entry_obj en_data;
+ case LINK_OBJ :
+ struct link_obj li_data;
+ case PRIVATE_OBJ :
+ opaque po_data<>;
+ case NO_OBJ :
+ void;
+ case BOGUS_OBJ :
+ void;
+ default :
+ void;
+};
+
+/*
+ * This is the basic NIS object data type. It consists of a generic part
+ * which all objects contain, and a specialized part which varies depending
+ * on the type of the object. All of the specialized sections have been
+ * described above. You might have wondered why they all start with an
+ * integer size, followed by the useful data. The answer is, when the
+ * server doesn't recognize the type returned it treats it as opaque data.
+ * And the definition for opaque data is {int size; char *data;}. In this
+ * way, servers and utility routines that do not understand a given type
+ * may still pass it around. One has to be careful in setting
+ * this variable accurately, it must take into account such things as
+ * XDR padding of structures etc. The best way to set it is to note one's
+ * position in the XDR encoding stream, encode the structure, look at the
+ * new position and calculate the size.
+ */
+struct nis_oid {
+ u_long ctime; /* Time of objects creation */
+ u_long mtime; /* Time of objects modification */
+};
+
+struct nis_object {
+ nis_oid zo_oid; /* object identity verifier. */
+ nis_name zo_name; /* The NIS name for this object */
+ nis_name zo_owner; /* NIS name of object owner. */
+ nis_name zo_group; /* NIS name of access group. */
+ nis_name zo_domain; /* The administrator for the object */
+ u_long zo_access; /* Access rights (owner, group, world) */
+ u_long zo_ttl; /* Object's time to live in seconds. */
+ objdata zo_data; /* Data structure for this type */
+};
+#if RPC_HDR
+%
+%#endif /* if __nis_object_h */
+%
+#endif
diff --git a/librpc/include/rpcsvc/nis_tags.h b/librpc/include/rpcsvc/nis_tags.h
new file mode 100644
index 0000000..0eaee6d
--- /dev/null
+++ b/librpc/include/rpcsvc/nis_tags.h
@@ -0,0 +1,137 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * Copyright (c) 1991, Sun Microsystems Inc.
+ */
+
+/*
+ * 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
+
+/* From: #pragma ident "@(#)nis_tags.h 1.10 94/05/03 SMI" */
+/* from file: zns_tags.h 1.7 Copyright (c) 1990 Sun Microsystems */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef ORIGINAL_DECLS
+#define NIS_DIR "data"
+#endif
+
+/* 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 */
+#ifdef ORIGINAL_DECLS
+#define MOD_RESERVED (1<<13) /* Spare MOD semantic */
+#else
+#define MOD_EXCLUSIVE (1<<13) /* Modify no overwrite on modified keys */
+#endif
+
+/* 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 */
+#ifndef ORIGINAL_DECLS
+#define TAG_GCACHE_ALL TAG_GCACHE
+#endif
+#define TAG_DCACHE 4 /* Flush the directory cache */
+#ifndef ORIGINAL_DECLS
+#define TAG_DCACHE_ONE TAG_DCACHE
+#endif
+#define TAG_OCACHE 5 /* Flush the Object Cache */
+#define TAG_SECURE 6 /* Set the security level */
+#ifndef ORIGINAL_DECLS
+#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 */
+#endif
+
+#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 */
+#ifndef ORIGINAL_DECLS
+#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 */
+#endif
+
+/*
+ * 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/librpc/include/rpcsvc/nislib.h b/librpc/include/rpcsvc/nislib.h
new file mode 100644
index 0000000..9f874d2
--- /dev/null
+++ b/librpc/include/rpcsvc/nislib.h
@@ -0,0 +1,317 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * Copyright (c) 1991, Sun Microsystems Inc.
+ */
+
+/*
+ * This file contains the interfaces that are visible in the SunOS 5.x
+ * implementation of NIS Plus. When using C++ the defined __cplusplus and
+ * __STDC__ should both be true.
+ */
+
+#ifndef _RPCSVC_NISLIB_H
+#define _RPCSVC_NISLIB_H
+
+/* From: #pragma ident "@(#)nislib.h 1.16 94/05/03 SMI" */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct signature {
+ int signature_len;
+ char *signature_val;
+};
+
+#ifdef __STDC__
+extern void nis_freeresult(nis_result *);
+extern nis_result * nis_lookup(nis_name, u_long);
+extern nis_result * nis_list(nis_name, u_long,
+ int (*)(nis_name, nis_object *, void *), void *);
+extern nis_result * nis_add(nis_name, nis_object *);
+extern nis_result * nis_remove(nis_name, nis_object *);
+extern nis_result * nis_modify(nis_name, nis_object *);
+
+extern nis_result * nis_add_entry(nis_name, nis_object *, u_long);
+extern nis_result * nis_remove_entry(nis_name, nis_object *, u_long);
+extern nis_result * nis_modify_entry(nis_name, nis_object *, u_long);
+extern nis_result * nis_first_entry(nis_name);
+extern nis_result * nis_next_entry(nis_name, netobj *);
+
+extern nis_error nis_mkdir(nis_name, nis_server *);
+extern nis_error nis_rmdir(nis_name, nis_server *);
+extern name_pos nis_dir_cmp(nis_name, nis_name);
+
+extern nis_name * nis_getnames(nis_name);
+extern void nis_freenames(nis_name *);
+extern nis_name nis_domain_of(nis_name);
+extern nis_name nis_leaf_of(nis_name);
+extern nis_name nis_leaf_of_r(const nis_name, char *, size_t);
+extern nis_name nis_name_of(nis_name);
+extern nis_name nis_local_group(void);
+extern nis_name nis_local_directory(void);
+extern nis_name nis_local_principal(void);
+extern nis_name nis_local_host(void);
+
+extern void nis_destroy_object(nis_object *);
+extern nis_object * nis_clone_object(nis_object *, nis_object *);
+extern void nis_print_object(nis_object *);
+
+extern char * nis_sperrno(nis_error);
+extern void nis_perror(nis_error, char *);
+extern char * nis_sperror(nis_error, char *);
+extern void nis_lerror(nis_error, char *);
+
+extern void nis_print_group_entry(nis_name);
+extern bool_t nis_ismember(nis_name, nis_name);
+extern nis_error nis_creategroup(nis_name, u_long);
+extern nis_error nis_destroygroup(nis_name);
+extern nis_error nis_addmember(nis_name, nis_name);
+extern nis_error nis_removemember(nis_name, nis_name);
+extern nis_error nis_verifygroup(nis_name);
+
+extern void nis_freeservlist(nis_server **);
+extern nis_server ** nis_getservlist(nis_name);
+extern nis_error nis_stats(nis_server *, nis_tag *, int, nis_tag **);
+extern nis_error nis_servstate(nis_server *, nis_tag *, int, nis_tag **);
+extern void nis_freetags(nis_tag *, int);
+
+extern nis_result * nis_checkpoint(nis_name);
+extern void nis_ping(nis_name, u_long, nis_object *);
+
+/*
+ * XXX: PLEASE NOTE THAT THE FOLLOWING FUNCTIONS ARE INTERNAL
+ * TO NIS+ AND SHOULD NOT BE USED BY ANY APPLICATION PROGRAM.
+ * THEIR SEMANTICS AND/OR SIGNATURE CAN CHANGE WITHOUT NOTICE.
+ * SO, PLEASE DO NOT USE THEM. YOU ARE WARNED!!!!
+ */
+
+extern char ** __break_name(nis_name, int *);
+extern int __name_distance(char **, char **);
+extern nis_result * nis_make_error(nis_error, u_long, u_long, u_long, u_long);
+extern nis_attr * __cvt2attr(int *, char **);
+extern void nis_free_request(ib_request *);
+extern nis_error nis_get_request(nis_name, nis_object *, netobj*, ib_request*);
+extern nis_object * nis_read_obj(char *);
+extern int nis_write_obj(char *, nis_object *);
+extern int nis_in_table(nis_name, NIS_HASH_TABLE *, int *);
+extern int nis_insert_item(NIS_HASH_ITEM *, NIS_HASH_TABLE *);
+extern NIS_HASH_ITEM * nis_find_item(nis_name, NIS_HASH_TABLE *);
+extern NIS_HASH_ITEM * nis_remove_item(nis_name, NIS_HASH_TABLE *);
+extern void nis_insert_name(nis_name, NIS_HASH_TABLE *);
+extern void nis_remove_name(nis_name, NIS_HASH_TABLE *);
+extern CLIENT * nis_make_rpchandle(nis_server *, int, u_long, u_long, u_long,
+ int, int);
+extern void * nis_get_static_storage(struct nis_sdata *, u_long, u_long);
+extern char * nis_data(char *);
+extern void nis_print_rights(u_long);
+extern void nis_print_directory(directory_obj *);
+extern void nis_print_group(group_obj *);
+extern void nis_print_table(table_obj *);
+extern void nis_print_link(link_obj *);
+extern void nis_print_entry(entry_obj *);
+extern nis_object * nis_get_object(char *, char *, char *, u_long, u_long,
+ zotypes);
+extern nis_server * __nis_init_callback(CLIENT *,
+ int (*)(nis_name, nis_object *, void *), void *);
+extern int nis_getdtblsize(void);
+extern int __nis_run_callback(netobj *, u_long, struct timeval *, CLIENT *);
+
+extern log_result *nis_dumplog(nis_server *, nis_name, u_long);
+extern log_result *nis_dump(nis_server *, nis_name,
+ int (*)(nis_name, nis_object *, void *));
+
+extern bool_t __do_ismember(nis_name, nis_name,
+ nis_result *(*)(nis_name, u_long));
+extern nis_name __nis_map_group(nis_name);
+extern nis_name __nis_map_group_r(nis_name, char*, size_t);
+
+extern nis_error __nis_CacheBind(char *, directory_obj *);
+extern nis_error __nis_CacheSearch(char *, directory_obj *);
+extern bool_t __nis_CacheRemoveEntry(directory_obj *);
+extern void __nis_CacheRestart(void);
+extern void __nis_CachePrint(void);
+extern void __nis_CacheDumpStatistics(void);
+extern bool_t writeColdStartFile(directory_obj *);
+
+extern CLIENT * __get_ti_clnt(char *, CLIENT *, char **, pid_t *);
+extern int __strcmp_case_insens(char *, char *);
+extern int __strncmp_case_insens(char *, char *);
+
+extern fd_result * nis_finddirectory(directory_obj *, nis_name);
+extern int __start_clock(int);
+extern u_long __stop_clock(int);
+
+/*
+ * This particular function is part of the FreeBSD NIS+ implementation
+ * only. Ideally it should be somewhere else, but it is used by both
+ * rpc.nisd and nis_cachemgr, and there aren't that many headers common
+ * to both programs.
+ */
+
+extern struct signature *__nis_calculate_encrypted_cksum(unsigned char *, unsigned int, char *, int);
+
+#else
+
+/* Non-prototype definitions (old fashioned C) */
+
+extern void nis_freeresult();
+extern nis_result * nis_lookup();
+extern nis_result * nis_list();
+extern nis_result * nis_add();
+extern nis_result * nis_remove();
+extern nis_result * nis_modify();
+
+extern nis_result * nis_add_entry();
+extern nis_result * nis_remove_entry();
+extern nis_result * nis_modify_entry();
+extern nis_result * nis_first_entry();
+extern nis_result * nis_next_entry();
+
+extern nis_error nis_mkdir();
+extern nis_error nis_rmdir();
+extern name_pos nis_dir_cmp();
+
+extern nis_name *nis_getnames();
+extern void nis_freenames();
+extern nis_name nis_domain_of();
+extern nis_name nis_leaf_of();
+extern nis_name nis_leaf_of_r();
+extern nis_name nis_name_of();
+extern nis_name nis_local_group();
+extern nis_name nis_local_directory();
+extern nis_name nis_local_principal();
+extern nis_name nis_local_host();
+
+extern void nis_destroy_object();
+extern nis_object * nis_clone_object();
+extern void nis_print_object();
+
+extern char * nis_sperrno();
+extern void nis_perror();
+extern char * nis_sperror();
+extern void nis_lerror();
+
+extern void nis_print_group_entry();
+extern bool_t nis_ismember();
+extern nis_error nis_creategroup();
+extern nis_error nis_destroygroup();
+extern nis_error nis_addmember();
+extern nis_error nis_removemember();
+extern nis_error nis_verifygroup();
+
+extern void nis_freeservlist();
+extern nis_server ** nis_getservlist();
+extern nis_error nis_stats();
+extern nis_error nis_servstate();
+extern void nis_freetags();
+
+extern nis_result * nis_checkpoint();
+extern void nis_ping();
+
+/*
+ * XXX: PLEASE NOTE THAT THE FOLLOWING FUNCTIONS ARE INTERNAL
+ * TO NIS+ AND SHOULD NOT BE USED BY ANY APPLICATION PROGRAM.
+ * THEIR SEMANTICS AND/OR SIGNATURE CAN CHANGE WITHOUT NOTICE.
+ * SO, PLEASE DO NOT USE THEM. YOU ARE WARNED!!!!
+ */
+extern char ** __break_name();
+extern int __name_distance();
+extern nis_result * nis_make_error();
+extern nis_attr * __cvt2attr();
+extern void nis_free_request();
+extern nis_error nis_get_request();
+extern nis_object * nis_read_obj();
+extern int nis_write_obj();
+extern int nis_in_table();
+extern int nis_insert_item();
+extern NIS_HASH_ITEM * nis_find_item();
+extern NIS_HASH_ITEM * nis_remove_item();
+extern void nis_insert_name();
+extern void nis_remove_name();
+extern CLIENT * nis_make_rpchandle();
+extern void * nis_get_static_storage();
+extern char * nis_data();
+
+extern void nis_print_rights();
+extern void nis_print_directory();
+extern void nis_print_group();
+extern void nis_print_table();
+extern void nis_print_link();
+extern void nis_print_entry();
+extern nis_object * nis_get_object();
+
+extern nis_server * __nis_init_callback();
+extern int nis_getdtblsize();
+extern int __nis_run_callback();
+
+extern log_result * nis_dump();
+extern log_result * nis_dumplog();
+
+extern bool_t __do_ismember();
+extern nis_name __nis_map_group();
+extern nis_name __nis_map_group_r();
+
+
+extern nis_error __nis_CacheBind();
+extern directory_obj * __nis_CacheSearch();
+extern bool_t __nis_CacheRemoveEntry();
+extern void __nis_CacheRestart();
+extern void __nis_CachePrint();
+extern void __nis_CacheDumpStatistics();
+extern bool_t writeColdStartFile();
+
+extern CLIENT * __get_ti_clnt();
+extern int __strcmp_case_insens();
+extern int __strncmp_case_insens();
+
+extern fd_result * nis_finddirectory();
+extern int __start_clock();
+extern u_long __stop_clock();
+
+/*
+ * This particular function is part of the FreeBSD NIS+ implementation
+ * only. Ideally it should be somewhere else, but it is used by both
+ * rpc.nisd and nis_cachemgr, and there aren't that many headers common
+ * to both programs.
+ */
+
+extern struct signature *__nis_calculate_encrypted_cksum();
+
+#endif
+
+#define NUL '\0'
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RPCSVC_NISLIB_H */
diff --git a/librpc/include/rpcsvc/nlm_prot.x b/librpc/include/rpcsvc/nlm_prot.x
new file mode 100644
index 0000000..fdc6d6e
--- /dev/null
+++ b/librpc/include/rpcsvc/nlm_prot.x
@@ -0,0 +1,183 @@
+/* @(#)nlm_prot.x 2.1 88/08/01 4.0 RPCSRC */
+/* @(#)nlm_prot.x 1.8 87/09/21 Copyr 1987 Sun Micro */
+
+/*
+ * Network lock manager protocol definition
+ * Copyright (C) 1986 Sun Microsystems, Inc.
+ *
+ * protocol used between local lock manager and remote lock manager
+ */
+
+#ifdef RPC_HDR
+%#define LM_MAXSTRLEN 1024
+%#define MAXNAMELEN LM_MAXSTRLEN+1
+#else
+%#ifndef lint
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/nlm_prot.x,v 1.8 1999/08/27 23:45:10 peter Exp $";
+%#endif /* not lint */
+#endif
+
+/*
+ * status of a call to the lock manager
+ */
+enum nlm_stats {
+ nlm_granted = 0,
+ nlm_denied = 1,
+ nlm_denied_nolocks = 2,
+ nlm_blocked = 3,
+ nlm_denied_grace_period = 4
+};
+
+struct nlm_holder {
+ bool exclusive;
+ int svid;
+ netobj oh;
+ unsigned l_offset;
+ unsigned l_len;
+};
+
+union nlm_testrply switch (nlm_stats stat) {
+ case nlm_denied:
+ struct nlm_holder holder;
+ default:
+ void;
+};
+
+struct nlm_stat {
+ nlm_stats stat;
+};
+
+struct nlm_res {
+ netobj cookie;
+ nlm_stat stat;
+};
+
+struct nlm_testres {
+ netobj cookie;
+ nlm_testrply stat;
+};
+
+struct nlm_lock {
+ string caller_name<LM_MAXSTRLEN>;
+ netobj fh; /* identify a file */
+ netobj oh; /* identify owner of a lock */
+ int svid; /* generated from pid for svid */
+ unsigned l_offset;
+ unsigned l_len;
+};
+
+struct nlm_lockargs {
+ netobj cookie;
+ bool block;
+ bool exclusive;
+ struct nlm_lock alock;
+ bool reclaim; /* used for recovering locks */
+ int state; /* specify local status monitor state */
+};
+
+struct nlm_cancargs {
+ netobj cookie;
+ bool block;
+ bool exclusive;
+ struct nlm_lock alock;
+};
+
+struct nlm_testargs {
+ netobj cookie;
+ bool exclusive;
+ struct nlm_lock alock;
+};
+
+struct nlm_unlockargs {
+ netobj cookie;
+ struct nlm_lock alock;
+};
+
+
+#ifdef RPC_HDR
+%/*
+% * The following enums are actually bit encoded for efficient
+% * boolean algebra.... DON'T change them.....
+% */
+#endif
+enum fsh_mode {
+ fsm_DN = 0, /* deny none */
+ fsm_DR = 1, /* deny read */
+ fsm_DW = 2, /* deny write */
+ fsm_DRW = 3 /* deny read/write */
+};
+
+enum fsh_access {
+ fsa_NONE = 0, /* for completeness */
+ fsa_R = 1, /* read only */
+ fsa_W = 2, /* write only */
+ fsa_RW = 3 /* read/write */
+};
+
+struct nlm_share {
+ string caller_name<LM_MAXSTRLEN>;
+ netobj fh;
+ netobj oh;
+ fsh_mode mode;
+ fsh_access access;
+};
+
+struct nlm_shareargs {
+ netobj cookie;
+ nlm_share share;
+ bool reclaim;
+};
+
+struct nlm_shareres {
+ netobj cookie;
+ nlm_stats stat;
+ int sequence;
+};
+
+struct nlm_notify {
+ string name<MAXNAMELEN>;
+ long state;
+};
+
+/*
+ * Over-the-wire protocol used between the network lock managers
+ */
+
+program NLM_PROG {
+ version NLM_VERS {
+
+ nlm_testres NLM_TEST(struct nlm_testargs) = 1;
+
+ nlm_res NLM_LOCK(struct nlm_lockargs) = 2;
+
+ nlm_res NLM_CANCEL(struct nlm_cancargs) = 3;
+ nlm_res NLM_UNLOCK(struct nlm_unlockargs) = 4;
+
+ /*
+ * remote lock manager call-back to grant lock
+ */
+ nlm_res NLM_GRANTED(struct nlm_testargs)= 5;
+ /*
+ * message passing style of requesting lock
+ */
+ void NLM_TEST_MSG(struct nlm_testargs) = 6;
+ void NLM_LOCK_MSG(struct nlm_lockargs) = 7;
+ void NLM_CANCEL_MSG(struct nlm_cancargs) =8;
+ void NLM_UNLOCK_MSG(struct nlm_unlockargs) = 9;
+ void NLM_GRANTED_MSG(struct nlm_testargs) = 10;
+ void NLM_TEST_RES(nlm_testres) = 11;
+ void NLM_LOCK_RES(nlm_res) = 12;
+ void NLM_CANCEL_RES(nlm_res) = 13;
+ void NLM_UNLOCK_RES(nlm_res) = 14;
+ void NLM_GRANTED_RES(nlm_res) = 15;
+ } = 1;
+
+ version NLM_VERSX {
+ nlm_shareres NLM_SHARE(nlm_shareargs) = 20;
+ nlm_shareres NLM_UNSHARE(nlm_shareargs) = 21;
+ nlm_res NLM_NM_LOCK(nlm_lockargs) = 22;
+ void NLM_FREE_ALL(nlm_notify) = 23;
+ } = 3;
+
+} = 100021;
diff --git a/librpc/include/rpcsvc/pmap_prot.x b/librpc/include/rpcsvc/pmap_prot.x
new file mode 100644
index 0000000..2e9c089
--- /dev/null
+++ b/librpc/include/rpcsvc/pmap_prot.x
@@ -0,0 +1,284 @@
+%/*
+% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+% * unrestricted use provided that this legend is included on all tape
+% * media and as a part of the software program in whole or part. Users
+% * may copy or modify Sun RPC without charge, but are not authorized
+% * to license or distribute it to anyone else except as part of a product or
+% * program developed by the user.
+% *
+% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+% *
+% * Sun RPC is provided with no support and without any obligation on the
+% * part of Sun Microsystems, Inc. to assist in its use, correction,
+% * modification or enhancement.
+% *
+% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+% * OR ANY PART THEREOF.
+% *
+% * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+% * or profits or other special, indirect and consequential damages, even if
+% * Sun has been advised of the possibility of such damages.
+% *
+% * Sun Microsystems, Inc.
+% * 2550 Garcia Avenue
+% * Mountain View, California 94043
+% */
+%/*
+% * Copyright (c) 1984,1989 by Sun Microsystems, Inc.
+% */
+
+%/* from pmap_prot.x */
+
+#ifdef RPC_HDR
+%
+%#pragma ident "@(#)pmap_prot.x 1.6 94/04/29 SMI"
+%
+%#ifndef _KERNEL
+%
+#endif
+
+/*
+ * Port Mapper Protocol Specification (in RPC Language)
+ * derived from RFC 1057
+ */
+
+%/*
+% * Protocol for the local binder service, or pmap.
+% *
+% * Copyright (C) 1984, Sun Microsystems, Inc.
+% *
+% * The following procedures are supported by the protocol:
+% *
+% * PMAPPROC_NULL() returns ()
+% * takes nothing, returns nothing
+% *
+% * PMAPPROC_SET(struct pmap) returns (bool_t)
+% * TRUE is success, FALSE is failure. Registers the tuple
+% * [prog, vers, prot, port].
+% *
+% * PMAPPROC_UNSET(struct pmap) returns (bool_t)
+% * TRUE is success, FALSE is failure. Un-registers pair
+% * [prog, vers]. prot and port are ignored.
+% *
+% * PMAPPROC_GETPORT(struct pmap) returns (long unsigned).
+% * 0 is failure. Otherwise returns the port number where the pair
+% * [prog, vers] is registered. It may lie!
+% *
+% * PMAPPROC_DUMP() RETURNS (struct pmaplist_ptr)
+% *
+% * PMAPPROC_CALLIT(unsigned, unsigned, unsigned, string<>)
+% * RETURNS (port, string<>);
+% * usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc,
+% * encapsulatedargs);
+% * Calls the procedure on the local machine. If it is not registered,
+% * this procedure is quite; ie it does not return error information!!!
+% * This procedure only is supported on rpc/udp and calls via
+% * rpc/udp. This routine only passes null authentication parameters.
+% * This file has no interface to xdr routines for PMAPPROC_CALLIT.
+% *
+% * The service supports remote procedure calls on udp/ip or tcp/ip socket 111.
+% */
+%
+const PMAPPORT = 111; /* portmapper port number */
+%
+%
+%/*
+% * A mapping of (program, version, protocol) to port number
+% */
+
+struct pmap {
+ unsigned long pm_prog;
+ unsigned long pm_vers;
+ unsigned long pm_prot;
+ unsigned long pm_port;
+};
+#ifdef RPC_HDR
+%
+%typedef pmap PMAP;
+%
+#endif
+%
+%/*
+% * Supported values for the "prot" field
+% */
+%
+const PMAP_IPPROTO_TCP = 6; /* protocol number for TCP/IP */
+const PMAP_IPPROTO_UDP = 17; /* protocol number for UDP/IP */
+%
+%
+%/*
+% * A list of mappings
+% *
+% * Below are two definitions for the pmaplist structure. This is done because
+% * xdr_pmaplist() is specified to take a struct pmaplist **, rather than a
+% * struct pmaplist * that rpcgen would produce. One version of the pmaplist
+% * structure (actually called pm__list) is used with rpcgen, and the other is
+% * defined only in the header file for compatibility with the specified
+% * interface.
+% */
+
+struct pm__list {
+ pmap pml_map;
+ struct pm__list *pml_next;
+};
+
+typedef pm__list *pmaplist_ptr; /* results of PMAPPROC_DUMP */
+
+#ifdef RPC_HDR
+%
+%typedef struct pm__list pmaplist;
+%typedef struct pm__list PMAPLIST;
+%
+%#ifndef __cplusplus
+%struct pmaplist {
+% PMAP pml_map;
+% struct pmaplist *pml_next;
+%};
+%#endif
+%
+%#ifdef __cplusplus
+%extern "C" {
+%#endif
+%#ifdef __STDC__
+%extern bool_t xdr_pmaplist(XDR *, pmaplist**);
+%#else /* K&R C */
+%bool_t xdr_pmaplist();
+%#endif
+%#ifdef __cplusplus
+%}
+%#endif
+%
+#endif
+
+%
+%/*
+% * Arguments to callit
+% */
+
+struct rmtcallargs {
+ unsigned long prog;
+ unsigned long vers;
+ unsigned long proc;
+ opaque args<>;
+};
+#ifdef RPC_HDR
+%
+%/*
+% * Client-side only representation of rmtcallargs structure.
+% *
+% * The routine that XDRs the rmtcallargs structure must deal with the
+% * opaque arguments in the "args" structure. xdr_rmtcall_args() needs to be
+% * passed the XDR routine that knows the args' structure. This routine
+% * doesn't need to go over-the-wire (and it wouldn't make sense anyway) since
+% * the application being called knows the args structure already. So we use a
+% * different "XDR" structure on the client side, p_rmtcallargs, which includes
+% * the args' XDR routine.
+% */
+%struct p_rmtcallargs {
+% u_long prog;
+% u_long vers;
+% u_long proc;
+% struct {
+% u_int args_len;
+% char *args_val;
+% } args;
+% xdrproc_t xdr_args; /* encodes args */
+%};
+%
+#endif /* def RPC_HDR */
+%
+%
+%/*
+% * Results of callit
+% */
+
+struct rmtcallres {
+ unsigned long port;
+ opaque res<>;
+};
+#ifdef RPC_HDR
+%
+%/*
+% * Client-side only representation of rmtcallres structure.
+% */
+%struct p_rmtcallres {
+% u_long port;
+% struct {
+% u_int res_len;
+% char *res_val;
+% } res;
+% xdrproc_t xdr_res; /* decodes res */
+%};
+%
+#endif /* def RPC_HDR */
+
+/*
+ * Port mapper procedures
+ */
+
+program PMAPPROG {
+ version PMAPVERS {
+ void
+ PMAPPROC_NULL(void) = 0;
+
+ bool
+ PMAPPROC_SET(pmap) = 1;
+
+ bool
+ PMAPPROC_UNSET(pmap) = 2;
+
+ unsigned long
+ PMAPPROC_GETPORT(pmap) = 3;
+
+ pmaplist_ptr
+ PMAPPROC_DUMP(void) = 4;
+
+ rmtcallres
+ PMAPPROC_CALLIT(rmtcallargs) = 5;
+ } = 2;
+} = 100000;
+%
+#ifdef RPC_HDR
+%#define PMAPVERS_PROTO ((u_long)2)
+%#define PMAPVERS_ORIG ((u_long)1)
+%
+%#else /* ndef _KERNEL */
+%
+%#include <rpc/pmap_rmt.h>
+%
+%#ifdef __cplusplus
+%extern "C" {
+%#endif
+%
+%#define PMAPPORT 111
+%
+%struct pmap {
+% long unsigned pm_prog;
+% long unsigned pm_vers;
+% long unsigned pm_prot;
+% long unsigned pm_port;
+%};
+%typedef struct pmap PMAP;
+%#ifdef __STDC__
+%extern bool_t xdr_pmap (XDR *, struct pmap *);
+%#else
+%extern bool_t xdr_pmap ();
+%#endif
+%
+%struct pmaplist {
+% struct pmap pml_map;
+% struct pmaplist *pml_next;
+%};
+%typedef struct pmaplist PMAPLIST;
+%typedef struct pmaplist *pmaplist_ptr;
+%
+%
+%#ifdef __cplusplus
+%}
+%#endif
+%
+%#endif /* ndef _KERNEL */
+#endif
diff --git a/librpc/include/rpcsvc/rex.x b/librpc/include/rpcsvc/rex.x
new file mode 100644
index 0000000..928efa2
--- /dev/null
+++ b/librpc/include/rpcsvc/rex.x
@@ -0,0 +1,235 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * Remote execution (rex) protocol specification
+ */
+
+#ifndef RPC_HDR
+%#ifndef lint
+%/*static char sccsid[] = "from: @(#)rex.x 1.3 87/09/18 Copyr 1987 Sun Micro";*/
+%/*static char sccsid[] = "from: @(#)rex.x 2.1 88/08/01 4.0 RPCSRC";*/
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/rex.x,v 1.6 1999/08/27 23:45:10 peter Exp $";
+%#endif /* not lint */
+#endif
+
+const STRINGSIZE = 1024;
+typedef string rexstring<1024>;
+
+/*
+ * values to pass to REXPROC_SIGNAL
+ */
+const SIGINT = 2; /* interrupt */
+
+/*
+ * Values for rst_flags, below
+ */
+const REX_INTERACTIVE = 1; /* interactive mode */
+
+struct rex_start {
+ rexstring rst_cmd<>; /* list of command and args */
+ rexstring rst_host; /* working directory host name */
+ rexstring rst_fsname; /* working directory file system name */
+ rexstring rst_dirwithin;/* working directory within file system */
+ rexstring rst_env<>; /* list of environment */
+ unsigned int rst_port0; /* port for stdin */
+ unsigned int rst_port1; /* port for stdout */
+ unsigned int rst_port2; /* port for stderr */
+ unsigned int rst_flags; /* options - see const above */
+};
+
+struct rex_result {
+ int rlt_stat; /* integer status code */
+ rexstring rlt_message; /* string message for human consumption */
+};
+
+
+struct sgttyb {
+ unsigned four; /* always equals 4 */
+ opaque chars[4];
+ /* chars[0] == input speed */
+ /* chars[1] == output speed */
+ /* chars[2] == kill character */
+ /* chars[3] == erase character */
+ unsigned flags;
+};
+/* values for speeds above (baud rates) */
+const B0 = 0;
+const B50 = 1;
+const B75 = 2;
+const B110 = 3;
+const B134 = 4;
+const B150 = 5;
+const B200 = 6;
+const B300 = 7;
+const B600 = 8;
+const B1200 = 9;
+const B1800 = 10;
+const B2400 = 11;
+const B4800 = 12;
+const B9600 = 13;
+const B19200 = 14;
+const B38400 = 15;
+
+/* values for flags above */
+const TANDEM = 0x00000001; /* send stopc on out q full */
+const CBREAK = 0x00000002; /* half-cooked mode */
+const LCASE = 0x00000004; /* simulate lower case */
+const ECHO = 0x00000008; /* echo input */
+const CRMOD = 0x00000010; /* map \r to \r\n on output */
+const RAW = 0x00000020; /* no i/o processing */
+const ODDP = 0x00000040; /* get/send odd parity */
+const EVENP = 0x00000080; /* get/send even parity */
+const ANYP = 0x000000c0; /* get any parity/send none */
+const NLDELAY = 0x00000300; /* \n delay */
+const NL0 = 0x00000000;
+const NL1 = 0x00000100; /* tty 37 */
+const NL2 = 0x00000200; /* vt05 */
+const NL3 = 0x00000300;
+const TBDELAY = 0x00000c00; /* horizontal tab delay */
+const TAB0 = 0x00000000;
+const TAB1 = 0x00000400; /* tty 37 */
+const TAB2 = 0x00000800;
+const XTABS = 0x00000c00; /* expand tabs on output */
+const CRDELAY = 0x00003000; /* \r delay */
+const CR0 = 0x00000000;
+const CR1 = 0x00001000; /* tn 300 */
+const CR2 = 0x00002000; /* tty 37 */
+const CR3 = 0x00003000; /* concept 100 */
+const VTDELAY = 0x00004000; /* vertical tab delay */
+const FF0 = 0x00000000;
+const FF1 = 0x00004000; /* tty 37 */
+const BSDELAY = 0x00008000; /* \b delay */
+const BS0 = 0x00000000;
+const BS1 = 0x00008000;
+const CRTBS = 0x00010000; /* do backspacing for crt */
+const PRTERA = 0x00020000; /* \ ... / erase */
+const CRTERA = 0x00040000; /* " \b " to wipe out char */
+const TILDE = 0x00080000; /* hazeltine tilde kludge */
+const MDMBUF = 0x00100000; /* start/stop output on carrier intr */
+const LITOUT = 0x00200000; /* literal output */
+const TOSTOP = 0x00400000; /* SIGTTOU on background output */
+const FLUSHO = 0x00800000; /* flush output to terminal */
+const NOHANG = 0x01000000; /* no SIGHUP on carrier drop */
+const L001000 = 0x02000000;
+const CRTKIL = 0x04000000; /* kill line with " \b " */
+const PASS8 = 0x08000000;
+const CTLECH = 0x10000000; /* echo control chars as ^X */
+const PENDIN = 0x20000000; /* tp->t_rawq needs reread */
+const DECCTQ = 0x40000000; /* only ^Q starts after ^S */
+const NOFLSH = 0x80000000; /* no output flush on signal */
+
+struct tchars {
+ unsigned six; /* always equals 6 */
+ opaque chars[6];
+ /* chars[0] == interrupt char */
+ /* chars[1] == quit char */
+ /* chars[2] == start output char */
+ /* chars[3] == stop output char */
+ /* chars[4] == end-of-file char */
+ /* chars[5] == input delimeter (like nl) */
+};
+
+struct ltchars {
+ unsigned six; /* always equals 6 */
+ opaque chars[6];
+ /* chars[0] == stop process signal */
+ /* chars[1] == delayed stop process signal */
+ /* chars[2] == reprint line */
+ /* chars[3] == flush output */
+ /* chars[4] == word erase */
+ /* chars[5] == literal next character */
+ unsigned mode;
+};
+
+struct rex_ttysize {
+ int ts_lines;
+ int ts_cols;
+};
+
+struct rex_ttymode {
+ sgttyb basic; /* standard unix tty flags */
+ tchars more; /* interrupt, kill characters, etc. */
+ ltchars yetmore; /* special Berkeley characters */
+ unsigned andmore; /* and Berkeley modes */
+};
+
+/* values for andmore above */
+const LCRTBS = 0x0001; /* do backspacing for crt */
+const LPRTERA = 0x0002; /* \ ... / erase */
+const LCRTERA = 0x0004; /* " \b " to wipe out char */
+const LTILDE = 0x0008; /* hazeltine tilde kludge */
+const LMDMBUF = 0x0010; /* start/stop output on carrier intr */
+const LLITOUT = 0x0020; /* literal output */
+const LTOSTOP = 0x0040; /* SIGTTOU on background output */
+const LFLUSHO = 0x0080; /* flush output to terminal */
+const LNOHANG = 0x0100; /* no SIGHUP on carrier drop */
+const LL001000 = 0x0200;
+const LCRTKIL = 0x0400; /* kill line with " \b " */
+const LPASS8 = 0x0800;
+const LCTLECH = 0x1000; /* echo control chars as ^X */
+const LPENDIN = 0x2000; /* needs reread */
+const LDECCTQ = 0x4000; /* only ^Q starts after ^S */
+const LNOFLSH = 0x8000; /* no output flush on signal */
+
+program REXPROG {
+ version REXVERS {
+
+ /*
+ * Start remote execution
+ */
+ rex_result
+ REXPROC_START(rex_start) = 1;
+
+ /*
+ * Wait for remote execution to terminate
+ */
+ rex_result
+ REXPROC_WAIT(void) = 2;
+
+ /*
+ * Send tty modes
+ */
+ void
+ REXPROC_MODES(rex_ttymode) = 3;
+
+ /*
+ * Send window size change
+ */
+ void
+ REXPROC_WINCH(rex_ttysize) = 4;
+
+ /*
+ * Send other signal
+ */
+ void
+ REXPROC_SIGNAL(int) = 5;
+ } = 1;
+} = 100017;
diff --git a/librpc/include/rpcsvc/rnusers.x b/librpc/include/rpcsvc/rnusers.x
new file mode 100644
index 0000000..393eaf4
--- /dev/null
+++ b/librpc/include/rpcsvc/rnusers.x
@@ -0,0 +1,122 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * Find out about remote users
+ */
+
+#ifndef RPC_HDR
+%#ifndef lint
+%/*static char sccsid[] = "from: @(#)rnusers.x 1.2 87/09/20 Copyr 1987 Sun Micro";*/
+%/*static char sccsid[] = "from: @(#)rnusers.x 2.1 88/08/01 4.0 RPCSRC";*/
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/rnusers.x,v 1.6 1999/08/27 23:45:10 peter Exp $";
+%#endif /* not lint */
+#endif
+
+const MAXUSERS = 100;
+const MAXUTLEN = 256;
+
+struct utmp {
+ string ut_line<MAXUTLEN>;
+ string ut_name<MAXUTLEN>;
+ string ut_host<MAXUTLEN>;
+ int ut_time;
+};
+
+
+struct utmpidle {
+ utmp ui_utmp;
+ unsigned int ui_idle;
+};
+
+typedef utmp utmparr<MAXUSERS>;
+
+typedef utmpidle utmpidlearr<MAXUSERS>;
+
+const RUSERS_MAXUSERLEN = 32;
+const RUSERS_MAXLINELEN = 32;
+const RUSERS_MAXHOSTLEN = 257;
+
+struct rusers_utmp {
+ string ut_user<RUSERS_MAXUSERLEN>; /* aka ut_name */
+ string ut_line<RUSERS_MAXLINELEN>; /* device */
+ string ut_host<RUSERS_MAXHOSTLEN>; /* host user logged on from */
+ int ut_type; /* type of entry */
+ int ut_time; /* time entry was made */
+ unsigned int ut_idle; /* minutes idle */
+};
+
+typedef rusers_utmp utmp_array<>;
+
+program RUSERSPROG {
+ /*
+ * Old version does not include idle information
+ */
+ version RUSERSVERS_ORIG {
+ int
+ RUSERSPROC_NUM(void) = 1;
+
+ utmparr
+ RUSERSPROC_NAMES(void) = 2;
+
+ utmparr
+ RUSERSPROC_ALLNAMES(void) = 3;
+ } = 1;
+
+ /*
+ * Includes idle information
+ */
+ version RUSERSVERS_IDLE {
+ int
+ RUSERSPROC_NUM(void) = 1;
+
+ utmpidlearr
+ RUSERSPROC_NAMES(void) = 2;
+
+ utmpidlearr
+ RUSERSPROC_ALLNAMES(void) = 3;
+ } = 2;
+
+ /*
+ * Version 3 rusers procedures (from Solaris).
+ * (Thanks a lot Sun.)
+ */
+ version RUSERSVERS_3 {
+ int
+ RUSERSPROC_NUM(void) = 1;
+
+ utmp_array
+ RUSERSPROC_NAMES(void) = 2;
+
+ utmp_array
+ RUSERSPROC_ALLNAMES(void) = 3;
+ } = 3;
+
+} = 100002;
diff --git a/librpc/include/rpcsvc/rquota.x b/librpc/include/rpcsvc/rquota.x
new file mode 100644
index 0000000..72864d1
--- /dev/null
+++ b/librpc/include/rpcsvc/rquota.x
@@ -0,0 +1,67 @@
+/*
+ * Remote quota protocol
+ * Requires unix authentication
+ */
+
+#ifndef RPC_HDR
+%#ifndef lint
+%/*static char sccsid[] = "from: @(#)rquota.x 1.2 87/09/20 Copyr 1987 Sun Micro";*/
+%/*static char sccsid[] = "from: @(#)rquota.x 2.1 88/08/01 4.0 RPCSRC";*/
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/rquota.x,v 1.6 1999/08/27 23:45:10 peter Exp $";
+%#endif /* not lint */
+#endif
+
+const RQ_PATHLEN = 1024;
+
+struct getquota_args {
+ string gqa_pathp<RQ_PATHLEN>; /* path to filesystem of interest */
+ int gqa_uid; /* inquire about quota for uid */
+};
+
+/*
+ * remote quota structure
+ */
+struct rquota {
+ int rq_bsize; /* block size for block counts */
+ bool rq_active; /* indicates whether quota is active */
+ unsigned int rq_bhardlimit; /* absolute limit on disk blks alloc */
+ unsigned int rq_bsoftlimit; /* preferred limit on disk blks */
+ unsigned int rq_curblocks; /* current block count */
+ unsigned int rq_fhardlimit; /* absolute limit on allocated files */
+ unsigned int rq_fsoftlimit; /* preferred file limit */
+ unsigned int rq_curfiles; /* current # allocated files */
+ unsigned int rq_btimeleft; /* time left for excessive disk use */
+ unsigned int rq_ftimeleft; /* time left for excessive files */
+};
+
+enum gqr_status {
+ Q_OK = 1, /* quota returned */
+ Q_NOQUOTA = 2, /* noquota for uid */
+ Q_EPERM = 3 /* no permission to access quota */
+};
+
+union getquota_rslt switch (gqr_status status) {
+case Q_OK:
+ rquota gqr_rquota; /* valid if status == Q_OK */
+case Q_NOQUOTA:
+ void;
+case Q_EPERM:
+ void;
+};
+
+program RQUOTAPROG {
+ version RQUOTAVERS {
+ /*
+ * Get all quotas
+ */
+ getquota_rslt
+ RQUOTAPROC_GETQUOTA(getquota_args) = 1;
+
+ /*
+ * Get active quotas only
+ */
+ getquota_rslt
+ RQUOTAPROC_GETACTIVEQUOTA(getquota_args) = 2;
+ } = 1;
+} = 100011;
diff --git a/librpc/include/rpcsvc/rstat.x b/librpc/include/rpcsvc/rstat.x
new file mode 100644
index 0000000..fee9d52
--- /dev/null
+++ b/librpc/include/rpcsvc/rstat.x
@@ -0,0 +1,151 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * Gather statistics on remote machines
+ */
+
+#ifdef RPC_HDR
+
+%#ifndef FSCALE
+%/*
+% * Scale factor for scaled integers used to count load averages.
+% */
+%#define FSHIFT 8 /* bits to right of fixed binary point */
+%#define FSCALE (1<<FSHIFT)
+%
+%#endif /* ndef FSCALE */
+
+#else
+
+%#ifndef lint
+%/*static char sccsid[] = "from: @(#)rstat.x 1.2 87/09/18 Copyr 1987 Sun Micro";*/
+%/*static char sccsid[] = "from: @(#)rstat.x 2.2 88/08/01 4.0 RPCSRC";*/
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/rstat.x,v 1.6 1999/08/27 23:45:11 peter Exp $";
+%#endif /* not lint */
+
+#endif /* def RPC_HDR */
+
+const RSTAT_CPUSTATES = 4;
+const RSTAT_DK_NDRIVE = 4;
+
+/*
+ * GMT since 0:00, January 1, 1970
+ */
+struct rstat_timeval {
+ unsigned int tv_sec; /* seconds */
+ unsigned int tv_usec; /* and microseconds */
+};
+
+struct statstime { /* RSTATVERS_TIME */
+ int cp_time[RSTAT_CPUSTATES];
+ int dk_xfer[RSTAT_DK_NDRIVE];
+ unsigned int v_pgpgin; /* these are cumulative sum */
+ unsigned int v_pgpgout;
+ unsigned int v_pswpin;
+ unsigned int v_pswpout;
+ unsigned int v_intr;
+ int if_ipackets;
+ int if_ierrors;
+ int if_oerrors;
+ int if_collisions;
+ unsigned int v_swtch;
+ int avenrun[3]; /* scaled by FSCALE */
+ rstat_timeval boottime;
+ rstat_timeval curtime;
+ int if_opackets;
+};
+
+struct statsswtch { /* RSTATVERS_SWTCH */
+ int cp_time[RSTAT_CPUSTATES];
+ int dk_xfer[RSTAT_DK_NDRIVE];
+ unsigned int v_pgpgin; /* these are cumulative sum */
+ unsigned int v_pgpgout;
+ unsigned int v_pswpin;
+ unsigned int v_pswpout;
+ unsigned int v_intr;
+ int if_ipackets;
+ int if_ierrors;
+ int if_oerrors;
+ int if_collisions;
+ unsigned int v_swtch;
+ unsigned int avenrun[3];/* scaled by FSCALE */
+ rstat_timeval boottime;
+ int if_opackets;
+};
+
+struct stats { /* RSTATVERS_ORIG */
+ int cp_time[RSTAT_CPUSTATES];
+ int dk_xfer[RSTAT_DK_NDRIVE];
+ unsigned int v_pgpgin; /* these are cumulative sum */
+ unsigned int v_pgpgout;
+ unsigned int v_pswpin;
+ unsigned int v_pswpout;
+ unsigned int v_intr;
+ int if_ipackets;
+ int if_ierrors;
+ int if_oerrors;
+ int if_collisions;
+ int if_opackets;
+};
+
+
+program RSTATPROG {
+ /*
+ * Newest version includes current time and context switching info
+ */
+ version RSTATVERS_TIME {
+ statstime
+ RSTATPROC_STATS(void) = 1;
+
+ unsigned int
+ RSTATPROC_HAVEDISK(void) = 2;
+ } = 3;
+ /*
+ * Does not have current time
+ */
+ version RSTATVERS_SWTCH {
+ statsswtch
+ RSTATPROC_STATS(void) = 1;
+
+ unsigned int
+ RSTATPROC_HAVEDISK(void) = 2;
+ } = 2;
+ /*
+ * Old version has no info about current time or context switching
+ */
+ version RSTATVERS_ORIG {
+ stats
+ RSTATPROC_STATS(void) = 1;
+
+ unsigned int
+ RSTATPROC_HAVEDISK(void) = 2;
+ } = 1;
+} = 100001;
diff --git a/librpc/include/rpcsvc/rwall.x b/librpc/include/rpcsvc/rwall.x
new file mode 100644
index 0000000..6c26c1f
--- /dev/null
+++ b/librpc/include/rpcsvc/rwall.x
@@ -0,0 +1,57 @@
+%/*
+% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+% * unrestricted use provided that this legend is included on all tape
+% * media and as a part of the software program in whole or part. Users
+% * may copy or modify Sun RPC without charge, but are not authorized
+% * to license or distribute it to anyone else except as part of a product or
+% * program developed by the user or with the express written consent of
+% * Sun Microsystems, Inc.
+% *
+% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+% *
+% * Sun RPC is provided with no support and without any obligation on the
+% * part of Sun Microsystems, Inc. to assist in its use, correction,
+% * modification or enhancement.
+% *
+% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+% * OR ANY PART THEREOF.
+% *
+% * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+% * or profits or other special, indirect and consequential damages, even if
+% * Sun has been advised of the possibility of such damages.
+% *
+% * Sun Microsystems, Inc.
+% * 2550 Garcia Avenue
+% * Mountain View, California 94043
+% */
+
+%/*
+% * Copyright (c) 1984, 1990 by Sun Microsystems, Inc.
+% */
+%
+%/* from @(#)rwall.x 1.6 91/03/11 TIRPC 1.0 */
+
+#ifdef RPC_HDR
+%
+%#ifndef _rpcsvc_rwall_h
+%#define _rpcsvc_rwall_h
+%
+%typedef char *wrapstring;
+%
+#endif
+
+program WALLPROG {
+ version WALLVERS {
+ void
+ WALLPROC_WALL(wrapstring) = 2;
+
+ } = 1;
+} = 100008;
+
+#ifdef RPC_HDR
+%
+%#endif /* ! _rpcsvc_rwall_h */
+#endif
diff --git a/librpc/include/rpcsvc/sm_inter.x b/librpc/include/rpcsvc/sm_inter.x
new file mode 100644
index 0000000..2071516
--- /dev/null
+++ b/librpc/include/rpcsvc/sm_inter.x
@@ -0,0 +1,122 @@
+/* @(#)sm_inter.x 2.2 88/08/01 4.0 RPCSRC */
+/* @(#)sm_inter.x 1.7 87/06/24 Copyr 1987 Sun Micro */
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * Status monitor protocol specification
+ * Copyright (C) 1986 Sun Microsystems, Inc.
+ *
+ */
+
+#ifndef RPC_HDR
+%#ifndef lint
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/sm_inter.x,v 1.8 1999/08/27 23:45:11 peter Exp $";
+%#endif /* not lint */
+#endif
+
+program SM_PROG {
+ version SM_VERS {
+ /* res_stat = stat_succ if status monitor agrees to monitor */
+ /* res_stat = stat_fail if status monitor cannot monitor */
+ /* if res_stat == stat_succ, state = state number of site sm_name */
+ struct sm_stat_res SM_STAT(struct sm_name) = 1;
+
+ /* res_stat = stat_succ if status monitor agrees to monitor */
+ /* res_stat = stat_fail if status monitor cannot monitor */
+ /* stat consists of state number of local site */
+ struct sm_stat_res SM_MON(struct mon) = 2;
+
+ /* stat consists of state number of local site */
+ struct sm_stat SM_UNMON(struct mon_id) = 3;
+
+ /* stat consists of state number of local site */
+ struct sm_stat SM_UNMON_ALL(struct my_id) = 4;
+
+ void SM_SIMU_CRASH(void) = 5;
+
+ } = 1;
+} = 100024;
+
+const SM_MAXSTRLEN = 1024;
+
+struct sm_name {
+ string mon_name<SM_MAXSTRLEN>;
+};
+
+struct my_id {
+ string my_name<SM_MAXSTRLEN>; /* name of the site iniates the monitoring request*/
+ int my_prog; /* rpc program # of the requesting process */
+ int my_vers; /* rpc version # of the requesting process */
+ int my_proc; /* rpc procedure # of the requesting process */
+};
+
+struct mon_id {
+ string mon_name<SM_MAXSTRLEN>; /* name of the site to be monitored */
+ struct my_id my_id;
+};
+
+
+struct mon{
+ struct mon_id mon_id;
+ opaque priv[16]; /* private information to store at monitor for requesting process */
+};
+
+
+/*
+ * state # of status monitor monitonically increases each time
+ * status of the site changes:
+ * an even number (>= 0) indicates the site is down and
+ * an odd number (> 0) indicates the site is up;
+ */
+struct sm_stat {
+ int state; /* state # of status monitor */
+};
+
+enum res {
+ stat_succ = 0, /* status monitor agrees to monitor */
+ stat_fail = 1 /* status monitor cannot monitor */
+};
+
+struct sm_stat_res {
+ res res_stat;
+ int state;
+};
+
+/*
+ * structure of the status message sent back by the status monitor
+ * when monitor site status changes
+ */
+struct status {
+ string mon_name<SM_MAXSTRLEN>;
+ int state;
+ opaque priv[16]; /* stored private information */
+};
diff --git a/librpc/include/rpcsvc/spray.x b/librpc/include/rpcsvc/spray.x
new file mode 100644
index 0000000..a4d086a
--- /dev/null
+++ b/librpc/include/rpcsvc/spray.x
@@ -0,0 +1,90 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * Spray a server with packets
+ * Useful for testing flakiness of network interfaces
+ */
+
+#ifndef RPC_HDR
+%#ifndef lint
+%/*static char sccsid[] = "from: @(#)spray.x 1.2 87/09/18 Copyr 1987 Sun Micro";*/
+%/*static char sccsid[] = "from: @(#)spray.x 2.1 88/08/01 4.0 RPCSRC";*/
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/spray.x,v 1.6 1999/08/27 23:45:11 peter Exp $";
+%#endif /* not lint */
+#endif
+
+const SPRAYMAX = 8845; /* max amount can spray */
+
+/*
+ * GMT since 0:00, 1 January 1970
+ */
+struct spraytimeval {
+ unsigned int sec;
+ unsigned int usec;
+};
+
+/*
+ * spray statistics
+ */
+struct spraycumul {
+ unsigned int counter;
+ spraytimeval clock;
+};
+
+/*
+ * spray data
+ */
+typedef opaque sprayarr<SPRAYMAX>;
+
+program SPRAYPROG {
+ version SPRAYVERS {
+ /*
+ * Just throw away the data and increment the counter
+ * This call never returns, so the client should always
+ * time it out.
+ */
+ void
+ SPRAYPROC_SPRAY(sprayarr) = 1;
+
+ /*
+ * Get the value of the counter and elapsed time since
+ * last CLEAR.
+ */
+ spraycumul
+ SPRAYPROC_GET(void) = 2;
+
+ /*
+ * Clear the counter and reset the elapsed time
+ */
+ void
+ SPRAYPROC_CLEAR(void) = 3;
+ } = 1;
+} = 100012;
diff --git a/librpc/include/rpcsvc/yp.x b/librpc/include/rpcsvc/yp.x
new file mode 100644
index 0000000..aa87265
--- /dev/null
+++ b/librpc/include/rpcsvc/yp.x
@@ -0,0 +1,379 @@
+/* @(#)yp.x 2.1 88/08/01 4.0 RPCSRC */
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * Protocol description file for the Yellow Pages Service
+ */
+
+#ifndef RPC_HDR
+%#ifndef lint
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/yp.x,v 1.12 1999/08/27 23:45:12 peter Exp $";
+%#endif /* not lint */
+#endif
+
+const YPMAXRECORD = 1024;
+const YPMAXDOMAIN = 64;
+const YPMAXMAP = 64;
+const YPMAXPEER = 64;
+
+
+enum ypstat {
+ YP_TRUE = 1,
+ YP_NOMORE = 2,
+ YP_FALSE = 0,
+ YP_NOMAP = -1,
+ YP_NODOM = -2,
+ YP_NOKEY = -3,
+ YP_BADOP = -4,
+ YP_BADDB = -5,
+ YP_YPERR = -6,
+ YP_BADARGS = -7,
+ YP_VERS = -8
+};
+
+
+enum ypxfrstat {
+ YPXFR_SUCC = 1,
+ YPXFR_AGE = 2,
+ YPXFR_NOMAP = -1,
+ YPXFR_NODOM = -2,
+ YPXFR_RSRC = -3,
+ YPXFR_RPC = -4,
+ YPXFR_MADDR = -5,
+ YPXFR_YPERR = -6,
+ YPXFR_BADARGS = -7,
+ YPXFR_DBM = -8,
+ YPXFR_FILE = -9,
+ YPXFR_SKEW = -10,
+ YPXFR_CLEAR = -11,
+ YPXFR_FORCE = -12,
+ YPXFR_XFRERR = -13,
+ YPXFR_REFUSED = -14
+};
+
+
+typedef string domainname<YPMAXDOMAIN>;
+typedef string mapname<YPMAXMAP>;
+typedef string peername<YPMAXPEER>;
+typedef opaque keydat<YPMAXRECORD>;
+typedef opaque valdat<YPMAXRECORD>;
+
+
+struct ypmap_parms {
+ domainname domain;
+ mapname map;
+ unsigned int ordernum;
+ peername peer;
+};
+
+struct ypreq_key {
+ domainname domain;
+ mapname map;
+ keydat key;
+};
+
+struct ypreq_nokey {
+ domainname domain;
+ mapname map;
+};
+
+struct ypreq_xfr {
+ ypmap_parms map_parms;
+ unsigned int transid;
+ unsigned int prog;
+ unsigned int port;
+};
+
+
+struct ypresp_val {
+ ypstat stat;
+ valdat val;
+};
+
+struct ypresp_key_val {
+ ypstat stat;
+#ifdef STUPID_SUN_BUG /* These are backwards */
+ keydat key;
+ valdat val;
+#else
+ valdat val;
+ keydat key;
+#endif
+};
+
+
+struct ypresp_master {
+ ypstat stat;
+ peername peer;
+};
+
+struct ypresp_order {
+ ypstat stat;
+ unsigned int ordernum;
+};
+
+union ypresp_all switch (bool more) {
+case TRUE:
+ ypresp_key_val val;
+case FALSE:
+ void;
+};
+
+struct ypresp_xfr {
+ unsigned int transid;
+ ypxfrstat xfrstat;
+};
+
+struct ypmaplist {
+ mapname map;
+ ypmaplist *next;
+};
+
+struct ypresp_maplist {
+ ypstat stat;
+ ypmaplist *maps;
+};
+
+enum yppush_status {
+ YPPUSH_SUCC = 1, /* Success */
+ YPPUSH_AGE = 2, /* Master's version not newer */
+ YPPUSH_NOMAP = -1, /* Can't find server for map */
+ YPPUSH_NODOM = -2, /* Domain not supported */
+ YPPUSH_RSRC = -3, /* Local resource alloc failure */
+ YPPUSH_RPC = -4, /* RPC failure talking to server */
+ YPPUSH_MADDR = -5, /* Can't get master address */
+ YPPUSH_YPERR = -6, /* YP server/map db error */
+ YPPUSH_BADARGS = -7, /* Request arguments bad */
+ YPPUSH_DBM = -8, /* Local dbm operation failed */
+ YPPUSH_FILE = -9, /* Local file I/O operation failed */
+ YPPUSH_SKEW = -10, /* Map version skew during transfer */
+ YPPUSH_CLEAR = -11, /* Can't send "Clear" req to local ypserv */
+ YPPUSH_FORCE = -12, /* No local order number in map use -f flag. */
+ YPPUSH_XFRERR = -13, /* ypxfr error */
+ YPPUSH_REFUSED = -14 /* Transfer request refused by ypserv */
+};
+
+struct yppushresp_xfr {
+ unsigned transid;
+ yppush_status status;
+};
+
+/*
+ * 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 {
+ opaque ypbind_binding_addr[4]; /* In network order */
+ opaque ypbind_binding_port[2]; /* In network order */
+};
+
+union ypbind_resp switch (ypbind_resptype ypbind_status) {
+case YPBIND_FAIL_VAL:
+ unsigned ypbind_error;
+case YPBIND_SUCC_VAL:
+ ypbind_binding ypbind_bindinfo;
+};
+
+/* Detailed failure reason codes for response field ypbind_error*/
+
+const YPBIND_ERR_ERR = 1; /* Internal error */
+const YPBIND_ERR_NOSERV = 2; /* No bound server for passed domain */
+const YPBIND_ERR_RESC = 3; /* System resource allocation failure */
+
+
+/*
+ * Request data structure for ypbind "Set domain" procedure.
+ */
+struct ypbind_setdom {
+ domainname ypsetdom_domain;
+ ypbind_binding ypsetdom_binding;
+ unsigned ypsetdom_vers;
+};
+
+
+/*
+ * NIS v1 support for backwards compatibility
+ */
+enum ypreqtype {
+ YPREQ_KEY = 1,
+ YPREQ_NOKEY = 2,
+ YPREQ_MAP_PARMS = 3
+};
+
+enum ypresptype {
+ YPRESP_VAL = 1,
+ YPRESP_KEY_VAL = 2,
+ YPRESP_MAP_PARMS = 3
+};
+
+union yprequest switch (ypreqtype yp_reqtype) {
+case YPREQ_KEY:
+ ypreq_key yp_req_keytype;
+case YPREQ_NOKEY:
+ ypreq_nokey yp_req_nokeytype;
+case YPREQ_MAP_PARMS:
+ ypmap_parms yp_req_map_parmstype;
+};
+
+union ypresponse switch (ypresptype yp_resptype) {
+case YPRESP_VAL:
+ ypresp_val yp_resp_valtype;
+case YPRESP_KEY_VAL:
+ ypresp_key_val yp_resp_key_valtype;
+case YPRESP_MAP_PARMS:
+ ypmap_parms yp_resp_map_parmstype;
+};
+
+#if !defined(YPBIND_ONLY) && !defined(YPPUSH_ONLY)
+/*
+ * YP access protocol
+ */
+program YPPROG {
+/*
+ * NIS v1 support for backwards compatibility
+ */
+ version YPOLDVERS {
+ void
+ YPOLDPROC_NULL(void) = 0;
+
+ bool
+ YPOLDPROC_DOMAIN(domainname) = 1;
+
+ bool
+ YPOLDPROC_DOMAIN_NONACK(domainname) = 2;
+
+ ypresponse
+ YPOLDPROC_MATCH(yprequest) = 3;
+
+ ypresponse
+ YPOLDPROC_FIRST(yprequest) = 4;
+
+ ypresponse
+ YPOLDPROC_NEXT(yprequest) = 5;
+
+ ypresponse
+ YPOLDPROC_POLL(yprequest) = 6;
+
+ ypresponse
+ YPOLDPROC_PUSH(yprequest) = 7;
+
+ ypresponse
+ YPOLDPROC_PULL(yprequest) = 8;
+
+ ypresponse
+ YPOLDPROC_GET(yprequest) = 9;
+ } = 1;
+
+ version YPVERS {
+ void
+ YPPROC_NULL(void) = 0;
+
+ bool
+ YPPROC_DOMAIN(domainname) = 1;
+
+ bool
+ YPPROC_DOMAIN_NONACK(domainname) = 2;
+
+ ypresp_val
+ YPPROC_MATCH(ypreq_key) = 3;
+
+ ypresp_key_val
+#ifdef STUPID_SUN_BUG /* should be ypreq_nokey */
+ YPPROC_FIRST(ypreq_key) = 4;
+#else
+ YPPROC_FIRST(ypreq_nokey) = 4;
+#endif
+ ypresp_key_val
+ YPPROC_NEXT(ypreq_key) = 5;
+
+ ypresp_xfr
+ YPPROC_XFR(ypreq_xfr) = 6;
+
+ void
+ YPPROC_CLEAR(void) = 7;
+
+ ypresp_all
+ YPPROC_ALL(ypreq_nokey) = 8;
+
+ ypresp_master
+ YPPROC_MASTER(ypreq_nokey) = 9;
+
+ ypresp_order
+ YPPROC_ORDER(ypreq_nokey) = 10;
+
+ ypresp_maplist
+ YPPROC_MAPLIST(domainname) = 11;
+ } = 2;
+} = 100004;
+#endif
+#if !defined(YPSERV_ONLY) && !defined(YPBIND_ONLY)
+/*
+ * YPPUSHPROC_XFRRESP is the callback routine for result of YPPROC_XFR
+ */
+program YPPUSH_XFRRESPPROG {
+ version YPPUSH_XFRRESPVERS {
+ void
+ YPPUSHPROC_NULL(void) = 0;
+#ifdef STUPID_SUN_BUG /* argument and return value are backwards */
+ yppushresp_xfr
+ YPPUSHPROC_XFRRESP(void) = 1;
+#else
+ void
+ YPPUSHPROC_XFRRESP(yppushresp_xfr) = 1;
+#endif
+ } = 1;
+} = 0x40000000; /* transient: could be anything up to 0x5fffffff */
+#endif
+#if !defined(YPSERV_ONLY) && !defined(YPPUSH_ONLY)
+/*
+ * YP binding protocol
+ */
+program YPBINDPROG {
+ version YPBINDVERS {
+ void
+ YPBINDPROC_NULL(void) = 0;
+
+ ypbind_resp
+ YPBINDPROC_DOMAIN(domainname) = 1;
+
+ void
+ YPBINDPROC_SETDOM(ypbind_setdom) = 2;
+ } = 2;
+} = 100007;
+
+#endif
diff --git a/librpc/include/rpcsvc/yp_prot.h b/librpc/include/rpcsvc/yp_prot.h
new file mode 100644
index 0000000..f29f3ce
--- /dev/null
+++ b/librpc/include/rpcsvc/yp_prot.h
@@ -0,0 +1,330 @@
+/*
+ * Copyright (c) 1992/3 Theo de Raadt <deraadt@fsa.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * $FreeBSD: src/include/rpcsvc/yp_prot.h,v 1.10 1999/08/27 23:45:12 peter Exp $
+ */
+
+#ifndef _RPCSVC_YP_PROT_H_
+#define _RPCSVC_YP_PROT_H_
+
+/*
+ * YPSERV PROTOCOL:
+ *
+ * ypserv supports the following procedures:
+ *
+ * YPPROC_NULL takes (void), returns (void).
+ * called to check if server is alive.
+ * YPPROC_DOMAIN takes (char *), returns (bool_t).
+ * true if ypserv serves the named domain.
+ * YPPROC_DOMAIN_NOACK takes (char *), returns (bool_t).
+ * true if ypserv serves the named domain.
+ * used for broadcasts, does not ack if ypserv
+ * doesn't handle named domain.
+ * YPPROC_MATCH takes (struct ypreq_key), returns (struct ypresp_val)
+ * does a lookup.
+ * YPPROC_FIRST takes (struct ypreq_nokey) returns (ypresp_key_val).
+ * gets the first key/datum from the map.
+ * YPPROC_NEXT takes (struct ypreq_key) returns (ypresp_key_val).
+ * gets the next key/datum from the map.
+ * YPPROC_XFR takes (struct ypreq_xfr), returns (void).
+ * tells ypserv to check if there is a new version of
+ * the map.
+ * YPPROC_CLEAR takes (void), returns (void).
+ * tells ypserv to flush it's file cache, so that
+ * newly transferred files will get read.
+ * YPPROC_ALL takes (struct ypreq_nokey), returns (bool_t and
+ * struct ypresp_key_val).
+ * returns an array of data, with the bool_t being
+ * false on the last datum. read the source, it's
+ * convoluted.
+ * YPPROC_MASTER takes (struct ypreq_nokey), returns (ypresp_master).
+ * YPPROC_ORDER takes (struct ypreq_nokey), returns (ypresp_order).
+ * YPPROC_MAPLIST takes (char *), returns (struct ypmaplist *).
+ */
+
+#ifndef BOOL_DEFINED
+typedef u_int bool;
+#define BOOL_DEFINED
+#endif
+
+/* Program and version symbols, magic numbers */
+
+#define YPPROG ((u_long)100004)
+#define YPVERS ((u_long)2)
+#define YPVERS_ORIG ((u_long)1)
+#define YPMAXRECORD ((u_long)1024)
+#define YPMAXDOMAIN ((u_long)64)
+#define YPMAXMAP ((u_long)64)
+#define YPMAXPEER ((u_long)256)
+
+/*
+ * I don't know if anything of sun's depends on this, or if they
+ * simply defined it so that their own code wouldn't try to send
+ * packets over the ethernet MTU. This YP code doesn't use it.
+ */
+#define YPMSGSZ 1600
+
+#ifndef DATUM
+typedef struct {
+ char *dptr;
+ int dsize;
+} datum;
+#define DATUM
+#endif
+
+struct ypmap_parms {
+ char *domain;
+ char *map;
+ u_long ordernum;
+ char *owner;
+};
+
+struct ypreq_key {
+ char *domain;
+ char *map;
+ datum keydat;
+};
+
+struct ypreq_nokey {
+ char *domain;
+ char *map;
+};
+
+struct ypreq_xfr {
+ struct ypmap_parms map_parms;
+ u_long transid;
+ u_long proto;
+ u_short 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
+
+struct ypresp_val {
+ u_long status;
+ datum valdat;
+};
+
+struct ypresp_key_val {
+ u_long status;
+ datum keydat;
+ datum valdat;
+};
+
+struct ypresp_master {
+ u_long status;
+ char *master;
+};
+
+struct ypresp_order {
+ u_long status;
+ u_long ordernum;
+};
+
+struct ypmaplist {
+ char ypml_name[YPMAXMAP + 1];
+ struct ypmaplist *ypml_next;
+};
+
+struct ypresp_maplist {
+ u_long status;
+ struct ypmaplist *list;
+};
+
+/* ypserv procedure numbers */
+#define YPPROC_NULL ((u_long)0)
+#define YPPROC_DOMAIN ((u_long)1)
+#define YPPROC_DOMAIN_NONACK ((u_long)2)
+#define YPPROC_MATCH ((u_long)3)
+#define YPPROC_FIRST ((u_long)4)
+#define YPPROC_NEXT ((u_long)5)
+#define YPPROC_XFR ((u_long)6)
+#define YPPROC_CLEAR ((u_long)7)
+#define YPPROC_ALL ((u_long)8)
+#define YPPROC_MASTER ((u_long)9)
+#define YPPROC_ORDER ((u_long)10)
+#define YPPROC_MAPLIST ((u_long)11)
+
+/* ypserv procedure return status values */
+#define YP_TRUE ((long)1) /* general purpose success code */
+#define YP_NOMORE ((long)2) /* no more entries in map */
+#define YP_FALSE ((long)0) /* general purpose failure code */
+#define YP_NOMAP ((long)-1) /* no such map in domain */
+#define YP_NODOM ((long)-2) /* domain not supported */
+#define YP_NOKEY ((long)-3) /* no such key in map */
+#define YP_BADOP ((long)-4) /* invalid operation */
+#define YP_BADDB ((long)-5) /* server data base is bad */
+#define YP_YPERR ((long)-6) /* YP server error */
+#define YP_BADARGS ((long)-7) /* request arguments bad */
+#define YP_VERS ((long)-8) /* YP server version mismatch */
+
+/*
+ * Sun's header file says:
+ * "Domain binding data structure, used by ypclnt package and ypserv modules.
+ * Users of the ypclnt package (or of this protocol) don't HAVE to know about
+ * it, but it must be available to users because _yp_dobind is a public
+ * interface."
+ *
+ * This is totally bogus! Nowhere else does Sun state that _yp_dobind() is
+ * a public interface, and I don't know any reason anyone would want to call
+ * it. But, just in case anyone does actually expect it to be available..
+ * we provide this.. exactly as Sun wants it.
+ */
+struct dom_binding {
+ struct dom_binding *dom_pnext;
+ char dom_domain[YPMAXDOMAIN + 1];
+ struct sockaddr_in dom_server_addr;
+ u_short dom_server_port;
+ int dom_socket;
+ CLIENT *dom_client;
+ u_short dom_local_port;
+ long dom_vers;
+};
+
+/*
+ * YPBIND PROTOCOL:
+ *
+ * ypbind supports the following procedures:
+ *
+ * YPBINDPROC_NULL takes (void), returns (void).
+ * to check if ypbind is running.
+ * YPBINDPROC_DOMAIN takes (char *), returns (struct ypbind_resp).
+ * requests that ypbind start to serve the
+ * named domain (if it doesn't already)
+ * YPBINDPROC_SETDOM takes (struct ypbind_setdom), returns (void).
+ * used by ypset.
+ */
+
+#define YPBINDPROG ((u_long)100007)
+#define YPBINDVERS ((u_long)2)
+#define YPBINDVERS_ORIG ((u_long)1)
+
+/* ypbind procedure numbers */
+#define YPBINDPROC_NULL ((u_long)0)
+#define YPBINDPROC_DOMAIN ((u_long)1)
+#define YPBINDPROC_SETDOM ((u_long)2)
+
+/* error code in ypbind_resp.ypbind_status */
+enum ypbind_resptype {
+ YPBIND_SUCC_VAL = 1,
+ YPBIND_FAIL_VAL = 2,
+ _YPBIND_RESPTYPE = 0xffffffff
+};
+
+/* network order, of course */
+struct ypbind_binding {
+ struct in_addr ypbind_binding_addr;
+ u_short ypbind_binding_port;
+};
+
+struct ypbind_resp {
+ enum ypbind_resptype ypbind_status;
+ union {
+ u_long ypbind_error;
+ struct ypbind_binding ypbind_bindinfo;
+ } ypbind_respbody;
+};
+
+/* error code in ypbind_resp.ypbind_respbody.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[YPMAXDOMAIN + 1];
+ struct ypbind_binding ypsetdom_binding;
+ u_short ypsetdom_vers;
+};
+#define ypsetdom_addr ypsetdom_binding.ypbind_binding_addr
+#define ypsetdom_port ypsetdom_binding.ypbind_binding_port
+
+/*
+ * YPPUSH PROTOCOL:
+ *
+ * Sun says:
+ * "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."
+ *
+ * This protocol is not implemented, naturally, because this YP
+ * implementation only does the client side.
+ */
+#define YPPUSHVERS ((u_long)1)
+#define YPPUSHVERS_ORIG ((u_long)1)
+
+/* yppush procedure numbers */
+#define YPPUSHPROC_NULL ((u_long)0)
+#define YPPUSHPROC_XFRRESP ((u_long)1)
+
+struct yppushresp_xfr {
+ u_long transid;
+ u_long status;
+};
+
+/* yppush status value in yppushresp_xfr.status */
+#define YPPUSH_SUCC ((long)1) /* Success */
+#define YPPUSH_AGE ((long)2) /* Master's version not newer */
+#define YPPUSH_NOMAP ((long)-1) /* Can't find server for map */
+#define YPPUSH_NODOM ((long)-2) /* Domain not supported */
+#define YPPUSH_RSRC ((long)-3) /* Local resource alloc failure */
+#define YPPUSH_RPC ((long)-4) /* RPC failure talking to server */
+#define YPPUSH_MADDR ((long)-5) /* Can't get master address */
+#define YPPUSH_YPERR ((long)-6) /* YP server/map db error */
+#define YPPUSH_BADARGS ((long)-7) /* Request arguments bad */
+#define YPPUSH_DBM ((long)-8) /* Local dbm operation failed */
+#define YPPUSH_FILE ((long)-9) /* Local file I/O operation failed */
+#define YPPUSH_SKEW ((long)-10) /* Map version skew during transfer */
+#define YPPUSH_CLEAR ((long)-11) /* Can't send "Clear" req to local ypserv */
+#define YPPUSH_FORCE ((long)-12) /* No local order number in map - use -f */
+#define YPPUSH_XFRERR ((long)-13) /* ypxfr error */
+#define YPPUSH_REFUSED ((long)-14) /* Transfer request refused by ypserv */
+
+struct inaddr;
+__BEGIN_DECLS
+bool_t xdr_datum (XDR *, datum *);
+bool_t xdr_ypreq_key (XDR *, struct ypreq_key *);
+bool_t xdr_ypreq_nokey (XDR *, struct ypreq_nokey *);
+bool_t xdr_ypreq_xfr (XDR *, struct ypreq_xfr *);
+bool_t xdr_ypresp_val (XDR *, struct ypresp_val *);
+bool_t xdr_ypresp_key_val (XDR *, struct ypresp_key_val *);
+bool_t xdr_ypbind_resp (XDR *, struct ypbind_resp *);
+bool_t xdr_ypbind_setdom (XDR *, struct ypbind_setdom *);
+bool_t xdr_yp_inaddr (XDR *, struct inaddr *);
+bool_t xdr_ypmap_parms (XDR *, struct ypmap_parms *);
+bool_t xdr_yppushresp_xfr (XDR *, struct yppushresp_xfr *);
+bool_t xdr_ypresp_order (XDR *, struct ypresp_order *);
+bool_t xdr_ypresp_master (XDR *, struct ypresp_master *);
+bool_t xdr_ypresp_maplist (XDR *, struct ypresp_maplist *);
+__END_DECLS
+
+#endif /* _RPCSVC_YP_PROT_H_ */
diff --git a/librpc/include/rpcsvc/ypclnt.h b/librpc/include/rpcsvc/ypclnt.h
new file mode 100644
index 0000000..6b8edfe
--- /dev/null
+++ b/librpc/include/rpcsvc/ypclnt.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 1992/3 Theo de Raadt <deraadt@fsa.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * $FreeBSD: src/include/rpcsvc/ypclnt.h,v 1.11 1999/08/27 23:45:12 peter Exp $
+ */
+
+#ifndef _RPCSVC_YPCLNT_H_
+#define _RPCSVC_YPCLNT_H_
+
+#include <sys/cdefs.h>
+
+#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 for 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 /* some 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 */
+
+struct ypall_callback {
+ /* return non-0 to stop getting called */
+ int (*foreach) (unsigned long, char *, int, char *, int, void *);
+ char *data; /* opaque pointer for use of callback fn */
+};
+
+struct dom_binding;
+
+__BEGIN_DECLS
+int yp_bind (char *dom);
+int _yp_dobind (char *dom, struct dom_binding **ypdb);
+void yp_unbind (char *dom);
+int yp_get_default_domain (char **domp);
+int yp_match (char *indomain, char *inmap,
+ const char *inkey, int inkeylen, char **outval,
+ int *outvallen);
+int yp_first (char *indomain, char *inmap,
+ char **outkey, int *outkeylen, char **outval,
+ int *outvallen);
+int yp_next (char *indomain, char *inmap,
+ char *inkey, int inkeylen, char **outkey,
+ int *outkeylen, char **outval, int *outvallen);
+int yp_master (char *indomain, char *inmap, char **outname);
+int yp_order (char *indomain, char *inmap, int *outorder);
+int yp_all (char *indomain, char *inmap,
+ struct ypall_callback *incallback);
+char * yperr_string (int incode);
+char * ypbinderr_string (int incode);
+int ypprot_err (unsigned int incode);
+__END_DECLS
+
+#endif /* _RPCSVC_YPCLNT_H_ */
diff --git a/librpc/include/rpcsvc/yppasswd.x b/librpc/include/rpcsvc/yppasswd.x
new file mode 100644
index 0000000..73dca8e
--- /dev/null
+++ b/librpc/include/rpcsvc/yppasswd.x
@@ -0,0 +1,75 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * YP password update protocol
+ * Requires unix authentication
+ */
+
+#ifndef RPC_HDR
+%#ifndef lint
+%/*static char sccsid[] = "from: @(#)yppasswd.x 1.1 87/04/13 Copyr 1987 Sun Micro";*/
+%/*static char sccsid[] = "from: @(#)yppasswd.x 2.1 88/08/01 4.0 RPCSRC";*/
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/yppasswd.x,v 1.6 1999/08/27 23:45:12 peter Exp $";
+%#endif /* not lint */
+#endif
+
+program YPPASSWDPROG {
+ version YPPASSWDVERS {
+ /*
+ * Update my passwd entry
+ */
+ int
+ YPPASSWDPROC_UPDATE(yppasswd) = 1;
+ } = 1;
+} = 100009;
+
+
+struct x_passwd {
+ string pw_name<>; /* username */
+ string pw_passwd<>; /* encrypted password */
+ int pw_uid; /* user id */
+ int pw_gid; /* group id */
+ string pw_gecos<>; /* in real life name */
+ string pw_dir<>; /* home directory */
+ string pw_shell<>; /* default shell */
+};
+
+struct yppasswd {
+ string oldpass<>; /* unencrypted old password */
+ x_passwd newpw; /* new passwd entry */
+};
+
+
+#ifdef RPC_HDR
+%#include <sys/cdefs.h>
+%extern int _yppasswd ( char * , struct x_passwd * );
+%#define yppasswd(x,y) _yppasswd(x,y)
+#endif
diff --git a/librpc/include/rpcsvc/ypupdate_prot.x b/librpc/include/rpcsvc/ypupdate_prot.x
new file mode 100644
index 0000000..f16d5ee
--- /dev/null
+++ b/librpc/include/rpcsvc/ypupdate_prot.x
@@ -0,0 +1,88 @@
+%/*
+% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+% * unrestricted use provided that this legend is included on all tape
+% * media and as a part of the software program in whole or part. Users
+% * may copy or modify Sun RPC without charge, but are not authorized
+% * to license or distribute it to anyone else except as part of a product or
+% * program developed by the user or with the express written consent of
+% * Sun Microsystems, Inc.
+% *
+% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+% *
+% * Sun RPC is provided with no support and without any obligation on the
+% * part of Sun Microsystems, Inc. to assist in its use, correction,
+% * modification or enhancement.
+% *
+% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+% * OR ANY PART THEREOF.
+% *
+% * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+% * or profits or other special, indirect and consequential damages, even if
+% * Sun has been advised of the possibility of such damages.
+% *
+% * Sun Microsystems, Inc.
+% * 2550 Garcia Avenue
+% * Mountain View, California 94043
+% */
+
+%/*
+% * Copyright (c) 1986, 1990 by Sun Microsystems, Inc.
+% */
+%
+%/* from @(#)ypupdate_prot.x 1.3 91/03/11 TIRPC 1.0 */
+#ifndef RPC_HDR
+%#ifndef lint
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/ypupdate_prot.x,v 1.3 1999/08/27 23:45:13 peter Exp $";
+%#endif
+#endif
+%
+%/*
+% * Compiled from ypupdate_prot.x using rpcgen
+% * This is NOT source code!
+% * DO NOT EDIT THIS FILE!
+% */
+
+/*
+ * YP update service protocol
+ */
+#ifdef RPC_HDR
+%
+%#ifndef _rpcsvc_ypupdate_prot_h
+%#define _rpcsvc_ypupdate_prot_h
+%
+#endif
+
+const MAXMAPNAMELEN = 255;
+const MAXYPDATALEN = 1023;
+const MAXERRMSGLEN = 255;
+
+program YPU_PROG {
+ version YPU_VERS {
+ u_int YPU_CHANGE(ypupdate_args) = 1;
+ u_int YPU_INSERT(ypupdate_args) = 2;
+ u_int YPU_DELETE(ypdelete_args) = 3;
+ u_int YPU_STORE(ypupdate_args) = 4;
+ } = 1;
+} = 100028;
+
+typedef opaque yp_buf<MAXYPDATALEN>;
+
+struct ypupdate_args {
+ string mapname<MAXMAPNAMELEN>;
+ yp_buf key;
+ yp_buf datum;
+};
+
+struct ypdelete_args {
+ string mapname<MAXMAPNAMELEN>;
+ yp_buf key;
+};
+
+#ifdef RPC_HDR
+%
+%#endif /* !_rpcsvc_ypupdate_prot_h */
+#endif
diff --git a/librpc/include/rpcsvc/ypxfrd.x b/librpc/include/rpcsvc/ypxfrd.x
new file mode 100644
index 0000000..1845a4f
--- /dev/null
+++ b/librpc/include/rpcsvc/ypxfrd.x
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 1995, 1996
+ * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Bill Paul.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bill Paul 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 Bill Paul 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.
+ *
+ * $FreeBSD: src/include/rpcsvc/ypxfrd.x,v 1.7 1999/08/27 23:45:13 peter Exp $
+ */
+
+/*
+ * This protocol definition file describes a file transfer
+ * system used to very quickly move NIS maps from one host to
+ * another. This is similar to what Sun does with their ypxfrd
+ * protocol, but it must be stressed that this protocol is _NOT_
+ * compatible with Sun's. There are a couple of reasons for this:
+ *
+ * 1) Sun's protocol is proprietary. The protocol definition is
+ * not freely available in any of the SunRPC source distributions,
+ * even though the NIS v2 protocol is.
+ *
+ * 2) The idea here is to transfer entire raw files rather than
+ * sending just the records. Sun uses ndbm for its NIS map files,
+ * while FreeBSD uses Berkeley DB. Both are hash databases, but the
+ * formats are incompatible, making it impossible for them to
+ * use each others' files. Even if FreeBSD adopted ndbm for its
+ * database format, FreeBSD/i386 is a little-endian OS and
+ * SunOS/SPARC is big-endian; ndbm is byte-order sensitive and
+ * not very smart about it, which means an attempt to read a
+ * database on a little-endian box that was created on a big-endian
+ * box (or vice-versa) can cause the ndbm code to eat itself.
+ * Luckily, Berkeley DB is able to deal with this situation in
+ * a more graceful manner.
+ *
+ * While the protocol is incompatible, the idea is the same: we just open
+ * up a TCP pipe to the client and transfer the raw map database
+ * from the master server to the slave. This is many times faster than
+ * the standard yppush/ypxfr transfer method since it saves us from
+ * having to recreate the map databases via the DB library each time.
+ * For example: creating a passwd database with 30,000 entries with yp_mkdb
+ * can take a couple of minutes, but to just copy the file takes only a few
+ * seconds.
+ */
+
+#ifndef RPC_HDR
+%#ifndef lint
+%static const char rcsid[] =
+% "$FreeBSD: src/include/rpcsvc/ypxfrd.x,v 1.7 1999/08/27 23:45:13 peter Exp $";
+%#endif /* not lint */
+#endif
+
+/* XXX cribbed from yp.x */
+const _YPMAXRECORD = 1024;
+const _YPMAXDOMAIN = 64;
+const _YPMAXMAP = 64;
+const _YPMAXPEER = 64;
+
+/* Suggested default -- not necesarrily the one used. */
+const YPXFRBLOCK = 32767;
+
+/*
+ * Possible return codes from the remote server.
+ */
+enum xfrstat {
+ XFR_REQUEST_OK = 1, /* Transfer request granted */
+ XFR_DENIED = 2, /* Transfer request denied */
+ XFR_NOFILE = 3, /* Requested map file doesn't exist */
+ XFR_ACCESS = 4, /* File exists, but I couldn't access it */
+ XFR_BADDB = 5, /* File is not a hash database */
+ XFR_READ_OK = 6, /* Block read successfully */
+ XFR_READ_ERR = 7, /* Read error during transfer */
+ XFR_DONE = 8, /* Transfer completed */
+ XFR_DB_ENDIAN_MISMATCH = 9, /* Database byte order mismatch */
+ XFR_DB_TYPE_MISMATCH = 10 /* Database type mismatch */
+};
+
+/*
+ * Database type specifications. The client can use this to ask
+ * the server for a particular type of database or just take whatever
+ * the server has to offer.
+ */
+enum xfr_db_type {
+ XFR_DB_ASCII = 1, /* Flat ASCII text */
+ XFR_DB_BSD_HASH = 2, /* Berkeley DB, hash method */
+ XFR_DB_BSD_BTREE = 3, /* Berkeley DB, btree method */
+ XFR_DB_BSD_RECNO = 4, /* Berkeley DB, recno method */
+ XFR_DB_BSD_MPOOL = 5, /* Berkeley DB, mpool method */
+ XFR_DB_BSD_NDBM = 6, /* Berkeley DB, hash, ndbm compat */
+ XFR_DB_GNU_GDBM = 7, /* GNU GDBM */
+ XFR_DB_DBM = 8, /* Old, deprecated dbm format */
+ XFR_DB_NDBM = 9, /* ndbm format (used by Sun's NISv2) */
+ XFR_DB_OPAQUE = 10, /* Mystery format -- just pass along */
+ XFR_DB_ANY = 11, /* I'll take any format you've got */
+ XFR_DB_UNKNOWN = 12 /* Unknown format */
+};
+
+/*
+ * Machine byte order specification. This allows the client to check
+ * that it's copying a map database from a machine of similar byte sex.
+ * This is necessary for handling database libraries that are fatally
+ * byte order sensitive.
+ *
+ * The XFR_ENDIAN_ANY type is for use with the Berkeley DB database
+ * formats; Berkeley DB is smart enough to make up for byte order
+ * differences, so byte sex isn't important.
+ */
+enum xfr_byte_order {
+ XFR_ENDIAN_BIG = 1, /* We want big endian */
+ XFR_ENDIAN_LITTLE = 2, /* We want little endian */
+ XFR_ENDIAN_ANY = 3 /* We'll take whatever you got */
+};
+
+typedef string xfrdomain<_YPMAXDOMAIN>;
+typedef string xfrmap<_YPMAXMAP>;
+typedef string xfrmap_filename<_YPMAXMAP>; /* actual name of map file */
+
+/*
+ * Ask the remote ypxfrd for a map using this structure.
+ * Note: we supply both a map name and a map file name. These are not
+ * the same thing. In the case of ndbm, maps are stored in two files:
+ * map.bykey.pag and may.bykey.dir. We may also have to deal with
+ * file extensions (on the off chance that the remote server is supporting
+ * multiple DB formats). To handle this, we tell the remote server both
+ * what map we want and, in the case of ndbm, whether we want the .dir
+ * or the .pag part. This name should not be a fully qualified path:
+ * it's up to the remote server to decide which directories to look in.
+ */
+struct ypxfr_mapname {
+ xfrmap xfrmap;
+ xfrdomain xfrdomain;
+ xfrmap_filename xfrmap_filename;
+ xfr_db_type xfr_db_type;
+ xfr_byte_order xfr_byte_order;
+};
+
+/* Read response using this structure. */
+union xfr switch (bool ok) {
+case TRUE:
+ opaque xfrblock_buf<>;
+case FALSE:
+ xfrstat xfrstat;
+};
+
+program YPXFRD_FREEBSD_PROG {
+ version YPXFRD_FREEBSD_VERS {
+ union xfr
+ YPXFRD_GETMAP(ypxfr_mapname) = 1;
+ } = 1;
+} = 600100069; /* 100069 + 60000000 -- 100069 is the Sun ypxfrd prog number */
diff --git a/librpc/src/rpc/DISCLAIMER b/librpc/src/rpc/DISCLAIMER
new file mode 100644
index 0000000..1a66d5f
--- /dev/null
+++ b/librpc/src/rpc/DISCLAIMER
@@ -0,0 +1,28 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
diff --git a/librpc/src/rpc/README b/librpc/src/rpc/README
new file mode 100644
index 0000000..ad9d70f
--- /dev/null
+++ b/librpc/src/rpc/README
@@ -0,0 +1,233 @@
+RPCSRC 4.0 7/11/89
+
+This distribution contains Sun Microsystem's implementation of the
+RPC and XDR protocols and is compatible with 4.2BSD and 4.3BSD. Also
+included is complete documentation, utilities, RPC service
+specification files, and demonstration services in the format used by
+the RPC protocol compiler (rpcgen). See WHAT'S NEW below for
+details.
+
+NOTE ABOUT SECURE RPC:
+
+This release of RPCSRC contains most of the code needed to implement
+Secure RPC (see "DES Authentication" in the RPC Protocol Specification,
+doc/rpc.rfc.ms). Due to legal considerations, we are unable to
+distribute an implementation of DES, the Data Encryption Standard, which
+Secure RPC requires. For this reason, all of the files, documentation, and
+programs associated with Secure RPC have been placed into a separate
+directory, secure_rpc. The RPC library contained in the main body of this
+release *DOES NOT* support Secure RPC. See secure_rpc/README for more
+details. (A DES library was posted in Volume 18 of comp.sources.unix.)
+
+If you wish to report bugs found in this release, send mail to:
+
+Portable ONC/NFS
+Sun Microsystems, Inc
+MS 12-33
+2550 Garcia Avenue
+Mountain View, CA 94043
+
+or send Email to nfsnet@sun.com (the Internet) or sun!nfsnet (Usenet).
+
+ROADMAP
+
+The directory hierarchy is as follows:
+
+ demo/ Various demonstration services
+ demo/dir Remote directory lister
+ demo/msg Remote console message delivery service
+ demo/sort Remote sort service
+
+ doc/ Documentation for RPC, XDR and NFS in "-ms" format.
+
+ etc/ Utilities (rpcinfo and portmap). portmap must be
+ started by root before any other RPC network services are
+ used. SEE BELOW FOR BUGFIX TO 4.3BSD COMPILER.
+
+ man/ Manual pages for RPC library, rpcgen, and utilities.
+
+ rpc/ The RPC and XDR library. SEE BELOW
+ FOR BUGFIX TO 4.2BSD COMPILER.
+
+ rpcgen/ The RPC Language compiler (for .x files)
+
+ rpcsvc/ Service definition files for various services and the
+ server and client code for the Remote Status service.
+
+ secure_rpc/ The files in this directory are used to build a version of
+ the RPC library with DES Authentication. See the README
+ file in that directory for more details.
+
+BUILD INSTRUCTIONS
+
+Makefiles can be found in all directories except for man. The
+Makefile in the top directory will cause these others to be invoked
+(except for in the doc, man and demo directories), in turn building the
+entire release.
+
+WARNING! THE DEFAULT INSTALLATION PROCEDURES WILL INSTALL FILES
+IN /usr/include, /usr/lib, /usr/bin and /etc.
+
+The master RPC include file, rpc/rpc.h, is used by all programs and
+routines that use RPC. It includes other RPC and system include files
+needed by the RPC system. PLEASE NOTE: If your system has NFS, it
+may have been based on Sun's NFS Source. The include files installed
+by this package may duplicate include files you will find on your NFS
+system. The RPCSRC 4.0 include files are upwardly compatible to all
+NFS Source include files as of the date of this distribution (not
+including any new definitions or declarations added by your system
+vendor). HOWEVER: Please read the comments towards the end of
+rpc/rpc.h regarding rpc/netdb.h. You may need to uncomment the
+inclusion of that file if the structures it defines are already
+defined by your system's include files.
+
+After making any compiler fixes that are needed (see below), at
+the top directory, type:
+
+ make install
+
+For all installations, the Makefile macro DESTDIR is prepended to the
+installation path. It is defined to be null in the Makefiles, so
+installations are relative to root. (You will probably need root
+privileges for installing the files under the default path.) To
+install the files under some other tree (e.g., /usr/local), use the
+command:
+
+ make install DESTDIR=/usr/local
+
+This will place the include files in /usr/local/usr/include, the RPC
+library in /usr/local/usr/lib, rpcgen in /usr/local/usr/bin, and the
+utilities in /usr/local/etc. You'll have to edit the Makefiles or
+install the files by hand if you want to do anything other than this
+kind of relocation of the installation tree.
+
+The RPC library will be built and installed first. By default it is
+installed in /usr/lib as "librpclib.a". The directory
+/usr/include/rpc will also be created, and several header files will
+be installed there. ALL RPC SERVICES INCLUDE THESE HEADER FILES.
+
+The programs in etc/ link in routines from librpclib.a. If you change
+where it is installed, be sure to edit etc/'s Makefile to reflect this.
+These programs are installed in /etc. PORTMAP MUST BE RUNNING ON
+YOUR SYSTEM BEFORE YOU START ANY OTHER RPC SERVICE.
+
+rpcgen is installed in /usr/bin. This program is required to build
+the demonstration services in demo and the rstat client and server in
+rpcsvc/.
+
+The rpcsvc/ directory will install its files in the directory
+/usr/include/rpcsvc. The Remote Status service (rstat_svc) will be
+compiled and installed in /etc. If you wish to make this service
+available, you should either start this service when needed or have
+it started at boot time by invoking it in your /etc/rc.local script.
+(Be sure that portmap is started first!) Sun has modified its
+version of inetd to automatically start RPC services. (Use "make
+LIB=" when building rstat on a Sun Workstation.) The Remote Status
+client (rstat) will be installed in /usr/bin. This program queries
+the rstat_svc on a remote host and prints a system status summary
+similar to the one printed by "uptime".
+
+The documentation is not built during the "make install" command.
+Typing "make" in the doc directory will cause all of the manuals to
+be formatted using nroff into a single file. We have had a report
+that certain "troff" equivalents have trouble processing the full
+manual. If you have trouble, try building the manuals individually
+(see the Makefile).
+
+The demonstration services in the demo directory are not built by the
+top-level "make install" command. To build these, cd to the demo
+directory and enter "make". The three services will be built.
+RPCGEN MUST BE INSTALLED in a path that make can find. To run the
+services, start the portmap program as root and invoke the service
+(you probably will want to put it in the background). rpcinfo can be
+used to check that the service succeeded in getting registered with
+portmap, and to ping the service (see rpcinfo's man page). You can
+then use the corresponding client program to exercise the service.
+To build these services on a Sun workstation, you must prevent the
+Makefile from trying to link the RPC library (as these routines are
+already a part of Sun's libc). Use: "make LIB=".
+
+BUGFIX FOR 4.3BSD COMPILER
+
+The use of a 'void *' declaration for one of the arguments in
+the reply_proc() procedure in etc/rpcinfo.c will trigger a bug
+in the 4.3BSD compiler. The bug is fixed by the following change to
+the compiler file mip/manifest.h:
+
+*** manifest.h.r1.1 Thu Apr 30 13:52:25 1987
+--- manifest.h.r1.2 Mon Nov 23 18:58:17 1987
+***************
+*** 21,27 ****
+ /*
+ * Bogus type values
+ */
+! #define TNULL PTR /* pointer to UNDEF */
+ #define TVOID FTN /* function returning UNDEF (for void) */
+
+ /*
+--- 21,27 ----
+ /*
+ * Bogus type values
+ */
+! #define TNULL INCREF(MOETY) /* pointer to MOETY -- impossible type */
+ #define TVOID FTN /* function returning UNDEF (for void) */
+
+ /*
+
+If you cannot fix your compiler, change the declaration in reply_proc()
+from 'void *' to 'char *'.
+
+BUGFIX FOR 4.2BSD COMPILER
+
+Unpatched 4.2BSD compilers complain about valid C. You can make old
+compilers happy by changing some voids to ints. However, the fix to
+the 4.2 VAX compiler is as follows (to mip/trees.c):
+
+*** trees.c.r1.1 Mon May 11 13:47:58 1987
+--- trees.c.r1.2 Wed Jul 2 18:28:52 1986
+***************
+*** 1247,1253 ****
+ if(o==CAST && mt1==0)return(TYPL+TYMATCH);
+ if( mt12 & MDBI ) return( TYPL+LVAL+TYMATCH );
+ else if( (mt1&MENU)||(mt2&MENU) ) return( LVAL+NCVT+TYPL+PTMATCH+PUN );
+! else if( mt12 == 0 ) break;
+ else if( mt1 & MPTR ) return( LVAL+PTMATCH+PUN );
+ else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN );
+ break;
+--- 1261,1269 ----
+ if(o==CAST && mt1==0)return(TYPL+TYMATCH);
+ if( mt12 & MDBI ) return( TYPL+LVAL+TYMATCH );
+ else if( (mt1&MENU)||(mt2&MENU) ) return( LVAL+NCVT+TYPL+PTMATCH+PUN );
+! /* if right is TVOID and looks like a CALL, is not ok */
+! else if (mt2 == 0 && (p->in.right->in.op == CALL || p->in.right->in.op == UNARY CALL))
+! break;
+ else if( mt1 & MPTR ) return( LVAL+PTMATCH+PUN );
+ else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN );
+ break;
+
+WHAT'S NEW IN THIS RELEASE: RPCSRC 4.0
+
+The previous release was RPCSRC 3.9. As with all previous releases,
+this release is based directly on files from Sun Microsystem's
+implementation.
+
+Upgrade from RPCSRC 3.9
+
+1) RPCSRC 4.0 upgrades RPCSRC 3.9. Improvements from SunOS 4.0 have
+ been integrated into this release.
+
+Secure RPC (in the secure_rpc/ directory)
+
+2) DES Authentication routines and programs are provided.
+3) A new manual, "Secure NFS" is provided, which describes Secure RPC
+ and Secure NFS.
+4) Skeleton routines and manual pages are provided which describe the
+ DES encryption procedures required by Secure RPC. HOWEVER, NO DES
+ ROUTINE IS PROVIDED.
+
+New Functionality
+
+5) rpcinfo can now be used to de-register services from the portmapper
+ which may have terminated abnormally.
+6) A new client, rstat, is provided which queries the rstat_svc and
+ prints a status line similar to the one displayed by "uptime".
diff --git a/librpc/src/rpc/auth_none.c b/librpc/src/rpc/auth_none.c
new file mode 100644
index 0000000..535749c
--- /dev/null
+++ b/librpc/src/rpc/auth_none.c
@@ -0,0 +1,140 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)auth_none.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)auth_none.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/auth_none.c,v 1.9 1999/08/28 00:00:32 peter Exp $";
+#endif
+
+/*
+ * auth_none.c
+ * Creates a client authentication handle for passing "null"
+ * credentials and verifiers to remote systems.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#define MAX_MARSHAL_SIZE 20
+
+/*
+ * Authenticator operations routines
+ */
+static void authnone_verf(AUTH*);
+static void authnone_destroy(AUTH*);
+static int authnone_marshal(AUTH*, XDR*);
+static int authnone_validate(AUTH*, struct opaque_auth *);
+static int authnone_refresh(AUTH*);
+
+static struct auth_ops ops = {
+ authnone_verf,
+ authnone_marshal,
+ authnone_validate,
+ authnone_refresh,
+ authnone_destroy
+};
+
+static struct authnone_private {
+ AUTH no_client;
+ char marshalled_client[MAX_MARSHAL_SIZE];
+ u_int mcnt;
+} *authnone_private;
+
+AUTH *
+authnone_create(void)
+{
+ struct authnone_private *ap = authnone_private;
+ XDR xdr_stream;
+ XDR *xdrs;
+
+ if (ap == 0) {
+ ap = (struct authnone_private *)calloc(1, sizeof (*ap));
+ if (ap == 0)
+ return (0);
+ authnone_private = ap;
+ }
+ if (!ap->mcnt) {
+ ap->no_client.ah_cred = ap->no_client.ah_verf = _null_auth;
+ ap->no_client.ah_ops = &ops;
+ xdrs = &xdr_stream;
+ xdrmem_create(xdrs, ap->marshalled_client, (u_int)MAX_MARSHAL_SIZE,
+ XDR_ENCODE);
+ (void)xdr_opaque_auth(xdrs, &ap->no_client.ah_cred);
+ (void)xdr_opaque_auth(xdrs, &ap->no_client.ah_verf);
+ ap->mcnt = XDR_GETPOS(xdrs);
+ XDR_DESTROY(xdrs);
+ }
+ return (&ap->no_client);
+}
+
+/*ARGSUSED*/
+static int
+authnone_marshal(AUTH *client, XDR *xdrs)
+{
+ struct authnone_private *ap = authnone_private;
+
+ if (ap == 0)
+ return (0);
+ return ((*xdrs->x_ops->x_putbytes)(xdrs,
+ ap->marshalled_client, ap->mcnt));
+}
+
+static void
+authnone_verf(AUTH *client)
+{
+}
+
+static int
+authnone_validate(AUTH *client, struct opaque_auth *opaque)
+{
+
+ return (TRUE);
+}
+
+static int
+authnone_refresh(AUTH *client)
+{
+
+ return (FALSE);
+}
+
+static void
+authnone_destroy(AUTH *client)
+{
+}
diff --git a/librpc/src/rpc/auth_unix.c b/librpc/src/rpc/auth_unix.c
new file mode 100644
index 0000000..99f5920
--- /dev/null
+++ b/librpc/src/rpc/auth_unix.c
@@ -0,0 +1,347 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)auth_unix.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)auth_unix.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/auth_unix.c,v 1.12 1999/12/29 05:04:16 peter Exp $";
+#endif
+
+/*
+ * auth_unix.c, Implements UNIX style authentication parameters.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * The system is very weak. The client uses no encryption for it's
+ * credentials and only sends null verifiers. The server sends backs
+ * null verifiers or optionally a verifier that suggests a new short hand
+ * for the credentials.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <sys/param.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#include <rpc/auth_unix.h>
+
+/*
+ * Unix authenticator operations vector
+ */
+static void authunix_nextverf(AUTH*);
+static int authunix_marshal(AUTH*, XDR*);
+static int authunix_validate(AUTH*, struct opaque_auth *);
+static int authunix_refresh(AUTH*);
+static void authunix_destroy(AUTH*);
+
+static struct auth_ops auth_unix_ops = {
+ authunix_nextverf,
+ authunix_marshal,
+ authunix_validate,
+ authunix_refresh,
+ authunix_destroy
+};
+
+/*
+ * This struct is pointed to by the ah_private field of an auth_handle.
+ */
+struct audata {
+ struct opaque_auth au_origcred; /* original credentials */
+ struct opaque_auth au_shcred; /* short hand cred */
+ u_long au_shfaults; /* short hand cache faults */
+ char au_marshed[MAX_AUTH_BYTES];
+ u_int au_mpos; /* xdr pos at end of marshed */
+};
+#define AUTH_PRIVATE(auth) ((struct audata *)auth->ah_private)
+
+static void marshal_new_auth(AUTH *);
+
+/*
+ * This goop is here because some servers refuse to accept a
+ * credential with more than some number (usually 8) supplementary
+ * groups. Blargh!
+ */
+static int authunix_maxgrouplist = 0;
+
+void
+set_rpc_maxgrouplist(int num)
+{
+ authunix_maxgrouplist = num;
+}
+
+/*
+ * Create a unix style authenticator.
+ * Returns an auth handle with the given stuff in it.
+ */
+AUTH *
+authunix_create(
+ char *machname,
+ int uid,
+ int gid,
+ int len,
+ int *aup_gids)
+{
+ struct authunix_parms aup;
+ char mymem[MAX_AUTH_BYTES];
+ struct timeval now;
+ XDR xdrs;
+ register AUTH *auth;
+ register struct audata *au;
+
+ /*
+ * Allocate and set up auth handle
+ */
+ auth = (AUTH *)mem_alloc(sizeof(*auth));
+#ifndef _KERNEL
+ if (auth == NULL) {
+ (void)fprintf(stderr, "authunix_create: out of memory\n");
+ return (NULL);
+ }
+#endif
+ au = (struct audata *)mem_alloc(sizeof(*au));
+#ifndef _KERNEL
+ if (au == NULL) {
+ (void)fprintf(stderr, "authunix_create: out of memory\n");
+ return (NULL);
+ }
+#endif
+ auth->ah_ops = &auth_unix_ops;
+ auth->ah_private = (caddr_t)au;
+ auth->ah_verf = au->au_shcred = _null_auth;
+ au->au_shfaults = 0;
+
+ /*
+ * fill in param struct from the given params
+ */
+ (void)gettimeofday(&now, (struct timezone *)0);
+ aup.aup_time = now.tv_sec;
+ aup.aup_machname = machname;
+ aup.aup_uid = uid;
+ aup.aup_gid = gid;
+ /* GW: continuation of max group list hack */
+ if(authunix_maxgrouplist != 0) {
+ aup.aup_len = ((len < authunix_maxgrouplist) ? len
+ : authunix_maxgrouplist);
+ } else {
+ aup.aup_len = (u_int)len;
+ }
+ aup.aup_gids = aup_gids;
+
+ /*
+ * Serialize the parameters into origcred
+ */
+ xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE);
+ if (! xdr_authunix_parms(&xdrs, &aup))
+ abort();
+ au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs);
+ au->au_origcred.oa_flavor = AUTH_UNIX;
+#ifdef _KERNEL
+ au->au_origcred.oa_base = mem_alloc((u_int) len);
+#else
+ if ((au->au_origcred.oa_base = mem_alloc((u_int) len)) == NULL) {
+ (void)fprintf(stderr, "authunix_create: out of memory\n");
+ return (NULL);
+ }
+#endif
+ memcpy(au->au_origcred.oa_base, mymem, (u_int)len);
+
+ /*
+ * set auth handle to reflect new cred.
+ */
+ auth->ah_cred = au->au_origcred;
+ marshal_new_auth(auth);
+ return (auth);
+}
+
+/*
+ * Returns an auth handle with parameters determined by doing lots of
+ * syscalls.
+ */
+AUTH *
+authunix_create_default(void)
+{
+ register int len;
+ char machname[MAX_MACHINE_NAME + 1];
+ register int uid;
+ register int gid;
+ int gids[NGRPS];
+ int i;
+ gid_t real_gids[NGROUPS];
+
+ if (gethostname(machname, MAX_MACHINE_NAME) == -1)
+ abort();
+ machname[MAX_MACHINE_NAME] = 0;
+ uid = (int)geteuid();
+ gid = (int)getegid();
+ if ((len = getgroups(NGROUPS, real_gids)) < 0)
+ abort();
+ if(len > NGRPS) len = NGRPS; /* GW: turn `gid_t's into `int's */
+ for(i = 0; i < len; i++) {
+ gids[i] = (int)real_gids[i];
+ }
+ return (authunix_create(machname, uid, gid, len, gids));
+}
+
+/*
+ * authunix operations
+ */
+
+static void
+authunix_nextverf(AUTH *auth)
+{
+ /* no action necessary */
+}
+
+static int
+authunix_marshal(AUTH *auth, XDR *xdrs)
+{
+ struct audata *au = AUTH_PRIVATE(auth);
+
+ return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos));
+}
+
+static int
+authunix_validate( AUTH *auth, struct opaque_auth *verf )
+{
+ register struct audata *au;
+ XDR xdrs;
+
+ if (verf->oa_flavor == AUTH_SHORT) {
+ au = AUTH_PRIVATE(auth);
+ xdrmem_create(&xdrs, verf->oa_base, verf->oa_length, XDR_DECODE);
+
+ if (au->au_shcred.oa_base != NULL) {
+ mem_free(au->au_shcred.oa_base,
+ au->au_shcred.oa_length);
+ au->au_shcred.oa_base = NULL;
+ }
+ if (xdr_opaque_auth(&xdrs, &au->au_shcred)) {
+ auth->ah_cred = au->au_shcred;
+ } else {
+ xdrs.x_op = XDR_FREE;
+ (void)xdr_opaque_auth(&xdrs, &au->au_shcred);
+ au->au_shcred.oa_base = NULL;
+ auth->ah_cred = au->au_origcred;
+ }
+ marshal_new_auth(auth);
+ }
+ return (TRUE);
+}
+
+static int
+authunix_refresh(AUTH *auth)
+{
+ struct audata *au = AUTH_PRIVATE(auth);
+ struct authunix_parms aup;
+ struct timeval now;
+ XDR xdrs;
+ int stat;
+
+ if (auth->ah_cred.oa_base == au->au_origcred.oa_base) {
+ /* there is no hope. Punt */
+ return (FALSE);
+ }
+ au->au_shfaults ++;
+
+ /* first deserialize the creds back into a struct authunix_parms */
+ aup.aup_machname = NULL;
+ aup.aup_gids = (int *)NULL;
+ xdrmem_create(&xdrs, au->au_origcred.oa_base,
+ au->au_origcred.oa_length, XDR_DECODE);
+ stat = xdr_authunix_parms(&xdrs, &aup);
+ if (! stat)
+ goto done;
+
+ /* update the time and serialize in place */
+ (void)gettimeofday(&now, (struct timezone *)0);
+ aup.aup_time = now.tv_sec;
+ xdrs.x_op = XDR_ENCODE;
+ XDR_SETPOS(&xdrs, 0);
+ stat = xdr_authunix_parms(&xdrs, &aup);
+ if (! stat)
+ goto done;
+ auth->ah_cred = au->au_origcred;
+ marshal_new_auth(auth);
+done:
+ /* free the struct authunix_parms created by deserializing */
+ xdrs.x_op = XDR_FREE;
+ (void)xdr_authunix_parms(&xdrs, &aup);
+ XDR_DESTROY(&xdrs);
+ return (stat);
+}
+
+static void
+authunix_destroy(AUTH *auth)
+{
+ struct audata *au = AUTH_PRIVATE(auth);
+
+ mem_free(au->au_origcred.oa_base, au->au_origcred.oa_length);
+
+ if (au->au_shcred.oa_base != NULL)
+ mem_free(au->au_shcred.oa_base, au->au_shcred.oa_length);
+
+ mem_free(auth->ah_private, sizeof(struct audata));
+
+ if (auth->ah_verf.oa_base != NULL)
+ mem_free(auth->ah_verf.oa_base, auth->ah_verf.oa_length);
+
+ mem_free((caddr_t)auth, sizeof(*auth));
+}
+
+/*
+ * Marshals (pre-serializes) an auth struct.
+ * sets private data, au_marshed and au_mpos
+ */
+static void
+marshal_new_auth(AUTH *auth)
+{
+ XDR xdr_stream;
+ XDR *xdrs = &xdr_stream;
+ struct audata *au = AUTH_PRIVATE(auth);
+
+ xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE);
+ if ((! xdr_opaque_auth(xdrs, &(auth->ah_cred))) ||
+ (! xdr_opaque_auth(xdrs, &(auth->ah_verf)))) {
+ perror("auth_none.c - Fatal marshalling problem");
+ } else {
+ au->au_mpos = XDR_GETPOS(xdrs);
+ }
+ XDR_DESTROY(xdrs);
+}
diff --git a/librpc/src/rpc/authunix_prot.c b/librpc/src/rpc/authunix_prot.c
new file mode 100644
index 0000000..9dc867a
--- /dev/null
+++ b/librpc/src/rpc/authunix_prot.c
@@ -0,0 +1,73 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)authunix_prot.c 1.15 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)authunix_prot.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/authunix_prot.c,v 1.6 1999/08/28 00:00:33 peter Exp $";
+#endif
+
+/*
+ * authunix_prot.c
+ * XDR for UNIX style authentication parameters for RPC
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#include <rpc/auth_unix.h>
+
+/*
+ * XDR for unix authentication parameters.
+ */
+bool_t
+xdr_authunix_parms(
+ XDR *xdrs,
+ struct authunix_parms *p)
+{
+
+ if (xdr_u_long(xdrs, &(p->aup_time))
+ && xdr_string(xdrs, &(p->aup_machname), MAX_MACHINE_NAME)
+ && xdr_int(xdrs, &(p->aup_uid))
+ && xdr_int(xdrs, &(p->aup_gid))
+ && xdr_array(xdrs, (caddr_t *)(void *)&(p->aup_gids),
+ &(p->aup_len), NGRPS, sizeof(int), (xdrproc_t) xdr_int) ) {
+ return (TRUE);
+ }
+ return (FALSE);
+}
diff --git a/librpc/src/rpc/bindresvport.3 b/librpc/src/rpc/bindresvport.3
new file mode 100644
index 0000000..02a079d
--- /dev/null
+++ b/librpc/src/rpc/bindresvport.3
@@ -0,0 +1,106 @@
+.\" @(#)bindresvport.3n 2.2 88/08/02 4.0 RPCSRC; from 1.7 88/03/14 SMI
+.\" $FreeBSD: src/lib/libc/rpc/bindresvport.3,v 1.10 2000/01/27 02:55:01 bde Exp $
+.\"
+.Dd January 27, 2000
+.Dt BINDRESVPORT 3
+.Os
+.Sh NAME
+.Nm bindresvport ,
+.Nm bindresvport_sa
+.Ndbind a socket to a privileged IP port
+.Sh SYNOPSIS
+.Fd #include <rpc/rpc.h>
+.Ft int
+.Fn bindresvport "int sd" "struct sockaddr_in *sin"
+.Ft int
+.Fn bindresvport_sa "int sd" "struct sockaddr *sa"
+.Sh DESCRIPTION
+.Fn bindresvport
+and
+.Fn bindresvport_sa
+are used to bind a socket descriptor to a privileged
+.Tn IP
+port, that is, a
+port number in the range 0-1023.
+.Pp
+Only root can bind to a privileged port; this call will fail for any
+other users.
+.Pp
+When
+.Va sin
+is not null,
+.Va sin->sin_family
+must be initialized to the address family of the socket, passed by
+.Va sd .
+If the value of sin->sin_port is non-zero
+.Fn bindresvport
+will attempt to use that specific port. If it fails, it chooses another
+privileged port automatically.
+.Pp
+It is legal to pass null pointer to
+.Va sin .
+In this case, the caller cannot get the port number
+.Fn bindresvport
+has picked.
+.Pp
+Function prototype of
+.Fn bindresvport
+is biased to
+.Dv AF_INET
+socket.
+.Fn bindresvport_sa
+acts exactly the same, with more neutral function prototype.
+Note that both functions behave exactly the same, and
+both support
+.Dv AF_INET6
+sockets as well as
+.Dv AF_INET
+sockets.
+.Sh RETURN VALUES
+.Fn bindresvport
+and
+.Fn bindresvport_sa
+return 0 if they are successful, otherwise \-1 is returned and
+.Va errno
+set to reflect the cause of the error.
+.Sh ERRORS
+The
+.Fn bindresvport
+and
+.Fn bindresvport_sa
+functions fail if:
+.Bl -tag -width Er
+.It Bq Er EBADF
+.Fa sd
+is not a valid descriptor.
+.It Bq Er ENOTSOCK
+.Fa sd
+is not a socket.
+.It Bq Er EADDRNOTAVAIL
+The specified address is not available from the local machine.
+.It Bq Er EADDRINUSE
+The specified address is already in use.
+.It Bq Er EINVAL
+The socket is already bound to an address,
+or the socket family and the family of specified address mismatch.
+.It Bq Er EACCES
+The requested address is protected, and the current user
+has inadequate permission to access it.
+.It Bq Er EFAULT
+The
+.Fa name
+parameter is not in a valid part of the user
+address space.
+.It Bq Er ENOBUFS
+Insufficient resources were available in the system
+to perform the operation.
+.It Bq Er EPFNOSUPPORT
+The protocol family has not been configured into the
+system, no implementation for it exists,
+or address family did not match between arguments.
+.El
+.Sh "SEE ALSO"
+.Xr bind 2 ,
+.Xr socket 2 ,
+.Xr rresvport 3 ,
+.Xr rresvport_af 3
diff --git a/librpc/src/rpc/bindresvport.c b/librpc/src/rpc/bindresvport.c
new file mode 100644
index 0000000..1c979de
--- /dev/null
+++ b/librpc/src/rpc/bindresvport.c
@@ -0,0 +1,162 @@
+#include "rtems-rpc-config.h"
+
+/* $NetBSD: bindresvport.c,v 1.19 2000/07/06 03:03:59 christos Exp $ */
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)bindresvport.c 1.8 88/02/08 SMI";*/
+/*static char *sccsid = "from: @(#)bindresvport.c 2.2 88/07/29 4.0 RPCSRC";*/
+/*from: OpenBSD: bindresvport.c,v 1.7 1996/07/30 16:25:47 downsj Exp */
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/bindresvport.c,v 1.12 2000/01/26 09:02:42 shin Exp $";
+#endif
+
+/*
+ * Copyright (c) 1987 by Sun Microsystems, Inc.
+ *
+ * Portions Copyright(C) 1996, Jason Downs. All rights reserved.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <rpc/rpc.h>
+
+/*
+ * Bind a socket to a privileged IP port
+ */
+int
+bindresvport(
+ int sd,
+ struct sockaddr_in *sin)
+{
+ return bindresvport_sa(sd, (struct sockaddr *)sin);
+}
+
+/*
+ * Bind a socket to a privileged IP port
+ */
+int
+bindresvport_sa(
+ int sd,
+ struct sockaddr *sa)
+{
+ int old, error, af;
+ struct sockaddr myaddr;
+ struct sockaddr_in *sin;
+#ifdef INET6
+ struct sockaddr_in6 *sin6;
+#endif
+ int proto, portrange, portlow;
+ u_int16_t port;
+ socklen_t salen;
+
+ if (sa == NULL) {
+ salen = sizeof(myaddr);
+ sa = (struct sockaddr *)&myaddr;
+
+ if (getsockname(sd, sa, &salen) == -1)
+ return -1; /* errno is correctly set */
+
+ af = sa->sa_family;
+ memset(&myaddr, 0, salen);
+ } else
+ af = sa->sa_family;
+
+ switch (af) {
+ case AF_INET:
+ proto = IPPROTO_IP;
+ portrange = IP_PORTRANGE;
+ portlow = IP_PORTRANGE_LOW;
+ sin = (struct sockaddr_in *)sa;
+ salen = sizeof(struct sockaddr_in);
+ port = sin->sin_port;
+ break;
+#ifdef INET6
+ case AF_INET6:
+ proto = IPPROTO_IPV6;
+ portrange = IPV6_PORTRANGE;
+ portlow = IPV6_PORTRANGE_LOW;
+ sin6 = (struct sockaddr_in6 *)sa;
+ salen = sizeof(struct sockaddr_in6);
+ port = sin6->sin6_port;
+ break;
+#endif
+ default:
+ errno = EPFNOSUPPORT;
+ return (-1);
+ }
+ sa->sa_family = af;
+ sa->sa_len = salen;
+
+ if (port == 0) {
+ socklen_t oldlen = sizeof(old);
+
+ error = getsockopt(sd, proto, portrange, &old, &oldlen);
+ if (error < 0)
+ return (error);
+
+ error = setsockopt(sd, proto, portrange, &portlow,
+ sizeof(portlow));
+ if (error < 0)
+ return (error);
+ }
+
+ error = bind(sd, sa, salen);
+
+ if (port == 0) {
+ int saved_errno = errno;
+
+ if (error) {
+ if (setsockopt(sd, proto, portrange, &old,
+ sizeof(old)) < 0)
+ errno = saved_errno;
+ return (error);
+ }
+
+ if (sa != (struct sockaddr *)&myaddr) {
+ /* Hmm, what did the kernel assign? */
+ if (getsockname(sd, sa, &salen) < 0)
+ errno = saved_errno;
+ return (error);
+ }
+ }
+ return (error);
+}
diff --git a/librpc/src/rpc/clnt_generic.c b/librpc/src/rpc/clnt_generic.c
new file mode 100644
index 0000000..6d97dfb
--- /dev/null
+++ b/librpc/src/rpc/clnt_generic.c
@@ -0,0 +1,147 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)clnt_generic.c 1.4 87/08/11 (C) 1987 SMI";*/
+/*static char *sccsid = "from: @(#)clnt_generic.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/clnt_generic.c,v 1.9 1999/08/28 00:00:35 peter Exp $";
+#endif
+
+/*
+ * Copyright (C) 1987, Sun Microsystems, Inc.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <sys/errno.h>
+#include <netdb.h>
+#include <string.h>
+
+/*
+ * Generic client creation: takes (hostname, program-number, protocol) and
+ * returns client handle. Default options are set, which the user can
+ * change using the rpc equivalent of ioctl()'s.
+ */
+CLIENT *
+clnt_create(
+ const char *hostname,
+ rpcprog_t prog,
+ rpcvers_t vers,
+ const char *proto)
+{
+ struct hostent *h;
+ struct protoent *p;
+ struct sockaddr_in sin;
+#ifndef __rtems__
+ struct sockaddr_un sun;
+#endif
+ int sock;
+ struct timeval tv;
+ CLIENT *client;
+
+#ifndef __rtems__
+ if (!strcmp(proto, "unix")) {
+ bzero((char *)&sun, sizeof(sun));
+ sun.sun_family = AF_UNIX;
+ strcpy(sun.sun_path, hostname);
+ sun.sun_len = sizeof(sun.sun_len) + sizeof(sun.sun_family) +
+ strlen(sun.sun_path) + 1;
+ sock = RPC_ANYSOCK;
+ client = clntunix_create(&sun, prog, vers, &sock, 0, 0);
+ if (client == NULL)
+ return(NULL);
+ tv.tv_sec = 25;
+ tv.tv_usec = 0;
+ clnt_control(client, CLSET_TIMEOUT, &tv);
+ return(client);
+ }
+#endif
+
+ h = gethostbyname(hostname);
+ if (h == NULL) {
+ rpc_createerr.cf_stat = RPC_UNKNOWNHOST;
+ return (NULL);
+ }
+ if (h->h_addrtype != AF_INET) {
+ /*
+ * Only support INET for now
+ */
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = EAFNOSUPPORT;
+ return (NULL);
+ }
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_len = sizeof(struct sockaddr_in);
+ sin.sin_family = h->h_addrtype;
+ sin.sin_port = 0;
+ memcpy((char*)&sin.sin_addr, h->h_addr, h->h_length);
+ p = getprotobyname(proto);
+ if (p == NULL) {
+ rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
+ rpc_createerr.cf_error.re_errno = EPFNOSUPPORT;
+ return (NULL);
+ }
+ sock = RPC_ANYSOCK;
+ switch (p->p_proto) {
+ case IPPROTO_UDP:
+ tv.tv_sec = 5;
+ tv.tv_usec = 0;
+ client = clntudp_create(&sin, prog, vers, tv, &sock);
+ if (client == NULL) {
+ return (NULL);
+ }
+#if 0 /* XXX do we need this? */
+ tv.tv_sec = 25;
+ tv.tv_usec = 0;
+ clnt_control(client, CLSET_TIMEOUT, &tv);
+#endif
+ break;
+ case IPPROTO_TCP:
+ client = clnttcp_create(&sin, prog, vers, &sock, 0, 0);
+ if (client == NULL) {
+ return (NULL);
+ }
+#if 0 /* XXX do we need this? */
+ tv.tv_sec = 25;
+ tv.tv_usec = 0;
+ clnt_control(client, CLSET_TIMEOUT, &tv);
+#endif
+ break;
+ default:
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = EPFNOSUPPORT;
+ return (NULL);
+ }
+ return (client);
+}
diff --git a/librpc/src/rpc/clnt_perror.c b/librpc/src/rpc/clnt_perror.c
new file mode 100644
index 0000000..121ebc9
--- /dev/null
+++ b/librpc/src/rpc/clnt_perror.c
@@ -0,0 +1,261 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)clnt_perror.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/clnt_perror.c,v 1.11 1999/08/28 00:00:35 peter Exp $";
+#endif
+
+/*
+ * clnt_perror.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <rpc/types.h>
+#include <rpc/auth.h>
+#include <rpc/clnt.h>
+
+static char *auth_errmsg(enum auth_stat stat);
+#define CLNT_PERROR_BUFLEN 256
+
+#define buf (rtems_rpc_task_variables->clnt_perror_buf)
+
+static char *
+_buf(void)
+{
+
+ if (buf == 0)
+ buf = (char *)malloc(CLNT_PERROR_BUFLEN);
+ return (buf);
+}
+
+/*
+ * Print reply error info
+ */
+char *
+clnt_sperror(
+ CLIENT *rpch,
+ const char *s)
+{
+ struct rpc_err e;
+ char *err;
+ char *str = _buf();
+ char *strstart = str;
+
+ if (str == 0)
+ return (0);
+ CLNT_GETERR(rpch, &e);
+
+ (void) sprintf(str, "%s: %s", s, clnt_sperrno(e.re_status));
+ str += strlen(str);
+
+ switch (e.re_status) {
+ case RPC_SUCCESS:
+ case RPC_CANTENCODEARGS:
+ case RPC_CANTDECODERES:
+ case RPC_TIMEDOUT:
+ case RPC_PROGUNAVAIL:
+ case RPC_PROCUNAVAIL:
+ case RPC_CANTDECODEARGS:
+ case RPC_SYSTEMERROR:
+ case RPC_UNKNOWNHOST:
+ case RPC_UNKNOWNPROTO:
+ case RPC_PMAPFAILURE:
+ case RPC_PROGNOTREGISTERED:
+ case RPC_FAILED:
+ break;
+
+ case RPC_CANTSEND:
+ case RPC_CANTRECV:
+ (void) snprintf(str, CLNT_PERROR_BUFLEN - (str - strstart),
+ "; errno = %s\n", strerror(e.re_errno));
+ break;
+
+ case RPC_VERSMISMATCH:
+ (void) sprintf(str,
+ "; low version = %lu, high version = %lu\n",
+ (u_long)e.re_vers.low, (u_long)e.re_vers.high);
+ break;
+
+ case RPC_AUTHERROR:
+ err = auth_errmsg(e.re_why);
+ (void) sprintf(str,"; why = ");
+ str += strlen(str);
+ if (err != NULL) {
+ (void) sprintf(str, "%s\n",err);
+ } else {
+ (void) sprintf(str,
+ "(unknown authentication error - %d)\n",
+ (int) e.re_why);
+ }
+ break;
+
+ case RPC_PROGVERSMISMATCH:
+ (void) sprintf(str,
+ "; low version = %lu, high version = %lu\n",
+ (u_long)e.re_vers.low, (u_long)e.re_vers.high);
+ break;
+
+ default: /* unknown */
+ (void) sprintf(str,
+ "; s1 = %lu, s2 = %lu\n",
+ (long)e.re_lb.s1, (long)e.re_lb.s2);
+ break;
+ }
+ strstart[CLNT_PERROR_BUFLEN-2] = '\n';
+ strstart[CLNT_PERROR_BUFLEN-1] = '\0';
+ return(strstart) ;
+}
+
+void
+clnt_perror(
+ CLIENT *rpch,
+ const char *s)
+{
+ (void) fprintf(stderr,"%s\n",clnt_sperror(rpch,s));
+}
+
+
+static const char *const rpc_errlist[] = {
+ "RPC: Success", /* 0 - RPC_SUCCESS */
+ "RPC: Can't encode arguments", /* 1 - RPC_CANTENCODEARGS */
+ "RPC: Can't decode result", /* 2 - RPC_CANTDECODERES */
+ "RPC: Unable to send", /* 3 - RPC_CANTSEND */
+ "RPC: Unable to receive", /* 4 - RPC_CANTRECV */
+ "RPC: Timed out", /* 5 - RPC_TIMEDOUT */
+ "RPC: Incompatible versions of RPC", /* 6 - RPC_VERSMISMATCH */
+ "RPC: Authentication error", /* 7 - RPC_AUTHERROR */
+ "RPC: Program unavailable", /* 8 - RPC_PROGUNAVAIL */
+ "RPC: Program/version mismatch", /* 9 - RPC_PROGVERSMISMATCH */
+ "RPC: Procedure unavailable", /* 10 - RPC_PROCUNAVAIL */
+ "RPC: Server can't decode arguments", /* 11 - RPC_CANTDECODEARGS */
+ "RPC: Remote system error", /* 12 - RPC_SYSTEMERROR */
+ "RPC: Unknown host", /* 13 - RPC_UNKNOWNHOST */
+ "RPC: Port mapper failure", /* 14 - RPC_PMAPFAILURE */
+ "RPC: Program not registered", /* 15 - RPC_PROGNOTREGISTERED */
+ "RPC: Failed (unspecified error)", /* 16 - RPC_FAILED */
+ "RPC: Unknown protocol" /* 17 - RPC_UNKNOWNPROTO */
+};
+
+
+/*
+ * This interface for use by clntrpc
+ */
+char *
+clnt_sperrno(
+ enum clnt_stat stat)
+{
+ unsigned int errnum = stat;
+
+ if (errnum < (sizeof(rpc_errlist)/sizeof(rpc_errlist[0])))
+ return (char *)rpc_errlist[errnum];
+
+ return ("RPC: (unknown error code)");
+}
+
+void
+clnt_perrno(
+ enum clnt_stat num)
+{
+ (void) fprintf(stderr,"%s\n",clnt_sperrno(num));
+}
+
+
+char *
+clnt_spcreateerror(
+ const char *s)
+{
+ char *str = _buf();
+
+ if (str == 0)
+ return(0);
+ switch (rpc_createerr.cf_stat) {
+ case RPC_PMAPFAILURE:
+ (void) snprintf(str, CLNT_PERROR_BUFLEN, "%s: %s - %s\n", s,
+ clnt_sperrno(rpc_createerr.cf_stat),
+ clnt_sperrno(rpc_createerr.cf_error.re_status));
+ break;
+
+ case RPC_SYSTEMERROR:
+ (void) snprintf(str, CLNT_PERROR_BUFLEN, "%s: %s - %s\n", s,
+ clnt_sperrno(rpc_createerr.cf_stat),
+ strerror(rpc_createerr.cf_error.re_errno));
+ break;
+ default:
+ (void) snprintf(str, CLNT_PERROR_BUFLEN, "%s: %s\n", s,
+ clnt_sperrno(rpc_createerr.cf_stat));
+ break;
+ }
+ str[CLNT_PERROR_BUFLEN-2] = '\n';
+ str[CLNT_PERROR_BUFLEN-1] = '\0';
+ return (str);
+}
+
+void
+clnt_pcreateerror(
+ const char *s)
+{
+ (void) fprintf(stderr,"%s\n",clnt_spcreateerror(s));
+}
+
+static const char *const auth_errlist[] = {
+ "Authentication OK", /* 0 - AUTH_OK */
+ "Invalid client credential", /* 1 - AUTH_BADCRED */
+ "Server rejected credential", /* 2 - AUTH_REJECTEDCRED */
+ "Invalid client verifier", /* 3 - AUTH_BADVERF */
+ "Server rejected verifier", /* 4 - AUTH_REJECTEDVERF */
+ "Client credential too weak", /* 5 - AUTH_TOOWEAK */
+ "Invalid server verifier", /* 6 - AUTH_INVALIDRESP */
+ "Failed (unspecified error)" /* 7 - AUTH_FAILED */
+};
+
+static char *
+auth_errmsg(
+ enum auth_stat stat)
+{
+ unsigned int errnum = stat;
+
+ if (errnum < (sizeof(auth_errlist)/sizeof(auth_errlist[0])))
+ return (char *)auth_errlist[errnum];
+
+ return(NULL);
+}
diff --git a/librpc/src/rpc/clnt_raw.c b/librpc/src/rpc/clnt_raw.c
new file mode 100644
index 0000000..8682622
--- /dev/null
+++ b/librpc/src/rpc/clnt_raw.c
@@ -0,0 +1,250 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)clnt_raw.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/clnt_raw.c,v 1.10 1999/08/28 00:00:36 peter Exp $";
+#endif
+
+/*
+ * clnt_raw.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * Memory based rpc for simple testing and timing.
+ * Interface to create an rpc client and server in the same process.
+ * This lets us similate rpc and get round trip overhead, without
+ * any interference from the kernel.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rpc/rpc.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#define MCALL_MSG_SIZE 24
+
+/*
+ * This is the "network" we will be moving stuff over.
+ */
+struct clnt_raw_private {
+ CLIENT client_object;
+ XDR xdr_stream;
+ char _raw_buf[UDPMSGSIZE];
+ union {
+ struct rpc_msg mashl_rpcmsg;
+ char mashl_callmsg[MCALL_MSG_SIZE];
+ } u;
+ u_int mcnt;
+};
+#define clntraw_private (rtems_rpc_task_variables->clnt_raw_private)
+
+static enum clnt_stat clntraw_call(CLIENT *h, rpcproc_t proc, xdrproc_t xargs, void *argsp, xdrproc_t xresults, void *resultsp, struct timeval timeout);
+static void clntraw_abort(void);
+static void clntraw_geterr(CLIENT *h, struct rpc_err*);
+static bool_t clntraw_freeres(CLIENT *, xdrproc_t, void*);
+static bool_t clntraw_control(CLIENT *, int, char *);
+static void clntraw_destroy(CLIENT *);
+
+static struct clnt_ops client_ops = {
+ clntraw_call,
+ clntraw_abort,
+ clntraw_geterr,
+ clntraw_freeres,
+ clntraw_destroy,
+ clntraw_control
+};
+
+/*
+ * Create a client handle for memory based rpc.
+ */
+CLIENT *
+clntraw_create(
+ u_long prog,
+ u_long vers )
+{
+ struct clnt_raw_private *clp = clntraw_private;
+ struct rpc_msg call_msg;
+ XDR *xdrs = &clp->xdr_stream;
+ CLIENT *client = &clp->client_object;
+
+ if (clp == 0) {
+ clp = (struct clnt_raw_private *)calloc(1, sizeof (*clp));
+ if (clp == 0)
+ return (0);
+ clntraw_private = clp;
+ }
+ /*
+ * pre-serialize the static part of the call msg and stash it away
+ */
+ call_msg.rm_direction = CALL;
+ call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
+ call_msg.rm_call.cb_prog = prog;
+ call_msg.rm_call.cb_vers = vers;
+ xdrmem_create(xdrs, clp->u.mashl_callmsg, MCALL_MSG_SIZE, XDR_ENCODE);
+ if (! xdr_callhdr(xdrs, &call_msg)) {
+ perror("clnt_raw.c - Fatal header serialization error.");
+ }
+ clp->mcnt = XDR_GETPOS(xdrs);
+ XDR_DESTROY(xdrs);
+
+ /*
+ * Set xdrmem for client/server shared buffer
+ */
+ xdrmem_create(xdrs, clp->_raw_buf, UDPMSGSIZE, XDR_FREE);
+
+ /*
+ * create client handle
+ */
+ client->cl_ops = &client_ops;
+ client->cl_auth = authnone_create();
+ return (client);
+}
+
+static enum clnt_stat
+clntraw_call(
+ CLIENT *h,
+ rpcproc_t proc,
+ xdrproc_t xargs,
+ void *argsp,
+ xdrproc_t xresults,
+ void *resultsp,
+ struct timeval timeout )
+{
+ struct clnt_raw_private *clp = clntraw_private;
+ XDR *xdrs = &clp->xdr_stream;
+ struct rpc_msg msg;
+ enum clnt_stat status;
+ struct rpc_err error;
+
+ if (clp == 0)
+ return (RPC_FAILED);
+call_again:
+ /*
+ * send request
+ */
+ xdrs->x_op = XDR_ENCODE;
+ XDR_SETPOS(xdrs, 0);
+ clp->u.mashl_rpcmsg.rm_xid ++ ;
+ if ((! XDR_PUTBYTES(xdrs, clp->u.mashl_callmsg, clp->mcnt)) ||
+ (! XDR_PUTLONG(xdrs, (long *)&proc)) ||
+ (! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
+ (! (*xargs)(xdrs, argsp))) {
+ return (RPC_CANTENCODEARGS);
+ }
+ (void)XDR_GETPOS(xdrs); /* called just to cause overhead */
+
+ /*
+ * We have to call server input routine here because this is
+ * all going on in one process. Yuk.
+ */
+ svc_getreq(1);
+
+ /*
+ * get results
+ */
+ xdrs->x_op = XDR_DECODE;
+ XDR_SETPOS(xdrs, 0);
+ msg.acpted_rply.ar_verf = _null_auth;
+ msg.acpted_rply.ar_results.where = resultsp;
+ msg.acpted_rply.ar_results.proc = xresults;
+ if (! xdr_replymsg(xdrs, &msg))
+ return (RPC_CANTDECODERES);
+ _seterr_reply(&msg, &error);
+ status = error.re_status;
+
+ if (status == RPC_SUCCESS) {
+ if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) {
+ status = RPC_AUTHERROR;
+ }
+ } /* end successful completion */
+ else {
+ if (AUTH_REFRESH(h->cl_auth))
+ goto call_again;
+ } /* end of unsuccessful completion */
+
+ if (status == RPC_SUCCESS) {
+ if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) {
+ status = RPC_AUTHERROR;
+ }
+ if (msg.acpted_rply.ar_verf.oa_base != NULL) {
+ xdrs->x_op = XDR_FREE;
+ (void)xdr_opaque_auth(xdrs, &(msg.acpted_rply.ar_verf));
+ }
+ }
+
+ return (status);
+}
+
+static void
+clntraw_geterr(CLIENT *cl, struct rpc_err *err)
+{
+}
+
+
+static bool_t
+clntraw_freeres(
+ CLIENT *cl,
+ xdrproc_t xdr_res,
+ void *res_ptr )
+{
+ struct clnt_raw_private *clp = clntraw_private;
+ XDR *xdrs = &clp->xdr_stream;
+ bool_t rval;
+
+ if (clp == 0)
+ {
+ rval = (bool_t) RPC_FAILED;
+ return (rval);
+ }
+ xdrs->x_op = XDR_FREE;
+ return ((*xdr_res)(xdrs, res_ptr));
+}
+
+static void
+clntraw_abort(void)
+{
+}
+
+static bool_t
+clntraw_control(CLIENT *cl, int request, char *info)
+{
+ return (FALSE);
+}
+
+static void
+clntraw_destroy(CLIENT *cl)
+{
+}
diff --git a/librpc/src/rpc/clnt_simple.c b/librpc/src/rpc/clnt_simple.c
new file mode 100644
index 0000000..6767a78
--- /dev/null
+++ b/librpc/src/rpc/clnt_simple.c
@@ -0,0 +1,129 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)clnt_simple.c 1.35 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)clnt_simple.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/clnt_simple.c,v 1.12 2000/01/27 23:06:35 jasone Exp $";
+#endif
+
+/*
+ * clnt_simple.c
+ * Simplified front end to rpc.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/param.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
+struct call_rpc_private {
+ CLIENT *client;
+ int socket;
+ int oldprognum, oldversnum, valid;
+ char *oldhost;
+};
+#define callrpc_private (rtems_rpc_task_variables->call_rpc_private)
+
+int
+callrpc(
+ char *host,
+ int prognum, int versnum, int procnum,
+ xdrproc_t inproc, char *in,
+ xdrproc_t outproc, char *out )
+{
+ register struct call_rpc_private *crp = callrpc_private;
+ struct sockaddr_in server_addr;
+ enum clnt_stat clnt_stat;
+ struct hostent *hp;
+ struct timeval timeout, tottimeout;
+
+ if (crp == 0) {
+ crp = (struct call_rpc_private *)calloc(1, sizeof (*crp));
+ if (crp == 0)
+ return (0);
+ callrpc_private = crp;
+ }
+ if (crp->oldhost == NULL) {
+ crp->oldhost = malloc(MAXHOSTNAMELEN);
+ crp->oldhost[0] = 0;
+ crp->socket = RPC_ANYSOCK;
+ }
+ if (crp->valid && crp->oldprognum == prognum && crp->oldversnum == versnum
+ && strcmp(crp->oldhost, host) == 0) {
+ /* reuse old client */
+ } else {
+ crp->valid = 0;
+ if (crp->socket != -1)
+ (void)_RPC_close(crp->socket);
+ crp->socket = RPC_ANYSOCK;
+ if (crp->client) {
+ clnt_destroy(crp->client);
+ crp->client = NULL;
+ }
+ if ((hp = gethostbyname(host)) == NULL)
+ return ((int) RPC_UNKNOWNHOST);
+ timeout.tv_usec = 0;
+ timeout.tv_sec = 5;
+ memset(&server_addr, 0, sizeof(server_addr));
+ memcpy((char *)&server_addr.sin_addr, hp->h_addr, hp->h_length);
+ server_addr.sin_len = sizeof(struct sockaddr_in);
+ server_addr.sin_family = AF_INET;
+ server_addr.sin_port = 0;
+ if ((crp->client = clntudp_create(&server_addr, (u_long)prognum,
+ (u_long)versnum, timeout, &crp->socket)) == NULL)
+ return ((int) rpc_createerr.cf_stat);
+ crp->valid = 1;
+ crp->oldprognum = prognum;
+ crp->oldversnum = versnum;
+ (void) strcpy(crp->oldhost, host);
+ }
+ tottimeout.tv_sec = 25;
+ tottimeout.tv_usec = 0;
+ clnt_stat = clnt_call(crp->client, procnum, inproc, in,
+ outproc, out, tottimeout);
+ /*
+ * if call failed, empty cache
+ */
+ if (clnt_stat != RPC_SUCCESS)
+ crp->valid = 0;
+ return ((int) clnt_stat);
+}
diff --git a/librpc/src/rpc/clnt_tcp.c b/librpc/src/rpc/clnt_tcp.c
new file mode 100644
index 0000000..b7ccd5a
--- /dev/null
+++ b/librpc/src/rpc/clnt_tcp.c
@@ -0,0 +1,608 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)clnt_tcp.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/clnt_tcp.c,v 1.14 2000/01/27 23:06:36 jasone Exp $";
+#endif
+
+/*
+ * clnt_tcp.c, Implements a TCP/IP based, client side RPC.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * TCP based RPC supports 'batched calls'.
+ * A sequence of calls may be batched-up in a send buffer. The rpc call
+ * return immediately to the client even though the call was not necessarily
+ * sent. The batching occurs if the results' xdr routine is NULL (0) AND
+ * the rpc timeout value is zero (see clnt.h, rpc).
+ *
+ * Clients should NOT casually batch calls that in fact return results; that is,
+ * the server side should be aware that a call is batched and not produce any
+ * return message. Batched calls that produce many result messages can
+ * deadlock (netlock) the client and the server....
+ *
+ * Now go hang yourself.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <errno.h>
+#include <rpc/pmap_clnt.h>
+#include <sys/select.h>
+
+#define MCALL_MSG_SIZE 24
+
+static int readtcp(char *, char*, int);
+static int writetcp(char *, char*, int);
+
+static enum clnt_stat clnttcp_call(CLIENT *, rpcproc_t, xdrproc_t, void*, xdrproc_t, void*, struct timeval);
+static void clnttcp_abort(void);
+static void clnttcp_geterr(CLIENT *, struct rpc_err*);
+static bool_t clnttcp_freeres(CLIENT *, xdrproc_t, void*);
+static bool_t clnttcp_control(CLIENT *, int, char *);
+static void clnttcp_destroy(CLIENT *);
+
+static struct clnt_ops tcp_ops = {
+ clnttcp_call,
+ clnttcp_abort,
+ clnttcp_geterr,
+ clnttcp_freeres,
+ clnttcp_destroy,
+ clnttcp_control
+};
+
+struct ct_data {
+ int ct_sock;
+ bool_t ct_closeit; /* close it on destroy */
+ struct timeval ct_wait; /* wait interval in milliseconds */
+ bool_t ct_waitset; /* wait set by clnt_control? */
+ struct sockaddr_in ct_addr;
+ struct rpc_err ct_error;
+ union {
+ char ct_mcallc[MCALL_MSG_SIZE]; /* marshalled callmsg */
+ u_int32_t ct_mcalli;
+ } ct_u;
+ u_int ct_mpos; /* pos after marshal */
+ XDR ct_xdrs; /* XDR stream */
+};
+
+/*
+ * Create a client handle for a tcp/ip connection.
+ * If *sockp<0, *sockp is set to a newly created TCP socket and it is
+ * connected to raddr. If *sockp non-negative then
+ * raddr is ignored. The rpc/tcp package does buffering
+ * similar to stdio, so the client must pick send and receive buffer sizes,];
+ * 0 => use the default.
+ * If raddr->sin_port is 0, then a binder on the remote machine is
+ * consulted for the right port number.
+ * NB: *sockp is copied into a private area.
+ * NB: It is the clients responsibility to close *sockp.
+ * NB: The rpch->cl_auth is set null authentication. Caller may wish to set this
+ * something more useful.
+ */
+CLIENT *
+clnttcp_create(
+ struct sockaddr_in *raddr,
+ u_long prog, /* program number */
+ u_long vers, /* version number */
+ int *sockp,
+ u_int sendsz,
+ u_int recvsz)
+{
+ CLIENT *h;
+ struct ct_data *ct = NULL; /* client handle */
+ struct timeval now;
+ struct rpc_msg call_msg;
+ static uintptr_t disrupt;
+
+ if (disrupt == 0)
+ disrupt = (uintptr_t)raddr;
+
+ h = (CLIENT *)mem_alloc(sizeof(*h));
+ if (h == NULL) {
+ (void)fprintf(stderr, "clnttcp_create: out of memory\n");
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = errno;
+ goto fooy;
+ }
+ ct = (struct ct_data *)mem_alloc(sizeof (*ct));
+ if (ct == NULL) {
+ (void)fprintf(stderr, "clnttcp_create: out of memory\n");
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = errno;
+ goto fooy;
+ }
+
+ /*
+ * If no port number given ask the pmap for one
+ */
+ if (raddr->sin_port == 0) {
+ u_short port;
+ if ((port = pmap_getport(raddr, prog, vers, IPPROTO_TCP)) == 0) {
+ mem_free((caddr_t)ct, sizeof(struct ct_data));
+ mem_free((caddr_t)h, sizeof(CLIENT));
+ return ((CLIENT *)NULL);
+ }
+ raddr->sin_port = htons(port);
+ }
+
+ /*
+ * If no socket given, open one
+ */
+ if (*sockp < 0) {
+ *sockp = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ (void)bindresvport(*sockp, (struct sockaddr_in *)0);
+ if ((*sockp < 0)
+ || (connect(*sockp, (struct sockaddr *)raddr,
+ sizeof(*raddr)) < 0)) {
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = errno;
+ if (*sockp != -1)
+ (void)_RPC_close(*sockp);
+ goto fooy;
+ }
+ ct->ct_closeit = TRUE;
+ } else {
+ ct->ct_closeit = FALSE;
+ }
+
+ /*
+ * Set up private data struct
+ */
+ ct->ct_sock = *sockp;
+ ct->ct_wait.tv_usec = 0;
+ ct->ct_waitset = FALSE;
+ ct->ct_addr = *raddr;
+
+ /*
+ * Initialize call message
+ */
+ (void)gettimeofday(&now, (struct timezone *)0);
+ call_msg.rm_xid = (++disrupt) ^ getpid() ^ now.tv_sec ^ now.tv_usec;
+ call_msg.rm_direction = CALL;
+ call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
+ call_msg.rm_call.cb_prog = prog;
+ call_msg.rm_call.cb_vers = vers;
+
+ /*
+ * pre-serialize the static part of the call msg and stash it away
+ */
+ xdrmem_create(&(ct->ct_xdrs), ct->ct_u.ct_mcallc, MCALL_MSG_SIZE,
+ XDR_ENCODE);
+ if (! xdr_callhdr(&(ct->ct_xdrs), &call_msg)) {
+ if (ct->ct_closeit) {
+ (void)_RPC_close(*sockp);
+ }
+ goto fooy;
+ }
+ ct->ct_mpos = XDR_GETPOS(&(ct->ct_xdrs));
+ XDR_DESTROY(&(ct->ct_xdrs));
+
+ /*
+ * Create a client handle which uses xdrrec for serialization
+ * and authnone for authentication.
+ */
+ xdrrec_create(&(ct->ct_xdrs), sendsz, recvsz,
+ (caddr_t)ct, readtcp, writetcp);
+ h->cl_ops = &tcp_ops;
+ h->cl_private = (caddr_t) ct;
+ h->cl_auth = authnone_create();
+ return (h);
+
+fooy:
+ /*
+ * Something goofed, free stuff and barf
+ */
+ if (ct)
+ mem_free((caddr_t)ct, sizeof(struct ct_data));
+ if (h)
+ mem_free((caddr_t)h, sizeof(CLIENT));
+ return ((CLIENT *)NULL);
+}
+
+static enum clnt_stat
+clnttcp_call(
+ CLIENT *h,
+ rpcproc_t proc,
+ xdrproc_t xdr_args,
+ void *args_ptr,
+ xdrproc_t xdr_results,
+ void *results_ptr,
+ struct timeval timeout)
+{
+ struct ct_data *ct = (struct ct_data *) h->cl_private;
+ XDR *xdrs = &(ct->ct_xdrs);
+ struct rpc_msg reply_msg;
+ u_int32_t x_id;
+ u_int32_t *msg_x_id = &ct->ct_u.ct_mcalli; /* yuk */
+ bool_t shipnow;
+ int refreshes = 2;
+
+ if (!ct->ct_waitset) {
+ ct->ct_wait = timeout;
+ }
+
+ shipnow =
+ (xdr_results == (xdrproc_t)0 && timeout.tv_sec == 0
+ && timeout.tv_usec == 0) ? FALSE : TRUE;
+
+call_again:
+ xdrs->x_op = XDR_ENCODE;
+ ct->ct_error.re_status = RPC_SUCCESS;
+ x_id = ntohl(--(*msg_x_id));
+ if ((! XDR_PUTBYTES(xdrs, ct->ct_u.ct_mcallc, ct->ct_mpos)) ||
+ (! XDR_PUTLONG(xdrs, (long *)&proc)) ||
+ (! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
+ (! (*xdr_args)(xdrs, args_ptr))) {
+ if (ct->ct_error.re_status == RPC_SUCCESS)
+ ct->ct_error.re_status = RPC_CANTENCODEARGS;
+ (void)xdrrec_endofrecord(xdrs, TRUE);
+ return (ct->ct_error.re_status);
+ }
+ if (! xdrrec_endofrecord(xdrs, shipnow)) {
+ return (ct->ct_error.re_status = RPC_CANTSEND);
+ }
+ if (! shipnow) {
+ return (RPC_SUCCESS);
+ }
+ /*
+ * Hack to provide rpc-based message passing
+ */
+ if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
+ return(ct->ct_error.re_status = RPC_TIMEDOUT);
+ }
+
+
+ /*
+ * Keep receiving until we get a valid transaction id
+ */
+ xdrs->x_op = XDR_DECODE;
+ while (TRUE) {
+ reply_msg.acpted_rply.ar_verf = _null_auth;
+ reply_msg.acpted_rply.ar_results.where = NULL;
+ reply_msg.acpted_rply.ar_results.proc = (xdrproc_t)xdr_void;
+ if (! xdrrec_skiprecord(xdrs))
+ return (ct->ct_error.re_status);
+ /* now decode and validate the response header */
+ if (! xdr_replymsg(xdrs, &reply_msg)) {
+ if (ct->ct_error.re_status == RPC_SUCCESS)
+ continue;
+ return (ct->ct_error.re_status);
+ }
+ if (reply_msg.rm_xid == x_id)
+ break;
+ }
+
+ /*
+ * process header
+ */
+ _seterr_reply(&reply_msg, &(ct->ct_error));
+ if (ct->ct_error.re_status == RPC_SUCCESS) {
+ if (! AUTH_VALIDATE(h->cl_auth, &reply_msg.acpted_rply.ar_verf)) {
+ ct->ct_error.re_status = RPC_AUTHERROR;
+ ct->ct_error.re_why = AUTH_INVALIDRESP;
+ } else if (! (*xdr_results)(xdrs, results_ptr)) {
+ if (ct->ct_error.re_status == RPC_SUCCESS)
+ ct->ct_error.re_status = RPC_CANTDECODERES;
+ }
+ /* free verifier ... */
+ if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
+ xdrs->x_op = XDR_FREE;
+ (void)xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf));
+ }
+ } /* end successful completion */
+ else {
+ /* maybe our credentials need to be refreshed ... */
+ if (refreshes-- && AUTH_REFRESH(h->cl_auth))
+ goto call_again;
+ } /* end of unsuccessful completion */
+ return (ct->ct_error.re_status);
+}
+
+static void
+clnttcp_geterr(
+ CLIENT *h,
+ struct rpc_err *errp)
+{
+ struct ct_data *ct;
+
+ ct = (struct ct_data *) h->cl_private;
+ *errp = ct->ct_error;
+}
+
+static bool_t
+clnttcp_freeres(
+ CLIENT *cl,
+ xdrproc_t xdr_res,
+ void *res_ptr)
+{
+ struct ct_data *ct;
+ XDR *xdrs;
+
+ ct = (struct ct_data *)cl->cl_private;
+ xdrs = &(ct->ct_xdrs);
+
+ xdrs->x_op = XDR_FREE;
+ return ((*xdr_res)(xdrs, res_ptr));
+}
+
+static void
+clnttcp_abort(void)
+{
+}
+
+
+static bool_t
+clnttcp_control(
+ CLIENT *cl,
+ int request,
+ char *info)
+{
+ struct ct_data *ct;
+ struct timeval *tv;
+ socklen_t len;
+
+ ct = (struct ct_data *)cl->cl_private;
+
+ switch (request) {
+ case CLSET_FD_CLOSE:
+ ct->ct_closeit = TRUE;
+ break;
+ case CLSET_FD_NCLOSE:
+ ct->ct_closeit = FALSE;
+ break;
+ case CLSET_TIMEOUT:
+ if (info == NULL)
+ return(FALSE);
+ tv = (struct timeval *)info;
+ ct->ct_wait.tv_sec = tv->tv_sec;
+ ct->ct_wait.tv_usec = tv->tv_usec;
+ ct->ct_waitset = TRUE;
+ break;
+ case CLGET_TIMEOUT:
+ if (info == NULL)
+ return(FALSE);
+ *(struct timeval *)info = ct->ct_wait;
+ break;
+ case CLGET_SERVER_ADDR:
+ if (info == NULL)
+ return(FALSE);
+ *(struct sockaddr_in *)info = ct->ct_addr;
+ break;
+ case CLGET_FD:
+ if (info == NULL)
+ return(FALSE);
+ *(int *)info = ct->ct_sock;
+ break;
+ case CLGET_XID:
+ /*
+ * use the knowledge that xid is the
+ * first element in the call structure
+ * This will get the xid of the PREVIOUS call
+ */
+ if (info == NULL)
+ return(FALSE);
+ *(u_int32_t *)info =
+ ntohl(*(u_int32_t *)&ct->ct_u.ct_mcalli);
+ break;
+ case CLSET_XID:
+ /* This will set the xid of the NEXT call */
+ if (info == NULL)
+ return(FALSE);
+ *(u_int32_t *)&ct->ct_u.ct_mcalli =
+ htonl(*((u_int32_t *)info) + 1);
+ /* decrement by 1 as clnttcp_call() increments once */
+ case CLGET_VERS:
+ /*
+ * This RELIES on the information that, in the call body,
+ * the version number field is the fifth field from the
+ * begining of the RPC header. MUST be changed if the
+ * call_struct is changed
+ */
+ if (info == NULL)
+ return(FALSE);
+ *(u_int32_t *)info =
+ ntohl(*(u_int32_t *)(ct->ct_u.ct_mcallc +
+ 4 * BYTES_PER_XDR_UNIT));
+ break;
+ case CLSET_VERS:
+ if (info == NULL)
+ return(FALSE);
+ *(u_int32_t *)(ct->ct_u.ct_mcallc +
+ 4 * BYTES_PER_XDR_UNIT) =
+ htonl(*(u_int32_t *)info);
+ break;
+
+ case CLGET_PROG:
+ /*
+ * This RELIES on the information that, in the call body,
+ * the program number field is the fourth field from the
+ * begining of the RPC header. MUST be changed if the
+ * call_struct is changed
+ */
+ if (info == NULL)
+ return(FALSE);
+ *(u_int32_t *)info = ntohl(*(u_int32_t *)(ct->ct_u.ct_mcallc +
+ 3 * BYTES_PER_XDR_UNIT));
+ break;
+
+ case CLSET_PROG:
+ if (info == NULL)
+ return(FALSE);
+ *(u_int32_t *)(ct->ct_u.ct_mcallc + 3 * BYTES_PER_XDR_UNIT)
+ = htonl(*(u_int32_t *)info);
+ break;
+
+ case CLGET_LOCAL_ADDR:
+ len = sizeof(struct sockaddr);
+ if (getsockname(ct->ct_sock, (struct sockaddr *)info, &len) <0)
+ return(FALSE);
+ break;
+
+ case CLGET_RETRY_TIMEOUT:
+ case CLSET_RETRY_TIMEOUT:
+ case CLGET_SVC_ADDR:
+ case CLSET_SVC_ADDR:
+ case CLSET_PUSH_TIMOD:
+ case CLSET_POP_TIMOD:
+ default:
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
+static void
+clnttcp_destroy(
+ CLIENT *h)
+{
+ struct ct_data *ct =
+ (struct ct_data *) h->cl_private;
+
+ if (ct->ct_closeit) {
+ (void)_RPC_close(ct->ct_sock);
+ }
+ XDR_DESTROY(&(ct->ct_xdrs));
+ mem_free(ct, sizeof(struct ct_data));
+ mem_free(h, sizeof(CLIENT));
+}
+
+/*
+ * Interface between xdr serializer and tcp connection.
+ * Behaves like the system calls, read & write, but keeps some error state
+ * around for the rpc level.
+ */
+static int
+readtcp(
+ char *_ct,
+ char *buf,
+ int len)
+{
+ struct ct_data *ct = (struct ct_data*) _ct;
+ fd_set *fds, readfds;
+ struct timeval start, after, duration, delta, tmp, tv;
+ int r, save_errno;
+
+ if (len == 0)
+ return (0);
+
+ if (ct->ct_sock + 1 > FD_SETSIZE) {
+ int bytes = howmany(ct->ct_sock + 1, NFDBITS) * sizeof(fd_mask);
+ fds = (fd_set *)malloc(bytes);
+ if (fds == NULL)
+ return (-1);
+ memset(fds, 0, bytes);
+ } else {
+ fds = &readfds;
+ FD_ZERO(fds);
+ }
+
+ gettimeofday(&start, NULL);
+ delta = ct->ct_wait;
+ while (TRUE) {
+ /* XXX we know the other bits are still clear */
+ FD_SET(ct->ct_sock, fds);
+ tv = delta; /* in case select writes back */
+ r = select(ct->ct_sock+1, fds, NULL, NULL, &tv);
+ save_errno = errno;
+
+ gettimeofday(&after, NULL);
+ timersub(&start, &after, &duration);
+ timersub(&ct->ct_wait, &duration, &tmp);
+ delta = tmp;
+ if (delta.tv_sec < 0 || !timerisset(&delta))
+ r = 0;
+
+ switch (r) {
+ case 0:
+ if (fds != &readfds)
+ free(fds);
+ ct->ct_error.re_status = RPC_TIMEDOUT;
+ return (-1);
+
+ case -1:
+ if (errno == EINTR)
+ continue;
+ if (fds != &readfds)
+ free(fds);
+ ct->ct_error.re_status = RPC_CANTRECV;
+ ct->ct_error.re_errno = save_errno;
+ return (-1);
+ }
+ break;
+ }
+ switch (len = _RPC_read(ct->ct_sock, buf, len)) {
+
+ case 0:
+ /* premature eof */
+ ct->ct_error.re_errno = ECONNRESET;
+ ct->ct_error.re_status = RPC_CANTRECV;
+ len = -1; /* it's really an error */
+ break;
+
+ case -1:
+ ct->ct_error.re_errno = errno;
+ ct->ct_error.re_status = RPC_CANTRECV;
+ break;
+ }
+ return (len);
+}
+
+static int
+writetcp(
+ char *_ct,
+ char *buf,
+ int len)
+{
+ struct ct_data *ct = (struct ct_data *) _ct;
+ int i, cnt;
+
+ for (cnt = len; cnt > 0; cnt -= i, buf += i) {
+ if ((i = _RPC_write(ct->ct_sock, buf, cnt)) == -1) {
+ ct->ct_error.re_errno = errno;
+ ct->ct_error.re_status = RPC_CANTSEND;
+ return (-1);
+ }
+ }
+ return (len);
+}
diff --git a/librpc/src/rpc/clnt_udp.c b/librpc/src/rpc/clnt_udp.c
new file mode 100644
index 0000000..93befc2
--- /dev/null
+++ b/librpc/src/rpc/clnt_udp.c
@@ -0,0 +1,582 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)clnt_udp.c 1.39 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)clnt_udp.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/clnt_udp.c,v 1.15 2000/01/27 23:06:36 jasone Exp $";
+#endif
+
+/*
+ * clnt_udp.c, Implements a UDP/IP based, client side RPC.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <netdb.h>
+#include <errno.h>
+#include <rpc/pmap_clnt.h>
+#include <sys/select.h>
+
+/*
+ * UDP bases client side rpc operations
+ */
+static enum clnt_stat clntudp_call(CLIENT *, rpcproc_t, xdrproc_t, void*, xdrproc_t, void*, struct timeval);
+static void clntudp_abort(void);
+static void clntudp_geterr(CLIENT *, struct rpc_err*);
+static bool_t clntudp_freeres(CLIENT *, xdrproc_t, void*);
+static bool_t clntudp_control(CLIENT *, int, char *);
+static void clntudp_destroy(CLIENT *);
+
+static struct clnt_ops udp_ops = {
+ clntudp_call,
+ clntudp_abort,
+ clntudp_geterr,
+ clntudp_freeres,
+ clntudp_destroy,
+ clntudp_control
+};
+
+/*
+ * Private data kept per client handle
+ */
+struct cu_data {
+ int cu_sock;
+ bool_t cu_closeit; /* opened by library */
+ struct sockaddr_in cu_raddr;
+ int cu_rlen;
+ struct timeval cu_wait; /* retransmit interval */
+ struct timeval cu_total; /* total time for the call */
+ struct rpc_err cu_error;
+ XDR cu_outxdrs;
+ u_int cu_xdrpos;
+ u_int cu_sendsz; /* send size */
+ union {
+ u_int32_t *pi32;
+ char *c;
+ } _cu_outbuf;
+#define cu_outbuf _cu_outbuf.c
+ u_int cu_recvsz; /* recv size */
+ union {
+ u_int32_t i32;
+ char c[1];
+ } _cu_inbuf;
+#define cu_inbuf _cu_inbuf.c
+};
+
+/*
+ * Create a UDP based client handle.
+ * If *sockp<0, *sockp is set to a newly created UPD socket.
+ * If raddr->sin_port is 0 a binder on the remote machine
+ * is consulted for the correct port number.
+ * NB: It is the clients responsibility to close *sockp.
+ * NB: The rpch->cl_auth is initialized to null authentication.
+ * Caller may wish to set this something more useful.
+ *
+ * wait is the amount of time used between retransmitting a call if
+ * no response has been heard; retransmition occurs until the actual
+ * rpc call times out.
+ *
+ * sendsz and recvsz are the maximum allowable packet sizes that can be
+ * sent and received.
+ */
+CLIENT *
+clntudp_bufcreate(
+ struct sockaddr_in *raddr,
+ u_long program, /* program number */
+ u_long version, /* version number */
+ struct timeval wait,
+ int *sockp,
+ u_int sendsz,
+ u_int recvsz)
+{
+ CLIENT *cl = NULL; /* client handle */
+ struct cu_data *cu = NULL; /* private data */
+ struct timeval now;
+ struct rpc_msg call_msg;
+ static uintptr_t disrupt;
+
+ if (disrupt == 0)
+ disrupt = (uintptr_t)raddr;
+
+ cl = (CLIENT *)mem_alloc(sizeof(CLIENT));
+ if (cl == NULL) {
+ (void) fprintf(stderr, "clntudp_create: out of memory\n");
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = errno;
+ goto fooy;
+ }
+ sendsz = ((sendsz + 3) / 4) * 4;
+ recvsz = ((recvsz + 3) / 4) * 4;
+ cu = mem_alloc(sizeof (*cu) + sendsz + recvsz);
+ if (cu == NULL) {
+ (void) fprintf(stderr, "clntudp_create: out of memory\n");
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = errno;
+ goto fooy;
+ }
+ cu->cu_outbuf = &cu->cu_inbuf[recvsz];
+
+ (void)gettimeofday(&now, (struct timezone *)0);
+ if (raddr->sin_port == 0) {
+ u_short port;
+ if ((port =
+ pmap_getport(raddr, program, version, IPPROTO_UDP)) == 0) {
+ goto fooy;
+ }
+ raddr->sin_port = htons(port);
+ }
+ cl->cl_ops = &udp_ops;
+ cl->cl_private = (caddr_t)cu;
+ cu->cu_raddr = *raddr;
+ cu->cu_rlen = sizeof (cu->cu_raddr);
+ cu->cu_wait = wait;
+ cu->cu_total.tv_sec = -1;
+ cu->cu_total.tv_usec = -1;
+ cu->cu_sendsz = sendsz;
+ cu->cu_recvsz = recvsz;
+ call_msg.rm_xid = (++disrupt) ^ getpid() ^ now.tv_sec ^ now.tv_usec;
+ call_msg.rm_direction = CALL;
+ call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
+ call_msg.rm_call.cb_prog = program;
+ call_msg.rm_call.cb_vers = version;
+ xdrmem_create(&(cu->cu_outxdrs), cu->cu_outbuf,
+ sendsz, XDR_ENCODE);
+ if (! xdr_callhdr(&(cu->cu_outxdrs), &call_msg)) {
+ goto fooy;
+ }
+ cu->cu_xdrpos = XDR_GETPOS(&(cu->cu_outxdrs));
+ if (*sockp < 0) {
+ int dontblock = 1;
+
+ *sockp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (*sockp < 0) {
+ rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+ rpc_createerr.cf_error.re_errno = errno;
+ goto fooy;
+ }
+ /* attempt to bind to priv port */
+ (void)bindresvport(*sockp, (struct sockaddr_in *)0);
+ /* the sockets rpc controls are non-blocking */
+ (void)ioctl(*sockp, FIONBIO, (char *) &dontblock);
+ cu->cu_closeit = TRUE;
+ } else {
+ cu->cu_closeit = FALSE;
+ }
+ cu->cu_sock = *sockp;
+ cl->cl_auth = authnone_create();
+ return (cl);
+fooy:
+ if (cu)
+ mem_free((caddr_t)cu, sizeof(*cu) + sendsz + recvsz);
+ if (cl)
+ mem_free((caddr_t)cl, sizeof(CLIENT));
+ return ((CLIENT *)NULL);
+}
+
+CLIENT *
+clntudp_create(
+ struct sockaddr_in *raddr,
+ u_long program, /* program number */
+ u_long version, /* version number */
+ struct timeval wait,
+ int *sockp)
+{
+
+ return(clntudp_bufcreate(raddr, program, version, wait, sockp,
+ UDPMSGSIZE, UDPMSGSIZE));
+}
+
+static enum clnt_stat
+clntudp_call(
+ CLIENT *cl, /* client handle */
+ rpcproc_t proc, /* procedure number */
+ xdrproc_t xargs, /* xdr routine for args */
+ void *argsp, /* pointer to args */
+ xdrproc_t xresults, /* xdr routine for results */
+ void *resultsp, /* pointer to results */
+ struct timeval utimeout ) /* seconds to wait before giving up */
+{
+ struct cu_data *cu = (struct cu_data *)cl->cl_private;
+ XDR *xdrs;
+ size_t outlen = 0;
+ int inlen;
+ socklen_t fromlen;
+ fd_set *fds, readfds;
+ struct sockaddr_in from;
+ struct rpc_msg reply_msg;
+ XDR reply_xdrs;
+ struct timeval time_waited, start, after, tmp1, tmp2, tv;
+ bool_t ok;
+ int nrefreshes = 2; /* number of times to refresh cred */
+ struct timeval timeout;
+
+ if (cu->cu_total.tv_usec == -1)
+ timeout = utimeout; /* use supplied timeout */
+ else
+ timeout = cu->cu_total; /* use default timeout */
+
+ if (cu->cu_sock + 1 > FD_SETSIZE) {
+ int bytes = howmany(cu->cu_sock + 1, NFDBITS) * sizeof(fd_mask);
+ fds = (fd_set *)malloc(bytes);
+ if (fds == NULL)
+ return (cu->cu_error.re_status = RPC_CANTSEND);
+ memset(fds, 0, bytes);
+ } else {
+ fds = &readfds;
+ FD_ZERO(fds);
+ }
+
+ timerclear(&time_waited);
+
+call_again:
+ xdrs = &(cu->cu_outxdrs);
+ xdrs->x_op = XDR_ENCODE;
+ XDR_SETPOS(xdrs, cu->cu_xdrpos);
+ /*
+ * the transaction is the first thing in the out buffer
+ */
+ (*(u_short *)(cu->cu_outbuf))++;
+ if ((! XDR_PUTLONG(xdrs, (long *)&proc)) ||
+ (! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
+ (! (*xargs)(xdrs, argsp))) {
+ if (fds != &readfds)
+ free(fds);
+ return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
+ }
+ outlen = (size_t)XDR_GETPOS(xdrs);
+
+send_again:
+ if (sendto(cu->cu_sock, cu->cu_outbuf, outlen, 0,
+ (struct sockaddr *)&(cu->cu_raddr), cu->cu_rlen) != outlen) {
+ cu->cu_error.re_errno = errno;
+ if (fds != &readfds)
+ free(fds);
+ return (cu->cu_error.re_status = RPC_CANTSEND);
+ }
+
+ /*
+ * Hack to provide rpc-based message passing
+ */
+ if (!timerisset(&timeout)) {
+ if (fds != &readfds)
+ free(fds);
+ return (cu->cu_error.re_status = RPC_TIMEDOUT);
+ }
+ /*
+ * sub-optimal code appears here because we have
+ * some clock time to spare while the packets are in flight.
+ * (We assume that this is actually only executed once.)
+ */
+ reply_msg.acpted_rply.ar_verf = _null_auth;
+ reply_msg.acpted_rply.ar_results.where = resultsp;
+ reply_msg.acpted_rply.ar_results.proc = xresults;
+
+ gettimeofday(&start, NULL);
+ for (;;) {
+ /* XXX we know the other bits are still clear */
+ FD_SET(cu->cu_sock, fds);
+ tv = cu->cu_wait;
+ switch (select(cu->cu_sock+1, fds, NULL, NULL, &tv)) {
+
+ case 0:
+ timeradd(&time_waited, &cu->cu_wait, &tmp1);
+ time_waited = tmp1;
+ if (timercmp(&time_waited, &timeout, <))
+ goto send_again;
+ if (fds != &readfds)
+ free(fds);
+ return (cu->cu_error.re_status = RPC_TIMEDOUT);
+
+ case -1:
+ if (errno == EINTR) {
+ gettimeofday(&after, NULL);
+ timersub(&after, &start, &tmp1);
+ timeradd(&time_waited, &tmp1, &tmp2);
+ time_waited = tmp2;
+ if (timercmp(&time_waited, &timeout, <))
+ continue;
+ if (fds != &readfds)
+ free(fds);
+ return (cu->cu_error.re_status = RPC_TIMEDOUT);
+ }
+ cu->cu_error.re_errno = errno;
+ if (fds != &readfds)
+ free(fds);
+ return (cu->cu_error.re_status = RPC_CANTRECV);
+ }
+
+ do {
+ fromlen = sizeof(struct sockaddr);
+ inlen = recvfrom(cu->cu_sock, cu->cu_inbuf,
+ (int) cu->cu_recvsz, 0,
+ (struct sockaddr *)&from, &fromlen);
+ } while (inlen < 0 && errno == EINTR);
+ if (inlen < 0) {
+ if (errno == EWOULDBLOCK)
+ continue;
+ cu->cu_error.re_errno = errno;
+ if (fds != &readfds)
+ free(fds);
+ return (cu->cu_error.re_status = RPC_CANTRECV);
+ }
+ if (inlen < sizeof(u_int32_t))
+ continue;
+ /* see if reply transaction id matches sent id */
+ if ( cu->_cu_inbuf.i32 != *cu->_cu_outbuf.pi32 )
+ continue;
+ /* we now assume we have the proper reply */
+ break;
+ }
+
+ /*
+ * now decode and validate the response
+ */
+ xdrmem_create(&reply_xdrs, cu->cu_inbuf, (u_int)inlen, XDR_DECODE);
+ ok = xdr_replymsg(&reply_xdrs, &reply_msg);
+ /* XDR_DESTROY(&reply_xdrs); save a few cycles on noop destroy */
+ if (ok) {
+ _seterr_reply(&reply_msg, &(cu->cu_error));
+ if (cu->cu_error.re_status == RPC_SUCCESS) {
+ if (! AUTH_VALIDATE(cl->cl_auth,
+ &reply_msg.acpted_rply.ar_verf)) {
+ cu->cu_error.re_status = RPC_AUTHERROR;
+ cu->cu_error.re_why = AUTH_INVALIDRESP;
+ }
+ if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
+ xdrs->x_op = XDR_FREE;
+ (void)xdr_opaque_auth(xdrs,
+ &(reply_msg.acpted_rply.ar_verf));
+ }
+ } /* end successful completion */
+ else {
+ /* maybe our credentials need to be refreshed ... */
+ if (nrefreshes > 0 && AUTH_REFRESH(cl->cl_auth)) {
+ nrefreshes--;
+ goto call_again;
+ }
+ } /* end of unsuccessful completion */
+ } /* end of valid reply message */
+ else {
+ /*
+ * It's possible for xdr_replymsg() to fail partway
+ * through its attempt to decode the result from the
+ * server. If this happens, it will leave the reply
+ * structure partially populated with dynamically
+ * allocated memory. (This can happen if someone uses
+ * clntudp_bufcreate() to create a CLIENT handle and
+ * specifies a receive buffer size that is too small.)
+ * This memory must be free()ed to avoid a leak.
+ */
+ int op = reply_xdrs.x_op;
+ reply_xdrs.x_op = XDR_FREE;
+ xdr_replymsg(&reply_xdrs, &reply_msg);
+ reply_xdrs.x_op = op;
+ cu->cu_error.re_status = RPC_CANTDECODERES;
+ }
+ if (fds != &readfds)
+ free(fds);
+ return (cu->cu_error.re_status);
+}
+
+static void
+clntudp_geterr(
+ CLIENT *cl,
+ struct rpc_err *errp)
+{
+ struct cu_data *cu = (struct cu_data *)cl->cl_private;
+
+ *errp = cu->cu_error;
+}
+
+
+static bool_t
+clntudp_freeres(
+ CLIENT *cl,
+ xdrproc_t xdr_res,
+ void *res_ptr)
+{
+ struct cu_data *cu = (struct cu_data *)cl->cl_private;
+ XDR *xdrs = &(cu->cu_outxdrs);
+
+ xdrs->x_op = XDR_FREE;
+ return ((*xdr_res)(xdrs, res_ptr));
+}
+
+static void
+clntudp_abort(void)
+{
+}
+
+
+static bool_t
+clntudp_control(
+ CLIENT *cl,
+ int request,
+ char *info)
+{
+ struct cu_data *cu = (struct cu_data *)cl->cl_private;
+ struct timeval *tv;
+ socklen_t len;
+
+ switch (request) {
+ case CLSET_FD_CLOSE:
+ cu->cu_closeit = TRUE;
+ break;
+ case CLSET_FD_NCLOSE:
+ cu->cu_closeit = FALSE;
+ break;
+ case CLSET_TIMEOUT:
+ if (info == NULL)
+ return(FALSE);
+ tv = (struct timeval *)info;
+ cu->cu_total.tv_sec = tv->tv_sec;
+ cu->cu_total.tv_usec = tv->tv_usec;
+ break;
+ case CLGET_TIMEOUT:
+ if (info == NULL)
+ return(FALSE);
+ *(struct timeval *)info = cu->cu_total;
+ break;
+ case CLSET_RETRY_TIMEOUT:
+ if (info == NULL)
+ return(FALSE);
+ tv = (struct timeval *)info;
+ cu->cu_wait.tv_sec = tv->tv_sec;
+ cu->cu_wait.tv_usec = tv->tv_usec;
+ break;
+ case CLGET_RETRY_TIMEOUT:
+ if (info == NULL)
+ return(FALSE);
+ *(struct timeval *)info = cu->cu_wait;
+ break;
+ case CLGET_SERVER_ADDR:
+ if (info == NULL)
+ return(FALSE);
+ *(struct sockaddr_in *)info = cu->cu_raddr;
+ break;
+ case CLGET_FD:
+ if (info == NULL)
+ return(FALSE);
+ *(int *)info = cu->cu_sock;
+ break;
+ case CLGET_XID:
+ /*
+ * use the knowledge that xid is the
+ * first element in the call structure *.
+ * This will get the xid of the PREVIOUS call
+ */
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)info = ntohl(*(u_long *)cu->cu_outbuf);
+ break;
+ case CLSET_XID:
+ /* This will set the xid of the NEXT call */
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)cu->cu_outbuf = htonl(*(u_long *)info - 1);
+ /* decrement by 1 as clntudp_call() increments once */
+ case CLGET_VERS:
+ /*
+ * This RELIES on the information that, in the call body,
+ * the version number field is the fifth field from the
+ * begining of the RPC header. MUST be changed if the
+ * call_struct is changed
+ */
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)info = ntohl(*(u_long *)(cu->cu_outbuf +
+ 4 * BYTES_PER_XDR_UNIT));
+ break;
+ case CLSET_VERS:
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)(cu->cu_outbuf + 4 * BYTES_PER_XDR_UNIT)
+ = htonl(*(u_long *)info);
+ break;
+ case CLGET_PROG:
+ /*
+ * This RELIES on the information that, in the call body,
+ * the program number field is the fourth field from the
+ * begining of the RPC header. MUST be changed if the
+ * call_struct is changed
+ */
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)info = ntohl(*(u_long *)(cu->cu_outbuf +
+ 3 * BYTES_PER_XDR_UNIT));
+ break;
+ case CLSET_PROG:
+ if (info == NULL)
+ return(FALSE);
+ *(u_long *)(cu->cu_outbuf + 3 * BYTES_PER_XDR_UNIT)
+ = htonl(*(u_long *)info);
+ break;
+ case CLGET_LOCAL_ADDR:
+ len = sizeof(struct sockaddr);
+ if (getsockname(cu->cu_sock, (struct sockaddr *)info, &len) <0)
+ return(FALSE);
+ break;
+ case CLGET_SVC_ADDR:
+ case CLSET_SVC_ADDR:
+ case CLSET_PUSH_TIMOD:
+ case CLSET_POP_TIMOD:
+ default:
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+static void
+clntudp_destroy(
+ CLIENT *cl)
+{
+ struct cu_data *cu = (struct cu_data *)cl->cl_private;
+
+ if (cu->cu_closeit) {
+ (void)_RPC_close(cu->cu_sock);
+ }
+ XDR_DESTROY(&(cu->cu_outxdrs));
+ mem_free(cu, (sizeof (*cu) + cu->cu_sendsz + cu->cu_recvsz));
+ mem_free(cl, sizeof (CLIENT));
+}
diff --git a/librpc/src/rpc/des_crypt.3 b/librpc/src/rpc/des_crypt.3
new file mode 100644
index 0000000..a92f577
--- /dev/null
+++ b/librpc/src/rpc/des_crypt.3
@@ -0,0 +1,130 @@
+.\" @(#)des_crypt.3 2.1 88/08/11 4.0 RPCSRC; from 1.16 88/03/02 SMI;
+.\" $FreeBSD: src/lib/libc/rpc/des_crypt.3,v 1.4 2000/03/02 09:13:45 sheldonh Exp $
+.\"
+.TH DES_CRYPT 3 "6 October 1987"
+.SH NAME
+des_crypt, ecb_crypt, cbc_crypt, des_setparity \- fast DES encryption
+.SH SYNOPSIS
+.nf
+.B #include <des_crypt.h>
+.LP
+.B int ecb_crypt(key, data, datalen, mode)
+.B char *key;
+.B char *data;
+.B unsigned datalen;
+.B unsigned mode;
+.LP
+.B int cbc_crypt(key, data, datalen, mode, ivec)
+.B char *key;
+.B char *data;
+.B unsigned datalen;
+.B unsigned mode;
+.B char *ivec;
+.LP
+.B void des_setparity(key)
+.B char *key;
+.fi
+.SH DESCRIPTION
+.IX encryption cbc_crypt "" \fLcbc_crypt\fP
+.IX "des encryption" cbc_crypt "DES encryption" \fLcbc_crypt\fP
+.IX encryption des_setparity "" \fLdes_setparity\fP
+.IX "des encryption" des_setparity "DES encryption" \fLdes_setparity\fP
+.B ecb_crypt(\|)
+and
+.B cbc_crypt(\|)
+implement the
+.SM NBS
+.SM DES
+(Data Encryption Standard).
+These routines are faster and more general purpose than
+.BR crypt (3).
+They also are able to utilize
+.SM DES
+hardware if it is available.
+.B ecb_crypt(\|)
+encrypts in
+.SM ECB
+(Electronic Code Book)
+mode, which encrypts blocks of data independently.
+.B cbc_crypt(\|)
+encrypts in
+.SM CBC
+(Cipher Block Chaining)
+mode, which chains together
+successive blocks.
+.SM CBC
+mode protects against insertions, deletions and
+substitutions of blocks.
+Also, regularities in the clear text will
+not appear in the cipher text.
+.LP
+Here is how to use these routines. The first parameter,
+.IR key ,
+is the 8-byte encryption key with parity.
+To set the key's parity, which for
+.SM DES
+is in the low bit of each byte, use
+.IR des_setparity .
+The second parameter,
+.IR data ,
+contains the data to be encrypted or decrypted.
+The
+third parameter,
+.IR datalen ,
+is the length in bytes of
+.IR data ,
+which must be a multiple of 8. The fourth parameter,
+.IR mode ,
+is formed by
+.SM OR\s0'ing
+together some things. For the encryption direction 'or' in either
+.SM DES_ENCRYPT
+or
+.SM DES_DECRYPT\s0.
+For software versus hardware
+encryption, 'or' in either
+.SM DES_HW
+or
+.SM DES_SW\s0.
+If
+.SM DES_HW
+is specified, and there is no hardware, then the encryption is performed
+in software and the routine returns
+.SM DESERR_NOHWDEVICE\s0.
+For
+.IR cbc_crypt ,
+the parameter
+.I ivec
+is the the 8-byte initialization
+vector for the chaining. It is updated to the next initialization
+vector upon return.
+.LP
+.SH "SEE ALSO"
+.BR des (1),
+.BR crypt (3)
+.SH DIAGNOSTICS
+.PD 0
+.TP 20
+.SM DESERR_NONE
+No error.
+.TP
+.SM DESERR_NOHWDEVICE
+Encryption succeeded, but done in software instead of the requested hardware.
+.TP
+.SM DESERR_HWERR
+An error occurred in the hardware or driver.
+.TP
+.SM DESERR_BADPARAM
+Bad parameter to routine.
+.PD
+.LP
+Given a result status
+.IR stat ,
+the macro
+.SM DES_FAILED\c
+.BR ( stat )
+is false only for the first two statuses.
+.SH RESTRICTIONS
+These routines are not available in RPCSRC 4.0.
+This information is provided to describe the DES interface expected by
+Secure RPC.
diff --git a/librpc/src/rpc/get_myaddress.c b/librpc/src/rpc/get_myaddress.c
new file mode 100644
index 0000000..a3410e9
--- /dev/null
+++ b/librpc/src/rpc/get_myaddress.c
@@ -0,0 +1,143 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)get_myaddress.c 1.4 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)get_myaddress.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/get_myaddress.c,v 1.17 2000/01/27 23:06:37 jasone Exp $";
+#endif
+
+/*
+ * get_myaddress.c
+ *
+ * Get client's IP address via ioctl. This avoids using the yellowpages.
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/pmap_prot.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+
+/*
+ * Determine the size of an ifreq structure when addresses larger
+ * than the pifreq structure size may be returned from the kernel.
+ */
+static size_t ifreqSize ( struct ifreq *pifreq )
+{
+ size_t size = pifreq->ifr_addr.sa_len + sizeof(pifreq->ifr_name);
+ if ( size < sizeof ( *pifreq ) ) {
+ size = sizeof ( *pifreq );
+ }
+ return size;
+}
+
+/*
+ * don't use gethostbyname, which would invoke yellow pages
+ *
+ * Avoid loopback interfaces. We return information from a loopback
+ * interface only if there are no other possible interfaces.
+ */
+int
+get_myaddress(
+ struct sockaddr_in *addr)
+{
+ int s;
+ struct ifconf ifc;
+ struct ifreq ifreq, *ifr;
+ int loopback = 0, gotit = 0;
+
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ return(-1);
+ }
+again:
+ ifc.ifc_len = sizeof ( struct ifreq ) * 8u;
+ ifc.ifc_buf = malloc ( ifc.ifc_len );
+ if ( ! ifc.ifc_buf ) {
+ _RPC_close(s);
+ return -1;
+ }
+ if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
+ _RPC_close(s);
+ free ( ifc.ifc_buf );
+ return(-1);
+ }
+ ifr = ifc.ifc_req;
+
+ while ( ifc.ifc_len >= ifreqSize ( ifr ) ) {
+ ifreq = *ifr;
+ if (ioctl(s, SIOCGIFFLAGS, (char *) &ifreq ) < 0) {
+ _RPC_close(s);
+ free ( ifc.ifc_buf );
+ return(-1);
+ }
+ if (((ifreq.ifr_flags & IFF_UP) &&
+ ifr->ifr_addr.sa_family == AF_INET &&
+ !(ifreq.ifr_flags & IFF_LOOPBACK)) ||
+ (loopback == 1 && (ifreq.ifr_flags & IFF_LOOPBACK)
+ && (ifr->ifr_addr.sa_family == AF_INET)
+ && (ifreq.ifr_flags & IFF_UP))) {
+ *addr = *((struct sockaddr_in *)&ifr->ifr_addr);
+ addr->sin_port = htons(PMAPPORT);
+ gotit = 1;
+ break;
+ }
+
+ const size_t len = ifreqSize ( ifr );
+ ifc.ifc_len -= len;
+ /*
+ * RTEMS seems to require copy up to properly aligned
+ * boundary at the beginning of the buffer?
+ */
+ memmove ( ifr, len + (char *) ifr, ifc.ifc_len );
+ }
+ if (gotit == 0 && loopback == 0) {
+ free ( ifc.ifc_buf );
+ loopback = 1;
+ goto again;
+ }
+ (void)_RPC_close(s);
+ free ( ifc.ifc_buf );
+ return (gotit ? 0 : -1);
+}
diff --git a/librpc/src/rpc/getrpcent.3 b/librpc/src/rpc/getrpcent.3
new file mode 100644
index 0000000..1e92e9d
--- /dev/null
+++ b/librpc/src/rpc/getrpcent.3
@@ -0,0 +1,98 @@
+.\" @(#)getrpcent.3n 2.2 88/08/02 4.0 RPCSRC; from 1.11 88/03/14 SMI
+.\" $FreeBSD: src/lib/libc/rpc/getrpcent.3,v 1.11 1999/08/28 00:00:39 peter Exp $
+.\"
+.Dd December 14, 1987
+.Dt GETRPCENT 3
+.Os
+.Sh NAME
+.Nm getrpcent ,
+.Nm getrpcbyname ,
+.Nm getrpcbynumber ,
+.Nm endrpcent ,
+.Nm setrpcent
+.Nd get RPC entry
+.Sh SYNOPSIS
+.Fd #include <rpc/rpc.h>
+.Ft struct rpcent *
+.Fn getrpcent void
+.Ft struct rpcent *
+.Fn getrpcbyname "char *name"
+.Ft struct rpcent *
+.Fn getrpcbynumber "int number"
+.Ft void
+.Fn setrpcent "int stayopen"
+.Ft void
+.Fn endrpcent void
+.Sh DESCRIPTION
+The
+.Fn getrpcent ,
+.Fn getrpcbyname ,
+and
+.Fn getrpcbynumber
+functions each return a pointer to an object with the
+following structure
+containing the broken-out
+fields of a line in the rpc program number data base,
+.Pa /etc/rpc .
+.Bd -literal
+
+struct rpcent {
+ char *r_name; /* name of server for this rpc program */
+ char **r_aliases; /* alias list */
+ long r_number; /* rpc program number */
+};
+.Ed
+.Pp
+The members of this structure are:
+.Bl -tag -width r_aliasesxxx
+.It Fa r_name
+The name of the server for this rpc program.
+.It Fa r_aliases
+A zero terminated list of alternate names for the rpc program.
+.It Fa r_number
+The rpc program number for this service.
+.El
+.Pp
+The
+.Fn getrpcent
+function reads the next line of the file, opening the file if necessary.
+The
+.Nm getrpcent
+function opens and rewinds the file. If the
+.Fa stayopen
+flag is non-zero,
+the net data base will not be closed after each call to
+.Fn getrpcent
+(either directly, or indirectly through one of
+the other
+.Fn getrpcent
+function family.
+.Pp
+.Fn endrpcent
+closes the file.
+.Pp
+.Fn getrpcbyname
+and
+.Fn getrpcbynumber
+sequentially search from the beginning
+of the file until a matching rpc program name or
+program number is found, or until end-of-file is encountered.
+.Sh FILES
+.Bl -tag -width /etc/rpc -compact
+.It Pa /etc/rpc
+.El
+.Sh "SEE ALSO"
+.Xr rpc 5 ,
+.Xr rpcinfo 8 ,
+.Xr ypserv 8
+.Sh DIAGNOSTICS
+A
+.Dv NULL
+pointer is returned on
+.Dv EOF
+or error.
+.Sh BUGS
+All information
+is contained in a static area
+so it must be copied if it is
+to be saved.
diff --git a/librpc/src/rpc/getrpcent.c b/librpc/src/rpc/getrpcent.c
new file mode 100644
index 0000000..a980c7d
--- /dev/null
+++ b/librpc/src/rpc/getrpcent.c
@@ -0,0 +1,303 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)getrpcent.c 1.14 91/03/11 Copyr 1984 Sun Micro";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/getrpcent.c,v 1.10 1999/08/28 00:00:39 peter Exp $";
+#endif
+
+/*
+ * Copyright (c) 1984 by Sun Microsystems, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#ifdef YP
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+#endif
+
+/*
+ * Internet version.
+ */
+struct rpcdata {
+ FILE *rpcf;
+ int stayopen;
+#define MAXALIASES 35
+ char *rpc_aliases[MAXALIASES];
+ struct rpcent rpc;
+ char line[BUFSIZ+1];
+#ifdef YP
+ char *domain;
+ char *current;
+ int currentlen;
+#endif
+} *rpcdata;
+
+#ifdef YP
+static int __yp_nomap = 0;
+extern int _yp_check(char **);
+#endif /* YP */
+
+static struct rpcent *interpret(char *val, int len);
+
+static char RPCDB[] = "/etc/rpc";
+
+static struct rpcdata *
+_rpcdata(void)
+{
+ register struct rpcdata *d = rpcdata;
+
+ if (d == 0) {
+ d = (struct rpcdata *)calloc(1, sizeof (struct rpcdata));
+ rpcdata = d;
+ }
+ return (d);
+}
+
+struct rpcent *
+getrpcbynumber(int number)
+{
+ register struct rpcdata *d = _rpcdata();
+ register struct rpcent *p;
+#ifdef YP
+ int reason;
+ char adrstr[16];
+#endif
+
+ if (d == 0)
+ return (0);
+#ifdef YP
+ if (!__yp_nomap && _yp_check(&d->domain)) {
+ sprintf(adrstr, "%d", number);
+ reason = yp_match(d->domain, "rpc.bynumber", adrstr, strlen(adrstr),
+ &d->current, &d->currentlen);
+ switch(reason) {
+ case 0:
+ break;
+ case YPERR_MAP:
+ __yp_nomap = 1;
+ goto no_yp;
+ break;
+ default:
+ return(0);
+ break;
+ }
+ d->current[d->currentlen] = '\0';
+ p = interpret(d->current, d->currentlen);
+ (void) free(d->current);
+ return p;
+ }
+no_yp:
+#endif /* YP */
+ setrpcent(0);
+ while ((p = getrpcent())) {
+ if (p->r_number == number)
+ break;
+ }
+ endrpcent();
+ return (p);
+}
+
+struct rpcent *
+getrpcbyname(char *name)
+{
+ struct rpcent *rpc = NULL;
+ char **rp;
+
+ setrpcent(0);
+ while ((rpc = getrpcent())) {
+ if (strcmp(rpc->r_name, name) == 0)
+ goto done;
+ for (rp = rpc->r_aliases; *rp != NULL; rp++) {
+ if (strcmp(*rp, name) == 0)
+ goto done;
+ }
+ }
+done:
+ endrpcent();
+ return (rpc);
+}
+
+void
+setrpcent(int f)
+{
+ register struct rpcdata *d = _rpcdata();
+
+ if (d == 0)
+ return;
+#ifdef YP
+ if (!__yp_nomap && _yp_check(NULL)) {
+ if (d->current)
+ free(d->current);
+ d->current = NULL;
+ d->currentlen = 0;
+ return;
+ }
+ __yp_nomap = 0;
+#endif /* YP */
+ if (d->rpcf == NULL)
+ d->rpcf = fopen(RPCDB, "r");
+ else
+ rewind(d->rpcf);
+ d->stayopen |= f;
+}
+
+void
+endrpcent(void)
+{
+ register struct rpcdata *d = _rpcdata();
+
+ if (d == 0)
+ return;
+#ifdef YP
+ if (!__yp_nomap && _yp_check(NULL)) {
+ if (d->current && !d->stayopen)
+ free(d->current);
+ d->current = NULL;
+ d->currentlen = 0;
+ return;
+ }
+ __yp_nomap = 0;
+#endif /* YP */
+ if (d->rpcf && !d->stayopen) {
+ fclose(d->rpcf);
+ d->rpcf = NULL;
+ }
+}
+
+struct rpcent *
+getrpcent(void)
+{
+ register struct rpcdata *d = _rpcdata();
+#ifdef YP
+ struct rpcent *hp;
+ int reason;
+ char *val = NULL;
+ int vallen;
+#endif
+
+ if (d == 0)
+ return(NULL);
+#ifdef YP
+ if (!__yp_nomap && _yp_check(&d->domain)) {
+ if (d->current == NULL && d->currentlen == 0) {
+ reason = yp_first(d->domain, "rpc.bynumber",
+ &d->current, &d->currentlen,
+ &val, &vallen);
+ } else {
+ reason = yp_next(d->domain, "rpc.bynumber",
+ d->current, d->currentlen,
+ &d->current, &d->currentlen,
+ &val, &vallen);
+ }
+ switch(reason) {
+ case 0:
+ break;
+ case YPERR_MAP:
+ __yp_nomap = 1;
+ goto no_yp;
+ break;
+ default:
+ return(0);
+ break;
+ }
+ val[vallen] = '\0';
+ hp = interpret(val, vallen);
+ (void) free(val);
+ return hp;
+ }
+no_yp:
+#endif /* YP */
+ if (d->rpcf == NULL && (d->rpcf = fopen(RPCDB, "r")) == NULL)
+ return (NULL);
+ /* -1 so there is room to append a \n below */
+ if (fgets(d->line, BUFSIZ - 1, d->rpcf) == NULL)
+ return (NULL);
+ return (interpret(d->line, strlen(d->line)));
+}
+
+static struct rpcent *
+interpret(
+ char *val,
+ int len)
+{
+ register struct rpcdata *d = _rpcdata();
+ char *p;
+ register char *cp, **q;
+
+ if (d == 0)
+ return (0);
+ (void) strncpy(d->line, val, BUFSIZ);
+ d->line[BUFSIZ] = '\0';
+ p = d->line;
+ p[len] = '\n';
+ if (*p == '#')
+ return (getrpcent());
+ cp = strpbrk(p, "#\n");
+ if (cp == NULL)
+ return (getrpcent());
+ *cp = '\0';
+ cp = strpbrk(p, " \t");
+ if (cp == NULL)
+ return (getrpcent());
+ *cp++ = '\0';
+ /* THIS STUFF IS INTERNET SPECIFIC */
+ d->rpc.r_name = d->line;
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+ d->rpc.r_number = atoi(cp);
+ q = d->rpc.r_aliases = d->rpc_aliases;
+ cp = strpbrk(cp, " \t");
+ if (cp != NULL)
+ *cp++ = '\0';
+ while (cp && *cp) {
+ if (*cp == ' ' || *cp == '\t') {
+ cp++;
+ continue;
+ }
+ if (q < &(d->rpc_aliases[MAXALIASES - 1]))
+ *q++ = cp;
+ cp = strpbrk(cp, " \t");
+ if (cp != NULL)
+ *cp++ = '\0';
+ }
+ *q = NULL;
+ return (&d->rpc);
+}
diff --git a/librpc/src/rpc/getrpcport.3 b/librpc/src/rpc/getrpcport.3
new file mode 100644
index 0000000..0e9175e
--- /dev/null
+++ b/librpc/src/rpc/getrpcport.3
@@ -0,0 +1,31 @@
+.\" @(#)getrpcport.3r 2.2 88/08/02 4.0 RPCSRC; from 1.12 88/02/26 SMI
+.\" $FreeBSD: src/lib/libc/rpc/getrpcport.3,v 1.6 1999/08/28 00:00:40 peter Exp $
+.\"
+.Dd October 6, 1987
+.Dt GETRPCPORT 3
+.Os
+.Sh NAME
+.Nm getrpcport
+.Nd get RPC port number
+.Sh SYNOPSIS
+.Ft int
+.Fn getrpcport "char *host" "int prognum" "int versnum" "int proto"
+.Sh DESCRIPTION
+.Fn getrpcport
+returns the port number for version
+.Fa versnum
+of the RPC program
+.Fa prognum
+running on
+.Fa host
+and using protocol
+.Fa proto .
+It returns 0 if it cannot contact the portmapper, or if
+.Fa prognum
+is not registered. If
+.Fa prognum
+is registered but not with version
+.Fa versnum ,
+it will still return a port number (for some version of the program)
+indicating that the program is indeed registered.
+The version mismatch will be detected upon the first call to the service.
diff --git a/librpc/src/rpc/getrpcport.c b/librpc/src/rpc/getrpcport.c
new file mode 100644
index 0000000..f1fa5a3
--- /dev/null
+++ b/librpc/src/rpc/getrpcport.c
@@ -0,0 +1,71 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)getrpcport.c 1.3 87/08/11 SMI";*/
+/*static char *sccsid = "from: @(#)getrpcport.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/getrpcport.c,v 1.10 1999/08/28 00:00:40 peter Exp $";
+#endif
+
+/*
+ * Copyright (c) 1985 by Sun Microsystems, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <rpc/pmap_clnt.h>
+#include <netdb.h>
+#include <sys/socket.h>
+
+int
+getrpcport(
+ char *host,
+ int prognum,
+ int versnum,
+ int proto )
+{
+ struct sockaddr_in addr;
+ struct hostent *hp;
+
+ if ((hp = gethostbyname(host)) == NULL)
+ return (0);
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_len = sizeof(struct sockaddr_in);
+ addr.sin_family = AF_INET;
+ addr.sin_port = 0;
+ memcpy((char *)&addr.sin_addr, hp->h_addr, hp->h_length);
+ return (pmap_getport(&addr, prognum, versnum, proto));
+}
diff --git a/librpc/src/rpc/netname.c b/librpc/src/rpc/netname.c
new file mode 100644
index 0000000..fd1145c
--- /dev/null
+++ b/librpc/src/rpc/netname.c
@@ -0,0 +1,141 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)netname.c 1.8 91/03/11 Copyr 1986 Sun Micro";
+#endif
+
+/*
+ * netname utility routines
+ * convert from unix names to network names and vice-versa
+ * This module is operating system dependent!
+ * What we define here will work with any unix system that has adopted
+ * the sun NIS domain architecture.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/param.h>
+#include <rpc/rpc.h>
+#include <rpc/rpc_com.h>
+#ifdef YP
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+#endif
+#include <ctype.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 256
+#endif
+#ifndef NGROUPS
+#define NGROUPS 16
+#endif
+
+static char *OPSYS = "unix";
+
+/*
+ * Figure out my fully qualified network name
+ */
+int
+getnetname(char name[MAXNETNAMELEN+1])
+{
+ uid_t uid;
+
+ uid = geteuid();
+ if (uid == 0) {
+ return (host2netname(name, (char *) NULL, (char *) NULL));
+ } else {
+ return (user2netname(name, uid, (char *) NULL));
+ }
+}
+
+
+/*
+ * Convert unix cred to network-name
+ */
+int
+user2netname(
+ char netname[MAXNETNAMELEN + 1],
+ uid_t uid,
+ char *domain)
+{
+ char *dfltdom;
+
+#define MAXIPRINT (11) /* max length of printed integer */
+
+ if (domain == NULL) {
+ if (_rpc_get_default_domain(&dfltdom) != 0) {
+ return (0);
+ }
+ domain = dfltdom;
+ }
+ if (strlen(domain) + 1 + MAXIPRINT > MAXNETNAMELEN) {
+ return (0);
+ }
+ (void) sprintf(netname, "%s.%ld@%s", OPSYS, (u_long)uid, domain);
+ return (1);
+}
+
+
+/*
+ * Convert host to network-name
+ */
+int
+host2netname(
+ char netname[MAXNETNAMELEN + 1],
+ char *host,
+ char *domain)
+{
+ char *dfltdom;
+ char hostname[MAXHOSTNAMELEN+1];
+
+ if (domain == NULL) {
+ if (_rpc_get_default_domain(&dfltdom) != 0) {
+ return (0);
+ }
+ domain = dfltdom;
+ }
+ if (host == NULL) {
+ (void) gethostname(hostname, sizeof(hostname));
+ host = hostname;
+ }
+ if (strlen(domain) + 1 + strlen(host) > MAXNETNAMELEN) {
+ return (0);
+ }
+ (void) sprintf(netname, "%s.%s@%s", OPSYS, host, domain);
+ return (1);
+}
diff --git a/librpc/src/rpc/netnamer.c b/librpc/src/rpc/netnamer.c
new file mode 100644
index 0000000..841f6b1
--- /dev/null
+++ b/librpc/src/rpc/netnamer.c
@@ -0,0 +1,333 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)netnamer.c 1.13 91/03/11 Copyr 1986 Sun Micro";
+#endif
+/*
+ * netname utility routines convert from unix names to network names and
+ * vice-versa This module is operating system dependent! What we define here
+ * will work with any unix system that has adopted the sun NIS domain
+ * architecture.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/param.h>
+#include <rpc/rpc.h>
+#include <rpc/rpc_com.h>
+#ifdef YP
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+#endif
+#include <ctype.h>
+#include <stdio.h>
+#include <grp.h>
+#include <pwd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static char *OPSYS = "unix";
+#ifdef YP
+static char *NETID = "netid.byname";
+#endif
+static char *NETIDFILE = "/etc/netid";
+
+static int getnetid ( char *, char * );
+static int _getgroups ( char *, gid_t * );
+
+#ifndef NGROUPS
+#define NGROUPS 16
+#endif
+
+/*
+ * Convert network-name into unix credential
+ */
+int
+netname2user(
+ char netname[MAXNETNAMELEN + 1],
+ uid_t *uidp,
+ gid_t *gidp,
+ int *gidlenp,
+ gid_t *gidlist)
+{
+ char *p;
+ int gidlen;
+ uid_t uid;
+ long luid;
+ struct passwd *pwd;
+ char val[1024];
+ char *val1, *val2;
+ char *domain;
+ int vallen;
+ int err;
+
+ if (getnetid(netname, val)) {
+ p = strtok(val, ":");
+ if (p == NULL)
+ return (0);
+ *uidp = (uid_t) atol(val);
+ p = strtok(NULL, "\n,");
+ *gidp = (gid_t) atol(p);
+ if (p == NULL) {
+ return (0);
+ }
+ gidlen = 0;
+ for (gidlen = 0; gidlen < NGROUPS; gidlen++) {
+ p = strtok(NULL, "\n,");
+ if (p == NULL)
+ break;
+ gidlist[gidlen] = (gid_t) atol(p);
+ }
+ *gidlenp = gidlen;
+
+ return (1);
+ }
+ val1 = strchr(netname, '.');
+ if (val1 == NULL)
+ return (0);
+ if (strncmp(netname, OPSYS, (val1-netname)))
+ return (0);
+ val1++;
+ val2 = strchr(val1, '@');
+ if (val2 == NULL)
+ return (0);
+ vallen = val2 - val1;
+ if (vallen > (1024 - 1))
+ vallen = 1024 - 1;
+ (void) strncpy(val, val1, 1024);
+ val[vallen] = 0;
+
+ err = _rpc_get_default_domain(&domain); /* change to rpc */
+ if (err)
+ return (0);
+
+ if (strcmp(val2 + 1, domain))
+ return (0); /* wrong domain */
+
+ if (sscanf(val, "%ld", &luid) != 1)
+ return (0);
+ uid = luid;
+
+ /* use initgroups method */
+ pwd = getpwuid(uid);
+ if (pwd == NULL)
+ return (0);
+ *uidp = pwd->pw_uid;
+ *gidp = pwd->pw_gid;
+ *gidlenp = _getgroups(pwd->pw_name, gidlist);
+ return (1);
+}
+
+/*
+ * initgroups
+ */
+
+static int
+_getgroups(
+ char *uname,
+ gid_t groups[NGROUPS])
+{
+ gid_t ngroups = 0;
+ register struct group *grp;
+ register int i;
+ register int j;
+ int filter;
+
+ setgrent();
+ while ((grp = getgrent())) {
+ for (i = 0; grp->gr_mem[i]; i++)
+ if (!strcmp(grp->gr_mem[i], uname)) {
+ if (ngroups == NGROUPS) {
+#ifdef DEBUG
+ fprintf(stderr,
+ "initgroups: %s is in too many groups\n", uname);
+#endif
+ goto toomany;
+ }
+ /* filter out duplicate group entries */
+ filter = 0;
+ for (j = 0; j < ngroups; j++)
+ if (groups[j] == grp->gr_gid) {
+ filter++;
+ break;
+ }
+ if (!filter)
+ groups[ngroups++] = grp->gr_gid;
+ }
+ }
+toomany:
+ endgrent();
+ return (ngroups);
+}
+
+/*
+ * Convert network-name to hostname
+ */
+int
+netname2host(
+ char netname[MAXNETNAMELEN + 1],
+ char *hostname,
+ int hostlen)
+{
+ int err;
+ char valbuf[1024];
+ char *val;
+ char *val2;
+ int vallen;
+ char *domain;
+
+ if (getnetid(netname, valbuf)) {
+ val = valbuf;
+ if ((*val == '0') && (val[1] == ':')) {
+ (void) strncpy(hostname, val + 2, hostlen);
+ return (1);
+ }
+ }
+ val = strchr(netname, '.');
+ if (val == NULL)
+ return (0);
+ if (strncmp(netname, OPSYS, (val - netname)))
+ return (0);
+ val++;
+ val2 = strchr(val, '@');
+ if (val2 == NULL)
+ return (0);
+ vallen = val2 - val;
+ if (vallen > (hostlen - 1))
+ vallen = hostlen - 1;
+ (void) strncpy(hostname, val, vallen);
+ hostname[vallen] = 0;
+
+ err = _rpc_get_default_domain(&domain); /* change to rpc */
+ if (err)
+ return (0);
+
+ if (strcmp(val2 + 1, domain))
+ return (0); /* wrong domain */
+ else
+ return (1);
+}
+
+/*
+ * reads the file /etc/netid looking for a + to optionally go to the
+ * network information service.
+ */
+int
+getnetid(
+ char *key,
+ char *ret)
+{
+ char buf[1024]; /* big enough */
+ char *res;
+ char *mkey;
+ char *mval;
+ FILE *fd;
+#ifdef YP
+ char *domain;
+ int err;
+ char *lookup;
+ int len;
+#endif
+
+ fd = fopen(NETIDFILE, "r");
+ if (fd == (FILE *) 0) {
+#ifdef YP
+ res = "+";
+ goto getnetidyp;
+#else
+ return (0);
+#endif
+ }
+ for (;;) {
+ if (fd == (FILE *) 0)
+ return (0); /* getnetidyp brings us here */
+ res = fgets(buf, 1024, fd);
+ if (res == 0) {
+ fclose(fd);
+ return (0);
+ }
+ if (res[0] == '#')
+ continue;
+ else if (res[0] == '+') {
+#ifdef YP
+ getnetidyp:
+ err = yp_get_default_domain(&domain);
+ if (err) {
+ continue;
+ }
+ lookup = NULL;
+ err = yp_match(domain, NETID, key,
+ strlen(key), &lookup, &len);
+ if (err) {
+#ifdef DEBUG
+ fprintf(stderr, "match failed error %d\n", err);
+#endif
+ continue;
+ }
+ lookup[len] = 0;
+ strcpy(ret, lookup);
+ free(lookup);
+ if (fd != NULL)
+ fclose(fd);
+ return (2);
+#else /* YP */
+#ifdef DEBUG
+ fprintf(stderr,
+"Bad record in %s '+' -- NIS not supported in this library copy\n",
+ NETIDFILE);
+#endif
+ continue;
+#endif /* YP */
+ } else {
+ mkey = strtok(buf, "\t ");
+ if (mkey == NULL) {
+ fprintf(stderr,
+ "Bad record in %s -- %s", NETIDFILE, buf);
+ continue;
+ }
+ mval = strtok(NULL, " \t#\n");
+ if (mval == NULL) {
+ fprintf(stderr,
+ "Bad record in %s val problem - %s", NETIDFILE, buf);
+ continue;
+ }
+ if (strcmp(mkey, key) == 0) {
+ strcpy(ret, mval);
+ fclose(fd);
+ return (1);
+
+ }
+ }
+ }
+}
diff --git a/librpc/src/rpc/pmap_clnt.c b/librpc/src/rpc/pmap_clnt.c
new file mode 100644
index 0000000..7aab450
--- /dev/null
+++ b/librpc/src/rpc/pmap_clnt.c
@@ -0,0 +1,153 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)pmap_clnt.c 1.37 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)pmap_clnt.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/pmap_clnt.c,v 1.11 2000/01/27 23:06:39 jasone Exp $";
+#endif
+
+/*
+ * pmap_clnt.c
+ * Client interface to pmap rpc service.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#include <netinet/in.h>
+
+static struct timeval timeout = { 5, 0 };
+static struct timeval tottimeout = { 60, 0 };
+
+#ifndef PORTMAPSOCK
+#define PORTMAPSOCK "/var/run/portmapsock"
+#endif
+
+/*
+ * Set a mapping between program,version and port.
+ * Calls the pmap service remotely to do the mapping.
+ */
+bool_t
+pmap_set(
+ u_long program,
+ u_long version,
+ int protocol,
+ int port) /* was u_short but changed to match prototype */
+{
+ struct sockaddr_in myaddress;
+ int socket = -1;
+ CLIENT *client;
+ struct pmap parms;
+ bool_t rslt;
+ struct stat st;
+
+ /*
+ * Temporary hack for backwards compatibility. Eventually
+ * this test will go away and we'll use only the "unix" transport.
+ */
+ if (stat(PORTMAPSOCK, &st) == 0 && st.st_mode & S_IFSOCK)
+ client = clnt_create(PORTMAPSOCK, PMAPPROG, PMAPVERS, "unix");
+ else {
+ if (get_myaddress(&myaddress) != 0)
+ return (FALSE);
+ myaddress.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS,
+ timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
+ }
+
+ if (client == (CLIENT *)NULL)
+ return (FALSE);
+ parms.pm_prog = program;
+ parms.pm_vers = version;
+ parms.pm_prot = protocol;
+ parms.pm_port = port;
+ if (CLNT_CALL(client, PMAPPROC_SET, (xdrproc_t)xdr_pmap, &parms, (xdrproc_t)xdr_bool, &rslt,
+ tottimeout) != RPC_SUCCESS) {
+ clnt_perror(client, "Cannot register service");
+ return (FALSE);
+ }
+ CLNT_DESTROY(client);
+ if (socket != -1)
+ (void)_RPC_close(socket);
+ return (rslt);
+}
+
+/*
+ * Remove the mapping between program, version and port.
+ * Calls the pmap service remotely to do the un-mapping.
+ */
+bool_t
+pmap_unset(
+ u_long program,
+ u_long version)
+{
+ struct sockaddr_in myaddress;
+ int socket = -1;
+ register CLIENT *client;
+ struct pmap parms;
+ bool_t rslt;
+ struct stat st;
+
+ /*
+ * Temporary hack for backwards compatibility. Eventually
+ * this test will go away and we'll use only the "unix" transport.
+ */
+ if (stat(PORTMAPSOCK, &st) == 0 && st.st_mode & S_IFSOCK)
+ client = clnt_create(PORTMAPSOCK, PMAPPROG, PMAPVERS, "unix");
+ else {
+ if (get_myaddress(&myaddress) != 0)
+ return (FALSE);
+ myaddress.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS,
+ timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
+ }
+ if (client == (CLIENT *)NULL)
+ return (FALSE);
+ parms.pm_prog = program;
+ parms.pm_vers = version;
+ parms.pm_port = parms.pm_prot = 0;
+ CLNT_CALL(client, PMAPPROC_UNSET, (xdrproc_t)xdr_pmap, &parms, (xdrproc_t)xdr_bool, &rslt,
+ tottimeout);
+ CLNT_DESTROY(client);
+ if (socket != -1)
+ (void)_RPC_close(socket);
+ return (rslt);
+}
diff --git a/librpc/src/rpc/pmap_getmaps.c b/librpc/src/rpc/pmap_getmaps.c
new file mode 100644
index 0000000..1645c5d
--- /dev/null
+++ b/librpc/src/rpc/pmap_getmaps.c
@@ -0,0 +1,93 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)pmap_getmaps.c 1.10 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)pmap_getmaps.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/pmap_getmaps.c,v 1.11 2000/01/27 23:06:39 jasone Exp $";
+#endif
+
+/*
+ * pmap_getmap.c
+ * Client interface to pmap rpc service.
+ * contains pmap_getmaps, which is only tcp service involved
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#define NAMELEN 255
+#define MAX_BROADCAST_SIZE 1400
+
+/*
+ * Get a copy of the current port maps.
+ * Calls the pmap service remotely to do get the maps.
+ */
+struct pmaplist *
+pmap_getmaps(struct sockaddr_in *address)
+{
+ struct pmaplist *head = NULL;
+ int socket = -1;
+ struct timeval minutetimeout;
+ CLIENT *client;
+
+ minutetimeout.tv_sec = 60;
+ minutetimeout.tv_usec = 0;
+ address->sin_port = htons(PMAPPORT);
+ client = clnttcp_create(address, PMAPPROG,
+ PMAPVERS, &socket, 50, 500);
+ if (client != NULL) {
+ if (CLNT_CALL(client, (rpcproc_t)PMAPPROC_DUMP,
+ (xdrproc_t)xdr_void, NULL,
+ (xdrproc_t)xdr_pmaplist, &head, minutetimeout) !=
+ RPC_SUCCESS) {
+ clnt_perror(client, "pmap_getmaps rpc problem");
+ }
+ CLNT_DESTROY(client);
+ }
+ if (socket != -1)
+ (void)_RPC_close(socket);
+ address->sin_port = 0;
+ return (head);
+}
diff --git a/librpc/src/rpc/pmap_getport.c b/librpc/src/rpc/pmap_getport.c
new file mode 100644
index 0000000..9a28937
--- /dev/null
+++ b/librpc/src/rpc/pmap_getport.c
@@ -0,0 +1,99 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)pmap_getport.c 1.9 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)pmap_getport.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/pmap_getport.c,v 1.10 2000/01/27 23:06:40 jasone Exp $";
+#endif
+
+/*
+ * pmap_getport.c
+ * Client interface to pmap rpc service.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <unistd.h>
+
+static const struct timeval timeout = { 5, 0 };
+static const struct timeval tottimeout = { 60, 0 };
+
+/*
+ * Find the mapped port for program,version.
+ * Calls the pmap service remotely to do the lookup.
+ * Returns 0 if no map exists.
+ */
+u_short
+pmap_getport(
+ struct sockaddr_in *address,
+ u_long program,
+ u_long version,
+ u_int protocol )
+{
+ u_short port = 0;
+ int socket = -1;
+ CLIENT *client;
+ struct pmap parms;
+
+ address->sin_port = htons(PMAPPORT);
+ client = clntudp_bufcreate(address, PMAPPROG,
+ PMAPVERS, timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
+ if (client != NULL) {
+ parms.pm_prog = program;
+ parms.pm_vers = version;
+ parms.pm_prot = protocol;
+ parms.pm_port = 0; /* not needed or used */
+ if (CLNT_CALL(client, (rpcproc_t)PMAPPROC_GETPORT,
+ (xdrproc_t)xdr_pmap,
+ &parms, (xdrproc_t)xdr_u_short, &port, tottimeout) !=
+ RPC_SUCCESS){
+ rpc_createerr.cf_stat = RPC_PMAPFAILURE;
+ clnt_geterr(client, &rpc_createerr.cf_error);
+ } else if (port == 0) {
+ rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
+ }
+ CLNT_DESTROY(client);
+ }
+ if (socket != -1)
+ (void)_RPC_close(socket);
+ address->sin_port = 0;
+ return (port);
+}
diff --git a/librpc/src/rpc/pmap_prot.c b/librpc/src/rpc/pmap_prot.c
new file mode 100644
index 0000000..33b0d0d
--- /dev/null
+++ b/librpc/src/rpc/pmap_prot.c
@@ -0,0 +1,65 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)pmap_prot.c 1.17 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)pmap_prot.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/pmap_prot.c,v 1.6 1999/08/28 00:00:42 peter Exp $";
+#endif
+
+/*
+ * pmap_prot.c
+ * Protocol for the local binder service, or pmap.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/pmap_prot.h>
+
+
+bool_t
+xdr_pmap(
+ XDR *xdrs,
+ struct pmap *regs)
+{
+
+ if (xdr_u_long(xdrs, &regs->pm_prog) &&
+ xdr_u_long(xdrs, &regs->pm_vers) &&
+ xdr_u_long(xdrs, &regs->pm_prot))
+ return (xdr_u_long(xdrs, &regs->pm_port));
+ return (FALSE);
+}
diff --git a/librpc/src/rpc/pmap_prot2.c b/librpc/src/rpc/pmap_prot2.c
new file mode 100644
index 0000000..c61eab5
--- /dev/null
+++ b/librpc/src/rpc/pmap_prot2.c
@@ -0,0 +1,124 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)pmap_prot2.c 1.3 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)pmap_prot2.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/pmap_prot2.c,v 1.7 1999/08/28 00:00:42 peter Exp $";
+#endif
+
+/*
+ * pmap_prot2.c
+ * Protocol for the local binder service, or pmap.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/pmap_prot.h>
+
+
+/*
+ * What is going on with linked lists? (!)
+ * First recall the link list declaration from pmap_prot.h:
+ *
+ * struct pmaplist {
+ * struct pmap pml_map;
+ * struct pmaplist *pml_map;
+ * };
+ *
+ * Compare that declaration with a corresponding xdr declaration that
+ * is (a) pointer-less, and (b) recursive:
+ *
+ * typedef union switch (bool_t) {
+ *
+ * case TRUE: struct {
+ * struct pmap;
+ * pmaplist_t foo;
+ * };
+ *
+ * case FALSE: struct {};
+ * } pmaplist_t;
+ *
+ * Notice that the xdr declaration has no nxt pointer while
+ * the C declaration has no bool_t variable. The bool_t can be
+ * interpreted as ``more data follows me''; if FALSE then nothing
+ * follows this bool_t; if TRUE then the bool_t is followed by
+ * an actual struct pmap, and then (recursively) by the
+ * xdr union, pamplist_t.
+ *
+ * This could be implemented via the xdr_union primitive, though this
+ * would cause a one recursive call per element in the list. Rather than do
+ * that we can ``unwind'' the recursion
+ * into a while loop and do the union arms in-place.
+ *
+ * The head of the list is what the C programmer wishes to past around
+ * the net, yet is the data that the pointer points to which is interesting;
+ * this sounds like a job for xdr_reference!
+ */
+bool_t
+xdr_pmaplist(
+ XDR *xdrs,
+ struct pmaplist **rp)
+{
+ /*
+ * more_elements is pre-computed in case the direction is
+ * XDR_ENCODE or XDR_FREE. more_elements is overwritten by
+ * xdr_bool when the direction is XDR_DECODE.
+ */
+ bool_t more_elements;
+ register int freeing = (xdrs->x_op == XDR_FREE);
+ register struct pmaplist **next = NULL;
+
+ while (TRUE) {
+ more_elements = (bool_t)(*rp != NULL);
+ if (! xdr_bool(xdrs, &more_elements))
+ return (FALSE);
+ if (! more_elements)
+ return (TRUE); /* we are done */
+ /*
+ * the unfortunate side effect of non-recursion is that in
+ * the case of freeing we must remember the next object
+ * before we free the current object ...
+ */
+ if (freeing)
+ next = &((*rp)->pml_next);
+ if (! xdr_reference(xdrs, (caddr_t *)rp,
+ (u_int)sizeof(struct pmaplist), (xdrproc_t) xdr_pmap))
+ return (FALSE);
+ rp = (freeing) ? next : &((*rp)->pml_next);
+ }
+}
diff --git a/librpc/src/rpc/pmap_rmt.c b/librpc/src/rpc/pmap_rmt.c
new file mode 100644
index 0000000..5576c87
--- /dev/null
+++ b/librpc/src/rpc/pmap_rmt.c
@@ -0,0 +1,444 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)pmap_rmt.c 1.21 87/08/27 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)pmap_rmt.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/pmap_rmt.c,v 1.15 2000/01/27 23:06:40 jasone Exp $";
+#endif
+
+/*
+ * pmap_rmt.c
+ * Client interface to pmap rpc service.
+ * remote call and broadcast service
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/ioctl.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#include <rpc/pmap_rmt.h>
+
+#include <stdlib.h>
+#include <sys/select.h>
+
+#define MAX_BROADCAST_SIZE 1400
+
+static const struct timeval timeout = { 3, 0 };
+
+/*
+ * pmapper remote-call-service interface.
+ * This routine is used to call the pmapper remote call service
+ * which will look up a service program in the port maps, and then
+ * remotely call that routine with the given parameters. This allows
+ * programs to do a lookup and call in one step.
+*/
+enum clnt_stat
+pmap_rmtcall(
+ struct sockaddr_in *addr,
+ u_long prog,
+ u_long vers,
+ u_long proc,
+ xdrproc_t xdrargs,
+ caddr_t argsp,
+ xdrproc_t xdrres,
+ caddr_t resp,
+ struct timeval tout,
+ u_long *port_ptr)
+{
+ int sock = -1;
+ CLIENT *client;
+ struct rmtcallargs a;
+ struct rmtcallres r;
+ enum clnt_stat stat;
+
+ assert(addr != NULL);
+ assert(port_ptr != NULL);
+
+ addr->sin_port = htons(PMAPPORT);
+ client = clntudp_create(addr, PMAPPROG, PMAPVERS, timeout, &sock);
+ if (client != NULL) {
+ a.prog = prog;
+ a.vers = vers;
+ a.proc = proc;
+ a.args_ptr = argsp;
+ a.xdr_args = xdrargs;
+ r.port_ptr = port_ptr;
+ r.results_ptr = resp;
+ r.xdr_results = xdrres;
+ stat = CLNT_CALL(client, (rpcproc_t)PMAPPROC_CALLIT,
+ (xdrproc_t)xdr_rmtcall_args, &a, (xdrproc_t)xdr_rmtcallres,
+ &r, tout);
+ CLNT_DESTROY(client);
+ } else {
+ stat = RPC_FAILED;
+ }
+ if (sock != -1)
+ (void)_RPC_close(sock);
+ addr->sin_port = 0;
+ return (stat);
+}
+
+
+/*
+ * XDR remote call arguments
+ * written for XDR_ENCODE direction only
+ */
+bool_t
+xdr_rmtcall_args(
+ XDR *xdrs,
+ struct rmtcallargs *cap)
+{
+ u_int lenposition, argposition, position;
+
+ assert(xdrs != NULL);
+ assert(cap != NULL);
+
+ if (xdr_u_long(xdrs, &(cap->prog)) &&
+ xdr_u_long(xdrs, &(cap->vers)) &&
+ xdr_u_long(xdrs, &(cap->proc))) {
+ lenposition = XDR_GETPOS(xdrs);
+ if (! xdr_u_long(xdrs, &(cap->arglen)))
+ return (FALSE);
+ argposition = XDR_GETPOS(xdrs);
+ if (! (*(cap->xdr_args))(xdrs, cap->args_ptr))
+ return (FALSE);
+ position = XDR_GETPOS(xdrs);
+ cap->arglen = (u_long)position - (u_long)argposition;
+ XDR_SETPOS(xdrs, lenposition);
+ if (! xdr_u_long(xdrs, &(cap->arglen)))
+ return (FALSE);
+ XDR_SETPOS(xdrs, position);
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
+/*
+ * XDR remote call results
+ * written for XDR_DECODE direction only
+ */
+bool_t
+xdr_rmtcallres(
+ XDR *xdrs,
+ struct rmtcallres *crp)
+{
+ caddr_t port_ptr;
+
+ assert(xdrs != NULL);
+ assert(crp != NULL);
+
+ port_ptr = (caddr_t)(void *)crp->port_ptr;
+ if (xdr_reference(xdrs, &port_ptr, sizeof (u_long),
+ (xdrproc_t)xdr_u_long) && xdr_u_long(xdrs, &crp->resultslen)) {
+ crp->port_ptr = (u_long *)(void *)port_ptr;
+ return ((*(crp->xdr_results))(xdrs, crp->results_ptr));
+ }
+ return (FALSE);
+}
+
+
+/*
+ * The following is kludged-up support for simple rpc broadcasts.
+ * Someday a large, complicated system will replace these trivial
+ * routines which only support udp/ip .
+ */
+
+static int
+getbroadcastnets(
+ struct in_addr *addrs,
+ int sock, /* any valid socket will do */
+ char *buf /* why allocxate more when we can use existing... */ )
+{
+ struct ifconf ifc;
+ struct ifreq ifreq, *ifr;
+ struct sockaddr_in *sin;
+ struct in_addr addr;
+ char *cp, *cplim;
+ int n, i = 0;
+
+ ifc.ifc_len = UDPMSGSIZE;
+ ifc.ifc_buf = buf;
+ if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
+ perror("broadcast: ioctl (get interface configuration)");
+ return (0);
+ }
+#define max(a, b) (a > b ? a : b)
+#define size(p) max((p).sa_len, sizeof(p))
+ cplim = buf + ifc.ifc_len; /*skip over if's with big ifr_addr's */
+ for (cp = buf; cp < cplim;
+ cp += sizeof (ifr->ifr_name) + size(ifr->ifr_addr)) {
+ ifr = (struct ifreq *)cp;
+ if (ifr->ifr_addr.sa_family != AF_INET)
+ continue;
+ ifreq = *ifr;
+ if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
+ perror("broadcast: ioctl (get interface flags)");
+ continue;
+ }
+ if ((ifreq.ifr_flags & IFF_BROADCAST) &&
+ (ifreq.ifr_flags & IFF_UP)) {
+ sin = (struct sockaddr_in *)&ifr->ifr_addr;
+#ifdef SIOCGIFBRDADDR /* 4.3BSD */
+ if (ioctl(sock, SIOCGIFBRDADDR, (char *)&ifreq) < 0) {
+ addr =
+ inet_makeaddr(inet_netof(sin->sin_addr),
+ INADDR_ANY);
+ } else {
+ addr = ((struct sockaddr_in*)
+ &ifreq.ifr_addr)->sin_addr;
+ }
+#else /* 4.2 BSD */
+ addr = inet_makeaddr(inet_netof(sin->sin_addr),
+ INADDR_ANY);
+#endif
+ for (n=i-1; n>=0; n--) {
+ if (addr.s_addr == addrs[n].s_addr)
+ break;
+ }
+ if (n<0) {
+ addrs[i++] = addr;
+ }
+ }
+ }
+ return (i);
+}
+
+typedef bool_t (*resultproc_t)(caddr_t, struct sockaddr_in *);
+
+enum clnt_stat
+clnt_broadcast(
+ u_long prog, /* program number */
+ u_long vers, /* version number */
+ u_long proc, /* procedure number */
+ xdrproc_t xargs, /* xdr routine for args */
+ caddr_t argsp, /* pointer to args */
+ xdrproc_t xresults, /* xdr routine for results */
+ caddr_t resultsp, /* pointer to results */
+ resultproc_t eachresult /* call with each result obtained */ )
+{
+ enum clnt_stat stat = RPC_SUCCESS; /* to avoid warning */
+ AUTH *unix_auth = authunix_create_default();
+ XDR xdr_stream;
+ register XDR *xdrs = &xdr_stream;
+ int outlen, inlen, nets;
+ socklen_t fromlen;
+ register int sock;
+ int on = 1;
+ fd_set *fds = 0, readfds; /* initialized to avoid warning */
+ register int i;
+ bool_t done = FALSE;
+ register u_long xid;
+ u_long port;
+ struct in_addr addrs[20];
+ struct sockaddr_in baddr, raddr; /* broadcast and response addresses */
+ struct rmtcallargs a;
+ struct rmtcallres r;
+ struct rpc_msg msg;
+ struct timeval t, tv;
+ char outbuf[MAX_BROADCAST_SIZE], inbuf[UDPMSGSIZE];
+ static uintptr_t disrupt;
+
+ if (disrupt == 0)
+ disrupt = (uintptr_t) resultsp;
+
+ /*
+ * initialization: create a socket, a broadcast address, and
+ * preserialize the arguments into a send buffer.
+ */
+ if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
+ perror("Cannot create socket for broadcast rpc");
+ stat = RPC_CANTSEND;
+ goto done_broad;
+ }
+#ifdef SO_BROADCAST
+ if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
+ perror("Cannot set socket option SO_BROADCAST");
+ stat = RPC_CANTSEND;
+ goto done_broad;
+ }
+#endif /* def SO_BROADCAST */
+ if (sock + 1 > FD_SETSIZE) {
+ int bytes = howmany(sock + 1, NFDBITS) * sizeof(fd_mask);
+ fds = (fd_set *)malloc(bytes);
+ if (fds == NULL) {
+ stat = RPC_CANTSEND;
+ goto done_broad;
+ }
+ memset(fds, 0, bytes);
+ } else {
+ fds = &readfds;
+ FD_ZERO(fds);
+ }
+
+ nets = getbroadcastnets(addrs, sock, inbuf);
+ memset(&baddr, 0, sizeof (baddr));
+ baddr.sin_len = sizeof(struct sockaddr_in);
+ baddr.sin_family = AF_INET;
+ baddr.sin_port = htons(PMAPPORT);
+ baddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ (void)gettimeofday(&t, (struct timezone *)0);
+ msg.rm_xid = xid = (++disrupt) ^ getpid() ^ t.tv_sec ^ t.tv_usec;
+ t.tv_usec = 0;
+ msg.rm_direction = CALL;
+ msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
+ msg.rm_call.cb_prog = PMAPPROG;
+ msg.rm_call.cb_vers = PMAPVERS;
+ msg.rm_call.cb_proc = PMAPPROC_CALLIT;
+ msg.rm_call.cb_cred = unix_auth->ah_cred;
+ msg.rm_call.cb_verf = unix_auth->ah_verf;
+ a.prog = prog;
+ a.vers = vers;
+ a.proc = proc;
+ a.xdr_args = xargs;
+ a.args_ptr = argsp;
+ r.port_ptr = &port;
+ r.xdr_results = xresults;
+ r.results_ptr = resultsp;
+ xdrmem_create(xdrs, outbuf, MAX_BROADCAST_SIZE, XDR_ENCODE);
+ if ((! xdr_callmsg(xdrs, &msg)) || (! xdr_rmtcall_args(xdrs, &a))) {
+ stat = RPC_CANTENCODEARGS;
+ goto done_broad;
+ }
+ outlen = (int)xdr_getpos(xdrs);
+ xdr_destroy(xdrs);
+ /*
+ * Basic loop: broadcast a packet and wait a while for response(s).
+ * The response timeout grows larger per iteration.
+ *
+ * XXX This will loop about 5 times the stop. If there are
+ * lots of signals being received by the process it will quit
+ * send them all in one quick burst, not paying attention to
+ * the intended function of sending them slowly over half a
+ * minute or so
+ */
+ for (t.tv_sec = 4; t.tv_sec <= 14; t.tv_sec += 2) {
+ for (i = 0; i < nets; i++) {
+ baddr.sin_addr = addrs[i];
+ if (sendto(sock, outbuf, outlen, 0,
+ (struct sockaddr *)&baddr,
+ sizeof (struct sockaddr)) != outlen) {
+ perror("Cannot send broadcast packet");
+ stat = RPC_CANTSEND;
+ goto done_broad;
+ }
+ }
+ if (eachresult == NULL) {
+ stat = RPC_SUCCESS;
+ goto done_broad;
+ }
+ recv_again:
+ msg.acpted_rply.ar_verf = _null_auth;
+ msg.acpted_rply.ar_results.where = (caddr_t)&r;
+ msg.acpted_rply.ar_results.proc = (xdrproc_t) xdr_rmtcallres;
+ /* XXX we know the other bits are still clear */
+ FD_SET(sock, fds);
+ tv = t; /* for select() that copies back */
+ switch (select(sock + 1, fds, NULL, NULL, &tv)) {
+
+ case 0: /* timed out */
+ stat = RPC_TIMEDOUT;
+ continue;
+
+ case -1: /* some kind of error */
+ if (errno == EINTR)
+ goto recv_again;
+ perror("Broadcast select problem");
+ stat = RPC_CANTRECV;
+ goto done_broad;
+
+ } /* end of select results switch */
+ try_again:
+ fromlen = sizeof(struct sockaddr);
+ inlen = recvfrom(sock, inbuf, UDPMSGSIZE, 0,
+ (struct sockaddr *)&raddr, &fromlen);
+ if (inlen < 0) {
+ if (errno == EINTR)
+ goto try_again;
+ perror("Cannot receive reply to broadcast");
+ stat = RPC_CANTRECV;
+ goto done_broad;
+ }
+ if (inlen < sizeof(u_int32_t))
+ goto recv_again;
+ /*
+ * see if reply transaction id matches sent id.
+ * If so, decode the results.
+ */
+ xdrmem_create(xdrs, inbuf, (u_int)inlen, XDR_DECODE);
+ if (xdr_replymsg(xdrs, &msg)) {
+ if ((msg.rm_xid == xid) &&
+ (msg.rm_reply.rp_stat == MSG_ACCEPTED) &&
+ (msg.acpted_rply.ar_stat == SUCCESS)) {
+ raddr.sin_port = htons((u_short)port);
+ done = (*eachresult)(resultsp, &raddr);
+ }
+ /* otherwise, we just ignore the errors ... */
+ }
+ xdrs->x_op = XDR_FREE;
+ msg.acpted_rply.ar_results.proc = (xdrproc_t) xdr_void;
+ (void)xdr_replymsg(xdrs, &msg);
+ (void)(*xresults)(xdrs, resultsp);
+ xdr_destroy(xdrs);
+ if (done) {
+ stat = RPC_SUCCESS;
+ goto done_broad;
+ } else {
+ goto recv_again;
+ }
+ }
+done_broad:
+ if (fds != &readfds)
+ free(fds);
+ if (sock >= 0)
+ (void)_RPC_close(sock);
+ AUTH_DESTROY(unix_auth);
+ return (stat);
+}
diff --git a/librpc/src/rpc/publickey.3 b/librpc/src/rpc/publickey.3
new file mode 100644
index 0000000..29094f9
--- /dev/null
+++ b/librpc/src/rpc/publickey.3
@@ -0,0 +1,47 @@
+.\" @(#)publickey.3r 2.1 88/08/07 4.0 RPCSRC
+.\" $FreeBSD: src/lib/libc/rpc/publickey.3,v 1.4 2000/03/02 09:13:46 sheldonh Exp $
+.\"
+.TH PUBLICKEY 3R "6 October 1987"
+.SH NAME
+publickey, getpublickey, getsecretkey \- get public or secret key
+.SH SYNOPSIS
+.nf
+.B #include <rpc/rpc.h>
+.B #include <rpc/key_prot.h>
+.LP
+.B getpublickey(netname, publickey)
+.B char netname[\s-1MAXNETNAMELEN\s0+1];
+.B char publickey[\s-1HEXKEYBYTES\s0+1];
+.LP
+.B getsecretkey(netname, secretkey, passwd)
+.B char netname[\s-1MAXNETNAMELEN\s0+1];
+.B char secretkey[\s-1HEXKEYBYTES\s0+1];
+.B char *passwd;
+.fi
+.SH DESCRIPTION
+.IX "getpublickey function" "" "\fLgetpublickey()\fP function"
+.IX "getsecretkey function" "" "\fLgetsecretkey()\fP function"
+These routines are used to get public and secret keys from the
+.SM YP
+database.
+.B getsecretkey(\|)
+has an extra argument,
+.IR passwd ,
+which is used to decrypt the encrypted secret key stored in the database.
+Both routines return 1 if they are successful in finding the key, 0 otherwise.
+The keys are returned as
+.SM NULL\s0-terminated,
+hexadecimal strings.
+If the password supplied to
+.B getsecretkey(\|)
+fails to decrypt the secret key, the routine will return 1 but the
+.I secretkey
+argument will be a
+.SM NULL
+string (``'').
+.SH "SEE ALSO"
+.BR publickey (5)
+.LP
+.I \s-1RPC\s0 Programmer's Manual
+in
+.TX NETP
diff --git a/librpc/src/rpc/publickey.5 b/librpc/src/rpc/publickey.5
new file mode 100644
index 0000000..9f7a325
--- /dev/null
+++ b/librpc/src/rpc/publickey.5
@@ -0,0 +1,38 @@
+.\" $FreeBSD: src/lib/libc/rpc/publickey.5,v 1.5 2000/03/02 09:13:46 sheldonh Exp $
+.\" @(#)publickey.5 2.1 88/08/07 4.0 RPCSRC; from 1.6 88/02/29 SMI;
+.TH PUBLICKEY 5 "19 October 1987"
+.SH NAME
+publickey \- public key database
+.SH SYNOPSIS
+.B /etc/publickey
+.SH DESCRIPTION
+.LP
+.B /etc/publickey
+is the public key database used for secure
+networking.
+Each entry in
+the database consists of a network user
+name (which may either refer to
+a user or a hostname), followed by the user's
+public key (in hex
+notation), a colon, and then the user's
+secret key encrypted with
+its login password (also in hex notation).
+.LP
+This file is altered either by the user through the
+.BR chkey (1)
+command or by the system administrator through the
+.BR newkey (8)
+command.
+The file
+.B /etc/publickey
+should only contain data on the NIS master machine, where it
+is converted into the
+.SM NIS
+database
+.BR publickey.byname .
+.SH SEE ALSO
+.BR chkey (1),
+.BR publickey (3R),
+.BR newkey (8),
+.BR ypupdated (8C)
diff --git a/librpc/src/rpc/rpc.3 b/librpc/src/rpc/rpc.3
new file mode 100644
index 0000000..f40b643
--- /dev/null
+++ b/librpc/src/rpc/rpc.3
@@ -0,0 +1,1767 @@
+.\" @(#)rpc.3n 2.4 88/08/08 4.0 RPCSRC; from 1.19 88/06/24 SMI
+.\" $FreeBSD: src/lib/libc/rpc/rpc.3,v 1.11 2000/03/02 09:13:47 sheldonh Exp $
+.\"
+.TH RPC 3 "16 February 1988"
+.SH NAME
+rpc \- library routines for remote procedure calls
+.SH SYNOPSIS AND DESCRIPTION
+These routines allow C programs to make procedure
+calls on other machines across the network.
+First, the client calls a procedure to send a
+data packet to the server.
+Upon receipt of the packet, the server calls a dispatch routine
+to perform the requested service, and then sends back a
+reply.
+Finally, the procedure call returns to the client.
+.LP
+Routines that are used for Secure RPC (DES authentication) are described in
+.BR rpc_secure (3).
+Secure RPC can be used only if DES encryption is available.
+.LP
+.ft B
+.nf
+.sp .5
+#include <rpc/rpc.h>
+.fi
+.ft R
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+void
+auth_destroy(auth)
+\s-1AUTH\s0 *auth;
+.fi
+.ft R
+.IP
+A macro that destroys the authentication information associated with
+.IR auth .
+Destruction usually involves deallocation of private data
+structures.
+The use of
+.I auth
+is undefined after calling
+.BR auth_destroy(\|) .
+.br
+.if t .ne 6
+.LP
+.ft B
+.nf
+.sp .5
+\s-1AUTH\s0 *
+authnone_create(\|)
+.fi
+.ft R
+.IP
+Create and returns an
+.SM RPC
+authentication handle that passes nonusable authentication
+information with each remote procedure call.
+This is the
+default authentication used by
+.SM RPC.
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+\s-1AUTH\s0 *
+authunix_create(host, uid, gid, len, aup_gids)
+char *host;
+int uid, gid, len, *aup.gids;
+.fi
+.ft R
+.IP
+Create and return an
+.SM RPC
+authentication handle that contains
+.UX
+authentication information.
+The parameter
+.I host
+is the name of the machine on which the information was
+created;
+.I uid
+is the user's user
+.SM ID ;
+.I gid
+is the user's current group
+.SM ID ;
+.I len
+and
+.I aup_gids
+refer to a counted array of groups to which the user belongs.
+It is easy to impersonate a user.
+.br
+.if t .ne 5
+.LP
+.ft B
+.nf
+.sp .5
+\s-1AUTH\s0 *
+authunix_create_default(\|)
+.fi
+.ft R
+.IP
+Calls
+.B authunix_create(\|)
+with the appropriate parameters.
+.br
+.if t .ne 13
+.LP
+.ft B
+.nf
+.sp .5
+callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out)
+char *host;
+u_long prognum, versnum, procnum;
+char *in, *out;
+xdrproc_t inproc, outproc;
+.fi
+.ft R
+.IP
+Call the remote procedure associated with
+.IR prognum ,
+.IR versnum ,
+and
+.I procnum
+on the machine,
+.IR host .
+The parameter
+.I in
+is the address of the procedure's argument(s), and
+.I out
+is the address of where to place the result(s);
+.I inproc
+is used to encode the procedure's parameters, and
+.I outproc
+is used to decode the procedure's results.
+This routine returns zero if it succeeds, or the value of
+.B "enum clnt_stat"
+cast to an integer if it fails.
+The routine
+.B clnt_perrno(\|)
+is handy for translating failure statuses into messages.
+.IP
+Warning: calling remote procedures with this routine
+uses
+.SM UDP/IP
+as a transport; see
+.B clntudp_create(\|)
+for restrictions.
+You do not have control of timeouts or authentication using
+this routine.
+.br
+.if t .ne 16
+.LP
+.ft B
+.nf
+.sp .5
+enum clnt_stat
+clnt_broadcast(prognum, versnum, procnum, inproc, in, outproc, out, eachresult)
+u_long prognum, versnum, procnum;
+char *in, *out;
+xdrproc_t inproc, outproc;
+resultproc_t eachresult;
+.fi
+.ft R
+.IP
+Like
+.BR callrpc(\|) ,
+except the call message is broadcast to all locally
+connected broadcast nets.
+Each time it receives a
+response, this routine calls
+.BR eachresult(\|) ,
+whose form is:
+.IP
+.RS 1i
+.ft B
+.nf
+eachresult(out, addr)
+char *out;
+struct sockaddr_in *addr;
+.ft R
+.fi
+.RE
+.IP
+where
+.I out
+is the same as
+.I out
+passed to
+.BR clnt_broadcast(\|) ,
+except that the remote procedure's output is decoded there;
+.I addr
+points to the address of the machine that sent the results.
+If
+.B eachresult(\|)
+returns zero,
+.B clnt_broadcast(\|)
+waits for more replies; otherwise it returns with appropriate
+status.
+.IP
+Warning: broadcast sockets are limited in size to the
+maximum transfer unit of the data link.
+For ethernet,
+this value is 1500 bytes.
+.br
+.if t .ne 13
+.LP
+.ft B
+.nf
+.sp .5
+enum clnt_stat
+clnt_call(clnt, procnum, inproc, in, outproc, out, tout)
+\s-1CLIENT\s0 *clnt;
+u_long
+procnum;
+xdrproc_t inproc, outproc;
+char *in, *out;
+struct timeval tout;
+.fi
+.ft R
+.IP
+A macro that calls the remote procedure
+.I procnum
+associated with the client handle,
+.IR clnt ,
+which is obtained with an
+.SM RPC
+client creation routine such as
+.BR clnt_create(\|) .
+The parameter
+.I in
+is the address of the procedure's argument(s), and
+.I out
+is the address of where to place the result(s);
+.I inproc
+is used to encode the procedure's parameters, and
+.I outproc
+is used to decode the procedure's results;
+.I tout
+is the time allowed for results to come back.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+clnt_destroy(clnt)
+\s-1CLIENT\s0 *clnt;
+.fi
+.ft R
+.IP
+A macro that destroys the client's
+.SM RPC
+handle.
+Destruction usually involves deallocation
+of private data structures, including
+.I clnt
+itself. Use of
+.I clnt
+is undefined after calling
+.BR clnt_destroy(\|) .
+If the
+.SM RPC
+library opened the associated socket, it will close it also.
+Otherwise, the socket remains open.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+\s-1CLIENT\s0 *
+clnt_create(host, prog, vers, proto)
+char *host;
+u_long prog, vers;
+char *proto;
+.fi
+.ft R
+.IP
+Generic client creation routine.
+.I host
+identifies the name of the remote host where the server
+is located.
+.I proto
+indicates which kind of transport protocol to use.
+The
+currently supported values for this field are \(lqudp\(rq
+and \(lqtcp\(rq.
+Default timeouts are set, but can be modified using
+.BR clnt_control(\|) .
+.IP
+Warning: Using
+.SM UDP
+has its shortcomings. Since
+.SM UDP\s0-based
+.SM RPC
+messages can only hold up to 8 Kbytes of encoded data,
+this transport cannot be used for procedures that take
+large arguments or return huge results.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+bool_t
+clnt_control(cl, req, info)
+\s-1CLIENT\s0 *cl;
+u_int req;
+char *info;
+.fi
+.ft R
+.IP
+A macro used to change or retrieve various information
+about a client object.
+.I req
+indicates the type of operation, and
+.I info
+is a pointer to the information.
+For both
+.SM UDP
+and
+.SM TCP\s0,
+the supported values of
+.I req
+and their argument types and what they do are:
+.IP
+.nf
+.ta +2.0i +2.0i +2.0i
+.SM CLSET_TIMEOUT\s0 struct timeval set total timeout
+.SM CLGET_TIMEOUT\s0 struct timeval get total timeout
+.fi
+.IP
+Note: if you set the timeout using
+.BR clnt_control(\|) ,
+the timeout parameter passed to
+.B clnt_call(\|)
+will be ignored in all future calls.
+.IP
+.nf
+.SM CLGET_SERVER_ADDR\s0 struct sockaddr_in get server's address
+.fi
+.br
+.IP
+The following operations are valid for
+.SM UDP
+only:
+.IP
+.nf
+.ta +2.0i ; +2.0i ; +2.0i
+.SM CLSET_RETRY_TIMEOUT\s0 struct timeval set the retry timeout
+.SM CLGET_RETRY_TIMEOUT\s0 struct timeval get the retry timeout
+.fi
+.br
+.IP
+The retry timeout is the time that
+.SM "UDP RPC"
+waits for the server to reply before
+retransmitting the request.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+clnt_freeres(clnt, outproc, out)
+\s-1CLIENT\s0 *clnt;
+xdrproc_t outproc;
+char *out;
+.fi
+.ft R
+.IP
+A macro that frees any data allocated by the
+.SM RPC/XDR
+system when it decoded the results of an
+.SM RPC
+call. The
+parameter
+.I out
+is the address of the results, and
+.I outproc
+is the
+.SM XDR
+routine describing the results.
+This routine returns one if the results were successfully
+freed,
+and zero otherwise.
+.br
+.if t .ne 6
+.LP
+.ft B
+.nf
+.sp .5
+void
+clnt_geterr(clnt, errp)
+\s-1CLIENT\s0 *clnt;
+struct rpc_err *errp;
+.fi
+.ft R
+.IP
+A macro that copies the error structure out of the client
+handle
+to the structure at address
+.IR errp .
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+void
+clnt_pcreateerror(s)
+char *s;
+.fi
+.ft R
+.IP
+Print a message to standard error indicating
+why a client
+.SM RPC
+handle could not be created.
+The message is prepended with string
+.I s
+and a colon.
+Used when a
+.BR clnt_create(\|) ,
+.BR clntraw_create(\|) ,
+.BR clnttcp_create(\|) ,
+or
+.B clntudp_create(\|)
+call fails.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+void
+clnt_perrno(stat)
+enum clnt_stat stat;
+.fi
+.ft R
+.IP
+Print a message to standard error corresponding
+to the condition indicated by
+.IR stat .
+Used after
+.BR callrpc(\|) .
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+clnt_perror(clnt, s)
+\s-1CLIENT\s0 *clnt;
+char *s;
+.fi
+.ft R
+.IP
+Print a message to standard error indicating why an
+.SM RPC
+call failed;
+.I clnt
+is the handle used to do the call.
+The message is prepended with string
+.I s
+and a colon.
+Used after
+.BR clnt_call(\|) .
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+char *
+clnt_spcreateerror
+char *s;
+.fi
+.ft R
+.IP
+Like
+.BR clnt_pcreateerror(\|) ,
+except that it returns a string
+instead of printing to the standard error.
+.IP
+Bugs: returns pointer to static data that is overwritten
+on each call.
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+char *
+clnt_sperrno(stat)
+enum clnt_stat stat;
+.fi
+.ft R
+.IP
+Take the same arguments as
+.BR clnt_perrno(\|) ,
+but instead of sending a message to the standard error
+indicating why an
+.SM RPC
+call failed, return a pointer to a string which contains
+the message. The string ends with a
+.SM NEWLINE\s0.
+.IP
+.B clnt_sperrno(\|)
+is used instead of
+.B clnt_perrno(\|)
+if the program does not have a standard error (as a program
+running as a server quite likely does not), or if the
+programmer
+does not want the message to be output with
+.BR printf ,
+or if a message format different from that supported by
+.B clnt_perrno(\|)
+is to be used.
+Note: unlike
+.B clnt_sperror(\|)
+and
+.BR clnt_spcreaterror(\|) ,
+.B clnt_sperrno(\|)
+returns pointer to static data, but the
+result will not get overwritten on each call.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+char *
+clnt_sperror(rpch, s)
+\s-1CLIENT\s0 *rpch;
+char *s;
+.fi
+.ft R
+.IP
+Like
+.BR clnt_perror(\|) ,
+except that (like
+.BR clnt_sperrno(\|) )
+it returns a string instead of printing to standard error.
+.IP
+Bugs: returns pointer to static data that is overwritten
+on each call.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+\s-1CLIENT\s0 *
+clntraw_create(prognum, versnum)
+u_long prognum, versnum;
+.fi
+.ft R
+.IP
+This routine creates a toy
+.SM RPC
+client for the remote program
+.IR prognum ,
+version
+.IR versnum .
+The transport used to pass messages to the service is
+actually a buffer within the process's address space, so the
+corresponding
+.SM RPC
+server should live in the same address space; see
+.BR svcraw_create(\|) .
+This allows simulation of
+.SM RPC
+and acquisition of
+.SM RPC
+overheads, such as round trip times, without any
+kernel interference.
+This routine returns
+.SM NULL
+if it fails.
+.br
+.if t .ne 15
+.LP
+.ft B
+.nf
+.sp .5
+\s-1CLIENT\s0 *
+clnttcp_create(addr, prognum, versnum, sockp, sendsz, recvsz)
+struct sockaddr_in *addr;
+u_long prognum, versnum;
+int *sockp;
+u_int sendsz, recvsz;
+.fi
+.ft R
+.IP
+This routine creates an
+.SM RPC
+client for the remote program
+.IR prognum ,
+version
+.IR versnum ;
+the client uses
+.SM TCP/IP
+as a transport.
+The remote program is located at Internet
+address
+.IR *addr .
+If
+.\"The following in-line font conversion is necessary for the hyphen indicator
+\fB\%addr\->sin_port\fR
+is zero, then it is set to the actual port that the remote
+program is listening on (the remote
+.B portmap
+service is consulted for this information). The parameter
+.I sockp
+is a socket; if it is
+.BR \s-1RPC_ANYSOCK\s0 ,
+then this routine opens a new one and sets
+.IR sockp .
+Since
+.SM TCP\s0-based
+.SM RPC
+uses buffered
+.SM I/O ,
+the user may specify the size of the send and receive buffers
+with the parameters
+.I sendsz
+and
+.IR recvsz ;
+values of zero choose suitable defaults.
+This routine returns
+.SM NULL
+if it fails.
+.br
+.if t .ne 15
+.LP
+.ft B
+.nf
+.sp .5
+\s-1CLIENT\s0 *
+clntudp_create(addr, prognum, versnum, wait, sockp)
+struct sockaddr_in *addr;
+u_long prognum, versnum;
+struct timeval wait;
+int *sockp;
+.fi
+.ft R
+.IP
+This routine creates an
+.SM RPC
+client for the remote program
+.IR prognum ,
+version
+.IR versnum ;
+the client uses
+.SM UDP/IP
+as a transport.
+The remote program is located at Internet
+address
+.IR addr .
+If
+\fB\%addr\->sin_port\fR
+is zero, then it is set to actual port that the remote
+program is listening on (the remote
+.B portmap
+service is consulted for this information). The parameter
+.I sockp
+is a socket; if it is
+.BR \s-1RPC_ANYSOCK\s0 ,
+then this routine opens a new one and sets
+.IR sockp .
+The
+.SM UDP
+transport resends the call message in intervals of
+.B wait
+time until a response is received or until the call times
+out.
+The total time for the call to time out is specified by
+.BR clnt_call(\|) .
+.IP
+Warning: since
+.SM UDP\s0-based
+.SM RPC
+messages can only hold up to 8 Kbytes
+of encoded data, this transport cannot be used for procedures
+that take large arguments or return huge results.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+\s-1CLIENT\s0 *
+clntudp_bufcreate(addr, prognum, versnum, wait, sockp, sendsize, recosize)
+struct sockaddr_in *addr;
+u_long prognum, versnum;
+struct timeval wait;
+int *sockp;
+unsigned int sendsize;
+unsigned int recosize;
+.fi
+.ft R
+.IP
+This routine creates an
+.SM RPC
+client for the remote program
+.IR prognum ,
+on
+.IR versnum ;
+the client uses
+.SM UDP/IP
+as a transport.
+The remote program is located at Internet
+address
+.IR addr .
+If
+\fB\%addr\->sin_port\fR
+is zero, then it is set to actual port that the remote
+program is listening on (the remote
+.B portmap
+service is consulted for this information). The parameter
+.I sockp
+is a socket; if it is
+.BR \s-1RPC_ANYSOCK\s0 ,
+then this routine opens a new one and sets
+.BR sockp .
+The
+.SM UDP
+transport resends the call message in intervals of
+.B wait
+time until a response is received or until the call times
+out.
+The total time for the call to time out is specified by
+.BR clnt_call(\|) .
+.IP
+This allows the user to specify the maximum packet size for sending and receiving
+.SM UDP\s0-based
+.SM RPC
+messages.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+int
+get_myaddress(addr)
+struct sockaddr_in *addr;
+.fi
+.ft R
+.IP
+Stuff the machine's
+.SM IP
+address into
+.IR *addr ,
+without consulting the library routines that deal with
+.BR /etc/hosts .
+The port number is always set to
+.BR htons(\s-1PMAPPORT\s0) .
+Returns zero on success, non-zero on failure.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+struct pmaplist *
+pmap_getmaps(addr)
+struct sockaddr_in *addr;
+.fi
+.ft R
+.IP
+A user interface to the
+.B portmap
+service, which returns a list of the current
+.SM RPC
+program-to-port mappings
+on the host located at
+.SM IP
+address
+.IR *addr .
+This routine can return
+.SM NULL .
+The command
+.RB ` "rpcinfo \-p" '
+uses this routine.
+.br
+.if t .ne 12
+.LP
+.ft B
+.nf
+.sp .5
+u_short
+pmap_getport(addr, prognum, versnum, protocol)
+struct sockaddr_in *addr;
+u_long prognum, versnum, protocol;
+.fi
+.ft R
+.IP
+A user interface to the
+.B portmap
+service, which returns the port number
+on which waits a service that supports program number
+.IR prognum ,
+version
+.IR versnum ,
+and speaks the transport protocol associated with
+.IR protocol .
+The value of
+.I protocol
+is most likely
+.B
+.SM IPPROTO_UDP
+or
+.BR \s-1IPPROTO_TCP\s0 .
+A return value of zero means that the mapping does not exist
+or that
+the
+.SM RPC
+system failed to contact the remote
+.B portmap
+service. In the latter case, the global variable
+.B rpc_createerr(\|)
+contains the
+.SM RPC
+status.
+.br
+.if t .ne 15
+.LP
+.ft B
+.nf
+.sp .5
+enum clnt_stat
+pmap_rmtcall(addr, prognum, versnum, procnum, inproc, in, outproc, out, tout, portp)
+struct sockaddr_in *addr;
+u_long prognum, versnum, procnum;
+char *in, *out;
+xdrproc_t inproc, outproc;
+struct timeval tout;
+u_long *portp;
+.fi
+.ft R
+.IP
+A user interface to the
+.B portmap
+service, which instructs
+.B portmap
+on the host at
+.SM IP
+address
+.I *addr
+to make an
+.SM RPC
+call on your behalf to a procedure on that host.
+The parameter
+.I *portp
+will be modified to the program's port number if the
+procedure
+succeeds.
+The definitions of other parameters are discussed
+in
+.B callrpc(\|)
+and
+.BR clnt_call(\|) .
+This procedure should be used for a \(lqping\(rq and nothing
+else.
+See also
+.BR clnt_broadcast(\|) .
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+pmap_set(prognum, versnum, protocol, port)
+u_long prognum, versnum, protocol;
+u_short port;
+.fi
+.ft R
+.IP
+A user interface to the
+.B portmap
+service, which establishes a mapping between the triple
+.RI [ prognum , versnum , protocol\fR]
+and
+.I port
+on the machine's
+.B portmap
+service.
+The value of
+.I protocol
+is most likely
+.B
+.SM IPPROTO_UDP
+or
+.BR \s-1IPPROTO_TCP\s0 .
+This routine returns one if it succeeds, zero otherwise.
+Automatically done by
+.BR svc_register(\|) .
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+pmap_unset(prognum, versnum)
+u_long prognum, versnum;
+.fi
+.ft R
+.IP
+A user interface to the
+.B portmap
+service, which destroys all mapping between the triple
+.RI [ prognum , versnum , *\fR]
+and
+.B ports
+on the machine's
+.B portmap
+service.
+This routine returns one if it succeeds, zero
+otherwise.
+.br
+.if t .ne 15
+.LP
+.ft B
+.nf
+.sp .5
+registerrpc(prognum, versnum, procnum, procname, inproc, outproc)
+u_long prognum, versnum, procnum;
+char *(*procname) (\|) ;
+xdrproc_t inproc, outproc;
+.fi
+.ft R
+.IP
+Register procedure
+.I procname
+with the
+.SM RPC
+service package. If a request arrives for program
+.IR prognum ,
+version
+.IR versnum ,
+and procedure
+.IR procnum ,
+.I procname
+is called with a pointer to its parameter(s);
+.I progname
+should return a pointer to its static result(s);
+.I inproc
+is used to decode the parameters while
+.I outproc
+is used to encode the results.
+This routine returns zero if the registration succeeded, \-1
+otherwise.
+.IP
+Warning: remote procedures registered in this form
+are accessed using the
+.SM UDP/IP
+transport; see
+.B svcudp_create(\|)
+for restrictions.
+.br
+.if t .ne 5
+.LP
+.ft B
+.nf
+.sp .5
+struct rpc_createerr rpc_createerr;
+.fi
+.ft R
+.IP
+A global variable whose value is set by any
+.SM RPC
+client creation routine
+that does not succeed. Use the routine
+.B clnt_pcreateerror(\|)
+to print the reason why.
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+svc_destroy(xprt)
+\s-1SVCXPRT\s0 *
+xprt;
+.fi
+.ft R
+.IP
+A macro that destroys the
+.SM RPC
+service transport handle,
+.IR xprt .
+Destruction usually involves deallocation
+of private data structures, including
+.I xprt
+itself. Use of
+.I xprt
+is undefined after calling this routine.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+fd_set svc_fdset;
+.fi
+.ft R
+.IP
+A global variable reflecting the
+.SM RPC
+service side's
+read file descriptor bit mask; it is suitable as a template parameter
+to the
+.B select
+system call.
+This is only of interest
+if a service implementor does not call
+.BR svc_run(\|) ,
+but rather does his own asynchronous event processing.
+This variable is read-only (do not pass its address to
+.BR select !),
+yet it may change after calls to
+.B svc_getreqset(\|)
+or any creation routines.
+.br
+As well, note that if the process has descriptor limits
+which are extended beyond
+.BR FD_SETSIZE ,
+this variable will only be usable for the first
+.BR FD_SETSIZE
+descriptors.
+.br
+.if t .ne 6
+.LP
+.ft B
+.nf
+.sp .5
+int svc_fds;
+.fi
+.ft R
+.IP
+Similar to
+.BR svc_fedset(\|) ,
+but limited to 32 descriptors.
+This
+interface is obsoleted by
+.BR svc_fdset(\|) .
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+svc_freeargs(xprt, inproc, in)
+\s-1SVCXPRT\s0 *xprt;
+xdrproc_t inproc;
+char *in;
+.fi
+.ft R
+.IP
+A macro that frees any data allocated by the
+.SM RPC/XDR
+system when it decoded the arguments to a service procedure
+using
+.BR svc_getargs(\|) .
+This routine returns 1 if the results were successfully
+freed,
+and zero otherwise.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+svc_getargs(xprt, inproc, in)
+\s-1SVCXPRT\s0 *xprt;
+xdrproc_t inproc;
+char *in;
+.fi
+.ft R
+.IP
+A macro that decodes the arguments of an
+.SM RPC
+request
+associated with the
+.SM RPC
+service transport handle,
+.IR xprt .
+The parameter
+.I in
+is the address where the arguments will be placed;
+.I inproc
+is the
+.SM XDR
+routine used to decode the arguments.
+This routine returns one if decoding succeeds, and zero
+otherwise.
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+struct sockaddr_in *
+svc_getcaller(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+The approved way of getting the network address of the caller
+of a procedure associated with the
+.SM RPC
+service transport handle,
+.IR xprt .
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+svc_getreqset(rdfds)
+fd_set *rdfds;
+.fi
+.ft R
+.IP
+This routine is only of interest if a service implementor
+does not call
+.BR svc_run(\|) ,
+but instead implements custom asynchronous event processing.
+It is called when the
+.B select
+system call has determined that an
+.SM RPC
+request has arrived on some
+.SM RPC
+.B socket(s) ;
+.I rdfds
+is the resultant read file descriptor bit mask.
+The routine returns when all sockets associated with the
+value of
+.I rdfds
+have been serviced.
+.br
+.if t .ne 6
+.LP
+.ft B
+.nf
+.sp .5
+svc_getreq(rdfds)
+int rdfds;
+.fi
+.ft R
+.IP
+Similar to
+.BR svc_getreqset(\|) ,
+but limited to 32 descriptors.
+This interface is obsoleted by
+.BR svc_getreqset(\|) .
+.br
+.if t .ne 17
+.LP
+.ft B
+.nf
+.sp .5
+svc_register(xprt, prognum, versnum, dispatch, protocol)
+\s-1SVCXPRT\s0 *xprt;
+u_long prognum, versnum;
+void (*dispatch) (\|);
+u_long protocol;
+.fi
+.ft R
+.IP
+Associates
+.I prognum
+and
+.I versnum
+with the service dispatch procedure,
+.IR dispatch .
+If
+.I protocol
+is zero, the service is not registered with the
+.B portmap
+service. If
+.I protocol
+is non-zero, then a mapping of the triple
+.RI [ prognum , versnum , protocol\fR]
+to
+\fB\%xprt\->xp_port\fR
+is established with the local
+.B portmap
+service (generally
+.I protocol
+is zero,
+.B
+.SM IPPROTO_UDP
+or
+.B
+.SM IPPROTO_TCP
+).
+The procedure
+.I dispatch
+has the following form:
+.RS 1i
+.ft B
+.nf
+dispatch(request, xprt)
+struct svc_req *request;
+\s-1SVCXPRT\s0 *xprt;
+.ft R
+.fi
+.RE
+.IP
+The
+.B svc_register(\|)
+routine returns one if it succeeds, and zero otherwise.
+.br
+.if t .ne 6
+.LP
+.ft B
+.nf
+.sp .5
+svc_run(\|)
+.fi
+.ft R
+.IP
+This routine never returns.
+It waits for
+.SM RPC
+requests to arrive, and calls the appropriate service
+procedure using
+.B svc_getreq(\|)
+when one arrives.
+This procedure is usually waiting for a
+.B select(\|)
+system call to return.
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+svc_sendreply(xprt, outproc, out)
+\s-1SVCXPRT\s0 *xprt;
+xdrproc_t outproc;
+char *out;
+.fi
+.ft R
+.IP
+Called by an
+.SM RPC
+service's dispatch routine to send the results of a
+remote procedure call. The parameter
+.I xprt
+is the request's associated transport handle;
+.I outproc
+is the
+.SM XDR
+routine which is used to encode the results; and
+.I out
+is the address of the results.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+void
+svc_unregister(prognum, versnum)
+u_long prognum, versnum;
+.fi
+.ft R
+.IP
+Remove all mapping of the double
+.RI [ prognum , versnum ]
+to dispatch routines, and of the triple
+.RI [ prognum , versnum , *\fR]
+to port number.
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+void
+svcerr_auth(xprt, why)
+\s-1SVCXPRT\s0 *xprt;
+enum auth_stat why;
+.fi
+.ft R
+.IP
+Called by a service dispatch routine that refuses to perform
+a remote procedure call due to an authentication error.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+void
+svcerr_decode(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+Called by a service dispatch routine that cannot successfully
+decode its parameters.
+See also
+.BR svc_getargs(\|) .
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+void
+svcerr_noproc(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+Called by a service dispatch routine that does not implement
+the procedure number that the caller requests.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+void
+svcerr_noprog(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+Called when the desired program is not registered with the
+.SM RPC
+package.
+Service implementors usually do not need this routine.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+void
+svcerr_progvers(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+Called when the desired version of a program is not registered
+with the
+.SM RPC
+package.
+Service implementors usually do not need this routine.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+void
+svcerr_systemerr(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+Called by a service dispatch routine when it detects a system
+error
+not covered by any particular protocol.
+For example, if a service can no longer allocate storage,
+it may call this routine.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+void
+svcerr_weakauth(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+Called by a service dispatch routine that refuses to perform
+a remote procedure call due to insufficient
+authentication parameters. The routine calls
+.BR "svcerr_auth(xprt, \s-1AUTH_TOOWEAK\s0)" .
+.br
+.if t .ne 11
+.LP
+.ft B
+.nf
+.sp .5
+\s-1SVCXPRT\s0 *
+svcraw_create(\|)
+.fi
+.ft R
+.IP
+This routine creates a toy
+.SM RPC
+service transport, to which it returns a pointer. The
+transport
+is really a buffer within the process's address space,
+so the corresponding
+.SM RPC
+client should live in the same
+address space;
+see
+.BR clntraw_create(\|) .
+This routine allows simulation of
+.SM RPC
+and acquisition of
+.SM RPC
+overheads (such as round trip times), without any kernel
+interference.
+This routine returns
+.SM NULL
+if it fails.
+.br
+.if t .ne 11
+.LP
+.ft B
+.nf
+.sp .5
+\s-1SVCXPRT\s0 *
+svctcp_create(sock, send_buf_size, recv_buf_size)
+int sock;
+u_int send_buf_size, recv_buf_size;
+.fi
+.ft R
+.IP
+This routine creates a
+.SM TCP/IP\s0-based
+.SM RPC
+service transport, to which it returns a pointer.
+The transport is associated with the socket
+.IR sock ,
+which may be
+.BR \s-1RPC_ANYSOCK\s0 ,
+in which case a new socket is created.
+If the socket is not bound to a local
+.SM TCP
+port, then this routine binds it to an arbitrary port. Upon
+completion,
+\fB\%xprt\->xp_sock\fR
+is the transport's socket descriptor, and
+\fB\%xprt\->xp_port\fR
+is the transport's port number.
+This routine returns
+.SM NULL
+if it fails.
+Since
+.SM TCP\s0-based
+.SM RPC
+uses buffered
+.SM I/O ,
+users may specify the size of buffers; values of zero
+choose suitable defaults.
+.br
+.if t .ne 11
+.LP
+.ft B
+.nf
+.sp .5
+\s-1SVCXPRT\s0 *
+svcfd_create(fd, sendsize, recvsize)
+int fd;
+u_int sendsize;
+u_int recvsize;
+.fi
+.ft R
+.IP
+Create a service on top of any open descriptor.
+Typically,
+this
+descriptor is a connected socket for a stream protocol such
+as
+.SM TCP\s0.
+.I sendsize
+and
+.I recvsize
+indicate sizes for the send and receive buffers. If they are
+zero, a reasonable default is chosen.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+\s-1SVCXPRT\s0 *
+svcudp_bufcreate(sock, sendsize, recosize)
+int sock;
+.fi
+.ft R
+.IP
+This routine creates a
+.SM UDP/IP\s0-based
+.SM RPC
+service transport, to which it returns a pointer.
+The transport is associated with the socket
+.IR sock ,
+which may be
+.B \s-1RPC_ANYSOCK\s0 ,
+in which case a new socket is created.
+If the socket is not bound to a local
+.SM UDP
+port, then this routine binds it to an arbitrary port.
+Upon
+completion,
+\fB\%xprt\->xp_sock\fR
+is the transport's socket descriptor, and
+\fB\%xprt\->xp_port\fR
+is the transport's port number.
+This routine returns
+.SM NULL
+if it fails.
+.IP
+This allows the user to specify the maximum packet size for sending and
+receiving
+.SM UDP\s0-based
+.SM RPC messages.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_accepted_reply(xdrs, ar)
+\s-1XDR\s0 *xdrs;
+struct accepted_reply *ar;
+.fi
+.ft R
+.IP
+Used for encoding
+.SM RPC
+reply messages.
+This routine is useful for users who
+wish to generate
+\s-1RPC\s0-style
+messages without using the
+.SM RPC
+package.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_authunix_parms(xdrs, aupp)
+\s-1XDR\s0 *xdrs;
+struct authunix_parms *aupp;
+.fi
+.ft R
+.IP
+Used for describing
+.SM UNIX
+credentials.
+This routine is useful for users
+who wish to generate these credentials without using the
+.SM RPC
+authentication package.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+void
+xdr_callhdr(xdrs, chdr)
+\s-1XDR\s0 *xdrs;
+struct rpc_msg *chdr;
+.fi
+.ft R
+.IP
+Used for describing
+.SM RPC
+call header messages.
+This routine is useful for users who wish to generate
+.SM RPC\s0-style
+messages without using the
+.SM RPC
+package.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_callmsg(xdrs, cmsg)
+\s-1XDR\s0 *xdrs;
+struct rpc_msg *cmsg;
+.fi
+.ft R
+.IP
+Used for describing
+.SM RPC
+call messages.
+This routine is useful for users who wish to generate
+.SM RPC\s0-style
+messages without using the
+.SM RPC
+package.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_opaque_auth(xdrs, ap)
+\s-1XDR\s0 *xdrs;
+struct opaque_auth *ap;
+.fi
+.ft R
+.IP
+Used for describing
+.SM RPC
+authentication information messages.
+This routine is useful for users who wish to generate
+.SM RPC\s0-style
+messages without using the
+.SM RPC
+package.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_pmap(xdrs, regs)
+\s-1XDR\s0 *xdrs;
+struct pmap *regs;
+.fi
+.ft R
+.IP
+Used for describing parameters to various
+.B portmap
+procedures, externally.
+This routine is useful for users who wish to generate
+these parameters without using the
+.B pmap
+interface.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_pmaplist(xdrs, rp)
+\s-1XDR\s0 *xdrs;
+struct pmaplist **rp;
+.fi
+.ft R
+.IP
+Used for describing a list of port mappings, externally.
+This routine is useful for users who wish to generate
+these parameters without using the
+.B pmap
+interface.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_rejected_reply(xdrs, rr)
+\s-1XDR\s0 *xdrs;
+struct rejected_reply *rr;
+.fi
+.ft R
+.IP
+Used for describing
+.SM RPC
+reply messages.
+This routine is useful for users who wish to generate
+.SM RPC\s0-style
+messages without using the
+.SM RPC
+package.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+xdr_replymsg(xdrs, rmsg)
+\s-1XDR\s0 *xdrs;
+struct rpc_msg *rmsg;
+.fi
+.ft R
+.IP
+Used for describing
+.SM RPC
+reply messages.
+This routine is useful for users who wish to generate
+.SM RPC
+style messages without using the
+.SM RPC
+package.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+void
+xprt_register(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+After
+.SM RPC
+service transport handles are created,
+they should register themselves with the
+.SM RPC
+service package.
+This routine modifies the global variable
+.BR svc_fds(\|) .
+Service implementors usually do not need this routine.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+void
+xprt_unregister(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+Before an
+.SM RPC
+service transport handle is destroyed,
+it should unregister itself with the
+.SM RPC
+service package.
+This routine modifies the global variable
+.BR svc_fds(\|) .
+Service implementors usually do not need this routine.
+.SH SEE ALSO
+.BR rpc_secure (3),
+.BR xdr (3)
+.br
+The following manuals:
+.RS
+.ft I
+Remote Procedure Calls: Protocol Specification
+.br
+Remote Procedure Call Programming Guide
+.br
+rpcgen Programming Guide
+.br
+.ft R
+.RE
+.IR "\s-1RPC\s0: Remote Procedure Call Protocol Specification" ,
+.SM RFC1050, Sun Microsystems, Inc.,
+.SM USC-ISI\s0.
+
diff --git a/librpc/src/rpc/rpc.5 b/librpc/src/rpc/rpc.5
new file mode 100644
index 0000000..36f895d
--- /dev/null
+++ b/librpc/src/rpc/rpc.5
@@ -0,0 +1,35 @@
+.\" $FreeBSD: src/lib/libc/rpc/rpc.5,v 1.6 1999/08/28 00:00:44 peter Exp $
+.\" @(#)rpc.5 2.2 88/08/03 4.0 RPCSRC; from 1.4 87/11/27 SMI;
+.Dd September 26, 1985
+.Dt RPC 5
+.Sh NAME
+.Nm rpc
+.Nd rpc program number data base
+.Sh SYNOPSIS
+/etc/rpc
+.Sh DESCRIPTION
+The
+.Pa /etc/rpc
+file contains user readable names that
+can be used in place of rpc program numbers.
+Each line has the following information:
+.Pp
+.Bl -bullet -compact
+.It
+name of server for the rpc program
+.It
+rpc program number
+.It
+aliases
+.El
+.Pp
+Items are separated by any number of blanks and/or
+tab characters.
+A ``#'' indicates the beginning of a comment; characters up to the end of
+the line are not interpreted by routines which search the file.
+.Sh FILES
+.Bl -tag -compact -width /etc/rpc
+.Pa /etc/rpc
+.El
+.Sh "SEE ALSO"
+.Xr getrpcent 3
diff --git a/librpc/src/rpc/rpc_callmsg.c b/librpc/src/rpc/rpc_callmsg.c
new file mode 100644
index 0000000..2d340ba
--- /dev/null
+++ b/librpc/src/rpc/rpc_callmsg.c
@@ -0,0 +1,198 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)rpc_callmsg.c 1.4 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)rpc_callmsg.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/rpc_callmsg.c,v 1.9 1999/08/28 00:00:45 peter Exp $";
+#endif
+
+/*
+ * rpc_callmsg.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/param.h>
+#include <stdlib.h>
+#include <string.h>
+#include <rpc/rpc.h>
+
+/*
+ * XDR a call message
+ */
+bool_t
+xdr_callmsg(
+ XDR *xdrs,
+ struct rpc_msg *cmsg)
+{
+ register int32_t *buf;
+ register struct opaque_auth *oa;
+
+ if (xdrs->x_op == XDR_ENCODE) {
+ if (cmsg->rm_call.cb_cred.oa_length > MAX_AUTH_BYTES) {
+ return (FALSE);
+ }
+ if (cmsg->rm_call.cb_verf.oa_length > MAX_AUTH_BYTES) {
+ return (FALSE);
+ }
+ buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT
+ + RNDUP(cmsg->rm_call.cb_cred.oa_length)
+ + 2 * BYTES_PER_XDR_UNIT
+ + RNDUP(cmsg->rm_call.cb_verf.oa_length));
+ if (buf != NULL) {
+ IXDR_PUT_LONG(buf, cmsg->rm_xid);
+ IXDR_PUT_ENUM(buf, cmsg->rm_direction);
+ if (cmsg->rm_direction != CALL) {
+ return (FALSE);
+ }
+ IXDR_PUT_LONG(buf, cmsg->rm_call.cb_rpcvers);
+ if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) {
+ return (FALSE);
+ }
+ IXDR_PUT_LONG(buf, cmsg->rm_call.cb_prog);
+ IXDR_PUT_LONG(buf, cmsg->rm_call.cb_vers);
+ IXDR_PUT_LONG(buf, cmsg->rm_call.cb_proc);
+ oa = &cmsg->rm_call.cb_cred;
+ IXDR_PUT_ENUM(buf, oa->oa_flavor);
+ IXDR_PUT_LONG(buf, oa->oa_length);
+ if (oa->oa_length) {
+ memcpy((caddr_t)buf, oa->oa_base, oa->oa_length);
+ buf += RNDUP(oa->oa_length) / sizeof (int32_t);
+ }
+ oa = &cmsg->rm_call.cb_verf;
+ IXDR_PUT_ENUM(buf, oa->oa_flavor);
+ IXDR_PUT_LONG(buf, oa->oa_length);
+ if (oa->oa_length) {
+ memcpy((caddr_t)buf, oa->oa_base, oa->oa_length);
+ /* no real need....
+ buf += RNDUP(oa->oa_length) / sizeof (int32_t);
+ */
+ }
+ return (TRUE);
+ }
+ }
+ if (xdrs->x_op == XDR_DECODE) {
+ buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT);
+ if (buf != NULL) {
+ cmsg->rm_xid = IXDR_GET_LONG(buf);
+ cmsg->rm_direction = IXDR_GET_ENUM(buf, enum msg_type);
+ if (cmsg->rm_direction != CALL) {
+ return (FALSE);
+ }
+ cmsg->rm_call.cb_rpcvers = IXDR_GET_LONG(buf);
+ if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) {
+ return (FALSE);
+ }
+ cmsg->rm_call.cb_prog = IXDR_GET_LONG(buf);
+ cmsg->rm_call.cb_vers = IXDR_GET_LONG(buf);
+ cmsg->rm_call.cb_proc = IXDR_GET_LONG(buf);
+ oa = &cmsg->rm_call.cb_cred;
+ oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t);
+ oa->oa_length = IXDR_GET_LONG(buf);
+ if (oa->oa_length) {
+ if (oa->oa_length > MAX_AUTH_BYTES) {
+ return (FALSE);
+ }
+ if (oa->oa_base == NULL) {
+ oa->oa_base = (caddr_t)
+ mem_alloc(oa->oa_length);
+ }
+ buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length));
+ if (buf == NULL) {
+ if (xdr_opaque(xdrs, oa->oa_base,
+ oa->oa_length) == FALSE) {
+ return (FALSE);
+ }
+ } else {
+ memcpy(oa->oa_base, (caddr_t)buf,
+ oa->oa_length);
+ /* no real need....
+ buf += RNDUP(oa->oa_length) /
+ sizeof (int32_t);
+ */
+ }
+ }
+ oa = &cmsg->rm_call.cb_verf;
+ buf = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (xdr_enum(xdrs, &oa->oa_flavor) == FALSE ||
+ xdr_u_int(xdrs, &oa->oa_length) == FALSE) {
+ return (FALSE);
+ }
+ } else {
+ oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t);
+ oa->oa_length = IXDR_GET_LONG(buf);
+ }
+ if (oa->oa_length) {
+ if (oa->oa_length > MAX_AUTH_BYTES) {
+ return (FALSE);
+ }
+ if (oa->oa_base == NULL) {
+ oa->oa_base = (caddr_t)
+ mem_alloc(oa->oa_length);
+ }
+ buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length));
+ if (buf == NULL) {
+ if (xdr_opaque(xdrs, oa->oa_base,
+ oa->oa_length) == FALSE) {
+ return (FALSE);
+ }
+ } else {
+ memcpy(oa->oa_base, (caddr_t)buf,
+ oa->oa_length);
+ /* no real need...
+ buf += RNDUP(oa->oa_length) /
+ sizeof (int32_t);
+ */
+ }
+ }
+ return (TRUE);
+ }
+ }
+ if (
+ xdr_u_int32_t(xdrs, &(cmsg->rm_xid)) &&
+ xdr_enum(xdrs, (enum_t *)(void *)&(cmsg->rm_direction)) &&
+ (cmsg->rm_direction == CALL) &&
+ xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
+ (cmsg->rm_call.cb_rpcvers == RPC_MSG_VERSION) &&
+ xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_prog)) &&
+ xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_vers)) &&
+ xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_proc)) &&
+ xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_cred)) )
+ return (xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_verf)));
+ return (FALSE);
+}
diff --git a/librpc/src/rpc/rpc_commondata.c b/librpc/src/rpc/rpc_commondata.c
new file mode 100644
index 0000000..cae9d21
--- /dev/null
+++ b/librpc/src/rpc/rpc_commondata.c
@@ -0,0 +1,47 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)rpc_commondata.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/rpc_commondata.c,v 1.7 1999/08/28 00:00:45 peter Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rpc/rpc.h>
+/*
+ * This file should only contain common data (global data) that is exported
+ * by public interfaces
+ */
+struct opaque_auth _null_auth;
+struct rpc_createerr rpc_createerr;
diff --git a/librpc/src/rpc/rpc_dtablesize.c b/librpc/src/rpc/rpc_dtablesize.c
new file mode 100644
index 0000000..d19cc04
--- /dev/null
+++ b/librpc/src/rpc/rpc_dtablesize.c
@@ -0,0 +1,67 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)rpc_dtablesize.c 1.2 87/08/11 Copyr 1987 Sun Micro";*/
+/*static char *sccsid = "from: @(#)rpc_dtablesize.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/rpc_dtablesize.c,v 1.10 1999/08/28 00:00:45 peter Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/select.h>
+#include <unistd.h>
+
+/*
+ * Cache the result of getdtablesize(), so we don't have to do an
+ * expensive system call every time.
+ */
+/*
+ * XXX In FreeBSD 2.x, you can have the maximum number of open file
+ * descriptors be greater than FD_SETSIZE (which us 256 by default).
+ *
+ * Since old programs tend to use this call to determine the first arg
+ * for select(), having this return > FD_SETSIZE is a Bad Idea(TM)!
+ */
+int
+_rpc_dtablesize(void)
+{
+ static int size;
+
+ if (size == 0) {
+ size = getdtablesize();
+ if (size > FD_SETSIZE)
+ size = FD_SETSIZE;
+ }
+ return (size);
+}
diff --git a/librpc/src/rpc/rpc_prot.c b/librpc/src/rpc/rpc_prot.c
new file mode 100644
index 0000000..ea4787e
--- /dev/null
+++ b/librpc/src/rpc/rpc_prot.c
@@ -0,0 +1,338 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)rpc_prot.c 2.3 88/08/07 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/rpc_prot.c,v 1.8 1999/08/28 00:00:46 peter Exp $";
+#endif
+
+/*
+ * rpc_prot.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * This set of routines implements the rpc message definition,
+ * its serializer and some common rpc utility routines.
+ * The routines are meant for various implementations of rpc -
+ * they are NOT for the rpc client or rpc service implementations!
+ * Because authentication stuff is easy and is part of rpc, the opaque
+ * routines are also in this program.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <sys/param.h>
+
+#include <rpc/rpc.h>
+
+static void accepted(enum accept_stat, struct rpc_err *);
+static void rejected(enum reject_stat, struct rpc_err *);
+
+/* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */
+
+extern struct opaque_auth _null_auth;
+
+/*
+ * XDR an opaque authentication struct
+ * (see auth.h)
+ */
+bool_t
+xdr_opaque_auth(
+ XDR *xdrs,
+ struct opaque_auth *ap)
+{
+
+ assert(xdrs != NULL);
+ assert(ap != NULL);
+
+ if (xdr_enum(xdrs, &(ap->oa_flavor)))
+ return (xdr_bytes(xdrs, &ap->oa_base,
+ &ap->oa_length, MAX_AUTH_BYTES));
+ return (FALSE);
+}
+
+/*
+ * XDR a DES block
+ */
+bool_t
+xdr_des_block(
+ XDR *xdrs,
+ des_block *blkp)
+{
+
+ assert(xdrs != NULL);
+ assert(blkp != NULL);
+
+ return (xdr_opaque(xdrs, (caddr_t)blkp, sizeof(des_block)));
+}
+
+/* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */
+
+/*
+ * XDR the MSG_ACCEPTED part of a reply message union
+ */
+bool_t
+xdr_accepted_reply(
+ XDR *xdrs,
+ struct accepted_reply *ar)
+{
+
+ /* personalized union, rather than calling xdr_union */
+ if (! xdr_opaque_auth(xdrs, &(ar->ar_verf)))
+ return (FALSE);
+ if (! xdr_enum(xdrs, (enum_t *)(void *)&(ar->ar_stat)))
+ return (FALSE);
+ switch (ar->ar_stat) {
+
+ case SUCCESS:
+ return ((*(ar->ar_results.proc))(xdrs, ar->ar_results.where));
+
+ case PROG_MISMATCH:
+ if (! xdr_u_int32_t(xdrs, &(ar->ar_vers.low)))
+ return (FALSE);
+ return (xdr_u_int32_t(xdrs, &(ar->ar_vers.high)));
+
+ case GARBAGE_ARGS:
+ case SYSTEM_ERR:
+ case PROC_UNAVAIL:
+ case PROG_UNAVAIL:
+ break;
+ }
+ return (TRUE); /* TRUE => open ended set of problems */
+}
+
+/*
+ * XDR the MSG_DENIED part of a reply message union
+ */
+bool_t
+xdr_rejected_reply(
+ XDR *xdrs,
+ struct rejected_reply *rr )
+{
+
+ /* personalized union, rather than calling xdr_union */
+ if (! xdr_enum(xdrs, (enum_t *)(void *)&(rr->rj_stat)))
+ return (FALSE);
+ switch (rr->rj_stat) {
+
+ case RPC_MISMATCH:
+ if (! xdr_u_int32_t(xdrs, &(rr->rj_vers.low)))
+ return (FALSE);
+ return (xdr_u_int32_t(xdrs, &(rr->rj_vers.high)));
+
+ case AUTH_ERROR:
+ return (xdr_enum(xdrs, (enum_t *)(void *)&(rr->rj_why)));
+ }
+ return (FALSE);
+}
+
+static const struct xdr_discrim reply_dscrm[3] = {
+ { (int)MSG_ACCEPTED, (xdrproc_t)xdr_accepted_reply },
+ { (int)MSG_DENIED, (xdrproc_t)xdr_rejected_reply },
+ { __dontcare__, NULL_xdrproc_t } };
+
+/*
+ * XDR a reply message
+ */
+bool_t
+xdr_replymsg(
+ XDR *xdrs,
+ struct rpc_msg *rmsg)
+{
+ if (
+ xdr_u_int32_t(xdrs, &(rmsg->rm_xid)) &&
+ xdr_enum(xdrs, (enum_t *)(void *)&(rmsg->rm_direction)) &&
+ (rmsg->rm_direction == REPLY) )
+ return (xdr_union(xdrs, (enum_t *)(void *)&(rmsg->rm_reply.rp_stat),
+ (caddr_t)&(rmsg->rm_reply.ru), reply_dscrm, NULL_xdrproc_t));
+ return (FALSE);
+}
+
+
+/*
+ * Serializes the "static part" of a call message header.
+ * The fields include: rm_xid, rm_direction, rpcvers, prog, and vers.
+ * The rm_xid is not really static, but the user can easily munge on the fly.
+ */
+bool_t
+xdr_callhdr(
+ XDR *xdrs,
+ struct rpc_msg *cmsg)
+{
+
+ cmsg->rm_direction = CALL;
+ cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION;
+ if (
+ (xdrs->x_op == XDR_ENCODE) &&
+ xdr_u_int32_t(xdrs, &(cmsg->rm_xid)) &&
+ xdr_enum(xdrs, (enum_t *)(void *)&(cmsg->rm_direction)) &&
+ xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
+ xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_prog)) )
+ return (xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_vers)));
+ return (FALSE);
+}
+
+/* ************************** Client utility routine ************* */
+
+static void
+accepted(
+ enum accept_stat acpt_stat,
+ struct rpc_err *error)
+{
+
+ assert(error != NULL);
+
+ switch (acpt_stat) {
+
+ case PROG_UNAVAIL:
+ error->re_status = RPC_PROGUNAVAIL;
+ return;
+
+ case PROG_MISMATCH:
+ error->re_status = RPC_PROGVERSMISMATCH;
+ return;
+
+ case PROC_UNAVAIL:
+ error->re_status = RPC_PROCUNAVAIL;
+ return;
+
+ case GARBAGE_ARGS:
+ error->re_status = RPC_CANTDECODEARGS;
+ return;
+
+ case SYSTEM_ERR:
+ error->re_status = RPC_SYSTEMERROR;
+ return;
+
+ case SUCCESS:
+ error->re_status = RPC_SUCCESS;
+ return;
+ }
+ /* something's wrong, but we don't know what ... */
+ error->re_status = RPC_FAILED;
+ error->re_lb.s1 = (int32_t)MSG_ACCEPTED;
+ error->re_lb.s2 = (int32_t)acpt_stat;
+}
+
+static void
+rejected(
+ enum reject_stat rjct_stat,
+ struct rpc_err *error)
+{
+
+ assert(error != NULL);
+
+ switch (rjct_stat) {
+ case RPC_MISMATCH:
+ error->re_status = RPC_VERSMISMATCH;
+ return;
+
+ case AUTH_ERROR:
+ error->re_status = RPC_AUTHERROR;
+ return;
+ }
+ /* something's wrong, but we don't know what ... */
+ error->re_status = RPC_FAILED;
+ error->re_lb.s1 = (int32_t)MSG_DENIED;
+ error->re_lb.s2 = (int32_t)rjct_stat;
+}
+
+/*
+ * given a reply message, fills in the error
+ */
+void
+_seterr_reply(
+ struct rpc_msg *msg,
+ struct rpc_err *error)
+{
+
+ assert(msg != NULL);
+ assert(error != NULL);
+
+ /* optimized for normal, SUCCESSful case */
+ switch (msg->rm_reply.rp_stat) {
+
+ case MSG_ACCEPTED:
+ if (msg->acpted_rply.ar_stat == SUCCESS) {
+ error->re_status = RPC_SUCCESS;
+ return;
+ }
+ accepted(msg->acpted_rply.ar_stat, error);
+ break;
+
+ case MSG_DENIED:
+ rejected(msg->rjcted_rply.rj_stat, error);
+ break;
+
+ default:
+ error->re_status = RPC_FAILED;
+ error->re_lb.s1 = (int32_t)(msg->rm_reply.rp_stat);
+ break;
+ }
+ switch (error->re_status) {
+
+ case RPC_VERSMISMATCH:
+ error->re_vers.low = msg->rjcted_rply.rj_vers.low;
+ error->re_vers.high = msg->rjcted_rply.rj_vers.high;
+ break;
+
+ case RPC_AUTHERROR:
+ error->re_why = msg->rjcted_rply.rj_why;
+ break;
+
+ case RPC_PROGVERSMISMATCH:
+ error->re_vers.low = msg->acpted_rply.ar_vers.low;
+ error->re_vers.high = msg->acpted_rply.ar_vers.high;
+ break;
+
+ case RPC_FAILED:
+ case RPC_SUCCESS:
+ case RPC_PROGNOTREGISTERED:
+ case RPC_PMAPFAILURE:
+ case RPC_UNKNOWNPROTO:
+ case RPC_UNKNOWNHOST:
+ case RPC_SYSTEMERROR:
+ case RPC_CANTDECODEARGS:
+ case RPC_PROCUNAVAIL:
+ case RPC_PROGUNAVAIL:
+ case RPC_TIMEDOUT:
+ case RPC_CANTRECV:
+ case RPC_CANTSEND:
+ case RPC_CANTDECODERES:
+ case RPC_CANTENCODEARGS:
+ default:
+ break;
+ }
+}
diff --git a/librpc/src/rpc/rpc_secure.3 b/librpc/src/rpc/rpc_secure.3
new file mode 100644
index 0000000..4efd9b8
--- /dev/null
+++ b/librpc/src/rpc/rpc_secure.3
@@ -0,0 +1,254 @@
+.\" @(#)rpc_secure.3n 2.1 88/08/08 4.0 RPCSRC; from 1.19 88/06/24 SMI
+.\" $FreeBSD: src/lib/libc/rpc/rpc_secure.3,v 1.6 2000/03/02 09:13:48 sheldonh Exp $
+.\"
+.Dd February 16, 1988
+.Dt RPC 3
+.Sh NAME
+.Nm rpc_secure
+.Nd library routines for secure remote procedure calls
+.Sh SYNOPSIS
+.Fd #include <rpc/rpc.h>
+.Ft AUTH *
+.Fo authdes_create
+.Fa "char *name"
+.Fa "unsigned window"
+.Fa "struct sockaddr *addr"
+.Fa "des_block *ckey"
+.Fc
+.Ft int
+.Fn authdes_getucred "struct authdes_cred *adc" "uid_t *uid" "gid_t *gid" "int *grouplen" "gid_t *groups"
+.Ft int
+.Fn getnetname "char *name"
+.Ft int
+.Fn host2netname "char *name" "char *host" "char *domain"
+.Ft int
+.Fn key_decryptsession "const char *remotename" "des_block *deskey"
+.Ft int
+.Fn key_encryptsession "const char *remotename" "des_block *deskey"
+.Ft int
+.Fn key_gendes "des_block *deskey"
+.Ft int
+.Fn key_setsecret "const char *key"
+.Ft int
+.Fn netname2host "char *name" "char *host" "int hostlen"
+.Ft int
+.Fn netname2user "char *name" "uid_t *uidp" "gid_t *gidp" "int *gidlenp" "gid_t *gidlist"
+.Ft int
+.Fn user2netname "char *name" "uid_t uid" "char *domain"
+.Sh DESCRIPTION
+These routines are part of the
+.Tn RPC
+library. They implement
+.Tn DES
+Authentication. See
+.Xr rpc 3
+for further details about
+.Tn RPC .
+.Pp
+The
+.Fn authdes_create
+is the first of two routines which interface to the
+.Tn RPC
+secure authentication system, known as
+.Tn DES
+authentication.
+The second is
+.Fn authdes_getucred ,
+below.
+.Pp
+Note: the keyserver daemon
+.Xr keyserv 8
+must be running for the
+.Tn DES
+authentication system to work.
+.Pp
+.Fn Authdes_create ,
+used on the client side, returns an authentication handle that
+will enable the use of the secure authentication system.
+The first parameter
+.Fa name
+is the network name, or
+.Fa netname ,
+of the owner of the server process.
+This field usually
+represents a
+.Fa hostname
+derived from the utility routine
+.Fn host2netname ,
+but could also represent a user name using
+.Fn user2netname .
+The second field is window on the validity of
+the client credential, given in seconds. A small
+window is more secure than a large one, but choosing
+too small of a window will increase the frequency of
+resynchronizations because of clock drift.
+The third
+parameter
+.Fa addr
+is optional. If it is
+.Dv NULL ,
+then the authentication system will assume
+that the local clock is always in sync with the server's
+clock, and will not attempt resynchronizations.
+If an address
+is supplied, however, then the system will use the address
+for consulting the remote time service whenever
+resynchronization
+is required.
+This parameter is usually the
+address of the
+.Tn RPC
+server itself.
+The final parameter
+.Fa ckey
+is also optional. If it is
+.Dv NULL ,
+then the authentication system will
+generate a random
+.Tn DES
+key to be used for the encryption of credentials.
+If it is supplied, however, then it will be used instead.
+.Pp
+.Fn Authdes_getucred ,
+the second of the two
+.Tn DES
+authentication routines,
+is used on the server side for converting a
+.Tn DES
+credential, which is
+operating system independent, into a
+.Ux
+credential.
+This routine differs from utility routine
+.Fn netname2user
+in that
+.Fn authdes_getucred
+pulls its information from a cache, and does not have to do a
+Yellow Pages lookup every time it is called to get its information.
+.Pp
+.Fn Getnetname
+installs the unique, operating-system independent netname of
+the
+caller in the fixed-length array
+.Fa name .
+Returns
+.Dv TRUE
+if it succeeds and
+.Dv FALSE
+if it fails.
+.Pp
+.Fn Host2netname
+converts from a domain-specific hostname to an
+operating-system independent netname.
+Returns
+.Dv TRUE
+if it succeeds and
+.Dv FALSE
+if it fails.
+Inverse of
+.Fn netname2host .
+.Pp
+.Fn Key_decryptsession
+is an interface to the keyserver daemon, which is associated
+with
+.Tn RPC Ns 's
+secure authentication system (
+.Tn DES
+authentication).
+User programs rarely need to call it, or its associated routines
+.Fn key_encryptsession ,
+.Fn key_gendes
+and
+.Fn key_setsecret .
+System commands such as
+.Xr login 1
+and the
+.Tn RPC
+library are the main clients of these four routines.
+.Pp
+.Fn Key_decryptsession
+takes a server netname and a
+.Tn DES
+key, and decrypts the key by
+using the the public key of the the server and the secret key
+associated with the effective uid of the calling process. It
+is the inverse of
+.Fn key_encryptsession .
+.Pp
+.Fn Key_encryptsession
+is a keyserver interface routine.
+It
+takes a server netname and a des key, and encrypts
+it using the public key of the the server and the secret key
+associated with the effective uid of the calling process. It
+is the inverse of
+.Fn key_decryptsession .
+.Pp
+.Fn Key_gendes
+is a keyserver interface routine.
+It
+is used to ask the keyserver for a secure conversation key.
+Choosing one
+.Qq random
+is usually not good enough,
+because
+the common ways of choosing random numbers, such as using the
+current time, are very easy to guess.
+.Pp
+.Fn Key_setsecret
+is a keyserver interface routine.
+It is used to set the key for
+the effective
+.Fa uid
+of the calling process.
+.Pp
+.Fn Netname2host
+converts from an operating-system independent netname to a
+domain-specific hostname.
+Returns
+.Dv TRUE
+if it succeeds and
+.Dv FALSE
+if it fails. Inverse of
+.Fn host2netname .
+.Pp
+.Fn Netname2user
+converts from an operating-system independent netname to a
+domain-specific user ID.
+Returns
+.Dv TRUE
+if it succeeds and
+.Dv FALSE
+if it fails.
+Inverse of
+.Fn user2netname .
+.Pp
+.Fn User2netname
+converts from a domain-specific username to an operating-system
+independent netname.
+Returns
+.Dv TRUE
+if it succeeds and
+.Dv FALSE
+if it fails.
+Inverse of
+.Fn netname2user .
+.Sh SEE ALSO
+.Xr rpc 3 ,
+.Xr xdr 3 ,
+.Xr keyserv 8
+.Pp
+The following manuals:
+.Rs
+.%B Remote Procedure Calls: Protocol Specification
+.Re
+.Rs
+.%B Remote Procedure Call Programming Guide
+.Re
+.Rs
+.%B Rpcgen Programming Guide
+.Re
+.Rs
+.%B RPC: Remote Procedure Call Protocol Specification
+.%O RFC1050, Sun Microsystems Inc., USC-ISI
+.Re
diff --git a/librpc/src/rpc/rpcdname.c b/librpc/src/rpc/rpcdname.c
new file mode 100644
index 0000000..2451d63
--- /dev/null
+++ b/librpc/src/rpc/rpcdname.c
@@ -0,0 +1,86 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)rpcdname.c 1.7 91/03/11 Copyr 1989 Sun Micro";
+#endif
+
+/*
+ * rpcdname.c
+ * Gets the default domain name
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <rpc/rpc.h>
+
+int getdomainname(char *, size_t);
+
+#define default_domain (rtems_rpc_task_variables->rpcdname_default_domain)
+
+static char *
+get_default_domain(void)
+{
+ char temp[256];
+
+ if (default_domain)
+ return (default_domain);
+ if (getdomainname(temp, sizeof(temp)) < 0)
+ return (0);
+ if (strlen(temp) > 0) {
+ default_domain = (char *)malloc((strlen(temp)+(size_t)1));
+ if (default_domain == 0)
+ return (0);
+ (void) strcpy(default_domain, temp);
+ return (default_domain);
+ }
+ return (0);
+}
+
+/*
+ * This is a wrapper for the system call getdomainname which returns a
+ * ypclnt.h error code in the failure case. It also checks to see that
+ * the domain name is non-null, knowing that the null string is going to
+ * get rejected elsewhere in the NIS client package.
+ */
+int
+_rpc_get_default_domain(
+ char **domain )
+{
+ if ((*domain = get_default_domain()) != 0)
+ return (0);
+ return (-1);
+}
diff --git a/librpc/src/rpc/rstat.1 b/librpc/src/rpc/rstat.1
new file mode 100644
index 0000000..6cc47c2
--- /dev/null
+++ b/librpc/src/rpc/rstat.1
@@ -0,0 +1,58 @@
+.\" $FreeBSD: src/lib/libc/rpc/rstat.1,v 1.5 1999/08/28 00:00:46 peter Exp $
+.\" @(#)rstat.1 2.1 88/08/03 4.0 RPCSRC
+.TH RSTAT 1 "3 August 1988"
+.SH NAME
+rstat \- remote status display
+.SH SYNOPSIS
+.B rstat
+.B host
+.SH DESCRIPTION
+.LP
+.B rstat
+displays a summary of the current system status of a particular
+.BR host .
+The output shows the current time of day, how long the system has
+been up,
+and the load averages.
+The load average numbers give the number of jobs in the run queue
+averaged over 1, 5 and 15 minutes.
+.PP
+The
+.B rstat_svc(8)
+daemon must be running on the remote host for this command to
+work.
+.B rstat
+uses an RPC protocol defined in /usr/include/rpcsvc/rstat.x.
+.SH EXAMPLE
+.RS
+.ft B
+.nf
+example% rstat otherhost
+7:36am up 6 days, 16:45, load average: 0.20, 0.23, 0.18
+example%
+.ft R
+.fi
+.RE
+.SH DIAGNOSTICS
+.LP
+rstat: RPC: Program not registered
+.IP
+The
+.B rstat_svc
+daemon has not been started on the remote host.
+.LP
+rstat: RPC: Timed out
+.IP
+A communication error occurred. Either the network is
+excessively congested, or the
+.B rstat_svc
+daemon has terminated on the remote host.
+.LP
+rstat: RPC: Port mapper failure - RPC: Timed out
+.IP
+The remote host is not running the portmapper (see
+.BR portmap(8) ),
+and cannot accommodate any RPC-based services. The host may be down.
+.SH "SEE ALSO"
+.BR portmap (8),
+.BR rstat_svc (8)
diff --git a/librpc/src/rpc/rstat_svc.8 b/librpc/src/rpc/rstat_svc.8
new file mode 100644
index 0000000..e2eae8b
--- /dev/null
+++ b/librpc/src/rpc/rstat_svc.8
@@ -0,0 +1,22 @@
+.\" $FreeBSD: src/lib/libc/rpc/rstat_svc.8,v 1.5 1999/08/28 00:00:47 peter Exp $
+.\" @(#)rstat_svc.8c 2.2 88/08/03 4.0 RPCSRC; from 1.10 87/09/09 SMI
+.TH RSTAT_SVC 8 "24 November 1987"
+.SH NAME
+rstat_svc \- kernel statistics server
+.SH SYNOPSIS
+.B /etc/rstat_svc
+.SH DESCRIPTION
+.LP
+.B rstat_svc
+is a server which returns performance statistics
+obtained from the kernel.
+These statistics are graphically displayed by the Sun Microsystems program,
+.BR perfmeter (1).
+The
+.B rstat_svc
+daemon is normally invoked at boot time through /etc/rc.local.
+.PP
+.B rstat_svc
+uses an RPC protocol defined in /usr/include/rpcsvc/rstat.x.
+.\" .SH "SEE ALSO"
+.\" .BR rstat (1),
diff --git a/librpc/src/rpc/rtems-rpc-config.h b/librpc/src/rpc/rtems-rpc-config.h
new file mode 100644
index 0000000..9448ab7
--- /dev/null
+++ b/librpc/src/rpc/rtems-rpc-config.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2018 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 _RTEMS_RPC_CONFIG_H_
+#define _RTEMS_RPC_CONFIG_H_
+
+#define _RPC_read read
+#define _RPC_write write
+#define _RPC_close close
+#define _RTEMS_RPC_INTERNAL_
+
+#endif /* _RTEMS_RPC_CONFIG_H_ */
diff --git a/librpc/src/rpc/rtems_portmapper.c b/librpc/src/rpc/rtems_portmapper.c
new file mode 100644
index 0000000..8118482
--- /dev/null
+++ b/librpc/src/rpc/rtems_portmapper.c
@@ -0,0 +1,502 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/wait.h>
+#include <sys/signal.h>
+
+static void reg_service(struct svc_req *rqstp, SVCXPRT *xprt);
+static void callit(struct svc_req *rqstp, SVCXPRT *xprt);
+static struct pmaplist *pmaplist;
+static int debugging = 0;
+
+#include <rtems.h>
+#define fork() (-1)
+
+
+static rtems_task rtems_portmapper (rtems_task_argument unused)
+{
+ SVCXPRT *xprt;
+ int sock;
+ struct sockaddr_in addr;
+ int len = sizeof(struct sockaddr_in);
+ register struct pmaplist *pml;
+
+ rtems_rpc_task_init ();
+ if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
+ perror("portmap cannot create socket");
+ rtems_task_exit();
+ }
+
+ addr.sin_addr.s_addr = 0;
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(PMAPPORT);
+ if (bind(sock, (struct sockaddr *)&addr, len) != 0) {
+ perror("portmap cannot bind");
+ close (sock);
+ rtems_task_exit();
+ }
+
+ if ((xprt = svcudp_create(sock)) == (SVCXPRT *)NULL) {
+ fprintf(stderr, "couldn't do udp_create\n");
+ close (sock);
+ rtems_task_exit();
+ }
+ /* make an entry for ourself */
+ pml = (struct pmaplist *)malloc(sizeof(struct pmaplist));
+ pml->pml_next = 0;
+ pml->pml_map.pm_prog = PMAPPROG;
+ pml->pml_map.pm_vers = PMAPVERS;
+ pml->pml_map.pm_prot = IPPROTO_UDP;
+ pml->pml_map.pm_port = PMAPPORT;
+ pmaplist = pml;
+
+ if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
+ perror("portmap cannot create socket");
+ close (sock);
+ rtems_task_exit();
+ }
+ if (bind(sock, (struct sockaddr *)&addr, len) != 0) {
+ perror("portmap cannot bind");
+ close (sock);
+ rtems_task_exit();
+ }
+ if ((xprt = svctcp_create(sock, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE))
+ == (SVCXPRT *)NULL) {
+ fprintf(stderr, "couldn't do tcp_create\n");
+ close (sock);
+ rtems_task_exit();
+ }
+ /* make an entry for ourself */
+ pml = (struct pmaplist *)malloc(sizeof(struct pmaplist));
+ pml->pml_map.pm_prog = PMAPPROG;
+ pml->pml_map.pm_vers = PMAPVERS;
+ pml->pml_map.pm_prot = IPPROTO_TCP;
+ pml->pml_map.pm_port = PMAPPORT;
+ pml->pml_next = pmaplist;
+ pmaplist = pml;
+
+ (void)svc_register(xprt, PMAPPROG, PMAPVERS, reg_service, FALSE);
+
+ svc_run();
+ fprintf(stderr, "run_svc returned unexpectedly\n");
+ close (sock);
+ rtems_task_exit();
+}
+
+static struct pmaplist *
+find_service(
+ u_long prog,
+ u_long vers,
+ int prot )
+{
+ register struct pmaplist *hit = NULL;
+ register struct pmaplist *pml;
+
+ for (pml = pmaplist; pml != NULL; pml = pml->pml_next) {
+ if ((pml->pml_map.pm_prog != prog) ||
+ (pml->pml_map.pm_prot != prot))
+ continue;
+ hit = pml;
+ if (pml->pml_map.pm_vers == vers)
+ break;
+ }
+ return (hit);
+}
+
+/*
+ * 1 OK, 0 not
+ */
+static void reg_service(
+ struct svc_req *rqstp,
+ SVCXPRT *xprt )
+{
+ struct pmap reg;
+ struct pmaplist *pml, *prevpml, *fnd;
+ int ans, port;
+ caddr_t t;
+
+#ifdef DEBUG
+ fprintf(stderr, "server: about do a switch\n");
+#endif
+ switch (rqstp->rq_proc) {
+
+ case PMAPPROC_NULL:
+ /*
+ * Null proc call
+ */
+ if ((!svc_sendreply(xprt, (xdrproc_t) xdr_void, NULL)) &&
+ debugging) {
+ abort();
+ }
+ break;
+
+ case PMAPPROC_SET:
+ /*
+ * Set a program,version to port mapping
+ */
+ if (!svc_getargs(xprt, (xdrproc_t) xdr_pmap, (caddr_t)&reg))
+ svcerr_decode(xprt);
+ else {
+ /*
+ * check to see if already used
+ * find_service returns a hit even if
+ * the versions don't match, so check for it
+ */
+ fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot);
+ if (fnd && fnd->pml_map.pm_vers == reg.pm_vers) {
+ if (fnd->pml_map.pm_port == reg.pm_port) {
+ ans = 1;
+ goto done;
+ }
+ else {
+ ans = 0;
+ goto done;
+ }
+ } else {
+ /*
+ * add to END of list
+ */
+ pml = (struct pmaplist *)
+ malloc(sizeof(struct pmaplist));
+ pml->pml_map = reg;
+ pml->pml_next = 0;
+ if (pmaplist == 0) {
+ pmaplist = pml;
+ } else {
+ for (fnd= pmaplist; fnd->pml_next != 0;
+ fnd = fnd->pml_next);
+ fnd->pml_next = pml;
+ }
+ ans = 1;
+ }
+ done:
+ if ((!svc_sendreply(xprt, (xdrproc_t) xdr_long, (caddr_t)&ans)) &&
+ debugging) {
+ fprintf(stderr, "svc_sendreply\n");
+ abort();
+ }
+ }
+ break;
+
+ case PMAPPROC_UNSET:
+ /*
+ * Remove a program,version to port mapping.
+ */
+ if (!svc_getargs(xprt, (xdrproc_t) xdr_pmap, (caddr_t)&reg))
+ svcerr_decode(xprt);
+ else {
+ ans = 0;
+ for (prevpml = NULL, pml = pmaplist; pml != NULL; ) {
+ if ((pml->pml_map.pm_prog != reg.pm_prog) ||
+ (pml->pml_map.pm_vers != reg.pm_vers)) {
+ /* both pml & prevpml move forwards */
+ prevpml = pml;
+ pml = pml->pml_next;
+ continue;
+ }
+ /* found it; pml moves forward, prevpml stays */
+ ans = 1;
+ t = (caddr_t)pml;
+ pml = pml->pml_next;
+ if (prevpml == NULL)
+ pmaplist = pml;
+ else
+ prevpml->pml_next = pml;
+ free(t);
+ }
+ if ((!svc_sendreply(xprt, (xdrproc_t) xdr_long, (caddr_t)&ans)) &&
+ debugging) {
+ fprintf(stderr, "svc_sendreply\n");
+ abort();
+ }
+ }
+ break;
+
+ case PMAPPROC_GETPORT:
+ /*
+ * Lookup the mapping for a program,version and return its port
+ */
+ if (!svc_getargs(xprt, (xdrproc_t) xdr_pmap, (caddr_t)&reg))
+ svcerr_decode(xprt);
+ else {
+ fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot);
+ if (fnd)
+ port = fnd->pml_map.pm_port;
+ else
+ port = 0;
+ if ((!svc_sendreply(xprt, (xdrproc_t) xdr_long, (caddr_t)&port)) &&
+ debugging) {
+ fprintf(stderr, "svc_sendreply\n");
+ abort();
+ }
+ }
+ break;
+
+ case PMAPPROC_DUMP:
+ /*
+ * Return the current set of mapped program,version
+ */
+ if (!svc_getargs(xprt, (xdrproc_t) xdr_void, NULL))
+ svcerr_decode(xprt);
+ else {
+ if ((!svc_sendreply(xprt, (xdrproc_t) xdr_pmaplist,
+ (caddr_t)&pmaplist)) && debugging) {
+ fprintf(stderr, "svc_sendreply\n");
+ abort();
+ }
+ }
+ break;
+
+ case PMAPPROC_CALLIT:
+ /*
+ * Calls a procedure on the local machine. If the requested
+ * procedure is not registered this procedure does not return
+ * error information!!
+ * This procedure is only supported on rpc/udp and calls via
+ * rpc/udp. It passes null authentication parameters.
+ */
+ callit(rqstp, xprt);
+ break;
+
+ default:
+ svcerr_noproc(xprt);
+ break;
+ }
+}
+
+
+/*
+ * Stuff for the rmtcall service
+ */
+#define ARGSIZE 9000
+
+struct encap_parms {
+ u_long arglen;
+ char *args;
+};
+
+static bool_t
+xdr_encap_parms(
+ XDR *xdrs,
+ struct encap_parms *epp )
+{
+
+ u_int temp_epp_arglen = epp->arglen;
+ return (xdr_bytes(xdrs, &(epp->args), &temp_epp_arglen, ARGSIZE));
+}
+
+struct rmtcallargs {
+ u_long rmt_prog;
+ u_long rmt_vers;
+ u_long rmt_port;
+ u_long rmt_proc;
+ struct encap_parms rmt_args;
+};
+
+static bool_t
+xdr_rmtcall_args(
+ register XDR *xdrs,
+ register struct rmtcallargs *cap )
+{
+
+ /* does not get a port number */
+ if (xdr_u_long(xdrs, &(cap->rmt_prog)) &&
+ xdr_u_long(xdrs, &(cap->rmt_vers)) &&
+ xdr_u_long(xdrs, &(cap->rmt_proc))) {
+ return (xdr_encap_parms(xdrs, &(cap->rmt_args)));
+ }
+ return (FALSE);
+}
+
+static bool_t
+xdr_rmtcall_result(
+ register XDR *xdrs,
+ register struct rmtcallargs *cap )
+{
+ if (xdr_u_long(xdrs, &(cap->rmt_port)))
+ return (xdr_encap_parms(xdrs, &(cap->rmt_args)));
+ return (FALSE);
+}
+
+/*
+ * only worries about the struct encap_parms part of struct rmtcallargs.
+ * The arglen must already be set!!
+ */
+static bool_t
+xdr_opaque_parms(
+ XDR *xdrs,
+ void *args,
+ ... )
+{
+ struct rmtcallargs *cap = (struct rmtcallargs *) args;
+
+ return (xdr_opaque(xdrs, cap->rmt_args.args, cap->rmt_args.arglen));
+}
+
+/*
+ * This routine finds and sets the length of incoming opaque paraters
+ * and then calls xdr_opaque_parms.
+ */
+static bool_t
+xdr_len_opaque_parms(
+ XDR *xdrs,
+ void *args,
+ ... )
+{
+ struct rmtcallargs *cap = (struct rmtcallargs *) args;
+ register u_int beginpos, lowpos, highpos, currpos, pos;
+
+ beginpos = lowpos = pos = xdr_getpos(xdrs);
+ highpos = lowpos + ARGSIZE;
+ while ((int)(highpos - lowpos) >= 0) {
+ currpos = (lowpos + highpos) / 2;
+ if (xdr_setpos(xdrs, currpos)) {
+ pos = currpos;
+ lowpos = currpos + 1;
+ } else {
+ highpos = currpos - 1;
+ }
+ }
+ xdr_setpos(xdrs, beginpos);
+ cap->rmt_args.arglen = pos - beginpos;
+ return (xdr_opaque_parms(xdrs, cap));
+}
+
+/*
+ * Call a remote procedure service
+ * This procedure is very quiet when things go wrong.
+ * The proc is written to support broadcast rpc. In the broadcast case,
+ * a machine should shut-up instead of complain, less the requestor be
+ * overrun with complaints at the expense of not hearing a valid reply ...
+ *
+ * This now forks so that the program & process that it calls can call
+ * back to the portmapper.
+ */
+static void
+callit(
+ struct svc_req *rqstp,
+ SVCXPRT *xprt )
+{
+ struct rmtcallargs a;
+ struct pmaplist *pml;
+ u_short port;
+ struct sockaddr_in me;
+ int pid, socket = -1;
+ CLIENT *client;
+ struct authunix_parms *au = (struct authunix_parms *)rqstp->rq_clntcred;
+ struct timeval timeout;
+ char buf[ARGSIZE];
+
+ timeout.tv_sec = 5;
+ timeout.tv_usec = 0;
+ a.rmt_args.args = buf;
+ if (!svc_getargs(xprt, (xdrproc_t) xdr_rmtcall_args, (caddr_t)&a))
+ return;
+ if ((pml = find_service(a.rmt_prog, a.rmt_vers, IPPROTO_UDP)) == NULL)
+ return;
+ /*
+ * fork a child to do the work. Parent immediately returns.
+ * Child exits upon completion.
+ */
+ if ((pid = fork()) != 0) {
+ if (debugging && (pid < 0)) {
+ fprintf(stderr, "portmap CALLIT: cannot fork.\n");
+ }
+ return;
+ }
+ port = pml->pml_map.pm_port;
+ get_myaddress(&me);
+ me.sin_port = htons(port);
+ client = clntudp_create(&me, a.rmt_prog, a.rmt_vers, timeout, &socket);
+ if (client != (CLIENT *)NULL) {
+ if (rqstp->rq_cred.oa_flavor == AUTH_UNIX) {
+ client->cl_auth = authunix_create(au->aup_machname,
+ au->aup_uid, au->aup_gid, au->aup_len, au->aup_gids);
+ }
+ a.rmt_port = (u_long)port;
+ if (clnt_call(client, a.rmt_proc, xdr_opaque_parms, &a,
+ xdr_len_opaque_parms, &a, timeout) == RPC_SUCCESS) {
+ svc_sendreply(xprt, (xdrproc_t) xdr_rmtcall_result, (caddr_t)&a);
+ }
+ AUTH_DESTROY(client->cl_auth);
+ clnt_destroy(client);
+ }
+ (void)close(socket);
+ exit(0);
+}
+
+/*
+ * Start the RPC portmapper
+ */
+int rtems_rpc_start_portmapper (int priority)
+{
+ rtems_mode mode;
+ rtems_status_code sc;
+ rtems_id tid;
+ static int started;
+
+ rtems_task_mode (RTEMS_NO_PREEMPT, RTEMS_PREEMPT_MASK, &mode);
+ if (started) {
+ rtems_task_mode (mode, RTEMS_PREEMPT_MASK, &mode);
+ return RTEMS_SUCCESSFUL;
+ }
+ sc = rtems_task_create (rtems_build_name('P', 'M', 'A', 'P'),
+ priority,
+ ARGSIZE + 8000,
+ RTEMS_PREEMPT|RTEMS_NO_TIMESLICE|RTEMS_NO_ASR|RTEMS_INTERRUPT_LEVEL(0),
+ RTEMS_NO_FLOATING_POINT|RTEMS_LOCAL,
+ &tid);
+ if (sc != RTEMS_SUCCESSFUL) {
+ rtems_task_mode (mode, RTEMS_PREEMPT_MASK, &mode);
+ return sc;
+ }
+ sc = rtems_task_start (tid, rtems_portmapper, 0);
+ if (sc != RTEMS_SUCCESSFUL) {
+ rtems_task_mode (mode, RTEMS_PREEMPT_MASK, &mode);
+ return sc;
+ }
+ started = 1;
+ rtems_task_mode (mode, RTEMS_PREEMPT_MASK, &mode);
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/librpc/src/rpc/rtems_rpc.c b/librpc/src/rpc/rtems_rpc.c
new file mode 100644
index 0000000..91e2b0f
--- /dev/null
+++ b/librpc/src/rpc/rtems_rpc.c
@@ -0,0 +1,127 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * RTEMS multi-tasking support
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rpc/rpc.h>
+#include <rtems.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <assert.h>
+
+/*
+ * RPC variables for single-thread
+ */
+static struct _rtems_rpc_task_variables rpc_default = {
+ -1, /* svc_maxfd */
+ {{0}}, /* svc_svc_fdset */
+ NULL, /* svc_xports */
+ 0, /* svc_xportssize */
+ 0, /* svc__svc_fdsetsize */
+ 0, /* svc__svc_fdset */
+ NULL, /* svc_svc_head */
+ 0, /* clnt_perror_buf */
+ 0, /* clnt_raw_private */
+ 0, /* call_rpc_private */
+ 0, /* svc_raw_private */
+
+ 0, /* svc_simple_proglst */
+ 0, /* svc_simple_pl */
+ 0, /* svc_simple_transp */
+
+ 0, /* rpcdname_default_domain */
+ 0 /* svc_auths_Auths */
+};
+
+/*
+ * RPC values for initializing a new per-task set of variables
+ */
+static const struct _rtems_rpc_task_variables rpc_init = {
+ -1, /* svc_maxfd */
+ {{0}}, /* svc_svc_fdset */
+ NULL, /* svc_xports */
+ 0, /* svc_xportssize */
+ 0, /* svc__svc_fdsetsize */
+ 0, /* svc__svc_fdset */
+ NULL, /* svc_svc_head */
+ 0, /* clnt_perror_buf */
+ 0, /* clnt_raw_private */
+ 0, /* call_rpc_private */
+ 0, /* svc_raw_private */
+
+ 0, /* svc_simple_proglst */
+ 0, /* svc_simple_pl */
+ 0, /* svc_simple_transp */
+
+ 0, /* rpcdname_default_domain */
+ 0 /* svc_auths_Auths */
+};
+
+/*
+ * Per-task pointer to RPC data
+ */
+static pthread_once_t rtems_rpc_task_variable_once = PTHREAD_ONCE_INIT;
+static pthread_key_t rtems_rpc_task_variable_key;
+
+/*
+ * Return the current task variable pointer.
+ */
+struct _rtems_rpc_task_variables *rtems_rpc_task_variables_get (void)
+{
+ void *ptr = pthread_getspecific(rtems_rpc_task_variable_key);
+ if (ptr == NULL) {
+ ptr = &rpc_default;
+ }
+ return (struct _rtems_rpc_task_variables *) ptr;
+}
+
+/*
+ * Key create function for task_variable_key.
+ */
+static void rtems_rpc_task_variable_make_key (void)
+{
+ int eno = pthread_key_create(&rtems_rpc_task_variable_key, NULL);
+ assert (eno == 0);
+ /*
+ * FIXME: Should have destructor which cleans up
+ * all RPC stuff:
+ * - Close all files
+ * - Go through and free linked list elements
+ * - Free other allocated memory (e.g. clnt_perror_buf)
+ */
+}
+
+/*
+ * Set up per-task RPC variables
+ */
+int rtems_rpc_task_init (void)
+{
+ struct _rtems_rpc_task_variables *tvp;
+ int eno = 0;
+
+ eno = pthread_once(
+ &rtems_rpc_task_variable_once,
+ rtems_rpc_task_variable_make_key
+ );
+ assert (eno == 0);
+
+ tvp = pthread_getspecific (rtems_rpc_task_variable_key);
+ if (tvp == NULL) {
+ tvp = malloc (sizeof *tvp);
+ if (tvp == NULL)
+ return RTEMS_NO_MEMORY;
+
+ eno = pthread_setspecific (rtems_rpc_task_variable_key, (void *) tvp);
+ if (eno != 0) {
+ free (tvp);
+ return RTEMS_INTERNAL_ERROR;
+ }
+ *tvp = rpc_init;
+ }
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/librpc/src/rpc/rtime.3 b/librpc/src/rpc/rtime.3
new file mode 100644
index 0000000..ad3e538
--- /dev/null
+++ b/librpc/src/rpc/rtime.3
@@ -0,0 +1,47 @@
+.\" @(#)rtime.3n 2.1 88/08/08 4.0 RPCSRC; from 1.5 88/02/08 SMI
+.\" $FreeBSD: src/lib/libc/rpc/rtime.3,v 1.4 2000/03/02 09:13:48 sheldonh Exp $
+.\"
+.TH RTIME 3 "22 November 1987"
+.SH NAME
+rtime \- get remote time
+.SH SYNOPSIS
+.nf
+.B #include <sys/types.h>
+.B #include <sys/time.h>
+.B #include <netinet/in.h>
+.LP
+.B int rtime(addrp, timep, timeout)
+.B struct sockaddr_in \(**addrp;
+.B struct timeval \(**timep;
+.B struct timeval \(**timeout;
+.fi
+.SH DESCRIPTION
+.B rtime(\|)
+consults the Internet Time Server at the address pointed to by
+.I addrp
+and returns the remote time in the
+.B timeval
+struct pointed to by
+.IR timep .
+Normally, the
+.SM UDP
+protocol is used when consulting the Time Server.
+The
+.I timeout
+parameter specifies how long the
+routine should wait before giving
+up when waiting for a reply. If
+.I timeout
+is specified as
+.SM NULL\s0,
+however, the routine will instead use
+.SM TCP
+and block until a reply is received from the time server.
+.LP
+The routine returns 0 if it is successful.
+Otherwise,
+it returns \-1 and
+.B errno
+is set to reflect the cause of the error.
+.SH "SEE ALSO"
+.BR timed (8c)
diff --git a/librpc/src/rpc/rtime.c b/librpc/src/rpc/rtime.c
new file mode 100644
index 0000000..4a77084
--- /dev/null
+++ b/librpc/src/rpc/rtime.c
@@ -0,0 +1,165 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+/*
+ * Copyright (c) 1988 by Sun Microsystems, Inc.
+
+ */
+
+/*
+ * rtime - get time from remote machine
+ *
+ * gets time, obtaining value from host
+ * on the udp/time socket. Since timeserver returns
+ * with time of day in seconds since Jan 1, 1900, must
+ * subtract seconds before Jan 1, 1970 to get
+ * what unix uses.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <netdb.h>
+#include <sys/select.h>
+#include <inttypes.h>
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/* from: static char sccsid[] = "@(#)rtime.c 2.2 88/08/10 4.0 RPCSRC; from 1.8 88/02/08 SMI"; */
+static const char rcsid[] = "$FreeBSD: src/lib/libc/rpc/rtime.c,v 1.5 2000/01/27 23:06:41 jasone Exp $";
+#endif
+
+extern int _rpc_dtablesize( void );
+
+#define NYEARS (UINT32_C(1970) - UINT32_C(1900))
+#define TOFFSET (UINT32_C(60)*UINT32_C(60)*UINT32_C(24)*(UINT32_C(365)*NYEARS + (NYEARS/UINT32_C(4))))
+
+static void do_close( int );
+
+int
+rtime(
+ struct sockaddr_in *addrp,
+ struct timeval *timep,
+ struct timeval *timeout )
+{
+ int s;
+ fd_set readfds;
+ int res;
+ uint32_t thetime;
+ struct sockaddr_in from;
+ socklen_t fromlen;
+ int type;
+ struct servent *serv;
+
+ if (timeout == NULL) {
+ type = SOCK_STREAM;
+ } else {
+ type = SOCK_DGRAM;
+ }
+ s = socket(AF_INET, type, 0);
+ if (s < 0) {
+ return(-1);
+ }
+ addrp->sin_family = AF_INET;
+
+ /* TCP and UDP port are the same in this case */
+ if ((serv = getservbyname("time", "tcp")) == NULL) {
+ return(-1);
+ }
+
+ addrp->sin_port = serv->s_port;
+
+ if (type == SOCK_DGRAM) {
+ res = sendto(s, (char *)&thetime, sizeof(thetime), 0,
+ (struct sockaddr *)addrp, sizeof(*addrp));
+ if (res < 0) {
+ do_close(s);
+ return(-1);
+ }
+ do {
+ FD_ZERO(&readfds);
+ FD_SET(s, &readfds);
+ res = select(_rpc_dtablesize(), &readfds,
+ (fd_set *)NULL, (fd_set *)NULL, timeout);
+ } while (res < 0 && errno == EINTR);
+ if (res <= 0) {
+ if (res == 0) {
+ errno = ETIMEDOUT;
+ }
+ do_close(s);
+ return(-1);
+ }
+ fromlen = sizeof(from);
+ res = recvfrom(s, (char *)&thetime, sizeof(thetime), 0,
+ (struct sockaddr *)&from, &fromlen);
+ do_close(s);
+ if (res < 0) {
+ return(-1);
+ }
+ } else {
+ if (connect(s, (struct sockaddr *)addrp, sizeof(*addrp)) < 0) {
+ do_close(s);
+ return(-1);
+ }
+ res = _RPC_read(s, (char *)&thetime, sizeof(thetime));
+ do_close(s);
+ if (res < 0) {
+ return(-1);
+ }
+ }
+ if (res != sizeof(thetime)) {
+ errno = EIO;
+ return(-1);
+ }
+ thetime = ntohl(thetime);
+ timep->tv_sec = thetime - TOFFSET;
+ timep->tv_usec = 0;
+ return(0);
+}
+
+static void
+do_close(int s)
+{
+ int save;
+
+ save = errno;
+ (void)_RPC_close(s);
+ errno = save;
+}
diff --git a/librpc/src/rpc/svc.c b/librpc/src/rpc/svc.c
new file mode 100644
index 0000000..a1f5769
--- /dev/null
+++ b/librpc/src/rpc/svc.c
@@ -0,0 +1,502 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)svc.c 1.44 88/02/08 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)svc.c 2.4 88/08/11 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/svc.c,v 1.14 1999/08/28 00:00:48 peter Exp $";
+#endif
+
+/*
+ * svc.c, Server-side remote procedure call interface.
+ *
+ * There are two sets of procedures here. The xprt routines are
+ * for handling transport handles. The svc routines handle the
+ * list of service routines.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#ifdef HAVE_STRINGS_H
+#include <strings.h> /* for ffs */
+#endif
+#include <stdlib.h>
+#include <sys/errno.h>
+#include <sys/param.h>
+#include <rpc/rpc.h>
+#include <rpc/pmap_clnt.h>
+
+#define xports (rtems_rpc_task_variables->svc_xports)
+#define xportssize (rtems_rpc_task_variables->svc_xportssize)
+
+#define NULL_SVC ((struct svc_callout *)0)
+#define RQCRED_SIZE 400 /* this size is excessive */
+
+#define max(a, b) (a > b ? a : b)
+
+/*
+ * The services list
+ * Each entry represents a set of procedures (an rpc program).
+ * The dispatch routine takes request structs and runs the
+ * apropriate procedure.
+ */
+struct svc_callout {
+ struct svc_callout *sc_next;
+ u_long sc_prog;
+ u_long sc_vers;
+ void (*sc_dispatch)(struct svc_req *r, SVCXPRT *xprt);
+};
+#define svc_head (rtems_rpc_task_variables->svc_svc_head)
+
+static struct svc_callout *svc_find(u_long prog, u_long vers,
+ struct svc_callout **prev);
+
+/* *************** SVCXPRT related stuff **************** */
+
+/*
+ * Activate a transport handle.
+ */
+void
+xprt_register(
+ SVCXPRT *xprt )
+{
+ register int sock = xprt->xp_sock;
+
+ if (sock + 1 > __svc_fdsetsize) {
+ int bytes = sizeof (fd_set);
+ fd_set *fds;
+
+ fds = (fd_set *)malloc(bytes);
+ memset(fds, 0, bytes);
+ if (__svc_fdset) {
+ memcpy(fds, __svc_fdset, bytes);
+ free(__svc_fdset);
+ }
+ __svc_fdset = fds;
+ __svc_fdsetsize = bytes * NBBY;
+ }
+
+ if (sock < FD_SETSIZE)
+ FD_SET(sock, &svc_fdset);
+ FD_SET(sock, __svc_fdset);
+
+ if (xports == NULL || sock + 1 > xportssize) {
+ SVCXPRT **xp;
+ int size = FD_SETSIZE;
+
+ if (sock + 1 > size)
+ size = sock + 1;
+ xp = (SVCXPRT **)mem_alloc(size * sizeof(SVCXPRT *));
+ memset(xp, 0, size * sizeof(SVCXPRT *));
+ if (xports) {
+ memcpy(xp, xports, xportssize * sizeof(SVCXPRT *));
+ free(xports);
+ }
+ xportssize = size;
+ xports = xp;
+ }
+ xports[sock] = xprt;
+ svc_maxfd = max(svc_maxfd, sock);
+}
+
+/*
+ * De-activate a transport handle.
+ */
+void
+xprt_unregister(
+ SVCXPRT *xprt )
+{
+ register int sock = xprt->xp_sock;
+
+ if (xports[sock] == xprt) {
+ xports[sock] = (SVCXPRT *)0;
+ if (sock < FD_SETSIZE)
+ FD_CLR(sock, &svc_fdset);
+ FD_CLR(sock, __svc_fdset);
+ if (sock == svc_maxfd) {
+ for (svc_maxfd--; svc_maxfd >= 0; svc_maxfd--)
+ if (xports[svc_maxfd])
+ break;
+ }
+ /*
+ * XXX could use svc_maxfd as a hint to
+ * decrease the size of __svc_fdset
+ */
+ }
+}
+
+
+/* ********************** CALLOUT list related stuff ************* */
+
+/*
+ * Add a service program to the callout list.
+ * The dispatch routine will be called when a rpc request for this
+ * program number comes in.
+ */
+bool_t
+svc_register(
+ SVCXPRT *xprt,
+ u_long prog,
+ u_long vers,
+ void (*dispatch)(struct svc_req *r, SVCXPRT *xprt),
+ int protocol )
+{
+ struct svc_callout *prev;
+ register struct svc_callout *s;
+
+ if ((s = svc_find(prog, vers, &prev)) != NULL_SVC) {
+ if (s->sc_dispatch == dispatch)
+ goto pmap_it; /* he is registering another xptr */
+ return (FALSE);
+ }
+ s = (struct svc_callout *)mem_alloc(sizeof(struct svc_callout));
+ if (s == (struct svc_callout *)0) {
+ return (FALSE);
+ }
+ s->sc_prog = prog;
+ s->sc_vers = vers;
+ s->sc_dispatch = dispatch;
+ s->sc_next = svc_head;
+ svc_head = s;
+pmap_it:
+ /* now register the information with the local binder service */
+ if (protocol) {
+ return (pmap_set(prog, vers, protocol, xprt->xp_port));
+ }
+ return (TRUE);
+}
+
+/*
+ * Remove a service program from the callout list.
+ */
+void
+svc_unregister(
+ u_long prog,
+ u_long vers )
+{
+ struct svc_callout *prev;
+ register struct svc_callout *s;
+
+ if ((s = svc_find(prog, vers, &prev)) == NULL_SVC)
+ return;
+ if (prev == NULL_SVC) {
+ svc_head = s->sc_next;
+ } else {
+ prev->sc_next = s->sc_next;
+ }
+ s->sc_next = NULL_SVC;
+ mem_free((char *) s, (u_int) sizeof(struct svc_callout));
+ /* now unregister the information with the local binder service */
+ (void)pmap_unset(prog, vers);
+}
+
+/*
+ * Search the callout list for a program number, return the callout
+ * struct.
+ */
+static struct svc_callout *
+svc_find(
+ u_long prog,
+ u_long vers,
+ struct svc_callout **prev )
+{
+ register struct svc_callout *s, *p;
+
+ p = NULL_SVC;
+ for (s = svc_head; s != NULL_SVC; s = s->sc_next) {
+ if ((s->sc_prog == prog) && (s->sc_vers == vers))
+ goto done;
+ p = s;
+ }
+done:
+ *prev = p;
+ return (s);
+}
+
+/* ******************* REPLY GENERATION ROUTINES ************ */
+
+/*
+ * Send a reply to an rpc request
+ */
+bool_t
+svc_sendreply(
+ register SVCXPRT *xprt,
+ xdrproc_t xdr_results,
+ void *xdr_location )
+{
+ struct rpc_msg rply;
+
+ rply.rm_direction = REPLY;
+ rply.rm_reply.rp_stat = MSG_ACCEPTED;
+ rply.acpted_rply.ar_verf = xprt->xp_verf;
+ rply.acpted_rply.ar_stat = SUCCESS;
+ rply.acpted_rply.ar_results.where = xdr_location;
+ rply.acpted_rply.ar_results.proc = xdr_results;
+ return (SVC_REPLY(xprt, &rply));
+}
+
+/*
+ * No procedure error reply
+ */
+void
+svcerr_noproc(
+ register SVCXPRT *xprt )
+{
+ struct rpc_msg rply;
+
+ rply.rm_direction = REPLY;
+ rply.rm_reply.rp_stat = MSG_ACCEPTED;
+ rply.acpted_rply.ar_verf = xprt->xp_verf;
+ rply.acpted_rply.ar_stat = PROC_UNAVAIL;
+ SVC_REPLY(xprt, &rply);
+}
+
+/*
+ * Can't decode args error reply
+ */
+void
+svcerr_decode(
+ register SVCXPRT *xprt )
+{
+ struct rpc_msg rply;
+
+ rply.rm_direction = REPLY;
+ rply.rm_reply.rp_stat = MSG_ACCEPTED;
+ rply.acpted_rply.ar_verf = xprt->xp_verf;
+ rply.acpted_rply.ar_stat = GARBAGE_ARGS;
+ SVC_REPLY(xprt, &rply);
+}
+
+/*
+ * Some system error
+ */
+void
+svcerr_systemerr(
+ register SVCXPRT *xprt )
+{
+ struct rpc_msg rply;
+
+ rply.rm_direction = REPLY;
+ rply.rm_reply.rp_stat = MSG_ACCEPTED;
+ rply.acpted_rply.ar_verf = xprt->xp_verf;
+ rply.acpted_rply.ar_stat = SYSTEM_ERR;
+ SVC_REPLY(xprt, &rply);
+}
+
+/*
+ * Authentication error reply
+ */
+void
+svcerr_auth(
+ SVCXPRT *xprt,
+ enum auth_stat why )
+{
+ struct rpc_msg rply;
+
+ rply.rm_direction = REPLY;
+ rply.rm_reply.rp_stat = MSG_DENIED;
+ rply.rjcted_rply.rj_stat = AUTH_ERROR;
+ rply.rjcted_rply.rj_why = why;
+ SVC_REPLY(xprt, &rply);
+}
+
+/*
+ * Auth too weak error reply
+ */
+void
+svcerr_weakauth(
+ SVCXPRT *xprt )
+{
+
+ svcerr_auth(xprt, AUTH_TOOWEAK);
+}
+
+/*
+ * Program unavailable error reply
+ */
+void
+svcerr_noprog(
+ register SVCXPRT *xprt )
+{
+ struct rpc_msg rply;
+
+ rply.rm_direction = REPLY;
+ rply.rm_reply.rp_stat = MSG_ACCEPTED;
+ rply.acpted_rply.ar_verf = xprt->xp_verf;
+ rply.acpted_rply.ar_stat = PROG_UNAVAIL;
+ SVC_REPLY(xprt, &rply);
+}
+
+/*
+ * Program version mismatch error reply
+ */
+void
+svcerr_progvers(
+ register SVCXPRT *xprt,
+ rpcvers_t low_vers,
+ rpcvers_t high_vers )
+{
+ struct rpc_msg rply;
+
+ rply.rm_direction = REPLY;
+ rply.rm_reply.rp_stat = MSG_ACCEPTED;
+ rply.acpted_rply.ar_verf = xprt->xp_verf;
+ rply.acpted_rply.ar_stat = PROG_MISMATCH;
+ rply.acpted_rply.ar_vers.low = low_vers;
+ rply.acpted_rply.ar_vers.high = high_vers;
+ SVC_REPLY(xprt, &rply);
+}
+
+/* ******************* SERVER INPUT STUFF ******************* */
+
+/*
+ * Get server side input from some transport.
+ *
+ * Statement of authentication parameters management:
+ * This function owns and manages all authentication parameters, specifically
+ * the "raw" parameters (msg.rm_call.cb_cred and msg.rm_call.cb_verf) and
+ * the "cooked" credentials (rqst->rq_clntcred).
+ * However, this function does not know the structure of the cooked
+ * credentials, so it make the following assumptions:
+ * a) the structure is contiguous (no pointers), and
+ * b) the cred structure size does not exceed RQCRED_SIZE bytes.
+ * In all events, all three parameters are freed upon exit from this routine.
+ * The storage is trivially management on the call stack in user land, but
+ * is mallocated in kernel land.
+ */
+
+void
+svc_getreq(
+ int rdfds )
+{
+ fd_set readfds;
+
+ FD_ZERO(&readfds);
+ readfds.fds_bits[0] = rdfds;
+ svc_getreqset(&readfds);
+}
+
+void
+svc_getreqset(
+ fd_set *readfds )
+{
+ svc_getreqset2(readfds, FD_SETSIZE);
+}
+
+void
+svc_getreqset2(
+ fd_set *readfds,
+ int width )
+{
+ enum xprt_stat stat;
+ struct rpc_msg msg;
+ int prog_found;
+ u_long low_vers;
+ u_long high_vers;
+ struct svc_req r;
+ register SVCXPRT *xprt;
+ register int bit;
+ register int sock;
+ register fd_mask mask, *maskp;
+ char cred_area[2*MAX_AUTH_BYTES + RQCRED_SIZE];
+ msg.rm_call.cb_cred.oa_base = cred_area;
+ msg.rm_call.cb_verf.oa_base = &(cred_area[MAX_AUTH_BYTES]);
+ r.rq_clntcred = &(cred_area[2*MAX_AUTH_BYTES]);
+
+
+ maskp = readfds->fds_bits;
+ for (sock = 0; sock < width; sock += NFDBITS) {
+ for (mask = *maskp++; (bit = ffs(mask)); mask ^= (1 << (bit - 1))) {
+ /* sock has input waiting */
+ xprt = xports[sock + bit - 1];
+ if (xprt == NULL)
+ /* But do we control sock? */
+ continue;
+ /* now receive msgs from xprtprt (support batch calls) */
+ do {
+ if (SVC_RECV(xprt, &msg)) {
+
+ /* now find the exported program and call it */
+ register struct svc_callout *s;
+ enum auth_stat why;
+
+ r.rq_xprt = xprt;
+ r.rq_prog = msg.rm_call.cb_prog;
+ r.rq_vers = msg.rm_call.cb_vers;
+ r.rq_proc = msg.rm_call.cb_proc;
+ r.rq_cred = msg.rm_call.cb_cred;
+ /* first authenticate the message */
+ if ((why= _authenticate(&r, &msg)) != AUTH_OK) {
+ svcerr_auth(xprt, why);
+ goto call_done;
+ }
+ /* now match message with a registered service*/
+ prog_found = FALSE;
+ low_vers = (u_long) - 1;
+ high_vers = 0;
+ for (s = svc_head; s != NULL_SVC; s = s->sc_next) {
+ if (s->sc_prog == r.rq_prog) {
+ if (s->sc_vers == r.rq_vers) {
+ (*s->sc_dispatch)(&r, xprt);
+ goto call_done;
+ } /* found correct version */
+ prog_found = TRUE;
+ if (s->sc_vers < low_vers)
+ low_vers = s->sc_vers;
+ if (s->sc_vers > high_vers)
+ high_vers = s->sc_vers;
+ } /* found correct program */
+ }
+ /*
+ * if we got here, the program or version
+ * is not served ...
+ */
+ if (prog_found)
+ svcerr_progvers(xprt,
+ low_vers, high_vers);
+ else
+ svcerr_noprog(xprt);
+ /* Fall through to ... */
+ }
+ call_done:
+ if ((stat = SVC_STAT(xprt)) == XPRT_DIED){
+ SVC_DESTROY(xprt);
+ break;
+ }
+ } while (stat == XPRT_MOREREQS);
+ }
+ }
+}
diff --git a/librpc/src/rpc/svc_auth.c b/librpc/src/rpc/svc_auth.c
new file mode 100644
index 0000000..0bee517
--- /dev/null
+++ b/librpc/src/rpc/svc_auth.c
@@ -0,0 +1,222 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+/*
+ * Copyright (c) 1986-1991 by Sun Microsystems Inc.
+ */
+
+/* #ident "@(#)svc_auth.c 1.16 94/04/24 SMI" */
+
+#if !defined(lint) && defined(SCCSIDS)
+#if 0
+static char sccsid[] = "@(#)svc_auth.c 1.26 89/02/07 Copyr 1984 Sun Micro";
+#else
+static const char rcsid[] =
+ "$FreeBSD: src/lib/libc/rpc/svc_auth.c,v 1.7 1999/12/29 05:04:16 peter Exp $";
+#endif
+#endif
+
+/*
+ * svc_auth.c, Server-side rpc authenticator interface.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef _KERNEL
+#include <sys/param.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#include <rpc/clnt.h>
+#include <rpc/rpc_msg.h>
+#include <rpc/svc.h>
+#include <rpc/svc_auth.h>
+#else
+#include <stdlib.h>
+#include <rpc/rpc.h>
+#endif
+#include <sys/types.h>
+
+/*
+ * svcauthsw is the bdevsw of server side authentication.
+ *
+ * Server side authenticators are called from authenticate by
+ * using the client auth struct flavor field to index into svcauthsw.
+ * The server auth flavors must implement a routine that looks
+ * like:
+ *
+ * enum auth_stat
+ * flavorx_auth(rqst, msg)
+ * register struct svc_req *rqst;
+ * register struct rpc_msg *msg;
+ *
+ */
+
+enum auth_stat _svcauth_null(struct svc_req *rqst, struct rpc_msg *msg); /* no authentication */
+enum auth_stat _svcauth_unix(struct svc_req *rqst, struct rpc_msg *msg); /* (system) unix style (uid, gids) */
+enum auth_stat _svcauth_short(struct svc_req *rqst, struct rpc_msg *msg); /* short hand unix style */
+enum auth_stat _svcauth_des(struct svc_req *rqst, struct rpc_msg *msg); /* des style */
+
+/* declarations to allow servers to specify new authentication flavors */
+struct authsvc {
+ int flavor;
+ enum auth_stat (*handler)(struct svc_req *rqst, struct rpc_msg *msg);
+ struct authsvc *next;
+};
+#define Auths (rtems_rpc_task_variables->svc_auths_Auths)
+
+/*
+ * The call rpc message, msg has been obtained from the wire. The msg contains
+ * the raw form of credentials and verifiers. authenticate returns AUTH_OK
+ * if the msg is successfully authenticated. If AUTH_OK then the routine also
+ * does the following things:
+ * set rqst->rq_xprt->verf to the appropriate response verifier;
+ * sets rqst->rq_client_cred to the "cooked" form of the credentials.
+ *
+ * NB: rqst->rq_cxprt->verf must be pre-alloctaed;
+ * its length is set appropriately.
+ *
+ * The caller still owns and is responsible for msg->u.cmb.cred and
+ * msg->u.cmb.verf. The authentication system retains ownership of
+ * rqst->rq_client_cred, the cooked credentials.
+ *
+ * There is an assumption that any flavour less than AUTH_NULL is
+ * invalid.
+ */
+enum auth_stat
+_authenticate(
+ struct svc_req *rqst,
+ struct rpc_msg *msg )
+{
+ register int cred_flavor;
+ register struct authsvc *asp;
+
+ rqst->rq_cred = msg->rm_call.cb_cred;
+ rqst->rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor;
+ rqst->rq_xprt->xp_verf.oa_length = 0;
+ cred_flavor = rqst->rq_cred.oa_flavor;
+ switch (cred_flavor) {
+ case AUTH_NULL:
+ return(_svcauth_null(rqst, msg));
+ case AUTH_UNIX:
+ return(_svcauth_unix(rqst, msg));
+ case AUTH_SHORT:
+ return(_svcauth_short(rqst, msg));
+ /*
+ * We leave AUTH_DES turned off by default because svcauth_des()
+ * needs getpublickey(), which is in librpcsvc, not libc. If we
+ * included AUTH_DES as a built-in flavor, programs that don't
+ * have -lrpcsvc in their Makefiles wouldn't link correctly, even
+ * though they don't use AUTH_DES. And I'm too lazy to go through
+ * the tree looking for all of them.
+ */
+#ifdef DES_BUILTIN
+ case AUTH_DES:
+ return(_svcauth_des(rqst, msg));
+#endif
+ }
+
+ /* flavor doesn't match any of the builtin types, so try new ones */
+ for (asp = Auths; asp; asp = asp->next) {
+ if (asp->flavor == cred_flavor) {
+ enum auth_stat as;
+
+ as = (*asp->handler)(rqst, msg);
+ return (as);
+ }
+ }
+
+ return (AUTH_REJECTEDCRED);
+}
+
+/*ARGSUSED*/
+enum auth_stat
+_svcauth_null(
+ struct svc_req *rqst,
+ struct rpc_msg *msg)
+{
+ return (AUTH_OK);
+}
+
+/*
+ * Allow the rpc service to register new authentication types that it is
+ * prepared to handle. When an authentication flavor is registered,
+ * the flavor is checked against already registered values. If not
+ * registered, then a new Auths entry is added on the list.
+ *
+ * There is no provision to delete a registration once registered.
+ *
+ * This routine returns:
+ * 0 if registration successful
+ * 1 if flavor already registered
+ * -1 if can't register (errno set)
+ */
+
+int
+svc_auth_reg(
+ int cred_flavor,
+ enum auth_stat (*handler)(struct svc_req *rqst, struct rpc_msg *msg))
+{
+ register struct authsvc *asp;
+
+ switch (cred_flavor) {
+ case AUTH_NULL:
+ case AUTH_UNIX:
+ case AUTH_SHORT:
+#ifdef DES_BUILTIN
+ case AUTH_DES:
+#endif
+ /* already registered */
+ return (1);
+
+ default:
+ for (asp = Auths; asp; asp = asp->next) {
+ if (asp->flavor == cred_flavor) {
+ /* already registered */
+ return (1);
+ }
+ }
+
+ /* this is a new one, so go ahead and register it */
+ asp = (struct authsvc *)mem_alloc(sizeof (*asp));
+ if (asp == NULL) {
+ return (-1);
+ }
+ asp->flavor = cred_flavor;
+ asp->handler = handler;
+ asp->next = Auths;
+ Auths = asp;
+ break;
+ }
+ return (0);
+}
diff --git a/librpc/src/rpc/svc_auth_unix.c b/librpc/src/rpc/svc_auth_unix.c
new file mode 100644
index 0000000..0dccc47
--- /dev/null
+++ b/librpc/src/rpc/svc_auth_unix.c
@@ -0,0 +1,154 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)svc_auth_unix.c 1.28 88/02/08 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)svc_auth_unix.c 2.3 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/svc_auth_unix.c,v 1.8 1999/08/28 00:00:49 peter Exp $";
+#endif
+
+/*
+ * svc_auth_unix.c
+ * Handles UNIX flavor authentication parameters on the service side of rpc.
+ * There are two svc auth implementations here: AUTH_UNIX and AUTH_SHORT.
+ * _svcauth_unix does full blown unix style uid,gid+gids auth,
+ * _svcauth_short uses a shorthand auth to index into a cache of longhand auths.
+ * Note: the shorthand has been gutted for efficiency.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <rpc/rpc.h>
+
+/*
+ * Unix longhand authenticator
+ */
+enum auth_stat
+_svcauth_unix(
+ struct svc_req *rqst,
+ struct rpc_msg *msg )
+{
+ register enum auth_stat stat;
+ XDR xdrs;
+ register struct authunix_parms *aup;
+ register int32_t *buf;
+ struct area {
+ struct authunix_parms area_aup;
+ char area_machname[MAX_MACHINE_NAME+1];
+ int area_gids[NGRPS];
+ } *area;
+ u_int auth_len;
+ int str_len, gid_len;
+ register int i;
+
+ area = (struct area *) rqst->rq_clntcred;
+ aup = &area->area_aup;
+ aup->aup_machname = area->area_machname;
+ aup->aup_gids = area->area_gids;
+ auth_len = (u_int)msg->rm_call.cb_cred.oa_length;
+ xdrmem_create(&xdrs, msg->rm_call.cb_cred.oa_base, auth_len,XDR_DECODE);
+ buf = XDR_INLINE(&xdrs, auth_len);
+ if (buf != NULL) {
+ aup->aup_time = IXDR_GET_LONG(buf);
+ str_len = IXDR_GET_U_LONG(buf);
+ if (str_len > MAX_MACHINE_NAME) {
+ stat = AUTH_BADCRED;
+ goto done;
+ }
+ memcpy(aup->aup_machname, (caddr_t)buf, (u_int)str_len);
+ aup->aup_machname[str_len] = 0;
+ str_len = RNDUP(str_len);
+ buf += str_len / sizeof (int32_t);
+ aup->aup_uid = IXDR_GET_LONG(buf);
+ aup->aup_gid = IXDR_GET_LONG(buf);
+ gid_len = IXDR_GET_U_LONG(buf);
+ if (gid_len > NGRPS) {
+ stat = AUTH_BADCRED;
+ goto done;
+ }
+ aup->aup_len = gid_len;
+ for (i = 0; i < gid_len; i++) {
+ aup->aup_gids[i] = IXDR_GET_LONG(buf);
+ }
+ /*
+ * five is the smallest unix credentials structure -
+ * timestamp, hostname len (0), uid, gid, and gids len (0).
+ */
+ if ((5 + gid_len) * BYTES_PER_XDR_UNIT + str_len > auth_len) {
+ (void) printf("bad auth_len gid %d str %d auth %d\n",
+ gid_len, str_len, auth_len);
+ stat = AUTH_BADCRED;
+ goto done;
+ }
+ } else if (! xdr_authunix_parms(&xdrs, aup)) {
+ xdrs.x_op = XDR_FREE;
+ (void)xdr_authunix_parms(&xdrs, aup);
+ stat = AUTH_BADCRED;
+ goto done;
+ }
+
+ /* get the verifier */
+ if ((u_int)msg->rm_call.cb_verf.oa_length) {
+ rqst->rq_xprt->xp_verf.oa_flavor =
+ msg->rm_call.cb_verf.oa_flavor;
+ rqst->rq_xprt->xp_verf.oa_base =
+ msg->rm_call.cb_verf.oa_base;
+ rqst->rq_xprt->xp_verf.oa_length =
+ msg->rm_call.cb_verf.oa_length;
+ } else {
+ rqst->rq_xprt->xp_verf.oa_flavor = AUTH_NULL;
+ rqst->rq_xprt->xp_verf.oa_length = 0;
+ }
+ stat = AUTH_OK;
+done:
+ XDR_DESTROY(&xdrs);
+ return (stat);
+}
+
+
+/*
+ * Shorthand unix authenticator
+ * Looks up longhand in a cache.
+ */
+/*ARGSUSED*/
+enum auth_stat
+_svcauth_short(
+ struct svc_req *rqst,
+ struct rpc_msg *msg )
+{
+ return (AUTH_REJECTEDCRED);
+}
diff --git a/librpc/src/rpc/svc_raw.c b/librpc/src/rpc/svc_raw.c
new file mode 100644
index 0000000..f3a6f57
--- /dev/null
+++ b/librpc/src/rpc/svc_raw.c
@@ -0,0 +1,175 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)svc_raw.c 1.15 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)svc_raw.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/svc_raw.c,v 1.7 1999/08/28 00:00:49 peter Exp $";
+#endif
+
+/*
+ * svc_raw.c, This a toy for simple testing and timing.
+ * Interface to create an rpc client and server in the same UNIX process.
+ * This lets us similate rpc and get rpc (round trip) overhead, without
+ * any interference from the kernal.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rpc/rpc.h>
+#include <stdlib.h>
+
+/*
+ * This is the "network" that we will be moving data over
+ */
+struct svc_raw_private {
+ char _raw_buf[UDPMSGSIZE];
+ SVCXPRT server;
+ XDR xdr_stream;
+ char verf_body[MAX_AUTH_BYTES];
+};
+#define svcraw_private ((struct svc_raw_private *)(rtems_rpc_task_variables)->svc_raw_private)
+
+static bool_t svcraw_recv(SVCXPRT *xprt, struct rpc_msg *msg);
+static enum xprt_stat svcraw_stat(SVCXPRT *xprt);
+static bool_t svcraw_getargs(SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr);
+static bool_t svcraw_reply(SVCXPRT *xprt, struct rpc_msg *msg);
+static bool_t svcraw_freeargs(SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr);
+static void svcraw_destroy(SVCXPRT *xprt);
+
+static struct xp_ops server_ops = {
+ svcraw_recv,
+ svcraw_stat,
+ svcraw_getargs,
+ svcraw_reply,
+ svcraw_freeargs,
+ svcraw_destroy
+};
+
+SVCXPRT *
+svcraw_create(void)
+{
+ register struct svc_raw_private *srp = svcraw_private;
+
+ if (srp == 0) {
+ srp = (struct svc_raw_private *)calloc(1, sizeof (*srp));
+ if (srp == 0)
+ return (0);
+ }
+ srp->server.xp_sock = 0;
+ srp->server.xp_port = 0;
+ srp->server.xp_ops = &server_ops;
+ srp->server.xp_verf.oa_base = srp->verf_body;
+ xdrmem_create(&srp->xdr_stream, srp->_raw_buf, UDPMSGSIZE, XDR_FREE);
+ return (&srp->server);
+}
+
+static enum xprt_stat
+svcraw_stat(SVCXPRT *xprt)
+{
+
+ return (XPRT_IDLE);
+}
+
+static bool_t
+svcraw_recv(
+ SVCXPRT *xprt,
+ struct rpc_msg *msg)
+{
+ register struct svc_raw_private *srp = svcraw_private;
+ register XDR *xdrs;
+
+ if (srp == 0)
+ return (0);
+ xdrs = &srp->xdr_stream;
+ xdrs->x_op = XDR_DECODE;
+ XDR_SETPOS(xdrs, 0);
+ if (! xdr_callmsg(xdrs, msg))
+ return (FALSE);
+ return (TRUE);
+}
+
+static bool_t
+svcraw_reply(
+ SVCXPRT *xprt,
+ struct rpc_msg *msg)
+{
+ register struct svc_raw_private *srp = svcraw_private;
+ register XDR *xdrs;
+
+ if (srp == 0)
+ return (FALSE);
+ xdrs = &srp->xdr_stream;
+ xdrs->x_op = XDR_ENCODE;
+ XDR_SETPOS(xdrs, 0);
+ if (! xdr_replymsg(xdrs, msg))
+ return (FALSE);
+ (void)XDR_GETPOS(xdrs); /* called just for overhead */
+ return (TRUE);
+}
+
+static bool_t
+svcraw_getargs(
+ SVCXPRT *xprt,
+ xdrproc_t xdr_args,
+ caddr_t args_ptr)
+{
+ register struct svc_raw_private *srp = svcraw_private;
+
+ if (srp == 0)
+ return (FALSE);
+ return ((*xdr_args)(&srp->xdr_stream, args_ptr));
+}
+
+static bool_t
+svcraw_freeargs(
+ SVCXPRT *xprt,
+ xdrproc_t xdr_args,
+ caddr_t args_ptr)
+{
+ register struct svc_raw_private *srp = svcraw_private;
+ register XDR *xdrs;
+
+ if (srp == 0)
+ return (FALSE);
+ xdrs = &srp->xdr_stream;
+ xdrs->x_op = XDR_FREE;
+ return ((*xdr_args)(xdrs, args_ptr));
+}
+
+static void
+svcraw_destroy(SVCXPRT *xprt)
+{
+}
diff --git a/librpc/src/rpc/svc_run.c b/librpc/src/rpc/svc_run.c
new file mode 100644
index 0000000..fc57fe2
--- /dev/null
+++ b/librpc/src/rpc/svc_run.c
@@ -0,0 +1,91 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)svc_run.c 1.1 87/10/13 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)svc_run.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/svc_run.c,v 1.10 1999/08/28 00:00:49 peter Exp $";
+#endif
+
+/*
+ * This is the rpc server side idle loop
+ * Wait for input, call server program.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rpc/rpc.h>
+#include <stdio.h>
+#include <sys/errno.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/select.h>
+
+void
+svc_run(void)
+{
+ fd_set *fds;
+
+ for (;;) {
+ if (__svc_fdset) {
+ int bytes = sizeof (fd_set);
+ fds = (fd_set *)malloc(bytes);
+ memcpy(fds, __svc_fdset, bytes);
+ } else
+ fds = NULL;
+ switch (select(svc_maxfd + 1, fds, NULL, NULL,
+ (struct timeval *)0)) {
+ case -1:
+ if (errno == EINTR) {
+ if (fds)
+ free(fds);
+ continue;
+ }
+ perror("svc_run: - select failed");
+ if (fds)
+ free(fds);
+ return;
+ case 0:
+ if (fds)
+ free(fds);
+ continue;
+ default:
+ /* if fds == NULL, select() can't return a result */
+ svc_getreqset2(fds, svc_maxfd + 1);
+ free(fds);
+ }
+ }
+}
diff --git a/librpc/src/rpc/svc_simple.c b/librpc/src/rpc/svc_simple.c
new file mode 100644
index 0000000..9f4b8fd
--- /dev/null
+++ b/librpc/src/rpc/svc_simple.c
@@ -0,0 +1,163 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)svc_simple.c 1.18 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)svc_simple.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/svc_simple.c,v 1.9 1999/08/28 00:00:50 peter Exp $";
+#endif
+
+/*
+ * svc_simple.c
+ * Simplified front end to rpc.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include <rpc/rpc.h>
+#include <rpc/pmap_clnt.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
+#include <inttypes.h> /* for PRIxx printf formats */
+
+struct prog_lst {
+ char *(*p_progname)(char *);
+ rpcprog_t p_prognum;
+ rpcproc_t p_procnum;
+ xdrproc_t p_inproc, p_outproc;
+ struct prog_lst *p_nxt;
+};
+static void universal(struct svc_req *, SVCXPRT *);
+#define proglst (rtems_rpc_task_variables->svc_simple_proglst)
+#define pl (rtems_rpc_task_variables->svc_simple_pl)
+#define transp (rtems_rpc_task_variables->svc_simple_transp)
+
+int
+registerrpc(
+ int prognum,
+ int versnum,
+ int procnum,
+ char *(*progname)(char *),
+ xdrproc_t inproc,
+ xdrproc_t outproc )
+{
+
+ if (procnum == NULLPROC) {
+ (void) fprintf(stderr,
+ "can't reassign procedure number %" PRIu32 "\n", NULLPROC);
+ return (-1);
+ }
+ if (transp == 0) {
+ transp = svcudp_create(RPC_ANYSOCK);
+ if (transp == NULL) {
+ (void) fprintf(stderr, "couldn't create an rpc server\n");
+ return (-1);
+ }
+ }
+ (void) pmap_unset((u_long)prognum, (u_long)versnum);
+ if (!svc_register(transp, (u_long)prognum, (u_long)versnum,
+ universal, IPPROTO_UDP)) {
+ (void) fprintf(stderr, "couldn't register prog %d vers %d\n",
+ prognum, versnum);
+ return (-1);
+ }
+ pl = (struct prog_lst *)malloc(sizeof(struct prog_lst));
+ if (pl == NULL) {
+ (void) fprintf(stderr, "registerrpc: out of memory\n");
+ return (-1);
+ }
+ pl->p_progname = progname;
+ pl->p_prognum = prognum;
+ pl->p_procnum = procnum;
+ pl->p_inproc = inproc;
+ pl->p_outproc = outproc;
+ pl->p_nxt = proglst;
+ proglst = pl;
+ return (0);
+}
+
+static void
+universal(
+ struct svc_req *rqstp,
+ SVCXPRT *atransp )
+{
+ int prog, proc;
+ char *outdata;
+ char xdrbuf[UDPMSGSIZE];
+ struct prog_lst *lpl;
+
+ /*
+ * enforce "procnum 0 is echo" convention
+ */
+ if (rqstp->rq_proc == NULLPROC) {
+ if (svc_sendreply(atransp, (xdrproc_t) xdr_void, NULL) == FALSE) {
+ (void) fprintf(stderr, "xxx\n");
+ exit(1);
+ }
+ return;
+ }
+ prog = rqstp->rq_prog;
+ proc = rqstp->rq_proc;
+ for (lpl = proglst; lpl != NULL; lpl = lpl->p_nxt)
+ if (lpl->p_prognum == prog && lpl->p_procnum == proc) {
+ /* decode arguments into a CLEAN buffer */
+ memset(xdrbuf, 0, sizeof(xdrbuf)); /* required ! */
+ if (!svc_getargs(atransp, lpl->p_inproc, xdrbuf)) {
+ svcerr_decode(atransp);
+ return;
+ }
+ outdata = (*(lpl->p_progname))(xdrbuf);
+ if (outdata == NULL &&
+ lpl->p_outproc != (xdrproc_t) xdr_void)
+ /* there was an error */
+ return;
+ if (!svc_sendreply(atransp, lpl->p_outproc, outdata)) {
+ (void) fprintf(stderr,
+ "trouble replying to prog %" PRIu32 "\n",
+ lpl->p_prognum);
+ exit(1);
+ }
+ /* free the decoded arguments */
+ (void)svc_freeargs(atransp, lpl->p_inproc, xdrbuf);
+ return;
+ }
+ (void) fprintf(stderr, "never registered prog %d\n", prog);
+ exit(1);
+}
diff --git a/librpc/src/rpc/svc_tcp.c b/librpc/src/rpc/svc_tcp.c
new file mode 100644
index 0000000..1827d1f
--- /dev/null
+++ b/librpc/src/rpc/svc_tcp.c
@@ -0,0 +1,491 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)svc_tcp.c 1.21 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)svc_tcp.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/svc_tcp.c,v 1.18 2000/01/27 23:06:41 jasone Exp $";
+#endif
+
+/*
+ * svc_tcp.c, Server side for TCP/IP based RPC.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * Actually implements two flavors of transporter -
+ * a tcp rendezvouser (a listner and connection establisher)
+ * and a record/tcp stream.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <sys/select.h>
+
+/*
+ * Ops vector for TCP/IP based rpc service handle
+ */
+static bool_t svctcp_recv(SVCXPRT *xprt, struct rpc_msg *msg);
+static enum xprt_stat svctcp_stat(SVCXPRT *xprt);
+static bool_t svctcp_getargs(SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr);
+static bool_t svctcp_reply(SVCXPRT *xprt, struct rpc_msg *msg);
+static bool_t svctcp_freeargs(SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr);
+static void svctcp_destroy(SVCXPRT *xprt);
+
+static struct xp_ops svctcp_op = {
+ svctcp_recv,
+ svctcp_stat,
+ svctcp_getargs,
+ svctcp_reply,
+ svctcp_freeargs,
+ svctcp_destroy
+};
+
+/*
+ * Ops vector for TCP/IP rendezvous handler
+ */
+static bool_t rendezvous_request(SVCXPRT *xprt, struct rpc_msg *msg);
+static enum xprt_stat rendezvous_stat(SVCXPRT *xprt);
+
+static struct xp_ops svctcp_rendezvous_op = {
+ rendezvous_request,
+ rendezvous_stat,
+ (bool_t (*)(SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr))abort,
+ (bool_t (*)(SVCXPRT *xprt, struct rpc_msg *msg))abort,
+ (bool_t (*)(SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr))abort,
+ svctcp_destroy
+};
+
+static int readtcp(char *, char*, int), writetcp(char *, char*, int);
+static SVCXPRT *makefd_xprt( int fd, u_int sendsize, u_int recvsize);
+
+struct tcp_rendezvous { /* kept in xprt->xp_p1 */
+ u_int sendsize;
+ u_int recvsize;
+};
+
+struct tcp_conn { /* kept in xprt->xp_p1 */
+ enum xprt_stat strm_stat;
+ u_long x_id;
+ XDR xdrs;
+ char verf_body[MAX_AUTH_BYTES];
+};
+
+/*
+ * Usage:
+ * xprt = svctcp_create(sock, send_buf_size, recv_buf_size);
+ *
+ * Creates, registers, and returns a (rpc) tcp based transporter.
+ * Once *xprt is initialized, it is registered as a transporter
+ * see (svc.h, xprt_register). This routine returns
+ * a NULL if a problem occurred.
+ *
+ * If sock<0 then a socket is created, else sock is used.
+ * If the socket, sock is not bound to a port then svctcp_create
+ * binds it to an arbitrary port. The routine then starts a tcp
+ * listener on the socket's associated port. In any (successful) case,
+ * xprt->xp_sock is the registered socket number and xprt->xp_port is the
+ * associated port number.
+ *
+ * Since tcp streams do buffered io similar to stdio, the caller can specify
+ * how big the send and receive buffers are via the second and third parms;
+ * 0 => use the system default.
+ */
+SVCXPRT *
+svctcp_create(
+ int sock,
+ u_int sendsize,
+ u_int recvsize)
+{
+ bool_t madesock = FALSE;
+ register SVCXPRT *xprt;
+ register struct tcp_rendezvous *r;
+ struct sockaddr_in addr;
+ socklen_t len = sizeof(struct sockaddr_in);
+ int on;
+
+ if (sock == RPC_ANYSOCK) {
+ if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
+ perror("svctcp_.c - udp socket creation problem");
+ return ((SVCXPRT *)NULL);
+ }
+ madesock = TRUE;
+ }
+ on = 1;
+ if (ioctl(sock, FIONBIO, &on) < 0) {
+ perror("svc_tcp.c - cannot turn on non-blocking mode");
+ if (madesock)
+ (void)_RPC_close(sock);
+ return ((SVCXPRT *)NULL);
+ }
+ memset(&addr, 0, sizeof (addr));
+ addr.sin_len = sizeof(struct sockaddr_in);
+ addr.sin_family = AF_INET;
+ if (bindresvport(sock, &addr)) {
+ addr.sin_port = 0;
+ (void)bind(sock, (struct sockaddr *)&addr, len);
+ }
+ if ((getsockname(sock, (struct sockaddr *)&addr, &len) != 0) ||
+ (listen(sock, 2) != 0)) {
+ perror("svctcp_.c - cannot getsockname or listen");
+ if (madesock)
+ (void)_RPC_close(sock);
+ return ((SVCXPRT *)NULL);
+ }
+ r = (struct tcp_rendezvous *)mem_alloc(sizeof(*r));
+ if (r == NULL) {
+ (void) fprintf(stderr, "svctcp_create: out of memory\n");
+ return (NULL);
+ }
+ r->sendsize = sendsize;
+ r->recvsize = recvsize;
+ xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
+ if (xprt == NULL) {
+ (void) fprintf(stderr, "svctcp_create: out of memory\n");
+ return (NULL);
+ }
+ xprt->xp_p2 = NULL;
+ xprt->xp_p1 = (caddr_t)r;
+ xprt->xp_verf = _null_auth;
+ xprt->xp_ops = &svctcp_rendezvous_op;
+ xprt->xp_port = ntohs(addr.sin_port);
+ xprt->xp_sock = sock;
+ xprt_register(xprt);
+ return (xprt);
+}
+
+/*
+ * Like svtcp_create(), except the routine takes any *open* UNIX file
+ * descriptor as its first input.
+ */
+SVCXPRT *
+svcfd_create(
+ int fd,
+ u_int sendsize,
+ u_int recvsize)
+{
+
+ return (makefd_xprt(fd, sendsize, recvsize));
+}
+
+static SVCXPRT *
+makefd_xprt(
+ int fd,
+ u_int sendsize,
+ u_int recvsize)
+{
+ register SVCXPRT *xprt;
+ register struct tcp_conn *cd;
+
+ xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
+ if (xprt == (SVCXPRT *)NULL) {
+ (void) fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n");
+ goto done;
+ }
+ cd = (struct tcp_conn *)mem_alloc(sizeof(struct tcp_conn));
+ if (cd == (struct tcp_conn *)NULL) {
+ (void) fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n");
+ mem_free((char *) xprt, sizeof(SVCXPRT));
+ xprt = (SVCXPRT *)NULL;
+ goto done;
+ }
+ cd->strm_stat = XPRT_IDLE;
+ xdrrec_create(&(cd->xdrs), sendsize, recvsize,
+ (caddr_t)xprt, readtcp, writetcp);
+ xprt->xp_p2 = NULL;
+ xprt->xp_p1 = (caddr_t)cd;
+ xprt->xp_verf.oa_base = cd->verf_body;
+ xprt->xp_addrlen = 0;
+ xprt->xp_ops = &svctcp_op; /* truely deals with calls */
+ xprt->xp_port = 0; /* this is a connection, not a rendezvouser */
+ xprt->xp_sock = fd;
+ xprt_register(xprt);
+ done:
+ return (xprt);
+}
+
+static bool_t
+rendezvous_request(
+ SVCXPRT *xprt,
+ struct rpc_msg *msg)
+{
+ int sock;
+ struct tcp_rendezvous *r;
+ struct sockaddr_in addr;
+ socklen_t len;
+ int off;
+
+ r = (struct tcp_rendezvous *)xprt->xp_p1;
+ again:
+ len = sizeof(struct sockaddr_in);
+ if ((sock = accept(xprt->xp_sock, (struct sockaddr *)&addr,
+ &len)) < 0) {
+ if (errno == EINTR)
+ goto again;
+ return (FALSE);
+ }
+ /*
+ * Guard against FTP bounce attacks.
+ */
+ if (addr.sin_port == htons(20)) {
+ _RPC_close(sock);
+ return (FALSE);
+ }
+ /*
+ * The listening socket is in FIONBIO mode and we inherit it.
+ */
+ off = 0;
+ if (ioctl(sock, FIONBIO, &off) < 0) {
+ _RPC_close(sock);
+ return (FALSE);
+ }
+ /*
+ * make a new transporter (re-uses xprt)
+ */
+ xprt = makefd_xprt(sock, r->sendsize, r->recvsize);
+ xprt->xp_raddr = addr;
+ xprt->xp_addrlen = len;
+ return (FALSE); /* there is never an rpc msg to be processed */
+}
+
+static enum xprt_stat
+rendezvous_stat(SVCXPRT *xprt)
+{
+
+ return (XPRT_IDLE);
+}
+
+static void
+svctcp_destroy(
+ SVCXPRT *xprt)
+{
+ register struct tcp_conn *cd = (struct tcp_conn *)xprt->xp_p1;
+
+ xprt_unregister(xprt);
+ (void)_RPC_close(xprt->xp_sock);
+ if (xprt->xp_port != 0) {
+ /* a rendezvouser socket */
+ xprt->xp_port = 0;
+ } else {
+ /* an actual connection socket */
+ XDR_DESTROY(&(cd->xdrs));
+ }
+ mem_free((caddr_t)cd, sizeof(struct tcp_conn));
+ mem_free((caddr_t)xprt, sizeof(SVCXPRT));
+}
+
+/*
+ * All read operations timeout after 35 seconds.
+ * A timeout is fatal for the connection.
+ */
+static struct timeval wait_per_try = { 35, 0 };
+
+/*
+ * reads data from the tcp conection.
+ * any error is fatal and the connection is closed.
+ * (And a read of zero bytes is a half closed stream => error.)
+ *
+ * Note: we have to be careful here not to allow ourselves to become
+ * blocked too long in this routine. While we're waiting for data from one
+ * client, another client may be trying to connect. To avoid this situation,
+ * some code from svc_run() is transplanted here: the select() loop checks
+ * all RPC descriptors including the one we want and calls svc_getreqset2()
+ * to handle new requests if any are detected.
+ */
+static int
+readtcp(
+ char *_xprt,
+ char *buf,
+ int len)
+{
+ SVCXPRT *xprt = (SVCXPRT*) _xprt;
+ register int sock = xprt->xp_sock;
+ struct timeval start, delta, tv;
+ struct timeval tmp1, tmp2;
+ fd_set *fds;
+
+ delta = wait_per_try;
+ fds = NULL;
+ gettimeofday(&start, NULL);
+ do {
+ int bytes = sizeof (fd_set);
+ if (fds != NULL)
+ free(fds);
+ fds = (fd_set *)malloc(bytes);
+ if (fds == NULL)
+ goto fatal_err;
+ memcpy(fds, __svc_fdset, bytes);
+
+ /* XXX we know the other bits are still clear */
+ FD_SET(sock, fds);
+ tv = delta; /* in case select() implements writeback */
+ switch (select(svc_maxfd + 1, fds, NULL, NULL, &tv)) {
+ case -1:
+ if (errno != EINTR)
+ goto fatal_err;
+ gettimeofday(&tmp1, NULL);
+ timersub(&tmp1, &start, &tmp2);
+ timersub(&wait_per_try, &tmp2, &tmp1);
+ if (tmp1.tv_sec < 0 || !timerisset(&tmp1))
+ goto fatal_err;
+ delta = tmp1;
+ continue;
+ case 0:
+ goto fatal_err;
+ default:
+ if (!FD_ISSET(sock, fds)) {
+ svc_getreqset2(fds, svc_maxfd + 1);
+ gettimeofday(&tmp1, NULL);
+ timersub(&tmp1, &start, &tmp2);
+ timersub(&wait_per_try, &tmp2, &tmp1);
+ if (tmp1.tv_sec < 0 || !timerisset(&tmp1))
+ goto fatal_err;
+ delta = tmp1;
+ continue;
+ }
+ }
+ } while (!FD_ISSET(sock, fds));
+ if ((len = _RPC_read(sock, buf, len)) > 0) {
+ if (fds != NULL)
+ free(fds);
+ return (len);
+ }
+fatal_err:
+ ((struct tcp_conn *)(xprt->xp_p1))->strm_stat = XPRT_DIED;
+ if (fds != NULL)
+ free(fds);
+ return (-1);
+}
+
+/*
+ * writes data to the tcp connection.
+ * Any error is fatal and the connection is closed.
+ */
+static int
+writetcp(
+ char *_xprt,
+ char *buf,
+ int len)
+{
+ SVCXPRT *xprt = (SVCXPRT *) _xprt;
+ register int i, cnt;
+
+ for (cnt = len; cnt > 0; cnt -= i, buf += i) {
+ if ((i = _RPC_write(xprt->xp_sock, buf, cnt)) < 0) {
+ ((struct tcp_conn *)(xprt->xp_p1))->strm_stat =
+ XPRT_DIED;
+ return (-1);
+ }
+ }
+ return (len);
+}
+
+static enum xprt_stat
+svctcp_stat(
+ SVCXPRT *xprt)
+{
+ register struct tcp_conn *cd =
+ (struct tcp_conn *)(xprt->xp_p1);
+
+ if (cd->strm_stat == XPRT_DIED)
+ return (XPRT_DIED);
+ if (! xdrrec_eof(&(cd->xdrs)))
+ return (XPRT_MOREREQS);
+ return (XPRT_IDLE);
+}
+
+static bool_t
+svctcp_recv(
+ SVCXPRT *xprt,
+ struct rpc_msg *msg)
+{
+ register struct tcp_conn *cd =
+ (struct tcp_conn *)(xprt->xp_p1);
+ register XDR *xdrs = &(cd->xdrs);
+
+ xdrs->x_op = XDR_DECODE;
+ (void)xdrrec_skiprecord(xdrs);
+ if (xdr_callmsg(xdrs, msg)) {
+ cd->x_id = msg->rm_xid;
+ return (TRUE);
+ }
+ cd->strm_stat = XPRT_DIED; /* XXXX */
+ return (FALSE);
+}
+
+static bool_t
+svctcp_getargs(
+ SVCXPRT *xprt,
+ xdrproc_t xdr_args,
+ caddr_t args_ptr)
+{
+
+ return ((*xdr_args)(&(((struct tcp_conn *)(xprt->xp_p1))->xdrs), args_ptr));
+}
+
+static bool_t
+svctcp_freeargs(
+ SVCXPRT *xprt,
+ xdrproc_t xdr_args,
+ caddr_t args_ptr)
+{
+ register XDR *xdrs =
+ &(((struct tcp_conn *)(xprt->xp_p1))->xdrs);
+
+ xdrs->x_op = XDR_FREE;
+ return ((*xdr_args)(xdrs, args_ptr));
+}
+
+static bool_t
+svctcp_reply(
+ SVCXPRT *xprt,
+ struct rpc_msg *msg)
+{
+ register struct tcp_conn *cd =
+ (struct tcp_conn *)(xprt->xp_p1);
+ register XDR *xdrs = &(cd->xdrs);
+ register bool_t stat;
+
+ xdrs->x_op = XDR_ENCODE;
+ msg->rm_xid = cd->x_id;
+ stat = xdr_replymsg(xdrs, msg);
+ (void)xdrrec_endofrecord(xdrs, TRUE);
+ return (stat);
+}
diff --git a/librpc/src/rpc/svc_udp.c b/librpc/src/rpc/svc_udp.c
new file mode 100644
index 0000000..94444c4
--- /dev/null
+++ b/librpc/src/rpc/svc_udp.c
@@ -0,0 +1,486 @@
+#include "rtems-rpc-config.h"
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)svc_udp.c 1.24 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)svc_udp.c 2.2 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/rpc/svc_udp.c,v 1.13 2000/01/27 23:06:41 jasone Exp $";
+#endif
+
+/*
+ * svc_udp.c,
+ * Server side for UDP/IP based RPC. (Does some caching in the hopes of
+ * achieving execute-at-most-once semantics.)
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/param.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <errno.h>
+
+#define rpc_buffer(xprt) ((xprt)->xp_p1)
+
+static bool_t svcudp_recv(SVCXPRT *xprt, struct rpc_msg *msg);
+static bool_t svcudp_reply(SVCXPRT *xprt, struct rpc_msg *msg);
+static enum xprt_stat svcudp_stat(SVCXPRT *xprt);
+static bool_t svcudp_getargs(SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr);
+static bool_t svcudp_freeargs(SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr);
+static void svcudp_destroy(SVCXPRT *xprt);
+static void cache_set (SVCXPRT *, u_long);
+static int cache_get (SVCXPRT *, struct rpc_msg *, char **, u_long *);
+
+static struct xp_ops svcudp_op = {
+ svcudp_recv,
+ svcudp_stat,
+ svcudp_getargs,
+ svcudp_reply,
+ svcudp_freeargs,
+ svcudp_destroy
+};
+
+/*
+ * kept in xprt->xp_p2
+ */
+struct svcudp_data {
+ u_int su_iosz; /* byte size of send.recv buffer */
+ u_long su_xid; /* transaction id */
+ XDR su_xdrs; /* XDR handle */
+ char su_verfbody[MAX_AUTH_BYTES]; /* verifier body */
+ char * su_cache; /* cached data, NULL if no cache */
+};
+#define su_data(xprt) ((struct svcudp_data *)(xprt->xp_p2))
+
+/*
+ * Usage:
+ * xprt = svcudp_create(sock);
+ *
+ * If sock<0 then a socket is created, else sock is used.
+ * If the socket, sock is not bound to a port then svcudp_create
+ * binds it to an arbitrary port. In any (successful) case,
+ * xprt->xp_sock is the registered socket number and xprt->xp_port is the
+ * associated port number.
+ * Once *xprt is initialized, it is registered as a transporter;
+ * see (svc.h, xprt_register).
+ * The routines returns NULL if a problem occurred.
+ */
+SVCXPRT *
+svcudp_bufcreate(
+ int sock,
+ u_int sendsz,
+ u_int recvsz )
+{
+ bool_t madesock = FALSE;
+ register SVCXPRT *xprt;
+ register struct svcudp_data *su;
+ struct sockaddr_in addr;
+ socklen_t len = sizeof(struct sockaddr_in);
+
+ if (sock == RPC_ANYSOCK) {
+ if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
+ perror("svcudp_create: socket creation problem");
+ return ((SVCXPRT *)NULL);
+ }
+ madesock = TRUE;
+ }
+ memset((char *)&addr, 0, sizeof (addr));
+ addr.sin_len = sizeof(struct sockaddr_in);
+ addr.sin_family = AF_INET;
+ if (bindresvport(sock, &addr)) {
+ addr.sin_port = 0;
+ (void)bind(sock, (struct sockaddr *)&addr, len);
+ }
+ if (getsockname(sock, (struct sockaddr *)&addr, &len) != 0) {
+ perror("svcudp_create - cannot getsockname");
+ if (madesock)
+ (void)_RPC_close(sock);
+ return ((SVCXPRT *)NULL);
+ }
+ xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
+ if (xprt == NULL) {
+ (void)fprintf(stderr, "svcudp_create: out of memory\n");
+ return (NULL);
+ }
+ su = (struct svcudp_data *)mem_alloc(sizeof(*su));
+ if (su == NULL) {
+ (void)fprintf(stderr, "svcudp_create: out of memory\n");
+ return (NULL);
+ }
+ su->su_iosz = ((MAX(sendsz, recvsz) + 3) / 4) * 4;
+ if ((rpc_buffer(xprt) = mem_alloc(su->su_iosz)) == NULL) {
+ (void)fprintf(stderr, "svcudp_create: out of memory\n");
+ return (NULL);
+ }
+ xdrmem_create(
+ &(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_DECODE);
+ su->su_cache = NULL;
+ xprt->xp_p2 = (caddr_t)su;
+ xprt->xp_verf.oa_base = su->su_verfbody;
+ xprt->xp_ops = &svcudp_op;
+ xprt->xp_port = ntohs(addr.sin_port);
+ xprt->xp_sock = sock;
+ xprt_register(xprt);
+ return (xprt);
+}
+
+SVCXPRT *
+svcudp_create(
+ int sock)
+{
+
+ return(svcudp_bufcreate(sock, UDPMSGSIZE, UDPMSGSIZE));
+}
+
+static enum xprt_stat
+svcudp_stat(
+ SVCXPRT *xprt)
+{
+
+ return (XPRT_IDLE);
+}
+
+static bool_t
+svcudp_recv(
+ SVCXPRT *xprt,
+ struct rpc_msg *msg)
+{
+ register struct svcudp_data *su = su_data(xprt);
+ register XDR *xdrs = &(su->su_xdrs);
+ register int rlen;
+ char *reply;
+ u_long replylen;
+
+ again:
+ xprt->xp_addrlen = sizeof(struct sockaddr_in);
+ rlen = recvfrom(xprt->xp_sock, rpc_buffer(xprt), (int) su->su_iosz,
+ 0, (struct sockaddr *)&(xprt->xp_raddr), &(xprt->xp_addrlen));
+ if (rlen == -1 && errno == EINTR)
+ goto again;
+ if (rlen == -1 || rlen < 4*sizeof(u_int32_t))
+ return (FALSE);
+ xdrs->x_op = XDR_DECODE;
+ XDR_SETPOS(xdrs, 0);
+ if (! xdr_callmsg(xdrs, msg))
+ return (FALSE);
+ su->su_xid = msg->rm_xid;
+ if (su->su_cache != NULL) {
+ if (cache_get(xprt, msg, &reply, &replylen)) {
+ (void) sendto(xprt->xp_sock, reply, (int) replylen, 0,
+ (struct sockaddr *) &xprt->xp_raddr, xprt->xp_addrlen);
+ return (TRUE);
+ }
+ }
+ return (TRUE);
+}
+
+static bool_t
+svcudp_reply(
+ SVCXPRT *xprt,
+ struct rpc_msg *msg)
+{
+ register struct svcudp_data *su = su_data(xprt);
+ register XDR *xdrs = &(su->su_xdrs);
+ register int slen;
+ register bool_t stat = FALSE;
+
+ xdrs->x_op = XDR_ENCODE;
+ XDR_SETPOS(xdrs, 0);
+ msg->rm_xid = su->su_xid;
+ if (xdr_replymsg(xdrs, msg)) {
+ slen = (int)XDR_GETPOS(xdrs);
+ if (sendto(xprt->xp_sock, rpc_buffer(xprt), slen, 0,
+ (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen)
+ == slen) {
+ stat = TRUE;
+ if (su->su_cache && slen >= 0) {
+ cache_set(xprt, (u_long) slen);
+ }
+ }
+ }
+ return (stat);
+}
+
+static bool_t
+svcudp_getargs(
+ SVCXPRT *xprt,
+ xdrproc_t xdr_args,
+ caddr_t args_ptr)
+{
+
+ return ((*xdr_args)(&(su_data(xprt)->su_xdrs), args_ptr));
+}
+
+static bool_t
+svcudp_freeargs(
+ SVCXPRT *xprt,
+ xdrproc_t xdr_args,
+ caddr_t args_ptr)
+{
+ register XDR *xdrs = &(su_data(xprt)->su_xdrs);
+
+ xdrs->x_op = XDR_FREE;
+ return ((*xdr_args)(xdrs, args_ptr));
+}
+
+static void
+svcudp_destroy(
+ SVCXPRT *xprt)
+{
+ register struct svcudp_data *su = su_data(xprt);
+
+ xprt_unregister(xprt);
+ (void)_RPC_close(xprt->xp_sock);
+ XDR_DESTROY(&(su->su_xdrs));
+ mem_free(rpc_buffer(xprt), su->su_iosz);
+ mem_free((caddr_t)su, sizeof(struct svcudp_data));
+ mem_free((caddr_t)xprt, sizeof(SVCXPRT));
+}
+
+
+/***********this could be a separate file*********************/
+
+/*
+ * Fifo cache for udp server
+ * Copies pointers to reply buffers into fifo cache
+ * Buffers are sent again if retransmissions are detected.
+ */
+
+#define SPARSENESS 4 /* 75% sparse */
+
+#define CACHE_PERROR(msg) \
+ (void) fprintf(stderr,"%s\n", msg)
+
+#define ALLOC(type, size) \
+ (type *) mem_alloc((unsigned) (sizeof(type) * (size)))
+
+#define BZERO(addr, type, size) \
+ memset((char *) addr, 0, sizeof(type) * (int) (size))
+
+/*
+ * An entry in the cache
+ */
+typedef struct cache_node *cache_ptr;
+struct cache_node {
+ /*
+ * Index into cache is xid, proc, vers, prog and address
+ */
+ u_long cache_xid;
+ u_long cache_proc;
+ u_long cache_vers;
+ u_long cache_prog;
+ struct sockaddr_in cache_addr;
+ /*
+ * The cached reply and length
+ */
+ char * cache_reply;
+ u_long cache_replylen;
+ /*
+ * Next node on the list, if there is a collision
+ */
+ cache_ptr cache_next;
+};
+
+
+
+/*
+ * The entire cache
+ */
+struct udp_cache {
+ u_long uc_size; /* size of cache */
+ cache_ptr *uc_entries; /* hash table of entries in cache */
+ cache_ptr *uc_fifo; /* fifo list of entries in cache */
+ u_long uc_nextvictim; /* points to next victim in fifo list */
+ u_long uc_prog; /* saved program number */
+ u_long uc_vers; /* saved version number */
+ u_long uc_proc; /* saved procedure number */
+ struct sockaddr_in uc_addr; /* saved caller's address */
+};
+
+
+/*
+ * the hashing function
+ */
+#define CACHE_LOC(transp, xid) \
+ (xid % (SPARSENESS*((struct udp_cache *) su_data(transp)->su_cache)->uc_size))
+
+
+/*
+ * Enable use of the cache.
+ * Note: there is no disable.
+ */
+int svcudp_enablecache(
+ SVCXPRT *transp,
+ u_long size)
+{
+ struct svcudp_data *su = su_data(transp);
+ struct udp_cache *uc;
+
+ if (su->su_cache != NULL) {
+ CACHE_PERROR("enablecache: cache already enabled");
+ return(0);
+ }
+ uc = ALLOC(struct udp_cache, 1);
+ if (uc == NULL) {
+ CACHE_PERROR("enablecache: could not allocate cache");
+ return(0);
+ }
+ uc->uc_size = size;
+ uc->uc_nextvictim = 0;
+ uc->uc_entries = ALLOC(cache_ptr, size * SPARSENESS);
+ if (uc->uc_entries == NULL) {
+ CACHE_PERROR("enablecache: could not allocate cache data");
+ return(0);
+ }
+ BZERO(uc->uc_entries, cache_ptr, size * SPARSENESS);
+ uc->uc_fifo = ALLOC(cache_ptr, size);
+ if (uc->uc_fifo == NULL) {
+ CACHE_PERROR("enablecache: could not allocate cache fifo");
+ return(0);
+ }
+ BZERO(uc->uc_fifo, cache_ptr, size);
+ su->su_cache = (char *) uc;
+ return(1);
+}
+
+
+/*
+ * Set an entry in the cache
+ */
+static void
+cache_set(
+ SVCXPRT *xprt,
+ u_long replylen)
+{
+ register cache_ptr victim;
+ register cache_ptr *vicp;
+ register struct svcudp_data *su = su_data(xprt);
+ struct udp_cache *uc = (struct udp_cache *) su->su_cache;
+ u_int loc;
+ char *newbuf;
+
+ /*
+ * Find space for the new entry, either by
+ * reusing an old entry, or by mallocing a new one
+ */
+ victim = uc->uc_fifo[uc->uc_nextvictim];
+ if (victim != NULL) {
+ loc = CACHE_LOC(xprt, victim->cache_xid);
+ for (vicp = &uc->uc_entries[loc];
+ *vicp != NULL && *vicp != victim;
+ vicp = &(*vicp)->cache_next)
+ ;
+ if (*vicp == NULL) {
+ CACHE_PERROR("cache_set: victim not found");
+ return;
+ }
+ *vicp = victim->cache_next; /* remote from cache */
+ newbuf = victim->cache_reply;
+ } else {
+ victim = ALLOC(struct cache_node, 1);
+ if (victim == NULL) {
+ CACHE_PERROR("cache_set: victim alloc failed");
+ return;
+ }
+ newbuf = mem_alloc(su->su_iosz);
+ if (newbuf == NULL) {
+ CACHE_PERROR("cache_set: could not allocate new rpc_buffer");
+ return;
+ }
+ }
+
+ /*
+ * Store it away
+ */
+ victim->cache_replylen = replylen;
+ victim->cache_reply = rpc_buffer(xprt);
+ rpc_buffer(xprt) = newbuf;
+ xdrmem_create(&(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_ENCODE);
+ victim->cache_xid = su->su_xid;
+ victim->cache_proc = uc->uc_proc;
+ victim->cache_vers = uc->uc_vers;
+ victim->cache_prog = uc->uc_prog;
+ victim->cache_addr = uc->uc_addr;
+ loc = CACHE_LOC(xprt, victim->cache_xid);
+ victim->cache_next = uc->uc_entries[loc];
+ uc->uc_entries[loc] = victim;
+ uc->uc_fifo[uc->uc_nextvictim++] = victim;
+ uc->uc_nextvictim %= uc->uc_size;
+}
+
+/*
+ * Try to get an entry from the cache
+ * return 1 if found, 0 if not found
+ */
+static int
+cache_get(
+ SVCXPRT *xprt,
+ struct rpc_msg *msg,
+ char **replyp,
+ u_long *replylenp)
+{
+ u_int loc;
+ register cache_ptr ent;
+ register struct svcudp_data *su = su_data(xprt);
+ register struct udp_cache *uc = (struct udp_cache *) su->su_cache;
+
+# define EQADDR(a1, a2) (memcmp(&a1, &a2, sizeof(a1)) == 0)
+
+ loc = CACHE_LOC(xprt, su->su_xid);
+ for (ent = uc->uc_entries[loc]; ent != NULL; ent = ent->cache_next) {
+ if (ent->cache_xid == su->su_xid &&
+ ent->cache_proc == uc->uc_proc &&
+ ent->cache_vers == uc->uc_vers &&
+ ent->cache_prog == uc->uc_prog &&
+ EQADDR(ent->cache_addr, uc->uc_addr)) {
+ *replyp = ent->cache_reply;
+ *replylenp = ent->cache_replylen;
+ return(1);
+ }
+ }
+ /*
+ * Failed to find entry
+ * Remember a few things so we can do a set later
+ */
+ uc->uc_proc = msg->rm_call.cb_proc;
+ uc->uc_vers = msg->rm_call.cb_vers;
+ uc->uc_prog = msg->rm_call.cb_prog;
+ uc->uc_addr = xprt->xp_raddr;
+ return(0);
+}
diff --git a/librpc/src/xdr/xdr.3 b/librpc/src/xdr/xdr.3
new file mode 100644
index 0000000..c1cdb11
--- /dev/null
+++ b/librpc/src/xdr/xdr.3
@@ -0,0 +1,837 @@
+.\" @(#)xdr.3n 2.2 88/08/03 4.0 RPCSRC; from 1.16 88/03/14 SMI
+.\" $FreeBSD: src/lib/libc/xdr/xdr.3,v 1.8 2000/03/02 09:14:05 sheldonh Exp $
+.\"
+.TH XDR 3 "16 February 1988"
+.SH NAME
+xdr \- library routines for external data representation
+.SH SYNOPSIS AND DESCRIPTION
+.LP
+These routines allow C programmers to describe
+arbitrary data structures in a machine-independent fashion.
+Data for remote procedure calls are transmitted using these
+routines.
+.LP
+.ft B
+.nf
+.sp .5
+xdr_array(xdrs, arrp, sizep, maxsize, elsize, elproc)
+\s-1XDR\s0 *xdrs;
+char **arrp;
+u_int *sizep, maxsize, elsize;
+xdrproc_t elproc;
+.fi
+.ft R
+.IP
+A filter primitive that translates between variable-length
+arrays
+and their corresponding external representations.
+The
+parameter
+.I arrp
+is the address of the pointer to the array, while
+.I sizep
+is the address of the element count of the array;
+this element count cannot exceed
+.IR maxsize .
+The parameter
+.I elsize
+is the
+.I sizeof
+each of the array's elements, and
+.I elproc
+is an
+.SM XDR
+filter that translates between
+the array elements' C form, and their external
+representation.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+xdr_bool(xdrs, bp)
+\s-1XDR\s0 *xdrs;
+bool_t *bp;
+.fi
+.ft R
+.IP
+A filter primitive that translates between booleans (C
+integers)
+and their external representations.
+When encoding data, this
+filter produces values of either one or zero.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+xdr_bytes(xdrs, sp, sizep, maxsize)
+\s-1XDR\s0 *xdrs;
+char **sp;
+u_int *sizep, maxsize;
+.fi
+.ft R
+.IP
+A filter primitive that translates between counted byte
+strings and their external representations.
+The parameter
+.I sp
+is the address of the string pointer.
+The length of the
+string is located at address
+.IR sizep ;
+strings cannot be longer than
+.IR maxsize .
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_char(xdrs, cp)
+\s-1XDR\s0 *xdrs;
+char *cp;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C characters
+and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+Note: encoded characters are not packed, and occupy 4 bytes
+each.
+For arrays of characters, it is worthwhile to
+consider
+.BR xdr_bytes(\|) ,
+.B xdr_opaque(\|)
+or
+.BR xdr_string(\|) .
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+void
+xdr_destroy(xdrs)
+\s-1XDR\s0 *xdrs;
+.fi
+.ft R
+.IP
+A macro that invokes the destroy routine associated with the
+.SM XDR
+stream,
+.IR xdrs .
+Destruction usually involves freeing private data structures
+associated with the stream. Using
+.I xdrs
+after invoking
+.B xdr_destroy(\|)
+is undefined.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_double(xdrs, dp)
+\s-1XDR\s0 *xdrs;
+double *dp;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C
+.B double
+precision numbers and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_enum(xdrs, ep)
+\s-1XDR\s0 *xdrs;
+enum_t *ep;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C
+.BR enum s
+(actually integers) and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+xdr_float(xdrs, fp)
+\s-1XDR\s0 *xdrs;
+float *fp;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C
+.BR float s
+and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+void
+xdr_free(proc, objp)
+xdrproc_t proc;
+char *objp;
+.fi
+.ft R
+.IP
+Generic freeing routine.
+The first argument is the
+.SM XDR
+routine for the object being freed.
+The second argument
+is a pointer to the object itself.
+Note: the pointer passed
+to this routine is
+.I not
+freed, but what it points to
+.I is
+freed (recursively).
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+u_int
+xdr_getpos(xdrs)
+\s-1XDR\s0 *xdrs;
+.fi
+.ft R
+.IP
+A macro that invokes the get-position routine
+associated with the
+.SM XDR
+stream,
+.IR xdrs .
+The routine returns an unsigned integer,
+which indicates the position of the
+.SM XDR
+byte stream.
+A desirable feature of
+.SM XDR
+streams is that simple arithmetic works with this number,
+although the
+.SM XDR
+stream instances need not guarantee this.
+.br
+.if t .ne 4
+.LP
+.ft B
+.nf
+.sp .5
+.br
+long *
+xdr_inline(xdrs, len)
+\s-1XDR\s0 *xdrs;
+int len;
+.fi
+.ft R
+.IP
+A macro that invokes the in-line routine associated with the
+.SM XDR
+stream,
+.IR xdrs .
+The routine returns a pointer
+to a contiguous piece of the stream's buffer;
+.I len
+is the byte length of the desired buffer.
+Note: pointer is cast to
+.BR "long *" .
+.IP
+Warning:
+.B xdr_inline(\|)
+may return
+.SM NULL
+(0)
+if it cannot allocate a contiguous piece of a buffer.
+Therefore the behavior may vary among stream instances;
+it exists for the sake of efficiency.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_int(xdrs, ip)
+\s-1XDR\s0 *xdrs;
+int *ip;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C integers
+and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_long(xdrs, lp)
+\s-1XDR\s0 *xdrs;
+long *lp;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C
+.B long
+integers and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 12
+.LP
+.ft B
+.nf
+.sp .5
+void
+xdrmem_create(xdrs, addr, size, op)
+\s-1XDR\s0 *xdrs;
+char *addr;
+u_int size;
+enum xdr_op op;
+.fi
+.ft R
+.IP
+This routine initializes the
+.SM XDR
+stream object pointed to by
+.IR xdrs .
+The stream's data is written to, or read from,
+a chunk of memory at location
+.I addr
+whose length is no more than
+.I size
+bytes long. The
+.I op
+determines the direction of the
+.SM XDR
+stream
+(either
+.BR \s-1XDR_ENCODE\s0 ,
+.BR \s-1XDR_DECODE\s0 ,
+or
+.BR \s-1XDR_FREE\s0 ).
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+xdr_opaque(xdrs, cp, cnt)
+\s-1XDR\s0 *xdrs;
+char *cp;
+u_int cnt;
+.fi
+.ft R
+.IP
+A filter primitive that translates between fixed size opaque
+data
+and its external representation.
+The parameter
+.I cp
+is the address of the opaque object, and
+.I cnt
+is its size in bytes.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+xdr_pointer(xdrs, objpp, objsize, xdrobj)
+\s-1XDR\s0 *xdrs;
+char **objpp;
+u_int objsize;
+xdrproc_t xdrobj;
+.fi
+.ft R
+.IP
+Like
+.B xdr_reference(\|)
+execpt that it serializes
+.SM NULL
+pointers, whereas
+.B xdr_reference(\|)
+does not. Thus,
+.B xdr_pointer(\|)
+can represent
+recursive data structures, such as binary trees or
+linked lists.
+.br
+.if t .ne 15
+.LP
+.ft B
+.nf
+.sp .5
+void
+xdrrec_create(xdrs, sendsize, recvsize, handle, readit, writeit)
+\s-1XDR\s0 *xdrs;
+u_int sendsize, recvsize;
+char *handle;
+int (*readit) (\|), (*writeit) (\|);
+.fi
+.ft R
+.IP
+This routine initializes the
+.SM XDR
+stream object pointed to by
+.IR xdrs .
+The stream's data is written to a buffer of size
+.IR sendsize ;
+a value of zero indicates the system should use a suitable
+default.
+The stream's data is read from a buffer of size
+.IR recvsize ;
+it too can be set to a suitable default by passing a zero
+value.
+When a stream's output buffer is full,
+.I writeit
+is called. Similarly, when a stream's input buffer is empty,
+.I readit
+is called. The behavior of these two routines is similar to
+the
+system calls
+.B read
+and
+.BR write ,
+except that
+.I handle
+is passed to the former routines as the first parameter.
+Note: the
+.SM XDR
+stream's
+.I op
+field must be set by the caller.
+.IP
+Warning: this
+.SM XDR
+stream implements an intermediate record stream.
+Therefore there are additional bytes in the stream
+to provide record boundary information.
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+xdrrec_endofrecord(xdrs, sendnow)
+\s-1XDR\s0 *xdrs;
+int sendnow;
+.fi
+.ft R
+.IP
+This routine can be invoked only on
+streams created by
+.BR xdrrec_create(\|) .
+The data in the output buffer is marked as a completed
+record,
+and the output buffer is optionally written out if
+.I sendnow
+is non-zero.
+This routine returns one if it succeeds, zero
+otherwise.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+xdrrec_eof(xdrs)
+\s-1XDR\s0 *xdrs;
+int empty;
+.fi
+.ft R
+.IP
+This routine can be invoked only on
+streams created by
+.BR xdrrec_create(\|) .
+After consuming the rest of the current record in the stream,
+this routine returns one if the stream has no more input,
+zero otherwise.
+.br
+.if t .ne 3
+.LP
+.ft B
+.nf
+.sp .5
+xdrrec_skiprecord(xdrs)
+\s-1XDR\s0 *xdrs;
+.fi
+.ft R
+.IP
+This routine can be invoked only on
+streams created by
+.BR xdrrec_create(\|) .
+It tells the
+.SM XDR
+implementation that the rest of the current record
+in the stream's input buffer should be discarded.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 11
+.LP
+.ft B
+.nf
+.sp .5
+xdr_reference(xdrs, pp, size, proc)
+\s-1XDR\s0 *xdrs;
+char **pp;
+u_int size;
+xdrproc_t proc;
+.fi
+.ft R
+.IP
+A primitive that provides pointer chasing within structures.
+The parameter
+.I pp
+is the address of the pointer;
+.I size
+is the
+.I sizeof
+the structure that
+.I *pp
+points to; and
+.I proc
+is an
+.SM XDR
+procedure that filters the structure
+between its C form and its external representation.
+This routine returns one if it succeeds, zero otherwise.
+.IP
+Warning: this routine does not understand
+.SM NULL
+pointers.
+Use
+.B xdr_pointer(\|)
+instead.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+xdr_setpos(xdrs, pos)
+\s-1XDR\s0 *xdrs;
+u_int pos;
+.fi
+.ft R
+.IP
+A macro that invokes the set position routine associated with
+the
+.SM XDR
+stream
+.IR xdrs .
+The parameter
+.I pos
+is a position value obtained from
+.BR xdr_getpos(\|) .
+This routine returns one if the
+.SM XDR
+stream could be repositioned,
+and zero otherwise.
+.IP
+Warning: it is difficult to reposition some types of
+.SM XDR
+streams, so this routine may fail with one
+type of stream and succeed with another.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+xdr_short(xdrs, sp)
+\s-1XDR\s0 *xdrs;
+short *sp;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C
+.B short
+integers and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+void
+xdrstdio_create(xdrs, file, op)
+\s-1XDR\s0 *xdrs;
+\s-1FILE\s0 *file;
+enum xdr_op op;
+.fi
+.ft R
+.IP
+This routine initializes the
+.SM XDR
+stream object pointed to by
+.IR xdrs .
+The
+.SM XDR
+stream data is written to, or read from, the Standard
+.B I/O
+stream
+.IR file .
+The parameter
+.I op
+determines the direction of the
+.SM XDR
+stream (either
+.BR \s-1XDR_ENCODE\s0 ,
+.BR \s-1XDR_DECODE\s0 ,
+or
+.BR \s-1XDR_FREE\s0 ).
+.IP
+Warning: the destroy routine associated with such
+.SM XDR
+streams calls
+.B fflush(\|)
+on the
+.I file
+stream, but never
+.BR fclose(\|) .
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+xdr_string(xdrs, sp, maxsize)
+\s-1XDR\s0
+*xdrs;
+char **sp;
+u_int maxsize;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C strings and
+their
+corresponding external representations.
+Strings cannot be longer than
+.IR maxsize .
+Note:
+.I sp
+is the address of the string's pointer.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+xdr_u_char(xdrs, ucp)
+\s-1XDR\s0 *xdrs;
+unsigned char *ucp;
+.fi
+.ft R
+.IP
+A filter primitive that translates between
+.B unsigned
+C characters and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+xdr_u_int(xdrs, up)
+\s-1XDR\s0 *xdrs;
+unsigned *up;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C
+.B unsigned
+integers and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_u_long(xdrs, ulp)
+\s-1XDR\s0 *xdrs;
+unsigned long *ulp;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C
+.B "unsigned long"
+integers and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_u_short(xdrs, usp)
+\s-1XDR\s0 *xdrs;
+unsigned short *usp;
+.fi
+.ft R
+.IP
+A filter primitive that translates between C
+.B "unsigned short"
+integers and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 16
+.LP
+.ft B
+.nf
+.sp .5
+xdr_union(xdrs, dscmp, unp, choices, dfault)
+\s-1XDR\s0 *xdrs;
+int *dscmp;
+char *unp;
+struct xdr_discrim *choices;
+bool_t (*defaultarm) (\|); /* may equal \s-1NULL\s0 */
+.fi
+.ft R
+.IP
+A filter primitive that translates between a discriminated C
+.B union
+and its corresponding external representation.
+It first
+translates the discriminant of the union located at
+.IR dscmp .
+This discriminant is always an
+.BR enum_t .
+Next the union located at
+.I unp
+is translated. The parameter
+.I choices
+is a pointer to an array of
+.B xdr_discrim(\|)
+structures.
+Each structure contains an ordered pair of
+.RI [ value , proc ].
+If the union's discriminant is equal to the associated
+.IR value ,
+then the
+.I proc
+is called to translate the union. The end of the
+.B xdr_discrim(\|)
+structure array is denoted by a routine of value
+.SM NULL\s0.
+If the discriminant is not found in the
+.I choices
+array, then the
+.I defaultarm
+procedure is called (if it is not
+.SM NULL\s0).
+Returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 6
+.LP
+.ft B
+.nf
+.sp .5
+xdr_vector(xdrs, arrp, size, elsize, elproc)
+\s-1XDR\s0 *xdrs;
+char *arrp;
+u_int size, elsize;
+xdrproc_t elproc;
+.fi
+.ft R
+.IP
+A filter primitive that translates between fixed-length
+arrays
+and their corresponding external representations. The
+parameter
+.I arrp
+is the address of the pointer to the array, while
+.I size
+is the element count of the array. The parameter
+.I elsize
+is the
+.I sizeof
+each of the array's elements, and
+.I elproc
+is an
+.SM XDR
+filter that translates between
+the array elements' C form, and their external
+representation.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 5
+.LP
+.ft B
+.nf
+.sp .5
+xdr_void(\|)
+.fi
+.ft R
+.IP
+This routine always returns one.
+It may be passed to
+.SM RPC
+routines that require a function parameter,
+where nothing is to be done.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+xdr_wrapstring(xdrs, sp)
+\s-1XDR\s0 *xdrs;
+char **sp;
+.fi
+.ft R
+.IP
+A primitive that calls
+.B "xdr_string(xdrs, sp,\s-1MAXUN.UNSIGNED\s0 );"
+where
+.B
+.SM MAXUN.UNSIGNED
+is the maximum value of an unsigned integer.
+.B xdr_wrapstring(\|)
+is handy because the
+.SM RPC
+package passes a maximum of two
+.SM XDR
+routines as parameters, and
+.BR xdr_string(\|) ,
+one of the most frequently used primitives, requires three.
+Returns one if it succeeds, zero otherwise.
+.SH SEE ALSO
+.BR rpc (3)
+.LP
+The following manuals:
+.RS
+.ft I
+eXternal Data Representation Standard: Protocol Specification
+.br
+eXternal Data Representation: Sun Technical Notes
+.ft R
+.br
+.IR "\s-1XDR\s0: External Data Representation Standard" ,
+.SM RFC1014, Sun Microsystems, Inc.,
+.SM USC-ISI\s0.
diff --git a/librpc/src/xdr/xdr.c b/librpc/src/xdr/xdr.c
new file mode 100644
index 0000000..80c29bb
--- /dev/null
+++ b/librpc/src/xdr/xdr.c
@@ -0,0 +1,858 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)xdr.c 1.35 87/08/12";*/
+/*static char *sccsid = "from: @(#)xdr.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/xdr/xdr.c,v 1.9 1999/08/28 00:02:55 peter Exp $";
+#endif
+
+/*
+ * xdr.c, Generic XDR routines implementation.
+ *
+ * Copyright (C) 1986, Sun Microsystems, Inc.
+ *
+ * These are the "generic" xdr routines used to serialize and de-serialize
+ * most common data items. See xdr.h for more info on the interface to
+ * xdr.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+#if defined(__rtems__)
+#define warnx(msg) fprintf(stderr, msg "\n");
+#endif
+
+/*
+ * constants specific to the xdr "protocol"
+ */
+#define XDR_FALSE ((long) 0)
+#define XDR_TRUE ((long) 1)
+#define LASTUNSIGNED ((u_int) 0-1)
+
+/*
+ * for unit alignment
+ */
+static const char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 };
+
+/*
+ * Free a data structure using XDR
+ * Not a filter, but a convenient utility nonetheless
+ */
+void
+xdr_free(
+ xdrproc_t proc,
+ char *objp)
+{
+ XDR x;
+
+ x.x_op = XDR_FREE;
+ (*proc)(&x, objp);
+}
+
+/*
+ * XDR nothing
+ */
+bool_t
+xdr_void(void)
+{
+
+ return (TRUE);
+}
+
+
+/*
+ * XDR integers
+ */
+bool_t
+xdr_int(
+ XDR *xdrs,
+ int *ip)
+{
+ long l;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ l = (long) *ip;
+ return (XDR_PUTLONG(xdrs, &l));
+
+ case XDR_DECODE:
+ if (!XDR_GETLONG(xdrs, &l)) {
+ return (FALSE);
+ }
+ *ip = (int) l;
+ return (TRUE);
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ /* NOTREACHED */
+ return (FALSE);
+}
+
+/*
+ * XDR unsigned integers
+ */
+bool_t
+xdr_u_int(
+ XDR *xdrs,
+ u_int *up)
+{
+ u_long l;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ l = (u_long) *up;
+ return (XDR_PUTLONG(xdrs, (long *)&l));
+
+ case XDR_DECODE:
+ if (!XDR_GETLONG(xdrs, (long *)&l)) {
+ return (FALSE);
+ }
+ *up = (u_int) l;
+ return (TRUE);
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ /* NOTREACHED */
+ return (FALSE);
+}
+
+
+/*
+ * XDR long integers
+ * same as xdr_u_long - open coded to save a proc call!
+ */
+bool_t
+xdr_long(
+ XDR *xdrs,
+ long *lp)
+{
+ switch (xdrs->x_op) {
+ case XDR_ENCODE:
+ return (XDR_PUTLONG(xdrs, lp));
+ case XDR_DECODE:
+ return (XDR_GETLONG(xdrs, lp));
+ case XDR_FREE:
+ return (TRUE);
+ }
+ /* NOTREACHED */
+ return (FALSE);
+}
+
+/*
+ * XDR unsigned long integers
+ * same as xdr_long - open coded to save a proc call!
+ */
+bool_t
+xdr_u_long(
+ XDR *xdrs,
+ u_long *ulp)
+{
+ switch (xdrs->x_op) {
+ case XDR_ENCODE:
+ return (XDR_PUTLONG(xdrs, (long *)ulp));
+ case XDR_DECODE:
+ return (XDR_GETLONG(xdrs, (long *)ulp));
+ case XDR_FREE:
+ return (TRUE);
+ }
+ /* NOTREACHED */
+ return (FALSE);
+}
+
+
+/*
+ * XDR 32-bit integers
+ * same as xdr_u_int32_t - open coded to save a proc call!
+ */
+bool_t
+xdr_int32_t(
+ XDR *xdrs,
+ int32_t *int32_p)
+{
+ long l;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ l = (long) *int32_p;
+ return (XDR_PUTLONG(xdrs, &l));
+
+ case XDR_DECODE:
+ if (!XDR_GETLONG(xdrs, &l)) {
+ return (FALSE);
+ }
+ *int32_p = (int32_t) l;
+ return (TRUE);
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ /* NOTREACHED */
+ return (FALSE);
+}
+
+/*
+ * XDR unsigned 32-bit integers
+ * same as xdr_int32_t - open coded to save a proc call!
+ */
+bool_t
+xdr_u_int32_t(
+ XDR *xdrs,
+ u_int32_t *u_int32_p)
+{
+ u_long l;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ l = (u_long) *u_int32_p;
+ return (XDR_PUTLONG(xdrs, (long *)&l));
+
+ case XDR_DECODE:
+ if (!XDR_GETLONG(xdrs, (long *)&l)) {
+ return (FALSE);
+ }
+ *u_int32_p = (u_int32_t) l;
+ return (TRUE);
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
+/*
+ * XDR short integers
+ */
+bool_t
+xdr_short(
+ XDR *xdrs,
+ short *sp)
+{
+ long l;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ l = (long) *sp;
+ return (XDR_PUTLONG(xdrs, &l));
+
+ case XDR_DECODE:
+ if (!XDR_GETLONG(xdrs, &l)) {
+ return (FALSE);
+ }
+ *sp = (short) l;
+ return (TRUE);
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ /* NOTREACHED */
+ return (FALSE);
+}
+
+/*
+ * XDR unsigned short integers
+ */
+bool_t
+xdr_u_short(
+ XDR *xdrs,
+ u_short *usp)
+{
+ u_long l;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ l = (u_long) *usp;
+ return (XDR_PUTLONG(xdrs, (long *)&l));
+
+ case XDR_DECODE:
+ if (!XDR_GETLONG(xdrs, (long *)&l)) {
+ return (FALSE);
+ }
+ *usp = (u_short) l;
+ return (TRUE);
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ /* NOTREACHED */
+ return (FALSE);
+}
+
+
+/*
+ * XDR 16-bit integers
+ */
+bool_t
+xdr_int16_t(
+ XDR *xdrs,
+ int16_t *int16_p)
+{
+ long l;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ l = (long) *int16_p;
+ return (XDR_PUTLONG(xdrs, &l));
+
+ case XDR_DECODE:
+ if (!XDR_GETLONG(xdrs, &l)) {
+ return (FALSE);
+ }
+ *int16_p = (int16_t) l;
+ return (TRUE);
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ /* NOTREACHED */
+ return (FALSE);
+}
+
+/*
+ * XDR unsigned 16-bit integers
+ */
+bool_t
+xdr_u_int16_t(
+ XDR *xdrs,
+ u_int16_t *u_int16_p)
+{
+ u_long l;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ l = (u_long) *u_int16_p;
+ return (XDR_PUTLONG(xdrs, (long *)&l));
+
+ case XDR_DECODE:
+ if (!XDR_GETLONG(xdrs, (long *)&l)) {
+ return (FALSE);
+ }
+ *u_int16_p = (u_int16_t) l;
+ return (TRUE);
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ /* NOTREACHED */
+ return (FALSE);
+}
+
+
+/*
+ * XDR a char
+ */
+bool_t
+xdr_char(
+ XDR *xdrs,
+ char *cp)
+{
+ int i;
+
+ i = (*cp);
+ if (!xdr_int(xdrs, &i)) {
+ return (FALSE);
+ }
+ *cp = i;
+ return (TRUE);
+}
+
+/*
+ * XDR an unsigned char
+ */
+bool_t
+xdr_u_char(
+ XDR *xdrs,
+ u_char *cp)
+{
+ u_int u;
+
+ u = (*cp);
+ if (!xdr_u_int(xdrs, &u)) {
+ return (FALSE);
+ }
+ *cp = u;
+ return (TRUE);
+}
+
+/*
+ * XDR booleans
+ */
+bool_t
+xdr_bool(
+ XDR *xdrs,
+ bool_t *bp)
+{
+ long lb;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ lb = *bp ? XDR_TRUE : XDR_FALSE;
+ return (XDR_PUTLONG(xdrs, &lb));
+
+ case XDR_DECODE:
+ if (!XDR_GETLONG(xdrs, &lb)) {
+ return (FALSE);
+ }
+ *bp = (lb == XDR_FALSE) ? FALSE : TRUE;
+ return (TRUE);
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ /* NOTREACHED */
+ return (FALSE);
+}
+
+/*
+ * XDR enumerations
+ */
+bool_t
+xdr_enum(
+ XDR *xdrs,
+ enum_t *ep)
+{
+#ifndef lint
+ /*
+ * enums are treated as ints
+ */
+ if (sizeof (enum_t) == sizeof (long)) {
+ return (xdr_long(xdrs, (long *)ep));
+ } else if (sizeof (enum_t) == sizeof (int)) {
+ return (xdr_int(xdrs, (int *)ep));
+ } else if (sizeof (enum_t) == sizeof (short)) {
+ return (xdr_short(xdrs, (short *)ep));
+ } else {
+ return (FALSE);
+ }
+#else
+ (void) (xdr_short(xdrs, (short *)ep));
+ (void) (xdr_int(xdrs, (int *)ep));
+ return (xdr_long(xdrs, (long *)ep));
+#endif
+}
+
+/*
+ * XDR opaque data
+ * Allows the specification of a fixed size sequence of opaque bytes.
+ * cp points to the opaque object and cnt gives the byte length.
+ */
+bool_t
+xdr_opaque(
+ XDR *xdrs,
+ caddr_t cp,
+ u_int cnt)
+{
+ u_int rndup;
+ static int crud[BYTES_PER_XDR_UNIT];
+
+ /*
+ * if no data we are done
+ */
+ if (cnt == 0)
+ return (TRUE);
+
+ /*
+ * round byte count to full xdr units
+ */
+ rndup = cnt % BYTES_PER_XDR_UNIT;
+ if (rndup > 0)
+ rndup = BYTES_PER_XDR_UNIT - rndup;
+
+ if (xdrs->x_op == XDR_DECODE) {
+ if (!XDR_GETBYTES(xdrs, cp, cnt)) {
+ return (FALSE);
+ }
+ if (rndup == 0)
+ return (TRUE);
+ return (XDR_GETBYTES(xdrs, (caddr_t)crud, rndup));
+ }
+
+ if (xdrs->x_op == XDR_ENCODE) {
+ if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
+ return (FALSE);
+ }
+ if (rndup == 0)
+ return (TRUE);
+ return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
+ }
+
+ if (xdrs->x_op == XDR_FREE) {
+ return (TRUE);
+ }
+
+ return (FALSE);
+}
+
+/*
+ * XDR counted bytes
+ * *cpp is a pointer to the bytes, *sizep is the count.
+ * If *cpp is NULL maxsize bytes are allocated
+ */
+bool_t
+xdr_bytes(
+ XDR *xdrs,
+ char **cpp,
+ u_int *sizep,
+ u_int maxsize)
+{
+ char *sp = *cpp; /* sp is the actual string pointer */
+ u_int nodesize;
+
+ /*
+ * first deal with the length since xdr bytes are counted
+ */
+ if (! xdr_u_int(xdrs, sizep)) {
+ return (FALSE);
+ }
+ nodesize = *sizep;
+ if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
+ return (FALSE);
+ }
+
+ /*
+ * now deal with the actual bytes
+ */
+ switch (xdrs->x_op) {
+
+ case XDR_DECODE:
+ if (nodesize == 0) {
+ return (TRUE);
+ }
+ if (sp == NULL) {
+ *cpp = sp = mem_alloc(nodesize);
+ }
+ if (sp == NULL) {
+ warnx("xdr_bytes: out of memory");
+ return (FALSE);
+ }
+ /* FALLTHROUGH */
+
+ case XDR_ENCODE:
+ return (xdr_opaque(xdrs, sp, nodesize));
+
+ case XDR_FREE:
+ if (sp != NULL) {
+ mem_free(sp, nodesize);
+ *cpp = NULL;
+ }
+ return (TRUE);
+ }
+ /* NOTREACHED */
+ return (FALSE);
+}
+
+/*
+ * Implemented here due to commonality of the object.
+ */
+bool_t
+xdr_netobj(
+ XDR *xdrs,
+ struct netobj *np)
+{
+
+ return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ));
+}
+
+/*
+ * XDR a descriminated union
+ * Support routine for discriminated unions.
+ * You create an array of xdrdiscrim structures, terminated with
+ * an entry with a null procedure pointer. The routine gets
+ * the discriminant value and then searches the array of xdrdiscrims
+ * looking for that value. It calls the procedure given in the xdrdiscrim
+ * to handle the discriminant. If there is no specific routine a default
+ * routine may be called.
+ * If there is no specific or default routine an error is returned.
+ */
+bool_t
+xdr_union(
+ XDR *xdrs,
+ enum_t *dscmp, /* enum to decide which arm to work on */
+ char *unp, /* the union itself */
+ const struct xdr_discrim *choices, /* [value, xdr proc] for each arm */
+ xdrproc_t dfault) /* default xdr routine */
+{
+ enum_t dscm;
+
+ /*
+ * we deal with the discriminator; it's an enum
+ */
+ if (! xdr_enum(xdrs, dscmp)) {
+ return (FALSE);
+ }
+ dscm = *dscmp;
+
+ /*
+ * search choices for a value that matches the discriminator.
+ * if we find one, execute the xdr routine for that value.
+ */
+ for (; choices->proc != NULL_xdrproc_t; choices++) {
+ if (choices->value == dscm)
+ return ((*(choices->proc))(xdrs, unp, LASTUNSIGNED));
+ }
+
+ /*
+ * no match - execute the default xdr routine if there is one
+ */
+ return ((dfault == NULL_xdrproc_t) ? FALSE :
+ (*dfault)(xdrs, unp, LASTUNSIGNED));
+}
+
+
+/*
+ * Non-portable xdr primitives.
+ * Care should be taken when moving these routines to new architectures.
+ */
+
+
+/*
+ * XDR null terminated ASCII strings
+ * xdr_string deals with "C strings" - arrays of bytes that are
+ * terminated by a NULL character. The parameter cpp references a
+ * pointer to storage; If the pointer is null, then the necessary
+ * storage is allocated. The last parameter is the max allowed length
+ * of the string as specified by a protocol.
+ */
+bool_t
+xdr_string(
+ XDR *xdrs,
+ char **cpp,
+ u_int maxsize)
+{
+ char *sp = *cpp; /* sp is the actual string pointer */
+ u_int size = 0;
+ u_int nodesize;
+
+ /*
+ * first deal with the length since xdr strings are counted-strings
+ */
+ switch (xdrs->x_op) {
+ case XDR_FREE:
+ if (sp == NULL) {
+ return(TRUE); /* already free */
+ }
+ /* FALLTHROUGH */
+ case XDR_ENCODE:
+ size = strlen(sp);
+ break;
+ case XDR_DECODE:
+ break;
+ }
+ if (! xdr_u_int(xdrs, &size)) {
+ return (FALSE);
+ }
+ if (size > maxsize) {
+ return (FALSE);
+ }
+ nodesize = size + 1;
+
+ /*
+ * now deal with the actual bytes
+ */
+ switch (xdrs->x_op) {
+
+ case XDR_DECODE:
+ if (nodesize == 0) {
+ return (TRUE);
+ }
+ if (sp == NULL)
+ *cpp = sp = mem_alloc(nodesize);
+ if (sp == NULL) {
+ warnx("xdr_string: out of memory");
+ return (FALSE);
+ }
+ sp[size] = 0;
+ /* FALLTHROUGH */
+
+ case XDR_ENCODE:
+ return (xdr_opaque(xdrs, sp, size));
+
+ case XDR_FREE:
+ mem_free(sp, nodesize);
+ *cpp = NULL;
+ return (TRUE);
+ }
+ /* NOTREACHED */
+ return (FALSE);
+}
+
+/*
+ * Wrapper for xdr_string that can be called directly from
+ * routines like clnt_call
+ */
+bool_t
+xdr_wrapstring(
+ XDR *xdrs,
+ char **cpp)
+{
+ return xdr_string(xdrs, cpp, LASTUNSIGNED);
+}
+
+/*
+ * XDR 64-bit integers
+ */
+bool_t
+xdr_int64_t(
+ XDR *xdrs,
+ int64_t *int64_p)
+{
+ int64_t x;
+
+ switch (xdrs->x_op) {
+ case XDR_ENCODE:
+ return (xdr_opaque(xdrs, (caddr_t)int64_p, sizeof(int64_t)));
+ case XDR_DECODE:
+ if (!xdr_opaque(xdrs, (caddr_t)&x, sizeof x)) {
+ return (FALSE);
+ }
+ *int64_p = x;
+ return (TRUE);
+ case XDR_FREE:
+ return (TRUE);
+ }
+ /* NOTREACHED */
+ return (FALSE);
+}
+
+
+/*
+ * XDR unsigned 64-bit integers
+ */
+bool_t
+xdr_u_int64_t(
+ XDR *xdrs,
+ u_int64_t *uint64_p)
+{
+ u_int64_t x;
+
+ switch (xdrs->x_op) {
+ case XDR_ENCODE:
+ return (xdr_opaque(xdrs, (caddr_t)uint64_p, sizeof(u_int64_t)));
+ case XDR_DECODE:
+ if (!xdr_opaque(xdrs, (caddr_t)&x, sizeof x)) {
+ return (FALSE);
+ }
+ *uint64_p = x;
+ return (TRUE);
+ case XDR_FREE:
+ return (TRUE);
+ }
+ /* NOTREACHED */
+ return (FALSE);
+}
+
+/* FIXME: RTEMS does not support u_longlong_t and longlong_t, yet */
+#if !defined(__rtems__)
+/*
+ * XDR hypers
+ */
+bool_t
+xdr_hyper(xdrs, llp)
+ XDR *xdrs;
+ longlong_t *llp;
+{
+
+ /*
+ * Don't bother open-coding this; it's a fair amount of code. Just
+ * call xdr_int64_t().
+ */
+ return (xdr_int64_t(xdrs, (int64_t *)llp));
+}
+
+
+/*
+ * XDR unsigned hypers
+ */
+bool_t
+xdr_u_hyper(xdrs, ullp)
+ XDR *xdrs;
+ u_longlong_t *ullp;
+{
+
+ /*
+ * Don't bother open-coding this; it's a fair amount of code. Just
+ * call xdr_u_int64_t().
+ */
+ return (xdr_u_int64_t(xdrs, (u_int64_t *)ullp));
+}
+
+
+/*
+ * XDR longlong_t's
+ */
+bool_t
+xdr_longlong_t(xdrs, llp)
+ XDR *xdrs;
+ longlong_t *llp;
+{
+
+ /*
+ * Don't bother open-coding this; it's a fair amount of code. Just
+ * call xdr_int64_t().
+ */
+ return (xdr_int64_t(xdrs, (int64_t *)llp));
+}
+
+
+/*
+ * XDR u_longlong_t's
+ */
+bool_t
+xdr_u_longlong_t(xdrs, ullp)
+ XDR *xdrs;
+ u_longlong_t *ullp;
+{
+
+ /*
+ * Don't bother open-coding this; it's a fair amount of code. Just
+ * call xdr_u_int64_t().
+ */
+ return (xdr_u_int64_t(xdrs, (u_int64_t *)ullp));
+}
+#endif
diff --git a/librpc/src/xdr/xdr_array.c b/librpc/src/xdr/xdr_array.c
new file mode 100644
index 0000000..190dc3c
--- /dev/null
+++ b/librpc/src/xdr/xdr_array.c
@@ -0,0 +1,160 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)xdr_array.c 1.10 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)xdr_array.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/xdr/xdr_array.c,v 1.8 1999/08/28 00:02:55 peter Exp $";
+#endif
+
+/*
+ * xdr_array.c, Generic XDR routines impelmentation.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * These are the "non-trivial" xdr primitives used to serialize and de-serialize
+ * arrays. See xdr.h for more info on the interface to xdr.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+#define LASTUNSIGNED ((u_int) 0-1)
+
+/*
+ * XDR an array of arbitrary elements
+ * *addrp is a pointer to the array, *sizep is the number of elements.
+ * If addrp is NULL (*sizep * elsize) bytes are allocated.
+ * elsize is the size (in bytes) of each element, and elproc is the
+ * xdr procedure to call to handle each element of the array.
+ */
+bool_t
+xdr_array(
+ register XDR *xdrs,
+ caddr_t *addrp, /* array pointer */
+ u_int *sizep, /* number of elements */
+ u_int maxsize, /* max numberof elements */
+ u_int elsize, /* size in bytes of each element */
+ xdrproc_t elproc) /* xdr routine to handle each element */
+{
+ register u_int i;
+ register caddr_t target = *addrp;
+ register u_int c; /* the actual element count */
+ register bool_t stat = TRUE;
+ register u_int nodesize;
+
+ /* like strings, arrays are really counted arrays */
+ if (! xdr_u_int(xdrs, sizep)) {
+ return (FALSE);
+ }
+ c = *sizep;
+ if ((c > maxsize) && (xdrs->x_op != XDR_FREE)) {
+ return (FALSE);
+ }
+ nodesize = c * elsize;
+
+ /*
+ * if we are deserializing, we may need to allocate an array.
+ * We also save time by checking for a null array if we are freeing.
+ */
+ if (target == NULL)
+ switch (xdrs->x_op) {
+ case XDR_DECODE:
+ if (c == 0)
+ return (TRUE);
+ *addrp = target = mem_alloc(nodesize);
+ if (target == NULL) {
+ (void) fprintf(stderr,
+ "xdr_array: out of memory\n");
+ return (FALSE);
+ }
+ memset(target, 0, nodesize);
+ break;
+
+ case XDR_FREE:
+ return (TRUE);
+ case XDR_ENCODE: /* to avoid warning */
+ break;
+ }
+
+ /*
+ * now we xdr each element of array
+ */
+ for (i = 0; (i < c) && stat; i++) {
+ stat = (*elproc)(xdrs, target, LASTUNSIGNED);
+ target += elsize;
+ }
+
+ /*
+ * the array may need freeing
+ */
+ if (xdrs->x_op == XDR_FREE) {
+ mem_free(*addrp, nodesize);
+ *addrp = NULL;
+ }
+ return (stat);
+}
+
+/*
+ * xdr_vector():
+ *
+ * XDR a fixed length array. Unlike variable-length arrays,
+ * the storage of fixed length arrays is static and unfreeable.
+ * > basep: base of the array
+ * > size: size of the array
+ * > elemsize: size of each element
+ * > xdr_elem: routine to XDR each element
+ */
+bool_t
+xdr_vector(
+ register XDR *xdrs,
+ register char *basep,
+ register u_int nelem,
+ register u_int elemsize,
+ register xdrproc_t xdr_elem)
+{
+ register u_int i;
+ register char *elptr;
+
+ elptr = basep;
+ for (i = 0; i < nelem; i++) {
+ if (! (*xdr_elem)(xdrs, elptr, LASTUNSIGNED)) {
+ return(FALSE);
+ }
+ elptr += elemsize;
+ }
+ return(TRUE);
+}
diff --git a/librpc/src/xdr/xdr_float.c b/librpc/src/xdr/xdr_float.c
new file mode 100644
index 0000000..b2282b3
--- /dev/null
+++ b/librpc/src/xdr/xdr_float.c
@@ -0,0 +1,344 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)xdr_float.c 1.12 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)xdr_float.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/xdr/xdr_float.c,v 1.7 1999/08/28 00:02:55 peter Exp $";
+#endif
+
+/*
+ * xdr_float.c, Generic XDR routines impelmentation.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * These are the "floating point" xdr routines used to (de)serialize
+ * most common data items. See xdr.h for more info on the interface to
+ * xdr.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+/*
+ * NB: Not portable.
+ * This routine works on machines with IEEE754 FP and Vaxen.
+ */
+
+#if defined(__alpha__) || \
+ defined(_AM29K) || \
+ defined(__arm__) || \
+ defined(__epiphany__) || defined(__EPIPHANY__) || \
+ defined(__hppa__) || \
+ defined(__i386__) || \
+ defined(__lm32__) || \
+ defined(__m68k__) || defined(__mc68000__) || \
+ defined(__mips__) || defined(__moxie__) || \
+ defined(__nios2__) || \
+ defined(__ns32k__) || \
+ defined(__or1k__) || defined(__or1knd__) || \
+ defined(__sparc__) || \
+ defined(__ppc__) || defined(__PPC__) || \
+ defined(__riscv) || \
+ defined(__sh__) || \
+ defined(__BFIN__) || \
+ defined(__m32c__) || \
+ defined(__v850) || \
+ defined(__x86_64__)
+
+#include <rtems/endian.h>
+#if !defined(IEEEFP)
+#define IEEEFP
+#endif
+
+#elif defined(_TMS320C3x) || defined(_TMS320C4x)
+#error "Texas Instruments C3x/C4x Not supported."
+
+#elif defined(vax)
+
+/* What IEEE single precision floating point looks like on a Vax */
+struct ieee_single {
+ unsigned int mantissa: 23;
+ unsigned int exp : 8;
+ unsigned int sign : 1;
+};
+
+/* Vax single precision floating point */
+struct vax_single {
+ unsigned int mantissa1 : 7;
+ unsigned int exp : 8;
+ unsigned int sign : 1;
+ unsigned int mantissa2 : 16;
+};
+
+#define VAX_SNG_BIAS 0x81
+#define IEEE_SNG_BIAS 0x7f
+
+static struct sgl_limits {
+ struct vax_single s;
+ struct ieee_single ieee;
+} sgl_limits[2] = {
+ {{ 0x7f, 0xff, 0x0, 0xffff }, /* Max Vax */
+ { 0x0, 0xff, 0x0 }}, /* Max IEEE */
+ {{ 0x0, 0x0, 0x0, 0x0 }, /* Min Vax */
+ { 0x0, 0x0, 0x0 }} /* Min IEEE */
+};
+/* end of vax */
+#else
+#error "xdr_float.c: unknown CPU"
+#endif
+
+
+bool_t
+xdr_float(
+ register XDR *xdrs,
+ register float *fp)
+{
+#ifdef IEEEFP
+ bool_t rv;
+ long tmpl;
+#else
+ struct ieee_single is;
+ struct vax_single vs, *vsp;
+ struct sgl_limits *lim;
+ int i;
+#endif
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+#ifdef IEEEFP
+ tmpl = *(int32_t *)fp;
+ return (XDR_PUTLONG(xdrs, &tmpl));
+#else
+ vs = *((struct vax_single *)fp);
+ for (i = 0, lim = sgl_limits;
+ i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
+ i++, lim++) {
+ if ((vs.mantissa2 == lim->s.mantissa2) &&
+ (vs.exp == lim->s.exp) &&
+ (vs.mantissa1 == lim->s.mantissa1)) {
+ is = lim->ieee;
+ goto shipit;
+ }
+ }
+ is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
+ is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2;
+ shipit:
+ is.sign = vs.sign;
+ return (XDR_PUTLONG(xdrs, (long *)&is));
+#endif
+
+ case XDR_DECODE:
+#ifdef IEEEFP
+ rv = XDR_GETLONG(xdrs, &tmpl);
+ *(int32_t *)fp = tmpl;
+ return (rv);
+#else
+ vsp = (struct vax_single *)fp;
+ if (!XDR_GETLONG(xdrs, (long *)&is))
+ return (FALSE);
+ for (i = 0, lim = sgl_limits;
+ i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
+ i++, lim++) {
+ if ((is.exp == lim->ieee.exp) &&
+ (is.mantissa == lim->ieee.mantissa)) {
+ *vsp = lim->s;
+ goto doneit;
+ }
+ }
+ vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
+ vsp->mantissa2 = is.mantissa;
+ vsp->mantissa1 = (is.mantissa >> 16);
+ doneit:
+ vsp->sign = is.sign;
+ return (TRUE);
+#endif
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ return (FALSE);
+}
+
+#ifdef vax
+/* What IEEE double precision floating point looks like on a Vax */
+struct ieee_double {
+ unsigned int mantissa1 : 20;
+ unsigned int exp : 11;
+ unsigned int sign : 1;
+ unsigned int mantissa2 : 32;
+};
+
+/* Vax double precision floating point */
+struct vax_double {
+ unsigned int mantissa1 : 7;
+ unsigned int exp : 8;
+ unsigned int sign : 1;
+ unsigned int mantissa2 : 16;
+ unsigned int mantissa3 : 16;
+ unsigned int mantissa4 : 16;
+};
+
+#define VAX_DBL_BIAS 0x81
+#define IEEE_DBL_BIAS 0x3ff
+#define MASK(nbits) ((1 << nbits) - 1)
+
+static struct dbl_limits {
+ struct vax_double d;
+ struct ieee_double ieee;
+} dbl_limits[2] = {
+ {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff }, /* Max Vax */
+ { 0x0, 0x7ff, 0x0, 0x0 }}, /* Max IEEE */
+ {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* Min Vax */
+ { 0x0, 0x0, 0x0, 0x0 }} /* Min IEEE */
+};
+
+#endif /* vax */
+
+
+bool_t
+xdr_double(
+ register XDR *xdrs,
+ double *dp)
+{
+#ifdef IEEEFP
+ register int32_t *i32p;
+ bool_t rv;
+ long tmpl;
+#else
+ register long *lp;
+ struct ieee_double id;
+ struct vax_double vd;
+ register struct dbl_limits *lim;
+ int i;
+#endif
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+#ifdef IEEEFP
+ i32p = (int32_t *)dp;
+#if BYTE_ORDER == BIG_ENDIAN
+ tmpl = *i32p++;
+ rv = XDR_PUTLONG(xdrs, &tmpl);
+ if (!rv)
+ return (rv);
+ tmpl = *i32p;
+ rv = XDR_PUTLONG(xdrs, &tmpl);
+#else
+ tmpl = *(i32p+1);
+ rv = XDR_PUTLONG(xdrs, &tmpl);
+ if (!rv)
+ return (rv);
+ tmpl = *i32p;
+ rv = XDR_PUTLONG(xdrs, &tmpl);
+#endif
+ return (rv);
+#else
+ vd = *((struct vax_double *)dp);
+ for (i = 0, lim = dbl_limits;
+ i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
+ i++, lim++) {
+ if ((vd.mantissa4 == lim->d.mantissa4) &&
+ (vd.mantissa3 == lim->d.mantissa3) &&
+ (vd.mantissa2 == lim->d.mantissa2) &&
+ (vd.mantissa1 == lim->d.mantissa1) &&
+ (vd.exp == lim->d.exp)) {
+ id = lim->ieee;
+ goto shipit;
+ }
+ }
+ id.exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
+ id.mantissa1 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3);
+ id.mantissa2 = ((vd.mantissa2 & MASK(3)) << 29) |
+ (vd.mantissa3 << 13) |
+ ((vd.mantissa4 >> 3) & MASK(13));
+ shipit:
+ id.sign = vd.sign;
+ lp = (long *)&id;
+ return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp));
+#endif
+
+ case XDR_DECODE:
+#ifdef IEEEFP
+ i32p = (int32_t *)dp;
+#if BYTE_ORDER == BIG_ENDIAN
+ rv = XDR_GETLONG(xdrs, &tmpl);
+ *i32p++ = tmpl;
+ if (!rv)
+ return (rv);
+ rv = XDR_GETLONG(xdrs, &tmpl);
+ *i32p = tmpl;
+#else
+ rv = XDR_GETLONG(xdrs, &tmpl);
+ *(i32p+1) = tmpl;
+ if (!rv)
+ return (rv);
+ rv = XDR_GETLONG(xdrs, &tmpl);
+ *i32p = tmpl;
+#endif
+ return (rv);
+#else
+ lp = (long *)&id;
+ if (!XDR_GETLONG(xdrs, lp++) || !XDR_GETLONG(xdrs, lp))
+ return (FALSE);
+ for (i = 0, lim = dbl_limits;
+ i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
+ i++, lim++) {
+ if ((id.mantissa2 == lim->ieee.mantissa2) &&
+ (id.mantissa1 == lim->ieee.mantissa1) &&
+ (id.exp == lim->ieee.exp)) {
+ vd = lim->d;
+ goto doneit;
+ }
+ }
+ vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
+ vd.mantissa1 = (id.mantissa1 >> 13);
+ vd.mantissa2 = ((id.mantissa1 & MASK(13)) << 3) |
+ (id.mantissa2 >> 29);
+ vd.mantissa3 = (id.mantissa2 >> 13);
+ vd.mantissa4 = (id.mantissa2 << 3);
+ doneit:
+ vd.sign = id.sign;
+ *dp = *((double *)&vd);
+ return (TRUE);
+#endif
+
+ case XDR_FREE:
+ return (TRUE);
+ }
+ return (FALSE);
+}
diff --git a/librpc/src/xdr/xdr_mem.c b/librpc/src/xdr/xdr_mem.c
new file mode 100644
index 0000000..5b30419
--- /dev/null
+++ b/librpc/src/xdr/xdr_mem.c
@@ -0,0 +1,245 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)xdr_mem.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/xdr/xdr_mem.c,v 1.8 1999/08/28 00:02:56 peter Exp $";
+#endif
+
+/*
+ * xdr_mem.h, XDR implementation using memory buffers.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * If you have some data to be interpreted as external data representation
+ * or to be converted to external data representation in a memory buffer,
+ * then this is the package for you.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <netinet/in.h>
+
+static bool_t xdrmem_getlong_aligned(XDR *xdrs, long *lp);
+static bool_t xdrmem_putlong_aligned(XDR *xdrs, const long *lp);
+static bool_t xdrmem_getlong_unaligned(XDR *xdrs, long *lp);
+static bool_t xdrmem_putlong_unaligned(XDR *xdrs, const long *lp);
+static bool_t xdrmem_getbytes(XDR *xdrs, caddr_t addr, u_int len);
+static bool_t xdrmem_putbytes(XDR *xdrs, const char *addr, u_int len);
+static u_int xdrmem_getpos(XDR *xdrs); /* XXX w/64-bit pointers, u_int not enough! */
+static bool_t xdrmem_setpos(XDR *xdrs, u_int pos);
+static int32_t *xdrmem_inline_aligned(XDR *xdrs, u_int len);
+static int32_t *xdrmem_inline_unaligned(XDR *xdrs, u_int len);
+static void xdrmem_destroy(XDR *);
+
+static struct xdr_ops xdrmem_ops_aligned = {
+ xdrmem_getlong_aligned,
+ xdrmem_putlong_aligned,
+ xdrmem_getbytes,
+ xdrmem_putbytes,
+ xdrmem_getpos,
+ xdrmem_setpos,
+ xdrmem_inline_aligned,
+ xdrmem_destroy
+};
+
+static struct xdr_ops xdrmem_ops_unaligned = {
+ xdrmem_getlong_unaligned,
+ xdrmem_putlong_unaligned,
+ xdrmem_getbytes,
+ xdrmem_putbytes,
+ xdrmem_getpos,
+ xdrmem_setpos,
+ xdrmem_inline_unaligned,
+ xdrmem_destroy
+};
+
+/*
+ * The procedure xdrmem_create initializes a stream descriptor for a
+ * memory buffer.
+ */
+void
+xdrmem_create(
+ XDR *xdrs,
+ char * addr,
+ u_int size,
+ enum xdr_op op)
+{
+
+ xdrs->x_op = op;
+ xdrs->x_ops = ((uintptr_t)addr & (sizeof(int32_t) - 1))
+ ? &xdrmem_ops_unaligned : &xdrmem_ops_aligned;
+ xdrs->x_private = xdrs->x_base = addr;
+ xdrs->x_handy = size;
+}
+
+static void
+xdrmem_destroy(XDR *xdrs)
+{
+
+}
+
+static bool_t
+xdrmem_getlong_aligned(
+ XDR *xdrs,
+ long *lp)
+{
+
+ if ((xdrs->x_handy -= sizeof(int32_t)) < 0)
+ return (FALSE);
+ *lp = ntohl(*(int32_t *)(xdrs->x_private));
+ xdrs->x_private += sizeof(int32_t);
+ return (TRUE);
+}
+
+static bool_t
+xdrmem_putlong_aligned(
+ XDR *xdrs,
+ const long *lp)
+{
+
+ if ((xdrs->x_handy -= sizeof(int32_t)) < 0)
+ return (FALSE);
+ *(int32_t *)xdrs->x_private = htonl(*lp);
+ xdrs->x_private += sizeof(int32_t);
+ return (TRUE);
+}
+
+static bool_t
+xdrmem_getlong_unaligned(
+ XDR *xdrs,
+ long *lp)
+{
+ int32_t l;
+
+ if ((xdrs->x_handy -= sizeof(int32_t)) < 0)
+ return (FALSE);
+ memcpy(&l, xdrs->x_private, sizeof(int32_t));
+ *lp = ntohl(l);
+ xdrs->x_private += sizeof(int32_t);
+ return (TRUE);
+}
+
+static bool_t
+xdrmem_putlong_unaligned(
+ XDR *xdrs,
+ const long *lp)
+{
+ int32_t l;
+
+ if ((xdrs->x_handy -= sizeof(int32_t)) < 0)
+ return (FALSE);
+ l = htonl(*lp);
+ memcpy(xdrs->x_private, &l, sizeof(int32_t));
+ xdrs->x_private += sizeof(int32_t);
+ return (TRUE);
+}
+
+static bool_t
+xdrmem_getbytes(
+ XDR *xdrs,
+ caddr_t addr,
+ u_int len)
+{
+
+ if ((xdrs->x_handy -= len) < 0)
+ return (FALSE);
+ memcpy(addr, xdrs->x_private, len);
+ xdrs->x_private += len;
+ return (TRUE);
+}
+
+static bool_t
+xdrmem_putbytes(
+ XDR *xdrs,
+ const char *addr,
+ u_int len)
+{
+
+ if ((xdrs->x_handy -= len) < 0)
+ return (FALSE);
+ memcpy(xdrs->x_private, addr, len);
+ xdrs->x_private += len;
+ return (TRUE);
+}
+
+static u_int
+xdrmem_getpos(
+ XDR *xdrs)
+{
+
+ /* XXX w/64-bit pointers, u_int not enough! */
+ return ((uintptr_t)xdrs->x_private - (uintptr_t)xdrs->x_base);
+}
+
+static bool_t
+xdrmem_setpos(
+ XDR *xdrs,
+ u_int pos)
+{
+ void *newaddr = xdrs->x_base + pos;
+ void *lastaddr = xdrs->x_private + xdrs->x_handy;
+
+ if (newaddr > lastaddr)
+ return (FALSE);
+ xdrs->x_private = newaddr;
+ xdrs->x_handy = (intptr_t)lastaddr - (intptr_t)newaddr;
+ return (TRUE);
+}
+
+static int32_t *
+xdrmem_inline_aligned(
+ XDR *xdrs,
+ u_int len)
+{
+ int32_t *buf = 0;
+
+ if (xdrs->x_handy >= len) {
+ xdrs->x_handy -= len;
+ buf = (int32_t *)xdrs->x_private;
+ xdrs->x_private += len;
+ }
+ return (buf);
+}
+
+static int32_t *
+xdrmem_inline_unaligned(
+ XDR *xdrs,
+ u_int len)
+{
+
+ return (0);
+}
diff --git a/librpc/src/xdr/xdr_rec.c b/librpc/src/xdr/xdr_rec.c
new file mode 100644
index 0000000..7e47527
--- /dev/null
+++ b/librpc/src/xdr/xdr_rec.c
@@ -0,0 +1,608 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)xdr_rec.c 1.21 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)xdr_rec.c 2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/xdr/xdr_rec.c,v 1.12 2000/01/19 06:12:32 wpaul Exp $";
+#endif
+
+/*
+ * xdr_rec.c, Implements TCP/IP based XDR streams with a "record marking"
+ * layer above tcp (for rpc's use).
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * These routines interface XDRSTREAMS to a tcp/ip connection.
+ * There is a record marking layer between the xdr stream
+ * and the tcp transport level. A record is composed on one or more
+ * record fragments. A record fragment is a thirty-two bit header followed
+ * by n bytes of data, where n is contained in the header. The header
+ * is represented as a htonl(u_long). Thegh order bit encodes
+ * whether or not the fragment is the last fragment of the record
+ * (1 => fragment is last, 0 => more fragments to follow.
+ * The other 31 bits encode the byte length of the fragment.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <netinet/in.h>
+#include <unistd.h> /* for lseek() */
+
+typedef struct rec_strm RECSTREAM;
+
+static u_int fix_buf_size(u_int);
+static bool_t flush_out(RECSTREAM *rstrm, bool_t eor);
+static bool_t get_input_bytes(RECSTREAM *rstrm, caddr_t addr, int len);
+static bool_t set_input_fragment(RECSTREAM *rstrm);
+static bool_t skip_input_bytes(RECSTREAM *rstrm, long cnt);
+
+static bool_t xdrrec_getlong(XDR *xdrs, long *lp);
+static bool_t xdrrec_putlong(XDR *xdrs, const long *lp);
+static bool_t xdrrec_getbytes(XDR *xdrs, caddr_t addr, u_int len);
+static bool_t xdrrec_putbytes(XDR *xdrs, const char *addr, u_int len);
+static u_int xdrrec_getpos(XDR *xdrs);
+static bool_t xdrrec_setpos(XDR *xdrs, u_int pos);
+static int32_t *xdrrec_inline(XDR *xdrs, u_int len);
+static void xdrrec_destroy(XDR *xdrs);
+
+static struct xdr_ops xdrrec_ops = {
+ xdrrec_getlong,
+ xdrrec_putlong,
+ xdrrec_getbytes,
+ xdrrec_putbytes,
+ xdrrec_getpos,
+ xdrrec_setpos,
+ xdrrec_inline,
+ xdrrec_destroy
+};
+
+/*
+ * A record is composed of one or more record fragments.
+ * A record fragment is a two-byte header followed by zero to
+ * 2**32-1 bytes. The header is treated as a long unsigned and is
+ * encode/decoded to the network via htonl/ntohl. The low order 31 bits
+ * are a byte count of the fragment. The highest order bit is a boolean:
+ * 1 => this fragment is the last fragment of the record,
+ * 0 => this fragment is followed by more fragment(s).
+ *
+ * The fragment/record machinery is not general; it is constructed to
+ * meet the needs of xdr and rpc based on tcp.
+ */
+
+#define LAST_FRAG ((u_int32_t)(1L << 31))
+
+struct rec_strm {
+ caddr_t tcp_handle;
+ caddr_t the_buffer;
+ /*
+ * out-goung bits
+ */
+ int (*writeit) (caddr_t, caddr_t, int);
+ caddr_t out_base; /* output buffer (points to frag header) */
+ caddr_t out_finger; /* next output position */
+ caddr_t out_boundry; /* data cannot up to this address */
+ u_int32_t *frag_header; /* beginning of current fragment */
+ bool_t frag_sent; /* true if buffer sent in middle of record */
+ /*
+ * in-coming bits
+ */
+ int (*readit) (caddr_t, caddr_t, int);
+ u_long in_size; /* fixed size of the input buffer */
+ caddr_t in_base;
+ caddr_t in_finger; /* location of next byte to be had */
+ caddr_t in_boundry; /* can read up to this location */
+ long fbtbc; /* fragment bytes to be consumed */
+ bool_t last_frag;
+ u_int sendsize;
+ u_int recvsize;
+};
+
+
+/*
+ * Create an xdr handle for xdrrec
+ * xdrrec_create fills in xdrs. Sendsize and recvsize are
+ * send and recv buffer sizes (0 => use default).
+ * tcp_handle is an opaque handle that is passed as the first parameter to
+ * the procedures readit and writeit. Readit and writeit are read and
+ * write respectively. They are like the system
+ * calls expect that they take an opaque handle rather than an fd.
+ */
+void
+xdrrec_create(
+ XDR *xdrs,
+ u_int sendsize,
+ u_int recvsize,
+ caddr_t tcp_handle,
+ int (*readit)(char*, char*, int), /* like read, but pass it a tcp_handle, not sock */
+ int (*writeit)(char*, char*, int) /* like write, but pass it a tcp_handle, not sock */
+)
+{
+ RECSTREAM *rstrm =
+ (RECSTREAM *)mem_alloc(sizeof(RECSTREAM));
+
+ if (rstrm == NULL) {
+ (void)fprintf(stderr, "xdrrec_create: out of memory\n");
+ /*
+ * This is bad. Should rework xdrrec_create to
+ * return a handle, and in this case return NULL
+ */
+ return;
+ }
+ /*
+ * adjust sizes and allocate buffer quad byte aligned
+ */
+ rstrm->sendsize = sendsize = fix_buf_size(sendsize);
+ rstrm->recvsize = recvsize = fix_buf_size(recvsize);
+ rstrm->the_buffer = mem_alloc(sendsize + recvsize + BYTES_PER_XDR_UNIT);
+ if (rstrm->the_buffer == NULL) {
+ (void)fprintf(stderr, "xdrrec_create: out of memory\n");
+ return;
+ }
+ for (rstrm->out_base = rstrm->the_buffer;
+ (uintptr_t)rstrm->out_base % BYTES_PER_XDR_UNIT != 0;
+ rstrm->out_base++);
+ rstrm->in_base = rstrm->out_base + sendsize;
+ /*
+ * now the rest ...
+ */
+ xdrs->x_ops = &xdrrec_ops;
+ xdrs->x_private = (caddr_t)rstrm;
+ rstrm->tcp_handle = tcp_handle;
+ rstrm->readit = readit;
+ rstrm->writeit = writeit;
+ rstrm->out_finger = rstrm->out_boundry = rstrm->out_base;
+ rstrm->frag_header = (u_int32_t *)rstrm->out_base;
+ rstrm->out_finger += sizeof(u_int32_t);
+ rstrm->out_boundry += sendsize;
+ rstrm->frag_sent = FALSE;
+ rstrm->in_size = recvsize;
+ rstrm->in_boundry = rstrm->in_base;
+ rstrm->in_finger = (rstrm->in_boundry += recvsize);
+ rstrm->fbtbc = 0;
+ rstrm->last_frag = TRUE;
+}
+
+
+/*
+ * The reoutines defined below are the xdr ops which will go into the
+ * xdr handle filled in by xdrrec_create.
+ */
+
+static bool_t
+xdrrec_getlong(
+ XDR *xdrs,
+ long *lp)
+{
+ RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+ int32_t *buflp = (int32_t *)(rstrm->in_finger);
+ int32_t mylong;
+
+ /* first try the inline, fast case */
+ if ((rstrm->fbtbc >= sizeof(int32_t)) &&
+ (((intptr_t)rstrm->in_boundry - (intptr_t)buflp) >= sizeof(int32_t))) {
+ *lp = (long)ntohl((u_int32_t)(*buflp));
+ rstrm->fbtbc -= sizeof(int32_t);
+ rstrm->in_finger += sizeof(int32_t);
+ } else {
+ if (! xdrrec_getbytes(xdrs, (caddr_t)&mylong, sizeof(int32_t)))
+ return (FALSE);
+ *lp = (long)ntohl((u_int32_t)mylong);
+ }
+ return (TRUE);
+}
+
+static bool_t
+xdrrec_putlong(
+ XDR *xdrs,
+ const long *lp)
+{
+ RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+ int32_t *dest_lp = ((int32_t *)(rstrm->out_finger));
+
+ if ((rstrm->out_finger += sizeof(int32_t)) > rstrm->out_boundry) {
+ /*
+ * this case should almost never happen so the code is
+ * inefficient
+ */
+ rstrm->out_finger -= sizeof(int32_t);
+ rstrm->frag_sent = TRUE;
+ if (! flush_out(rstrm, FALSE))
+ return (FALSE);
+ dest_lp = ((int32_t *)(rstrm->out_finger));
+ rstrm->out_finger += sizeof(int32_t);
+ }
+ *dest_lp = (int32_t)htonl((u_int32_t)(*lp));
+ return (TRUE);
+}
+
+static bool_t /* must manage buffers, fragments, and records */
+xdrrec_getbytes(
+ XDR *xdrs,
+ caddr_t addr,
+ u_int len)
+{
+ RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+ int current;
+
+ while (len > 0) {
+ current = rstrm->fbtbc;
+ if (current == 0) {
+ if (rstrm->last_frag)
+ return (FALSE);
+ if (! set_input_fragment(rstrm))
+ return (FALSE);
+ continue;
+ }
+ current = (len < current) ? len : current;
+ if (! get_input_bytes(rstrm, addr, current))
+ return (FALSE);
+ addr += current;
+ rstrm->fbtbc -= current;
+ len -= current;
+ }
+ return (TRUE);
+}
+
+static bool_t
+xdrrec_putbytes(
+ XDR *xdrs,
+ const char *addr,
+ u_int len)
+{
+ RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+ long current;
+
+ while (len > 0) {
+ current = (intptr_t)rstrm->out_boundry -
+ (intptr_t)rstrm->out_finger;
+ current = (len < current) ? len : current;
+ memcpy(rstrm->out_finger, addr, current);
+ rstrm->out_finger += current;
+ addr += current;
+ len -= current;
+ if (rstrm->out_finger == rstrm->out_boundry) {
+ rstrm->frag_sent = TRUE;
+ if (! flush_out(rstrm, FALSE))
+ return (FALSE);
+ }
+ }
+ return (TRUE);
+}
+
+static u_int
+xdrrec_getpos(
+ XDR *xdrs)
+{
+ RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
+ long pos;
+
+ pos = lseek((intptr_t)rstrm->tcp_handle, (off_t) 0, 1);
+ if (pos != -1)
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ pos += rstrm->out_finger - rstrm->out_base;
+ break;
+
+ case XDR_DECODE:
+ pos -= rstrm->in_boundry - rstrm->in_finger;
+ break;
+
+ default:
+ pos = -1;
+ break;
+ }
+ return ((u_int) pos);
+}
+
+static bool_t
+xdrrec_setpos(
+ XDR *xdrs,
+ u_int pos)
+{
+ RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
+ u_int currpos = xdrrec_getpos(xdrs);
+ int delta = currpos - pos;
+ caddr_t newpos;
+
+ if ((int)currpos != -1)
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ newpos = rstrm->out_finger - delta;
+ if ((newpos > (caddr_t)(rstrm->frag_header)) &&
+ (newpos < rstrm->out_boundry)) {
+ rstrm->out_finger = newpos;
+ return (TRUE);
+ }
+ break;
+
+ case XDR_DECODE:
+ newpos = rstrm->in_finger - delta;
+ if ((delta < (int)(rstrm->fbtbc)) &&
+ (newpos <= rstrm->in_boundry) &&
+ (newpos >= rstrm->in_base)) {
+ rstrm->in_finger = newpos;
+ rstrm->fbtbc -= delta;
+ return (TRUE);
+ }
+ break;
+ case XDR_FREE: /* to avoid warning */
+ break;
+ }
+ return (FALSE);
+}
+
+static int32_t *
+xdrrec_inline(
+ XDR *xdrs,
+ u_int len)
+{
+ RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
+ int32_t * buf = NULL;
+
+ switch (xdrs->x_op) {
+
+ case XDR_ENCODE:
+ if ((rstrm->out_finger + len) <= rstrm->out_boundry) {
+ buf = (int32_t *) rstrm->out_finger;
+ rstrm->out_finger += len;
+ }
+ break;
+
+ case XDR_DECODE:
+ if ((len <= rstrm->fbtbc) &&
+ ((rstrm->in_finger + len) <= rstrm->in_boundry)) {
+ buf = (int32_t *) rstrm->in_finger;
+ rstrm->fbtbc -= len;
+ rstrm->in_finger += len;
+ }
+ break;
+ case XDR_FREE: /* to avoid warning */
+ break;
+ }
+ return (buf);
+}
+
+static void
+xdrrec_destroy(
+ XDR *xdrs)
+{
+ RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
+
+ mem_free(rstrm->the_buffer,
+ rstrm->sendsize + rstrm->recvsize + BYTES_PER_XDR_UNIT);
+ mem_free((caddr_t)rstrm, sizeof(RECSTREAM));
+}
+
+
+/*
+ * Exported routines to manage xdr records
+ */
+
+/*
+ * Before reading (deserializing from the stream, one should always call
+ * this procedure to guarantee proper record alignment.
+ */
+bool_t
+xdrrec_skiprecord(
+ XDR *xdrs)
+{
+ RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+
+ while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) {
+ if (! skip_input_bytes(rstrm, rstrm->fbtbc))
+ return (FALSE);
+ rstrm->fbtbc = 0;
+ if ((! rstrm->last_frag) && (! set_input_fragment(rstrm)))
+ return (FALSE);
+ }
+ rstrm->last_frag = FALSE;
+ return (TRUE);
+}
+
+/*
+ * Look ahead fuction.
+ * Returns TRUE iff there is no more input in the buffer
+ * after consuming the rest of the current record.
+ */
+bool_t
+xdrrec_eof(
+ XDR *xdrs)
+{
+ RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+
+ while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) {
+ if (! skip_input_bytes(rstrm, rstrm->fbtbc))
+ return (TRUE);
+ rstrm->fbtbc = 0;
+ if ((! rstrm->last_frag) && (! set_input_fragment(rstrm)))
+ return (TRUE);
+ }
+ if (rstrm->in_finger == rstrm->in_boundry)
+ return (TRUE);
+ return (FALSE);
+}
+
+/*
+ * The client must tell the package when an end-of-record has occurred.
+ * The second paraemters tells whether the record should be flushed to the
+ * (output) tcp stream. (This let's the package support batched or
+ * pipelined procedure calls.) TRUE => immmediate flush to tcp connection.
+ */
+bool_t
+xdrrec_endofrecord(
+ XDR *xdrs,
+ bool_t sendnow)
+{
+ RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+ u_long len; /* fragment length */
+
+ if (sendnow || rstrm->frag_sent ||
+ ((uintptr_t)rstrm->out_finger + sizeof(u_int32_t) >=
+ (uintptr_t)rstrm->out_boundry)) {
+ rstrm->frag_sent = FALSE;
+ return (flush_out(rstrm, TRUE));
+ }
+ len = (uintptr_t)(rstrm->out_finger) - (uintptr_t)(rstrm->frag_header) -
+ sizeof(u_int32_t);
+ *(rstrm->frag_header) = htonl((u_int32_t)len | LAST_FRAG);
+ rstrm->frag_header = (u_int32_t *)rstrm->out_finger;
+ rstrm->out_finger += sizeof(u_int32_t);
+ return (TRUE);
+}
+
+
+/*
+ * Internal useful routines
+ */
+static bool_t
+flush_out(
+ RECSTREAM *rstrm,
+ bool_t eor)
+{
+ u_int32_t eormask = (eor == TRUE) ? LAST_FRAG : 0;
+ u_int32_t len = (uintptr_t)(rstrm->out_finger) -
+ (uintptr_t)(rstrm->frag_header) - sizeof(u_int32_t);
+
+ *(rstrm->frag_header) = htonl(len | eormask);
+ len = (uintptr_t)(rstrm->out_finger) - (uintptr_t)(rstrm->out_base);
+ if ((*(rstrm->writeit))(rstrm->tcp_handle, rstrm->out_base, (int)len)
+ != (int)len)
+ return (FALSE);
+ rstrm->frag_header = (u_int32_t *)rstrm->out_base;
+ rstrm->out_finger = (caddr_t)rstrm->out_base + sizeof(u_int32_t);
+ return (TRUE);
+}
+
+static bool_t /* knows nothing about records! Only about input buffers */
+fill_input_buf(
+ RECSTREAM *rstrm)
+{
+ caddr_t where;
+ u_long i;
+ long len;
+
+ where = rstrm->in_base;
+ i = (uintptr_t)rstrm->in_boundry % BYTES_PER_XDR_UNIT;
+ where += i;
+ len = rstrm->in_size - i;
+ if ((len = (*(rstrm->readit))(rstrm->tcp_handle, where, len)) == -1)
+ return (FALSE);
+ rstrm->in_finger = where;
+ where += len;
+ rstrm->in_boundry = where;
+ return (TRUE);
+}
+
+static bool_t /* knows nothing about records! Only about input buffers */
+get_input_bytes(
+ RECSTREAM *rstrm,
+ caddr_t addr,
+ int len)
+{
+ long current;
+
+ while (len > 0) {
+ current = (intptr_t)rstrm->in_boundry - (intptr_t)rstrm->in_finger;
+ if (current == 0) {
+ if (! fill_input_buf(rstrm))
+ return (FALSE);
+ continue;
+ }
+ current = (len < current) ? len : current;
+ memcpy(addr, rstrm->in_finger, current);
+ rstrm->in_finger += current;
+ addr += current;
+ len -= current;
+ }
+ return (TRUE);
+}
+
+static bool_t /* next two bytes of the input stream are treated as a header */
+set_input_fragment(
+ RECSTREAM *rstrm)
+{
+ u_int32_t header;
+
+ if (! get_input_bytes(rstrm, (caddr_t)&header, sizeof(header)))
+ return (FALSE);
+ header = (long)ntohl(header);
+ rstrm->last_frag = ((header & LAST_FRAG) == 0) ? FALSE : TRUE;
+ /*
+ * Sanity check. Try not to accept wildly incorrect
+ * record sizes. Unfortunately, the only record size
+ * we can positively identify as being 'wildly incorrect'
+ * is zero. Ridiculously large record sizes may look wrong,
+ * but we don't have any way to be certain that they aren't
+ * what the client actually intended to send us.
+ */
+ if (header == 0)
+ return(FALSE);
+ rstrm->fbtbc = header & (~LAST_FRAG);
+ return (TRUE);
+}
+
+static bool_t /* consumes input bytes; knows nothing about records! */
+skip_input_bytes(
+ RECSTREAM *rstrm,
+ long cnt)
+{
+ long current;
+
+ while (cnt > 0) {
+ current = (intptr_t)rstrm->in_boundry - (intptr_t)rstrm->in_finger;
+ if (current == 0) {
+ if (! fill_input_buf(rstrm))
+ return (FALSE);
+ continue;
+ }
+ current = (cnt < current) ? cnt : current;
+ rstrm->in_finger += current;
+ cnt -= current;
+ }
+ return (TRUE);
+}
+
+static u_int
+fix_buf_size(
+ u_int s)
+{
+
+ if (s < 100)
+ s = 4000;
+ return (RNDUP(s));
+}
diff --git a/librpc/src/xdr/xdr_reference.c b/librpc/src/xdr/xdr_reference.c
new file mode 100644
index 0000000..a2a6ee5
--- /dev/null
+++ b/librpc/src/xdr/xdr_reference.c
@@ -0,0 +1,142 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)xdr_reference.c 1.11 87/08/11 SMI";*/
+/*static char *sccsid = "from: @(#)xdr_reference.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/xdr/xdr_reference.c,v 1.8 1999/08/28 00:02:56 peter Exp $";
+#endif
+
+/*
+ * xdr_reference.c, Generic XDR routines impelmentation.
+ *
+ * Copyright (C) 1987, Sun Microsystems, Inc.
+ *
+ * These are the "non-trivial" xdr primitives used to serialize and de-serialize
+ * "pointers". See xdr.h for more info on the interface to xdr.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+#define LASTUNSIGNED ((u_int) 0-1)
+
+/*
+ * XDR an indirect pointer
+ * xdr_reference is for recursively translating a structure that is
+ * referenced by a pointer inside the structure that is currently being
+ * translated. pp references a pointer to storage. If *pp is null
+ * the necessary storage is allocated.
+ * size is the sizeof the referneced structure.
+ * proc is the routine to handle the referenced structure.
+ */
+bool_t
+xdr_reference(
+ register XDR *xdrs,
+ caddr_t *pp, /* the pointer to work on */
+ u_int size, /* size of the object pointed to */
+ xdrproc_t proc) /* xdr routine to handle the object */
+{
+ register caddr_t loc = *pp;
+ register bool_t stat;
+
+ if (loc == NULL)
+ switch (xdrs->x_op) {
+ case XDR_FREE:
+ return (TRUE);
+
+ case XDR_DECODE:
+ *pp = loc = (caddr_t) mem_alloc(size);
+ if (loc == NULL) {
+ (void) fprintf(stderr,
+ "xdr_reference: out of memory\n");
+ return (FALSE);
+ }
+ memset(loc, 0, (int)size);
+ break;
+ case XDR_ENCODE: /* to avoid warning */
+ break;
+ }
+
+ stat = (*proc)(xdrs, loc, LASTUNSIGNED);
+
+ if (xdrs->x_op == XDR_FREE) {
+ mem_free(loc, size);
+ *pp = NULL;
+ }
+ return (stat);
+}
+
+
+/*
+ * xdr_pointer():
+ *
+ * XDR a pointer to a possibly recursive data structure. This
+ * differs with xdr_reference in that it can serialize/deserialiaze
+ * trees correctly.
+ *
+ * What's sent is actually a union:
+ *
+ * union object_pointer switch (boolean b) {
+ * case TRUE: object_data data;
+ * case FALSE: void nothing;
+ * }
+ *
+ * > objpp: Pointer to the pointer to the object.
+ * > obj_size: size of the object.
+ * > xdr_obj: routine to XDR an object.
+ *
+ */
+bool_t
+xdr_pointer(
+ register XDR *xdrs,
+ char **objpp,
+ u_int obj_size,
+ xdrproc_t xdr_obj)
+{
+
+ bool_t more_data;
+
+ more_data = (*objpp != NULL);
+ if (! xdr_bool(xdrs,&more_data)) {
+ return (FALSE);
+ }
+ if (! more_data) {
+ *objpp = NULL;
+ return (TRUE);
+ }
+ return (xdr_reference(xdrs,objpp,obj_size,xdr_obj));
+}
diff --git a/librpc/src/xdr/xdr_sizeof.c b/librpc/src/xdr/xdr_sizeof.c
new file mode 100644
index 0000000..72a7ff9
--- /dev/null
+++ b/librpc/src/xdr/xdr_sizeof.c
@@ -0,0 +1,167 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+/*
+ * xdr_sizeof.c
+ *
+ * Copyright 1990 Sun Microsystems, Inc.
+ *
+ * General purpose routine to see how much space something will use
+ * when serialized using XDR.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <sys/types.h>
+#include <stdlib.h>
+
+/* ARGSUSED */
+static bool_t
+x_putlong(
+ XDR *xdrs,
+ const long *longp)
+{
+ xdrs->x_handy += BYTES_PER_XDR_UNIT;
+ return (TRUE);
+}
+
+/* ARGSUSED */
+static bool_t
+x_putbytes(
+ XDR *xdrs,
+ const char *bp,
+ u_int len)
+{
+ xdrs->x_handy += len;
+ return (TRUE);
+}
+
+static u_int
+x_getpostn(
+ XDR *xdrs)
+{
+ return (xdrs->x_handy);
+}
+
+/* ARGSUSED */
+static bool_t
+x_setpostn(
+ XDR *xdrs,
+ u_int pos)
+{
+ /* This is not allowed */
+ return (FALSE);
+}
+
+static int32_t *
+x_inline(
+ XDR *xdrs,
+ u_int len)
+{
+ if (len == 0) {
+ return (NULL);
+ }
+ if (xdrs->x_op != XDR_ENCODE) {
+ return (NULL);
+ }
+ if (len < (intptr_t) xdrs->x_base) {
+ /* x_private was already allocated */
+ xdrs->x_handy += len;
+ return ((int32_t *) xdrs->x_private);
+ } else {
+ /* Free the earlier space and allocate new area */
+ if (xdrs->x_private)
+ free(xdrs->x_private);
+ if ((xdrs->x_private = (caddr_t) malloc(len)) == NULL) {
+ xdrs->x_base = 0;
+ return (NULL);
+ }
+ xdrs->x_base = (caddr_t)((intptr_t) len);
+ xdrs->x_handy += len;
+ return ((int32_t *) xdrs->x_private);
+ }
+}
+
+static int
+harmless(void)
+{
+ /* Always return FALSE/NULL, as the case may be */
+ return (0);
+}
+
+static void
+x_destroy(
+ XDR *xdrs)
+{
+ xdrs->x_handy = 0;
+ xdrs->x_base = 0;
+ if (xdrs->x_private) {
+ free(xdrs->x_private);
+ xdrs->x_private = NULL;
+ }
+ return;
+}
+
+unsigned long
+xdr_sizeof(
+ xdrproc_t func,
+ void *data)
+{
+ XDR x;
+ struct xdr_ops ops;
+ bool_t stat;
+ /* to stop ANSI-C compiler from complaining */
+ typedef bool_t (* dummyfunc1)(XDR *, long *);
+ typedef bool_t (* dummyfunc2)(XDR *, caddr_t, u_int);
+
+ ops.x_putlong = x_putlong;
+ ops.x_putbytes = x_putbytes;
+ ops.x_inline = x_inline;
+ ops.x_getpostn = x_getpostn;
+ ops.x_setpostn = x_setpostn;
+ ops.x_destroy = x_destroy;
+
+ /* the other harmless ones */
+ ops.x_getlong = (dummyfunc1) harmless;
+ ops.x_getbytes = (dummyfunc2) harmless;
+
+ x.x_op = XDR_ENCODE;
+ x.x_ops = &ops;
+ x.x_handy = 0;
+ x.x_private = (caddr_t) NULL;
+ x.x_base = (caddr_t) 0;
+
+ stat = func(&x, data);
+ if (x.x_private)
+ free(x.x_private);
+ return (stat == TRUE ? (unsigned) x.x_handy: 0);
+}
diff --git a/librpc/src/xdr/xdr_stdio.c b/librpc/src/xdr/xdr_stdio.c
new file mode 100644
index 0000000..ca67941
--- /dev/null
+++ b/librpc/src/xdr/xdr_stdio.c
@@ -0,0 +1,194 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)xdr_stdio.c 1.16 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)xdr_stdio.c 2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$FreeBSD: src/lib/libc/xdr/xdr_stdio.c,v 1.7 1999/08/28 00:02:56 peter Exp $";
+#endif
+
+/*
+ * xdr_stdio.c, XDR implementation on standard i/o file.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * This set of routines implements a XDR on a stdio stream.
+ * XDR_ENCODE serializes onto the stream, XDR_DECODE de-serializes
+ * from the stream.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rpc/types.h>
+#include <stdio.h>
+#include <rpc/xdr.h>
+#include <netinet/in.h>
+
+static bool_t xdrstdio_getlong(XDR *xdrs, long *lp);
+static bool_t xdrstdio_putlong(XDR *xdrs, const long *lp);
+static bool_t xdrstdio_getbytes(XDR *xdrs, caddr_t addr, u_int len);
+static bool_t xdrstdio_putbytes(XDR *xdrs, const char *addr, u_int len);
+static u_int xdrstdio_getpos(XDR *xdrs);
+static bool_t xdrstdio_setpos(XDR *xdrs, u_int pos);
+static int32_t *xdrstdio_inline(XDR *xdrs, u_int len);
+static void xdrstdio_destroy(XDR *);
+
+/*
+ * Ops vector for stdio type XDR
+ */
+static struct xdr_ops xdrstdio_ops = {
+ xdrstdio_getlong, /* deseraialize a long int */
+ xdrstdio_putlong, /* seraialize a long int */
+ xdrstdio_getbytes, /* deserialize counted bytes */
+ xdrstdio_putbytes, /* serialize counted bytes */
+ xdrstdio_getpos, /* get offset in the stream */
+ xdrstdio_setpos, /* set offset in the stream */
+ xdrstdio_inline, /* prime stream for inline macros */
+ xdrstdio_destroy /* destroy stream */
+};
+
+/*
+ * Initialize a stdio xdr stream.
+ * Sets the xdr stream handle xdrs for use on the stream file.
+ * Operation flag is set to op.
+ */
+void
+xdrstdio_create(
+ XDR *xdrs,
+ FILE *file,
+ enum xdr_op op)
+{
+
+ xdrs->x_op = op;
+ xdrs->x_ops = &xdrstdio_ops;
+ xdrs->x_private = (caddr_t)file;
+ xdrs->x_handy = 0;
+ xdrs->x_base = 0;
+}
+
+/*
+ * Destroy a stdio xdr stream.
+ * Cleans up the xdr stream handle xdrs previously set up by xdrstdio_create.
+ */
+static void
+xdrstdio_destroy(
+ XDR *xdrs)
+{
+ (void)fflush((FILE *)xdrs->x_private);
+ /* xx should we close the file ?? */
+}
+
+static bool_t
+xdrstdio_getlong(
+ XDR *xdrs,
+ long *lp)
+{
+
+ if (fread((caddr_t)lp, sizeof(int32_t), 1,
+ (FILE *)xdrs->x_private) != 1)
+ return (FALSE);
+ *lp = (long)ntohl((int32_t)*lp);
+ return (TRUE);
+}
+
+static bool_t
+xdrstdio_putlong(
+ XDR *xdrs,
+ const long *lp)
+{
+
+ long mycopy = (long)htonl((int32_t)*lp);
+
+ if (fwrite((caddr_t)&mycopy, sizeof(int32_t), 1,
+ (FILE *)xdrs->x_private) != 1)
+ return (FALSE);
+ return (TRUE);
+}
+
+static bool_t
+xdrstdio_getbytes(
+ XDR *xdrs,
+ caddr_t addr,
+ u_int len )
+{
+
+ if ((len != 0) && (fread(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1))
+ return (FALSE);
+ return (TRUE);
+}
+
+static bool_t
+xdrstdio_putbytes(
+ XDR *xdrs,
+ const char *addr,
+ u_int len)
+{
+
+ if ((len != 0) && (fwrite(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1))
+ return (FALSE);
+ return (TRUE);
+}
+
+static u_int
+xdrstdio_getpos(
+ XDR *xdrs)
+{
+
+ return ((u_int) ftell((FILE *)xdrs->x_private));
+}
+
+static bool_t
+xdrstdio_setpos(
+ XDR *xdrs,
+ u_int pos)
+{
+
+ return ((fseek((FILE *)xdrs->x_private, (long)pos, 0) < 0) ?
+ FALSE : TRUE);
+}
+
+static int32_t *
+xdrstdio_inline(
+ XDR *xdrs,
+ u_int len)
+{
+
+ /*
+ * Must do some work to implement this: must insure
+ * enough data in the underlying stdio buffer,
+ * that the buffer is aligned so that we can indirect through a
+ * long *, and stuff this pointer in xdrs->x_buf. Doing
+ * a fread or fwrite to a scratch buffer would defeat
+ * most of the gains to be had here and require storage
+ * management on this buffer, so we don't do this.
+ */
+ return (NULL);
+}
diff --git a/lnetworking.py b/lnetworking.py
index 6489b81..5e14e52 100644
--- a/lnetworking.py
+++ b/lnetworking.py
@@ -31,7 +31,7 @@ import os
source_files = []
include_files = {}
test_source = []
-exclude_dirs = ['pppd', 'nfsclient', 'testsuites']
+exclude_dirs = ['pppd', 'nfsclient', 'testsuites', 'librpc/include']
exclude_headers = ['rtems-bsd-user-space.h', 'rtems-bsd-kernel-space.h']
for root, dirs, files in os.walk("."):