summaryrefslogtreecommitdiffstatsabout
diff options
context:
space:
mode:
authorHanhui <sylixos@gmail.com>2017-08-12 07:34:22 (GMT)
committer Hanhui <sylixos@gmail.com>2017-08-12 07:34:22 (GMT)
commit4fd5edcb36eeb0f2d50b17eff3b6668b703c8487 (patch)
tree5b7e476bae0eba41329ac47c772eb7f5abb6e8ea
downloadlibsunrpc-4fd5edcb36eeb0f2d50b17eff3b6668b703c8487.zip
libsunrpc-4fd5edcb36eeb0f2d50b17eff3b6668b703c8487.tar.gz
libsunrpc-4fd5edcb36eeb0f2d50b17eff3b6668b703c8487.tar.bz2
libsunrpc first push.
-rw-r--r--.cproject26
-rw-r--r--.gitignore4
-rw-r--r--.project75
-rw-r--r--.reproject13
-rw-r--r--Makefile87
-rw-r--r--config.mk45
-rw-r--r--libsunrpc.mk139
-rw-r--r--portmap.mk93
-rw-r--r--portmap/portmap.c509
-rw-r--r--sunrpc/Makefile227
-rw-r--r--sunrpc/Versions131
-rw-r--r--sunrpc/auth_des.c472
-rw-r--r--sunrpc/auth_none.c135
-rw-r--r--sunrpc/auth_unix.c358
-rw-r--r--sunrpc/authdes_prot.c81
-rw-r--r--sunrpc/authuxprot.c66
-rw-r--r--sunrpc/bindrsvprt.c114
-rw-r--r--sunrpc/clnt_gen.c179
-rw-r--r--sunrpc/clnt_perr.c401
-rw-r--r--sunrpc/clnt_raw.c251
-rw-r--r--sunrpc/clnt_simp.c156
-rw-r--r--sunrpc/clnt_tcp.c531
-rw-r--r--sunrpc/clnt_udp.c632
-rw-r--r--sunrpc/clnt_unix.c599
-rw-r--r--sunrpc/create_xid.c72
-rw-r--r--sunrpc/des.h1
-rw-r--r--sunrpc/des_crypt.c120
-rw-r--r--sunrpc/des_impl.c596
-rw-r--r--sunrpc/des_soft.c78
-rw-r--r--sunrpc/etc.rpc70
-rw-r--r--sunrpc/get_myaddr.c105
-rw-r--r--sunrpc/getprotobyname.c52
-rw-r--r--sunrpc/getrpcbyname.c32
-rw-r--r--sunrpc/getrpcbyname_r.c31
-rw-r--r--sunrpc/getrpcbynumber.c32
-rw-r--r--sunrpc/getrpcbynumber_r.c31
-rw-r--r--sunrpc/getrpcent.c28
-rw-r--r--sunrpc/getrpcent_r.c32
-rw-r--r--sunrpc/getrpcport.c69
-rw-r--r--sunrpc/key_call.c577
-rw-r--r--sunrpc/key_prot.c169
-rw-r--r--sunrpc/netname.c217
-rw-r--r--sunrpc/openchild.c107
-rw-r--r--sunrpc/pm_getmaps.c90
-rw-r--r--sunrpc/pm_getport.c155
-rw-r--r--sunrpc/pmap_clnt.c167
-rw-r--r--sunrpc/pmap_prot.c50
-rw-r--r--sunrpc/pmap_prot2.c111
-rw-r--r--sunrpc/pmap_rmt.c394
-rw-r--r--sunrpc/proto.h65
-rw-r--r--sunrpc/publickey.c121
-rw-r--r--sunrpc/rpc/auth.h212
-rw-r--r--sunrpc/rpc/auth_des.h111
-rw-r--r--sunrpc/rpc/auth_unix.h88
-rw-r--r--sunrpc/rpc/clnt.h427
-rw-r--r--sunrpc/rpc/des_crypt.h100
-rw-r--r--sunrpc/rpc/key_prot.h343
-rw-r--r--sunrpc/rpc/netdb.h76
-rw-r--r--sunrpc/rpc/pmap_clnt.h97
-rw-r--r--sunrpc/rpc/pmap_prot.h107
-rw-r--r--sunrpc/rpc/pmap_rmt.h67
-rw-r--r--sunrpc/rpc/rpc.h102
-rw-r--r--sunrpc/rpc/rpc_des.h72
-rw-r--r--sunrpc/rpc/rpc_msg.h198
-rw-r--r--sunrpc/rpc/rpc_sylixos.h116
-rw-r--r--sunrpc/rpc/svc.h338
-rw-r--r--sunrpc/rpc/svc_auth.h52
-rw-r--r--sunrpc/rpc/types.h109
-rw-r--r--sunrpc/rpc/xdr.h379
-rw-r--r--sunrpc/rpc_clntout.c333
-rw-r--r--sunrpc/rpc_cmsg.c197
-rw-r--r--sunrpc/rpc_common.c54
-rw-r--r--sunrpc/rpc_cout.c811
-rw-r--r--sunrpc/rpc_dtable.c49
-rw-r--r--sunrpc/rpc_hout.c607
-rw-r--r--sunrpc/rpc_main.c1460
-rw-r--r--sunrpc/rpc_parse.c687
-rw-r--r--sunrpc/rpc_parse.h165
-rw-r--r--sunrpc/rpc_prot.c276
-rw-r--r--sunrpc/rpc_sample.c336
-rw-r--r--sunrpc/rpc_scan.c548
-rw-r--r--sunrpc/rpc_scan.h104
-rw-r--r--sunrpc/rpc_svcout.c1093
-rw-r--r--sunrpc/rpc_tblout.c178
-rw-r--r--sunrpc/rpc_thread.c144
-rw-r--r--sunrpc/rpc_util.c525
-rw-r--r--sunrpc/rpc_util.h154
-rw-r--r--sunrpc/rpcgen.c2
-rw-r--r--sunrpc/rpcinfo.c739
-rw-r--r--sunrpc/rpcsvc/bootparam.h23
-rw-r--r--sunrpc/rpcsvc/bootparam_prot.x97
-rw-r--r--sunrpc/rpcsvc/key_prot.x283
-rw-r--r--sunrpc/rpcsvc/klm_prot.x130
-rw-r--r--sunrpc/rpcsvc/mount.x161
-rw-r--r--sunrpc/rpcsvc/nfs_prot.x352
-rw-r--r--sunrpc/rpcsvc/nlm_prot.x203
-rw-r--r--sunrpc/rpcsvc/rex.x229
-rw-r--r--sunrpc/rpcsvc/rquota.x61
-rw-r--r--sunrpc/rpcsvc/rstat.x145
-rw-r--r--sunrpc/rpcsvc/rusers.x228
-rw-r--r--sunrpc/rpcsvc/sm_inter.x110
-rw-r--r--sunrpc/rpcsvc/spray.x84
-rw-r--r--sunrpc/rpcsvc/yppasswd.x61
-rw-r--r--sunrpc/rtime.c144
-rw-r--r--sunrpc/svc.c592
-rw-r--r--sunrpc/svc_auth.c116
-rw-r--r--sunrpc/svc_authux.c147
-rw-r--r--sunrpc/svc_raw.c158
-rw-r--r--sunrpc/svc_run.c110
-rw-r--r--sunrpc/svc_simple.c190
-rw-r--r--sunrpc/svc_tcp.c434
-rw-r--r--sunrpc/svc_udp.c625
-rw-r--r--sunrpc/svc_unix.c538
-rw-r--r--sunrpc/svcauth_des.c596
-rw-r--r--sunrpc/test-rpcent.c74
-rw-r--r--sunrpc/thrsvc.c109
-rw-r--r--sunrpc/tst-getmyaddr.c24
-rw-r--r--sunrpc/tst-xdrmem.c204
-rw-r--r--sunrpc/tst-xdrmem2.c113
-rw-r--r--sunrpc/xcrypt.c219
-rw-r--r--sunrpc/xdr.c828
-rw-r--r--sunrpc/xdr_array.c167
-rw-r--r--sunrpc/xdr_float.c299
-rw-r--r--sunrpc/xdr_intXX_t.c229
-rw-r--r--sunrpc/xdr_mem.c238
-rw-r--r--sunrpc/xdr_rec.c658
-rw-r--r--sunrpc/xdr_ref.c143
-rw-r--r--sunrpc/xdr_sizeof.c165
-rw-r--r--sunrpc/xdr_stdio.c197
129 files changed, 29836 insertions, 0 deletions
diff --git a/.cproject b/.cproject
new file mode 100644
index 0000000..2117e82
--- /dev/null
+++ b/.cproject
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+ <storageModule moduleId="org.eclipse.cdt.core.settings">
+ <cconfiguration id="org.eclipse.cdt.core.default.config.319554528">
+ <storageModule buildSystemId="org.eclipse.cdt.core.defaultConfigDataProvider" id="org.eclipse.cdt.core.default.config.319554528" moduleId="org.eclipse.cdt.core.settings" name="Configuration">
+ <externalSettings/>
+ <extensions>
+ <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+ </extensions>
+ </storageModule>
+ <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+ </cconfiguration>
+ </storageModule>
+ <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+ <storageModule moduleId="org.eclipse.cdt.core.pathentry">
+ <pathentry kind="mac" name="__GNUC__" path="" value="4"/>
+ <pathentry kind="mac" name="SYLIXOS" path="" value=""/>
+ <pathentry kind="mac" name="__arm__" path="" value=""/>
+ <pathentry base-ref="libsunrpc" include="D:/SylixOSDev/workspace_test/sylixos-base-new/libsylixos/SylixOS" kind="inc" path="" system="true"/>
+ <pathentry base-ref="libsunrpc" include="D:/SylixOSDev/workspace_test/sylixos-base-new/libsylixos/SylixOS/include" kind="inc" path="" system="true"/>
+ <pathentry base-ref="libsunrpc" include="D:/SylixOSDev/workspace_test/sylixos-base-new/libsylixos/SylixOS/include/network" kind="inc" path="" system="true"/>
+ <pathentry base-ref="libsunrpc" include="D:/SylixOSDev/workspace_test/sylixos-base-new/libcextern/libcextern/include" kind="inc" path="" system="true"/>
+ <pathentry base-ref="libsunrpc" include="C:/ACOINFO/RealEvo/compiler/arm-sylixos-toolchain/arm-sylixos-eabi/include" kind="inc" path="" system="true"/>
+ <pathentry base-ref="libsunrpc" include="C:/ACOINFO/RealEvo/compiler/arm-sylixos-toolchain/lib/gcc/arm-sylixos-eabi/4.9.3/include" kind="inc" path="" system="true"/>
+ </storageModule>
+</cproject>
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1b8c7c6
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+/Debug
+/Release
+/.settings
+/.rcsetting
diff --git a/.project b/.project
new file mode 100644
index 0000000..ece1055
--- /dev/null
+++ b/.project
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>libsunrpc</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>com.sylixos.realevo.projectmgr.SylixOSBuilder</name>
+ <triggers>clean,full,incremental,</triggers>
+ <arguments>
+ <dictionary>
+ <key>org.eclipse.cdt.core.errorOutputParser</key>
+ <value>org.eclipse.cdt.core.GASErrorParser;org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.VCErrorParser;org.eclipse.cdt.core.CWDLocator;org.eclipse.cdt.core.MakeErrorParser;</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.append_environment</key>
+ <value>true</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.build.arguments</key>
+ <value></value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.build.command</key>
+ <value>make</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.build.target.auto</key>
+ <value>all</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.build.target.clean</key>
+ <value>clean</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.build.target.inc</key>
+ <value>all</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.enableAutoBuild</key>
+ <value>false</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.enableCleanBuild</key>
+ <value>true</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.enableFullBuild</key>
+ <value>true</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.enabledIncrementalBuild</key>
+ <value>true</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.environment</key>
+ <value></value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.stopOnError</key>
+ <value>false</value>
+ </dictionary>
+ <dictionary>
+ <key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
+ <value>true</value>
+ </dictionary>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.cdt.core.cnature</nature>
+ <nature>com.sylixos.realevo.projectmgr.SylixOSNature</nature>
+ </natures>
+</projectDescription>
diff --git a/.reproject b/.reproject
new file mode 100644
index 0000000..cc5f2cf
--- /dev/null
+++ b/.reproject
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="GB2312" standalone="no"?>
+<SylixOSSetting>
+<BaseSetting BeLite="false" ProjectType="SylixOSSoProject" RealEvoVer="3.3.2 Ultimate"/>
+<BuildSetting CoustomCfgMakefile="false" NotScanSourceFile="false"/>
+<OutputSetting>
+<OutputPath Name="Output" Path="Release:Debug" TreeNode="Output"/>
+<OutputPath Name="Debug" Path="Debug" TreeNode="Debug"/>
+<OutputPath Name="Release" Path="Release" TreeNode="Release"/>
+</OutputSetting>
+<UploadPath>
+<PairItem key="$(WORKSPACE_libsunrpc)\$(Output)\strip\libsunrpc.so" value="/lib/libsunrpc.so"/>
+</UploadPath>
+</SylixOSSetting>
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..ccdedb4
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,87 @@
+#*********************************************************************************************************
+#
+# 中国软件开源组织
+#
+# 嵌入式实时操作系统
+#
+# SylixOS(TM) LW : long wing
+#
+# Copyright All Rights Reserved
+#
+#--------------文件信息--------------------------------------------------------------------------------
+#
+# 文 件 名: Makefile
+#
+# 创 建 人: RealEvo-IDE
+#
+# 文件创建日期: 2017 年 08 月 12 日
+#
+# 描 述: 本文件由 RealEvo-IDE 生成,用于配置 Makefile 功能,请勿手动修改
+#*********************************************************************************************************
+
+#*********************************************************************************************************
+# Include config.mk
+#*********************************************************************************************************
+CONFIG_MK_EXIST = $(shell if [ -f ../config.mk ]; then echo exist; else echo notexist; fi;)
+ifeq ($(CONFIG_MK_EXIST), exist)
+include ../config.mk
+else
+CONFIG_MK_EXIST = $(shell if [ -f config.mk ]; then echo exist; else echo notexist; fi;)
+ifeq ($(CONFIG_MK_EXIST), exist)
+include config.mk
+else
+CONFIG_MK_EXIST =
+endif
+endif
+
+#*********************************************************************************************************
+# Include sylixos base config.mk
+#*********************************************************************************************************
+EMPTY =
+SPACE = $(EMPTY) $(EMPTY)
+
+SYLIXOS_BASE_PATH_BAK := $(SYLIXOS_BASE_PATH)
+TOOLCHAIN_PREFIX_BAK := $(TOOLCHAIN_PREFIX)
+DEBUG_LEVEL_BAK := $(DEBUG_LEVEL)
+CPU_TYPE_BAK := $(CPU_TYPE)
+FPU_TYPE_BAK := $(FPU_TYPE)
+
+SYLIXOS_BASE_CONFIGMK = $(subst $(SPACE),\ ,$(SYLIXOS_BASE_PATH))/config.mk
+include $(SYLIXOS_BASE_CONFIGMK)
+
+SYLIXOS_BASE_PATH := $(SYLIXOS_BASE_PATH_BAK)
+DEBUG_LEVEL := $(DEBUG_LEVEL_BAK)
+
+ifneq ($(TOOLCHAIN_PREFIX_BAK),)
+TOOLCHAIN_PREFIX := $(TOOLCHAIN_PREFIX_BAK)
+endif
+
+ifneq ($(CPU_TYPE_BAK),)
+CPU_TYPE := $(CPU_TYPE_BAK)
+endif
+
+ifneq ($(FPU_TYPE_BAK),)
+FPU_TYPE := $(FPU_TYPE_BAK)
+endif
+
+#*********************************************************************************************************
+# Include header.mk
+#*********************************************************************************************************
+MKTEMP = $(subst $(SPACE),\ ,$(SYLIXOS_BASE_PATH))/libsylixos/SylixOS/mktemp
+
+include $(MKTEMP)/header.mk
+
+#*********************************************************************************************************
+# Include targets makefiles
+#*********************************************************************************************************
+include portmap.mk
+include libsunrpc.mk
+
+#*********************************************************************************************************
+# Include end.mk
+#*********************************************************************************************************
+include $(END_MK)
+
+#*********************************************************************************************************
+# End
+#*********************************************************************************************************
diff --git a/config.mk b/config.mk
new file mode 100644
index 0000000..04853f3
--- /dev/null
+++ b/config.mk
@@ -0,0 +1,45 @@
+#*********************************************************************************************************
+#
+# 中国软件开源组织
+#
+# 嵌入式实时操作系统
+#
+# SylixOS(TM) LW : long wing
+#
+# Copyright All Rights Reserved
+#
+#--------------文件信息--------------------------------------------------------------------------------
+#
+# 文 件 名: config.mk
+#
+# 创 建 人: RealEvo-IDE
+#
+# 文件创建日期: 2016 年 10 月 08 日
+#
+# 描 述: 本文由RealEvo-IDE生成,用于配置Makefile功能,请勿手动修改
+#*********************************************************************************************************
+
+#*********************************************************************************************************
+# SylixOS Base Project path
+#*********************************************************************************************************
+SYLIXOS_BASE_PATH = ..
+
+#*********************************************************************************************************
+# Toolchain prefix
+#*********************************************************************************************************
+TOOLCHAIN_PREFIX = arm-sylixos-eabi-
+
+#*********************************************************************************************************
+# Debug options (debug or release)
+#*********************************************************************************************************
+DEBUG_LEVEL = debug
+
+#*********************************************************************************************************
+# NOTICE: libsylixos, BSP and other kernel modules projects CAN NOT use vfp!
+#*********************************************************************************************************
+FPU_TYPE = disable
+CPU_TYPE = arm920t
+
+#*********************************************************************************************************
+# End
+#*********************************************************************************************************
diff --git a/libsunrpc.mk b/libsunrpc.mk
new file mode 100644
index 0000000..78339da
--- /dev/null
+++ b/libsunrpc.mk
@@ -0,0 +1,139 @@
+#*********************************************************************************************************
+#
+# 中国软件开源组织
+#
+# 嵌入式实时操作系统
+#
+# SylixOS(TM) LW : long wing
+#
+# Copyright All Rights Reserved
+#
+#--------------文件信息--------------------------------------------------------------------------------
+#
+# 文 件 名: libsunrpc.mk
+#
+# 创 建 人: RealEvo-IDE
+#
+# 文件创建日期: 2017 年 08 月 11 日
+#
+# 描 述: 本文件由 RealEvo-IDE 生成,用于配置 Makefile 功能,请勿手动修改
+#*********************************************************************************************************
+
+#*********************************************************************************************************
+# Clear setting
+#*********************************************************************************************************
+include $(CLEAR_VARS_MK)
+
+#*********************************************************************************************************
+# Target
+#*********************************************************************************************************
+LOCAL_TARGET_NAME := libsunrpc.so
+
+#*********************************************************************************************************
+# Source list
+#*********************************************************************************************************
+LOCAL_SRCS := \
+sunrpc/authdes_prot.c \
+sunrpc/authuxprot.c \
+sunrpc/auth_none.c \
+sunrpc/auth_unix.c \
+sunrpc/bindrsvprt.c \
+sunrpc/clnt_gen.c \
+sunrpc/clnt_perr.c \
+sunrpc/clnt_raw.c \
+sunrpc/clnt_simp.c \
+sunrpc/clnt_tcp.c \
+sunrpc/clnt_udp.c \
+sunrpc/clnt_unix.c \
+sunrpc/create_xid.c \
+sunrpc/des_crypt.c \
+sunrpc/des_impl.c \
+sunrpc/des_soft.c \
+sunrpc/getprotobyname.c \
+sunrpc/getrpcport.c \
+sunrpc/get_myaddr.c \
+sunrpc/key_call.c \
+sunrpc/key_prot.c \
+sunrpc/pmap_clnt.c \
+sunrpc/pmap_prot.c \
+sunrpc/pmap_prot2.c \
+sunrpc/pmap_rmt.c \
+sunrpc/pm_getmaps.c \
+sunrpc/pm_getport.c \
+sunrpc/rpc_cmsg.c \
+sunrpc/rpc_common.c \
+sunrpc/rpc_dtable.c \
+sunrpc/rpc_prot.c \
+sunrpc/rpc_thread.c \
+sunrpc/rtime.c \
+sunrpc/svc.c \
+sunrpc/svc_auth.c \
+sunrpc/svc_authux.c \
+sunrpc/svc_raw.c \
+sunrpc/svc_run.c \
+sunrpc/svc_simple.c \
+sunrpc/svc_tcp.c \
+sunrpc/svc_udp.c \
+sunrpc/svc_unix.c \
+sunrpc/xcrypt.c \
+sunrpc/xdr.c \
+sunrpc/xdr_array.c \
+sunrpc/xdr_float.c \
+sunrpc/xdr_intXX_t.c \
+sunrpc/xdr_mem.c \
+sunrpc/xdr_rec.c \
+sunrpc/xdr_ref.c \
+sunrpc/xdr_sizeof.c \
+sunrpc/xdr_stdio.c
+
+#*********************************************************************************************************
+# Header file search path (eg. LOCAL_INC_PATH := -I"Your header files search path")
+#*********************************************************************************************************
+LOCAL_INC_PATH := -I"./sunrpc"
+
+#*********************************************************************************************************
+# Pre-defined macro (eg. -DYOUR_MARCO=1)
+#*********************************************************************************************************
+LOCAL_DSYMBOL :=
+
+#*********************************************************************************************************
+# Compiler flags
+#*********************************************************************************************************
+LOCAL_CFLAGS :=
+LOCAL_CXXFLAGS :=
+
+#*********************************************************************************************************
+# Depend library (eg. LOCAL_DEPEND_LIB := -la LOCAL_DEPEND_LIB_PATH := -L"Your library search path")
+#*********************************************************************************************************
+LOCAL_DEPEND_LIB :=
+LOCAL_DEPEND_LIB_PATH :=
+
+#*********************************************************************************************************
+# C++ config
+#*********************************************************************************************************
+LOCAL_USE_CXX := no
+LOCAL_USE_CXX_EXCEPT := no
+
+#*********************************************************************************************************
+# Code coverage config
+#*********************************************************************************************************
+LOCAL_USE_GCOV := no
+
+#*********************************************************************************************************
+# OpenMP config
+#*********************************************************************************************************
+LOCAL_USE_OMP := no
+
+#*********************************************************************************************************
+# User link command
+#*********************************************************************************************************
+LOCAL_PRE_LINK_CMD :=
+LOCAL_POST_LINK_CMD :=
+LOCAL_PRE_STRIP_CMD :=
+LOCAL_POST_STRIP_CMD :=
+
+include $(LIBRARY_MK)
+
+#*********************************************************************************************************
+# End
+#*********************************************************************************************************
diff --git a/portmap.mk b/portmap.mk
new file mode 100644
index 0000000..185c650
--- /dev/null
+++ b/portmap.mk
@@ -0,0 +1,93 @@
+#*********************************************************************************************************
+#
+# 中国软件开源组织
+#
+# 嵌入式实时操作系统
+#
+# SylixOS(TM) LW : long wing
+#
+# Copyright All Rights Reserved
+#
+#--------------文件信息--------------------------------------------------------------------------------
+#
+# 文 件 名: portmap.mk
+#
+# 创 建 人: RealEvo-IDE
+#
+# 文件创建日期: 2017 年 08 月 07 日
+#
+# 描 述: 本文件由 RealEvo-IDE 生成,用于配置 Makefile 功能,请勿手动修改
+#*********************************************************************************************************
+
+#*********************************************************************************************************
+# Clear setting
+#*********************************************************************************************************
+include $(CLEAR_VARS_MK)
+
+#*********************************************************************************************************
+# Target
+#*********************************************************************************************************
+LOCAL_TARGET_NAME := portmap
+
+#*********************************************************************************************************
+# Source list
+#*********************************************************************************************************
+LOCAL_SRCS := \
+./portmap/portmap.c
+
+#*********************************************************************************************************
+# Header file search path (eg. LOCAL_INC_PATH := -I"Your header files search path")
+#*********************************************************************************************************
+LOCAL_INC_PATH := -I"./sunrpc"
+
+#*********************************************************************************************************
+# Pre-defined macro (eg. -DYOUR_MARCO=1)
+#*********************************************************************************************************
+LOCAL_DSYMBOL :=
+
+#*********************************************************************************************************
+# Compiler flags
+#*********************************************************************************************************
+LOCAL_CFLAGS :=
+LOCAL_CXXFLAGS :=
+
+#*********************************************************************************************************
+# Depend library (eg. LOCAL_DEPEND_LIB := -la LOCAL_DEPEND_LIB_PATH := -L"Your library search path")
+#*********************************************************************************************************
+LOCAL_DEPEND_LIB := -lsunrpc
+LOCAL_DEPEND_LIB_PATH := -L"./$(OUTDIR)"
+
+#*********************************************************************************************************
+# C++ config
+#*********************************************************************************************************
+LOCAL_USE_CXX := no
+LOCAL_USE_CXX_EXCEPT := no
+
+#*********************************************************************************************************
+# Code coverage config
+#*********************************************************************************************************
+LOCAL_USE_GCOV := no
+
+#*********************************************************************************************************
+# OpenMP config
+#*********************************************************************************************************
+LOCAL_USE_OMP := no
+
+#*********************************************************************************************************
+# User link command
+#*********************************************************************************************************
+LOCAL_PRE_LINK_CMD :=
+LOCAL_POST_LINK_CMD :=
+LOCAL_PRE_STRIP_CMD :=
+LOCAL_POST_STRIP_CMD :=
+
+#*********************************************************************************************************
+# Depend target
+#*********************************************************************************************************
+LOCAL_DEPEND_TARGET := ./$(OUTDIR)/libsunrpc.so
+
+include $(APPLICATION_MK)
+
+#*********************************************************************************************************
+# End
+#*********************************************************************************************************
diff --git a/portmap/portmap.c b/portmap/portmap.c
new file mode 100644
index 0000000..2c49ad9
--- /dev/null
+++ b/portmap/portmap.c
@@ -0,0 +1,509 @@
+/*
+ * Copyright (c) 1984 by Sun Microsystems, Inc.
+ */
+
+/*
+ * portmap.c, Implements the program,version to port number mapping for rpc.
+ */
+
+/*
+ * 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
+ */
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+static SVCXPRT *pmapXprt;
+struct pmaplist *pmapList;
+static int debugging = 0;
+
+static void reg_service(struct svc_req *, SVCXPRT *);
+static void reg_service_internal(struct svc_req *, SVCXPRT *);
+static void callit(struct svc_req *, SVCXPRT *);
+
+int main (int argc, char **argv)
+{
+ SVCXPRT *xprt = NULL;
+ int udp_sockfd;
+ int tcp_sockfd;
+ struct sockaddr_in addr;
+ socklen_t len = (socklen_t)sizeof(struct sockaddr_in);
+
+ memset(&addr, 0, sizeof(addr));
+
+ addr.sin_addr.s_addr = 0;
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons((u_short)PMAPPORT);
+
+ if ((udp_sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
+ perror("portmap cannot create socket");
+ abort();
+
+ } else {
+ if (bind(udp_sockfd, (struct sockaddr *)&addr, len) != 0) {
+ perror("portmap cannot bind");
+ abort();
+ }
+
+ xprt = svcudp_create(udp_sockfd);
+ if (xprt == NULL) {
+ fprintf(stderr, "couldn't do svcudp_create\n");
+ abort();
+ }
+ }
+
+ if ((tcp_sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
+ perror("portmap cannot create socket");
+ abort();
+
+ } else {
+ if (bind(tcp_sockfd, (struct sockaddr *)&addr, len) != 0) {
+ perror("portmap cannot bind");
+ abort();
+ }
+
+ if ((xprt = svctcp_create(tcp_sockfd, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE)) == (SVCXPRT *)NULL) {
+ fprintf(stderr, "couldn't do svctcp_create\n");
+ abort();
+ }
+ }
+
+ (void)svc_register(xprt, PMAPPROG, PMAPVERS, reg_service, (rpcproc_t)0);
+ pmapXprt = xprt;
+ svc_run();
+ fprintf(stderr, "svc_run returned unexpectedly\n");
+ abort();
+}
+
+static struct pmaplist *
+find_service(prog, vers, prot)
+ u_long prog;
+ u_long vers;
+ u_long 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);
+}
+
+/*
+ * Wrapper function to register the portmapper service
+ * with the portmapper. Actual function "reg_service_internal
+ * will be called at the end of this function.
+ */
+static void reg_service (rqstp, xprt)
+ struct svc_req *rqstp;
+ SVCXPRT *xprt;
+{
+ struct pmaplist *pml, *fnd;
+ static BOOL bPmapFirstTime = TRUE;
+
+ if (bPmapFirstTime) {
+ bPmapFirstTime = FALSE;
+
+ /*
+ * While registering the PORT MAPPER DAEMON
+ * it cannot set it's own entry. This can be a problem
+ * when somebody tries to query a PMAP service info.
+ * The service is registered but the entries are missing in
+ * the pmap list. Hence this workaround when the PMAP request
+ * comes for the first time.
+ * Here we will register a service on UDP port
+ */
+ pml = (struct pmaplist *)malloc(sizeof(struct pmaplist));
+ if (pml == NULL)
+ return;
+
+ pml->pml_map.pm_prog = PMAPPROG;
+ pml->pml_map.pm_vers = PMAPVERS;
+ pml->pml_map.pm_prot = IPPROTO_UDP;
+ pml->pml_map.pm_port = pmapXprt->xp_port;
+ 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;
+ }
+ /*
+ * Now register the service for TCP port
+ */
+ 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 = pmapXprt->xp_port;
+ 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;
+ }
+ }
+ reg_service_internal(rqstp, xprt);
+}
+
+static void reg_service_internal(rqstp, xprt)
+ struct svc_req *rqstp;
+ SVCXPRT *xprt;
+{
+ struct pmap reg;
+ struct pmaplist *pml, *prevpml, *fnd;
+ bool_t ans;
+ u_short port;
+ caddr_t t;
+
+ switch ((int)rqstp->rq_proc) {
+
+ case PMAPPROC_NULL:
+ /*
+ * Null proc call
+ */
+ if ((!svc_sendreply(xprt, (xdrproc_t)xdr_void, (char *)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_bool, (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_bool, (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_u_short, (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
+
+typedef struct encap_parms {
+ u_long arglen;
+ char *args;
+} ENCAP_PARMS;
+
+static bool_t
+xdr_encap_parms(xdrs, epp)
+ XDR *xdrs;
+ struct encap_parms *epp;
+{
+ return (xdr_bytes(xdrs, &(epp->args), (u_int *)&(epp->arglen), (u_int)ARGSIZE));
+}
+
+typedef struct rmtcallargs {
+ u_long rmt_prog;
+ u_long rmt_vers;
+ u_long rmt_port;
+ u_long rmt_proc;
+ struct encap_parms rmt_args;
+} RMTCALLARGS;
+
+static bool_t
+xdr_rmtcall_args(xdrs, cap)
+ 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(xdrs, cap)
+ 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(xdrs, cap)
+ XDR *xdrs;
+ struct rmtcallargs *cap;
+{
+ return (xdr_opaque(xdrs, cap->rmt_args.args, (u_int)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(xdrs, cap)
+ register XDR *xdrs;
+ struct rmtcallargs *cap;
+{
+ 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 ...
+ */
+static void
+callit(rqstp, xprt)
+ struct svc_req *rqstp;
+ SVCXPRT *xprt;
+{
+ char *buf;
+ struct rmtcallargs a;
+ struct pmaplist *pml;
+ u_short port;
+ struct sockaddr_in me;
+ int socket = -1;
+ CLIENT *client;
+ struct authunix_parms *au = (struct authunix_parms *)rqstp->rq_clntcred;
+ struct timeval timeout;
+
+ timeout.tv_sec = 5;
+ timeout.tv_usec = 0;
+ buf = malloc(ARGSIZE);
+ if (buf == NULL)
+ return;
+
+ a.rmt_args.args = buf;
+ if (!svc_getargs(xprt, xdr_rmtcall_args, (caddr_t )&a)) {
+ free(buf);
+ return;
+ }
+
+ if ((pml = find_service(a.rmt_prog, a.rmt_vers, IPPROTO_UDP)) == NULL) {
+ free(buf);
+ return;
+ }
+
+ port = (u_short)pml->pml_map.pm_port;
+ get_myaddress(&me);
+ me.sin_port = (u_short)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,
+ (int)au->aup_len,
+ au->aup_gids);
+ if (client->cl_auth == NULL) {
+ free(buf);
+ return;
+ }
+ }
+ a.rmt_port = (u_long)port;
+ if (clnt_call(client, a.rmt_proc,
+ xdr_opaque_parms, (caddr_t)&a,
+ xdr_len_opaque_parms, (caddr_t)&a,
+ timeout) == RPC_SUCCESS) {
+ (void)svc_sendreply(xprt, xdr_rmtcall_result, (char *)&a);
+ }
+ AUTH_DESTROY(client->cl_auth);
+ clnt_destroy(client);
+ }
+ free(buf);
+ return;
+
+ /*
+ * the following close ALWAYS fails
+ * because clnt_destroy was called, which closed the socket.
+ */
+ /*
+ * (void)close(socket);
+ */
+}
+
diff --git a/sunrpc/Makefile b/sunrpc/Makefile
new file mode 100644
index 0000000..789ef42
--- /dev/null
+++ b/sunrpc/Makefile
@@ -0,0 +1,227 @@
+# Copyright (C) 1994-2016 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+#
+# Sub-makefile for sunrpc portion of the library.
+#
+subdir := sunrpc
+
+include ../Makeconfig
+
+# The code in this subdirectory is taken from Sun's RPCSRC-4.0
+# distribution with some additional changes from the TI-RPC package
+# which is also available from Sun. The files are heavily changed to
+# compile cleanly and to fit in the GNU environment. All the code
+# from Sun's rpc, etc, and rpcgen subdirectories is in this directory;
+# the rpc subdirectory contains only the header files. Other than
+# that, several files were renamed so as not to exceed 14-character
+# file name limits:
+#
+# authunix_prot.c -> authuxprot.c
+# bindresvport.c -> bindrsvprt.c
+# clnt_generic.c -> clnt_gen.c
+# clnt_perror.c -> clnt_perr.c
+# clnt_simple.c -> clnt_simp.c
+# get_myaddress.c -> get_myaddr.c
+# pmap_getmaps.c -> pm_getmaps.c
+# pmap_getport.c -> pm_getport.c
+# rpc_callmsg.c -> rpc_cmsg.c
+# rpc_commondata.c -> rpc_common.c
+# rpc_dtablesize.c -> rpc_dtable.c
+# svc_auth_unix.c -> svc_authux.c
+# xdr_reference.c -> xdr_ref.c
+
+rpcsvc = bootparam_prot.x nlm_prot.x rstat.x \
+ yppasswd.x klm_prot.x rex.x sm_inter.x mount.x \
+ rusers.x spray.x nfs_prot.x rquota.x key_prot.x
+headers-in-tirpc = $(addprefix rpc/,auth.h auth_unix.h clnt.h pmap_clnt.h \
+ pmap_prot.h pmap_rmt.h rpc.h rpc_msg.h \
+ svc.h svc_auth.h types.h xdr.h auth_des.h \
+ des_crypt.h)
+headers-not-in-tirpc = $(addprefix rpc/,key_prot.h rpc_des.h) \
+ $(rpcsvc:%=rpcsvc/%) rpcsvc/bootparam.h
+headers = rpc/netdb.h
+install-others = $(inst_sysconfdir)/rpc
+generated += $(rpcsvc:%.x=rpcsvc/%.h) $(rpcsvc:%.x=x%.c) $(rpcsvc:%.x=x%.stmp) \
+ $(rpcsvc:%.x=rpcsvc/%.stmp) rpcgen
+generated-dirs += rpcsvc
+
+ifeq ($(link-obsolete-rpc),yes)
+headers += $(headers-in-tirpc) $(headers-not-in-tirpc)
+endif
+
+ifeq ($(build-shared),yes)
+need-export-routines := auth_des auth_unix clnt_gen clnt_perr clnt_tcp \
+ clnt_udp get_myaddr key_call netname pm_getport \
+ rpc_thread svc svc_tcp svc_udp xcrypt xdr_array xdr \
+ xdr_intXX_t xdr_mem xdr_ref xdr_sizeof xdr_stdio \
+ svc_run
+
+routines := auth_none authuxprot bindrsvprt clnt_raw clnt_simp \
+ rpc_dtable getrpcport pmap_clnt pm_getmaps pmap_prot pmap_prot2 \
+ pmap_rmt rpc_prot rpc_common rpc_cmsg svc_auth svc_authux svc_raw \
+ svc_simple xdr_float xdr_rec publickey authdes_prot \
+ des_crypt des_impl des_soft key_prot openchild rtime svcauth_des \
+ getrpcent getrpcbyname getrpcbynumber \
+ getrpcent_r getrpcbyname_r getrpcbynumber_r \
+ clnt_unix svc_unix create_xid $(need-export-routines)
+ifneq ($(link-obsolete-rpc),yes)
+# We only add the RPC for compatibility to libc.so.
+shared-only-routines = $(routines)
+endif
+endif
+
+# We do not build rpcinfo anymore. It is not needed for a bootstrap
+# and not wanted on complete systems.
+# others := rpcinfo
+# install-sbin := rpcinfo
+install-bin := rpcgen
+rpcgen-objs = rpc_main.o rpc_hout.o rpc_cout.o rpc_parse.o \
+ rpc_scan.o rpc_util.o rpc_svcout.o rpc_clntout.o \
+ rpc_tblout.o rpc_sample.o
+extra-objs = $(rpcgen-objs) $(addprefix cross-,$(rpcgen-objs))
+others += rpcgen
+
+tests = tst-xdrmem tst-xdrmem2 test-rpcent
+xtests := tst-getmyaddr
+
+ifeq ($(have-thread-library),yes)
+xtests += thrsvc
+endif
+
+headers += $(rpcsvc:%.x=rpcsvc/%.h)
+extra-libs := librpcsvc
+extra-libs-others := librpcsvc # Make it in `others' pass, not `lib' pass.
+librpcsvc-routines = $(rpcsvc:%.x=x%)
+librpcsvc-inhibit-o = .os # Build no shared rpcsvc library.
+omit-deps = $(librpcsvc-routines)
+
+ifeq (yes,$(build-shared))
+rpc-compat-routines = $(addprefix compat-,$(need-export-routines))
+rpc-compat-routines.os = $(addprefix $(objpfx), \
+ $(addsuffix .os,$(rpc-compat-routines)))
+extra-objs += $(addsuffix .os,$(rpc-compat-routines))
+endif
+
+include ../Rules
+
+ifeq (yes,$(build-shared))
+subdir_lib: $(objpfx)librpc_compat_pic.a
+$(objpfx)librpc_compat_pic.a: $(rpc-compat-routines.os)
+ $(AR) cr$(verbose) $@ $^
+$(rpc-compat-routines.os): $(objpfx)compat-%.os: %.c $(before-compile)
+ $(compile-command.c) -DEXPORT_RPC_SYMBOLS
+endif
+
+CFLAGS-xbootparam_prot.c = -Wno-unused $(PIC-ccflag)
+CFLAGS-xnlm_prot.c = -Wno-unused $(PIC-ccflag)
+CFLAGS-xrstat.c = -Wno-unused $(PIC-ccflag)
+CFLAGS-xyppasswd.c = -Wno-unused $(PIC-ccflag)
+CFLAGS-xklm_prot.c = -Wno-unused $(PIC-ccflag)
+CFLAGS-xrex.c = -Wno-unused $(PIC-ccflag)
+CFLAGS-xsm_inter.c = -Wno-unused $(PIC-ccflag)
+CFLAGS-xmount.c = -Wno-unused $(PIC-ccflag)
+CFLAGS-xrusers.c = -Wno-unused $(PIC-ccflag)
+CFLAGS-xspray.c = -Wno-unused $(PIC-ccflag)
+CFLAGS-xnfs_prot.c = -Wno-unused $(PIC-ccflag)
+CFLAGS-xrquota.c = -Wno-unused $(PIC-ccflag)
+CFLAGS-xkey_prot.c = -Wno-unused $(PIC-ccflag)
+CFLAGS-auth_unix.c = -fexceptions
+CFLAGS-key_call.c = -fexceptions
+CFLAGS-pmap_rmt.c = -fexceptions
+CFLAGS-clnt_perr.c = -fexceptions
+CFLAGS-openchild.c = -fexceptions
+
+sunrpc-CPPFLAGS = -D_RPC_THREAD_SAFE_
+CPPFLAGS += $(sunrpc-CPPFLAGS)
+BUILD_CPPFLAGS += $(sunrpc-CPPFLAGS)
+
+$(objpfx)tst-getmyaddr: $(common-objpfx)linkobj/libc.so
+$(objpfx)tst-xdrmem: $(common-objpfx)linkobj/libc.so
+$(objpfx)tst-xdrmem2: $(common-objpfx)linkobj/libc.so
+
+$(objpfx)rpcgen: $(addprefix $(objpfx),$(rpcgen-objs))
+
+cross-rpcgen-objs := $(addprefix $(objpfx)cross-,$(rpcgen-objs))
+
+# When generic makefile support for build system programs is
+# available, it should replace this code. See
+# <http://sourceware.org/bugzilla/show_bug.cgi?id=14087>.
+$(cross-rpcgen-objs): $(objpfx)cross-%.o: %.c $(before-compile)
+ $(BUILD_CC) $($(basename $(<F))-CFLAGS) $(ALL_BUILD_CFLAGS) $< \
+ $(OUTPUT_OPTION) $(native-compile-mkdep-flags) -c
+
+$(objpfx)cross-rpcgen: $(cross-rpcgen-objs)
+ $(BUILD_CC) $^ $(BUILD_LDFLAGS) -o $@
+
+# This makes sure -DIN_MODULE is passed for all these modules.
+cpp-srcs-left := $(rpcgen-objs:.o=.c)
+lib := nonlib
+include $(patsubst %,$(..)cppflags-iterator.mk,$(cpp-srcs-left))
+
+# How we run rpcgen to generate sources and headers in the rules below.
+# Setting CPP tells it how to run the C preprocessor correctly. Note
+# that $(built-program-file) requires that the just-built cross-rpcgen
+# binary be the second dependency listed in each rule using rpcgen-cmd.
+rpcgen-cmd = CPP='$(CC) -E -x c-header' $(built-program-file) -Y ../scripts
+
+# Install the rpc data base file.
+$(inst_sysconfdir)/rpc: etc.rpc $(+force)
+ $(do-install)
+
+# Generate the rpcsvc headers with rpcgen.
+# We use a stamp file to avoid unnessary recompilation each time rpcgen is
+# relinked.
+$(rpcsvc:%.x=$(objpfx)rpcsvc/%.h): $(objpfx)rpcsvc/%.h: $(objpfx)rpcsvc/%.stmp
+ @:
+$(objpfx)rpcsvc/%.stmp: rpcsvc/%.x $(objpfx)cross-rpcgen
+ $(make-target-directory)
+ -@rm -f ${@:stmp=T} $@
+ $(rpcgen-cmd) -h $< -o ${@:stmp=T}
+ $(move-if-change) $(@:stmp=T) $(@:stmp=h)
+ touch $@
+
+# Generate the rpcsvc XDR functions with rpcgen.
+$(rpcsvc:%.x=$(objpfx)x%.c): $(objpfx)x%.c: $(objpfx)x%.stmp
+ @:
+$(objpfx)x%.stmp: rpcsvc/%.x $(objpfx)cross-rpcgen
+ -@rm -f ${@:stmp=T} $@
+ $(rpcgen-cmd) -c $< -o ${@:stmp=T}
+ $(move-if-change) $(@:stmp=T) $(@:stmp=c)
+ touch $@
+
+# The generated source files depend on the corresponding generated headers.
+# Gratuitous dependency on generated .c file here just gets it mentioned to
+# avoid being an intermediate file and getting removed.
+define o-iterator-doit
+$(rpcsvc:%.x=$(objpfx)x%$o): $(objpfx)x%$o: $(objpfx)x%.c $(objpfx)rpcsvc/%.h
+endef
+object-suffixes-left = $(filter-out $(librpcsvc-inhibit-o),$(object-suffixes))
+include $(o-iterator)
+
+rpcsvc-dt-files := $(foreach o,$(filter-out $(librpcsvc-inhibit-o),\
+ $(object-suffixes)),\
+ $(rpcsvc:%.x=$(objpfx)x%$o.dt))
+rpcsvc-depfiles := $(patsubst %.dt,%.d,$(wildcard $(rpcsvc-dt-files))) \
+ $(wildcard $(rpcsvc-dt-files:.dt=.d))
+ifdef rpcsvc-depfiles
+ifneq ($(no_deps),t)
+-include $(rpcsvc-depfiles)
+endif
+endif
+
+$(objpfx)thrsvc: $(common-objpfx)linkobj/libc.so $(shared-thread-library)
diff --git a/sunrpc/Versions b/sunrpc/Versions
new file mode 100644
index 0000000..77bc6a4
--- /dev/null
+++ b/sunrpc/Versions
@@ -0,0 +1,131 @@
+libc {
+ GLIBC_2.0 {
+ # global variables.
+ _null_auth;
+
+ # functions used in other libraries
+ _rpc_dtablesize; _seterr_reply;
+
+ # variables in normal name space
+ rpc_createerr; svc_fdset; svcauthdes_stats;
+
+ # a*
+ authnone_create; authunix_create; authunix_create_default;
+
+ # b*
+ bindresvport;
+
+ # c*
+ callrpc;
+ clnt_broadcast; clnt_create; clnt_pcreateerror; clnt_perrno;
+ clnt_perror; clnt_spcreateerror; clnt_sperrno; clnt_sperror;
+ clntraw_create; clnttcp_create; clntudp_bufcreate; clntudp_create;
+
+ # e*
+ endrpcent;
+
+ # g*
+ get_myaddress; getpublickey; getsecretkey;
+ getrpcbyname; getrpcbyname_r; getrpcbynumber; getrpcbynumber_r;
+ getrpcent; getrpcent_r; getrpcport;
+
+ # p*
+ pmap_getmaps; pmap_getport; pmap_rmtcall; pmap_set; pmap_unset;
+
+ # r*
+ registerrpc;
+
+ # s*
+ setrpcent;
+ svc_exit; svc_getreq; svc_getreqset; svc_register; svc_run;
+ svc_sendreply; svc_unregister; svcerr_auth; svcerr_decode;
+ svcerr_noproc; svcerr_noprog; svcerr_progvers; svcerr_systemerr;
+ svcerr_weakauth; svcfd_create; svcraw_create; svctcp_create;
+ svcudp_bufcreate; svcudp_create; svcudp_enablecache;
+
+ # x*
+ xdr_accepted_reply; xdr_array; xdr_authunix_parms; xdr_bool; xdr_bytes;
+ xdr_callhdr; xdr_callmsg; xdr_char; xdr_cryptkeyarg; xdr_cryptkeyarg2;
+ xdr_cryptkeyres; xdr_des_block; xdr_double; xdr_enum; xdr_float;
+ xdr_free; xdr_int; xdr_key_netstarg; xdr_key_netstres; xdr_keybuf;
+ xdr_keystatus; xdr_long; xdr_netobj; xdr_opaque; xdr_opaque_auth;
+ xdr_pmap; xdr_pmaplist; xdr_pointer; xdr_reference; xdr_rejected_reply;
+ xdr_replymsg; xdr_rmtcall_args; xdr_rmtcallres; xdr_short; xdr_string;
+ xdr_u_char; xdr_u_int; xdr_u_long; xdr_u_short; xdr_union; xdr_vector;
+ xdr_void; xdr_wrapstring; xdrmem_create; xdrrec_create;
+ xdrrec_endofrecord; xdrrec_eof; xdrrec_skiprecord; xdrstdio_create;
+ xencrypt; xprt_register; xprt_unregister;
+ }
+ GLIBC_2.1 {
+ # Special Pointer to avoid keyserv deadlock
+ __key_decryptsession_pk_LOCAL; __key_encryptsession_pk_LOCAL;
+ __key_gendes_LOCAL;
+
+ # _*
+ _authenticate;
+
+ # a*
+ authdes_create; authdes_getucred; authdes_pk_create;
+
+ # c*
+ cbc_crypt; clntunix_create;
+
+ # d*
+ des_setparity;
+
+ # e*
+ ecb_crypt;
+
+ # g*
+ getnetname;
+
+ # h*
+ host2netname;
+
+ # k*
+ key_decryptsession; key_decryptsession_pk; key_encryptsession;
+ key_encryptsession_pk; key_gendes; key_get_conv; key_secretkey_is_set;
+ key_setnet; key_setsecret;
+
+ # n*
+ netname2host; netname2user;
+
+ # p*
+ passwd2des;
+
+ # r*
+ rtime;
+
+ # s*
+ svcunix_create; svcunixfd_create;
+
+ # u*
+ user2netname;
+
+ # x*
+ xdecrypt; xdr_authdes_cred; xdr_authdes_verf;
+ xdr_getcredres; xdr_int16_t; xdr_int32_t; xdr_int8_t;
+ xdr_netnamestr; xdr_sizeof;
+ xdr_uint16_t; xdr_uint32_t; xdr_uint8_t; xdr_unixcred;
+ }
+ GLIBC_2.1.1 {
+ xdr_hyper; xdr_u_hyper; xdr_longlong_t; xdr_u_longlong_t;
+ xdr_int64_t; xdr_uint64_t;
+ }
+ GLIBC_2.1.2 {
+ getrpcbyname_r; getrpcbynumber_r; getrpcent_r;
+ }
+ GLIBC_2.2 {
+ svc_getreq_common; svc_getreq_poll; svc_max_pollfd; svc_pollfd;
+ }
+ GLIBC_2.2.3 {
+ __rpc_thread_svc_fdset; __rpc_thread_createerr;
+ __rpc_thread_svc_pollfd; __rpc_thread_svc_max_pollfd;
+ }
+ GLIBC_2.3.4 {
+ xdr_quad_t; xdr_u_quad_t;
+ }
+ GLIBC_PRIVATE {
+ __libc_clntudp_bufcreate; __libc_rpc_getport;
+ }
+}
diff --git a/sunrpc/auth_des.c b/sunrpc/auth_des.c
new file mode 100644
index 0000000..11435c5
--- /dev/null
+++ b/sunrpc/auth_des.c
@@ -0,0 +1,472 @@
+/*
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * auth_des.c, client-side implementation of DES authentication
+ */
+
+#include <string.h>
+#include <stdint.h>
+#include <rpc/des_crypt.h>
+#include <rpc/types.h>
+#include <rpc/auth.h>
+#include <rpc/auth_des.h>
+#include <rpc/xdr.h>
+#include <netinet/in.h> /* XXX: just to get htonl() and ntohl() */
+#include <sys/socket.h>
+
+#define MILLION 1000000L
+#define RTIME_TIMEOUT 5 /* seconds to wait for sync */
+
+#define AUTH_PRIVATE(auth) (struct ad_private *) auth->ah_private
+#define ALLOC(object_type) (object_type *) mem_alloc(sizeof(object_type))
+#define FREE(ptr, size) mem_free((char *)(ptr), (int) size)
+#define ATTEMPT(xdr_op) if (!(xdr_op)) return (FALSE)
+
+#define debug(msg) /* printf("%s\n", msg) */
+
+#if defined SYLIXOS
+extern bool_t
+xdr_authdes_verf (register XDR *xdrs, register struct authdes_verf *verf);
+extern bool_t
+xdr_authdes_cred (XDR *xdrs, struct authdes_cred *cred);
+#endif
+
+/*
+ * DES authenticator operations vector
+ */
+static void authdes_nextverf (AUTH *);
+static bool_t authdes_marshal (AUTH *, XDR *);
+static bool_t authdes_validate (AUTH *, struct opaque_auth *);
+static bool_t authdes_refresh (AUTH *);
+static void authdes_destroy (AUTH *);
+static bool_t synchronize (struct sockaddr *, struct rpc_timeval *)
+ internal_function;
+
+static const struct auth_ops authdes_ops = {
+ authdes_nextverf,
+ authdes_marshal,
+ authdes_validate,
+ authdes_refresh,
+ authdes_destroy
+};
+
+
+/*
+ * This struct is pointed to by the ah_private field of an "AUTH *"
+ */
+struct ad_private {
+ char *ad_fullname; /* client's full name */
+ u_int ad_fullnamelen; /* length of name, rounded up */
+ char *ad_servername; /* server's full name */
+ u_int ad_servernamelen; /* length of name, rounded up */
+ uint32_t ad_window; /* client specified window */
+ bool_t ad_dosync; /* synchronize? */
+ struct sockaddr ad_syncaddr; /* remote host to synch with */
+ struct rpc_timeval ad_timediff; /* server's time - client's time */
+ uint32_t ad_nickname; /* server's nickname for client */
+ struct authdes_cred ad_cred; /* storage for credential */
+ struct authdes_verf ad_verf; /* storage for verifier */
+ struct rpc_timeval ad_timestamp; /* timestamp sent */
+ des_block ad_xkey; /* encrypted conversation key */
+ u_char ad_pkey[1024]; /* Servers actual public key */
+};
+
+
+/*
+ * Create the client des authentication object
+ */
+AUTH *
+authdes_create (const char *servername, u_int window,
+ struct sockaddr *syncaddr, des_block *ckey)
+ /* servername - network name of server */
+ /* window - time to live */
+ /* syncaddr - optional addr of host to sync with */
+ /* ckey - optional conversation key to use */
+{
+ char pkey_data[1024];
+ netobj pkey;
+
+ if (!getpublickey (servername, pkey_data))
+ return NULL;
+
+ pkey.n_bytes = pkey_data;
+ pkey.n_len = strlen (pkey_data) + 1;
+ return authdes_pk_create (servername, &pkey, window, syncaddr, ckey);
+}
+#ifdef EXPORT_RPC_SYMBOLS
+libc_hidden_def (authdes_create)
+#else
+libc_hidden_nolink_sunrpc (authdes_create, GLIBC_2_1)
+#endif
+
+AUTH *
+authdes_pk_create (const char *servername, netobj *pkey, u_int window,
+ struct sockaddr *syncaddr, des_block *ckey)
+{
+ AUTH *auth;
+ struct ad_private *ad;
+ char namebuf[MAXNETNAMELEN + 1];
+
+ /*
+ * Allocate everything now
+ */
+ auth = ALLOC (AUTH);
+ ad = ALLOC (struct ad_private);
+
+ if (auth == NULL || ad == NULL)
+ {
+ debug ("authdes_create: out of memory");
+ goto failed;
+ }
+
+ memset (ad, 0, sizeof (struct ad_private));
+ memcpy (ad->ad_pkey, pkey->n_bytes, pkey->n_len);
+ if (!getnetname (namebuf))
+ goto failed;
+ ad->ad_fullnamelen = RNDUP (strlen (namebuf));
+ ad->ad_fullname = mem_alloc (ad->ad_fullnamelen + 1);
+
+ ad->ad_servernamelen = strlen (servername);
+ ad->ad_servername = mem_alloc (ad->ad_servernamelen + 1);
+
+ if (ad->ad_fullname == NULL || ad->ad_servername == NULL)
+ {
+ debug ("authdes_create: out of memory");
+ goto failed;
+ }
+
+ /*
+ * Set up private data
+ */
+ memcpy (ad->ad_fullname, namebuf, ad->ad_fullnamelen + 1);
+ memcpy (ad->ad_servername, servername, ad->ad_servernamelen + 1);
+ ad->ad_timediff.tv_sec = ad->ad_timediff.tv_usec = 0;
+ if (syncaddr != NULL)
+ {
+ ad->ad_syncaddr = *syncaddr;
+ ad->ad_dosync = TRUE;
+ }
+ else
+ ad->ad_dosync = FALSE;
+
+ ad->ad_window = window;
+ if (ckey == NULL)
+ {
+ if (key_gendes (&auth->ah_key) < 0)
+ {
+ debug ("authdes_create: unable to gen conversation key");
+ goto failed;
+ }
+ }
+ else
+ auth->ah_key = *ckey;
+
+ /*
+ * Set up auth handle
+ */
+ auth->ah_cred.oa_flavor = AUTH_DES;
+ auth->ah_verf.oa_flavor = AUTH_DES;
+ auth->ah_ops = (struct auth_ops *) &authdes_ops;
+ auth->ah_private = (caddr_t) ad;
+
+ if (!authdes_refresh (auth))
+ goto failed;
+
+ return auth;
+
+failed:
+ if (auth != NULL)
+ FREE (auth, sizeof (AUTH));
+ if (ad != NULL)
+ {
+ if (ad->ad_fullname != NULL)
+ FREE (ad->ad_fullname, ad->ad_fullnamelen + 1);
+ if (ad->ad_servername != NULL)
+ FREE (ad->ad_servername, ad->ad_servernamelen + 1);
+ FREE (ad, sizeof (struct ad_private));
+ }
+ return NULL;
+}
+#ifdef EXPORT_RPC_SYMBOLS
+libc_hidden_def (authdes_pk_create)
+#else
+libc_hidden_nolink_sunrpc (authdes_pk_create, GLIBC_2_1)
+#endif
+
+/*
+ * Implement the five authentication operations
+ */
+
+
+/*
+ * 1. Next Verifier
+ */
+/*ARGSUSED */
+static void
+authdes_nextverf (AUTH *auth)
+{
+ /* what the heck am I supposed to do??? */
+}
+
+
+
+/*
+ * 2. Marshal
+ */
+static bool_t
+authdes_marshal (AUTH *auth, XDR *xdrs)
+{
+ struct ad_private *ad = AUTH_PRIVATE (auth);
+ struct authdes_cred *cred = &ad->ad_cred;
+ struct authdes_verf *verf = &ad->ad_verf;
+ des_block cryptbuf[2];
+ des_block ivec;
+ int status;
+ int len;
+ register int32_t *ixdr;
+ struct timeval tval;
+
+ /*
+ * Figure out the "time", accounting for any time difference
+ * with the server if necessary.
+ */
+ __gettimeofday (&tval, (struct timezone *) NULL);
+ ad->ad_timestamp.tv_sec = tval.tv_sec + ad->ad_timediff.tv_sec;
+ ad->ad_timestamp.tv_usec = tval.tv_usec + ad->ad_timediff.tv_usec;
+ if (ad->ad_timestamp.tv_usec >= MILLION)
+ {
+ ad->ad_timestamp.tv_usec -= MILLION;
+ ad->ad_timestamp.tv_sec += 1;
+ }
+
+ /*
+ * XDR the timestamp and possibly some other things, then
+ * encrypt them.
+ * XXX We have a real Year 2038 problem here.
+ */
+ ixdr = (int32_t *) cryptbuf;
+ IXDR_PUT_INT32 (ixdr, ad->ad_timestamp.tv_sec);
+ IXDR_PUT_INT32 (ixdr, ad->ad_timestamp.tv_usec);
+ if (ad->ad_cred.adc_namekind == ADN_FULLNAME)
+ {
+ IXDR_PUT_U_INT32 (ixdr, ad->ad_window);
+ IXDR_PUT_U_INT32 (ixdr, ad->ad_window - 1);
+ ivec.key.high = ivec.key.low = 0;
+ status = cbc_crypt ((char *) &auth->ah_key, (char *) cryptbuf,
+ 2 * sizeof (des_block), DES_ENCRYPT | DES_HW, (char *) &ivec);
+ }
+ else
+ status = ecb_crypt ((char *) &auth->ah_key, (char *) cryptbuf,
+ sizeof (des_block), DES_ENCRYPT | DES_HW);
+
+ if (DES_FAILED (status))
+ {
+ debug ("authdes_marshal: DES encryption failure");
+ return FALSE;
+ }
+ ad->ad_verf.adv_xtimestamp = cryptbuf[0];
+ if (ad->ad_cred.adc_namekind == ADN_FULLNAME)
+ {
+ ad->ad_cred.adc_fullname.window = cryptbuf[1].key.high;
+ ad->ad_verf.adv_winverf = cryptbuf[1].key.low;
+ }
+ else
+ {
+ ad->ad_cred.adc_nickname = ad->ad_nickname;
+ ad->ad_verf.adv_winverf = 0;
+ }
+
+ /*
+ * Serialize the credential and verifier into opaque
+ * authentication data.
+ */
+ if (ad->ad_cred.adc_namekind == ADN_FULLNAME)
+ len = ((1 + 1 + 2 + 1) * BYTES_PER_XDR_UNIT + ad->ad_fullnamelen);
+ else
+ len = (1 + 1) * BYTES_PER_XDR_UNIT;
+
+ if ((ixdr = xdr_inline (xdrs, 2 * BYTES_PER_XDR_UNIT)) != NULL)
+ {
+ IXDR_PUT_INT32 (ixdr, AUTH_DES);
+ IXDR_PUT_U_INT32 (ixdr, len);
+ }
+ else
+ {
+ ATTEMPT (xdr_putint32 (xdrs, &auth->ah_cred.oa_flavor));
+ ATTEMPT (xdr_putint32 (xdrs, &len));
+ }
+ ATTEMPT (xdr_authdes_cred (xdrs, cred));
+
+ len = (2 + 1) * BYTES_PER_XDR_UNIT;
+ if ((ixdr = xdr_inline (xdrs, 2 * BYTES_PER_XDR_UNIT)) != NULL)
+ {
+ IXDR_PUT_INT32 (ixdr, AUTH_DES);
+ IXDR_PUT_U_INT32 (ixdr, len);
+ }
+ else
+ {
+ ATTEMPT (xdr_putint32 (xdrs, &auth->ah_verf.oa_flavor));
+ ATTEMPT (xdr_putint32 (xdrs, &len));
+ }
+ ATTEMPT (xdr_authdes_verf (xdrs, verf));
+
+ return TRUE;
+}
+
+
+/*
+ * 3. Validate
+ */
+static bool_t
+authdes_validate (AUTH *auth, struct opaque_auth *rverf)
+{
+ struct ad_private *ad = AUTH_PRIVATE (auth);
+ struct authdes_verf verf;
+ int status;
+ register uint32_t *ixdr;
+
+ if (rverf->oa_length != (2 + 1) * BYTES_PER_XDR_UNIT)
+ return FALSE;
+
+ ixdr = (uint32_t *) rverf->oa_base;
+ verf.adv_xtimestamp.key.high = *ixdr++;
+ verf.adv_xtimestamp.key.low = *ixdr++;
+ verf.adv_int_u = *ixdr++; /* nickname not XDR'd ! */
+
+ /*
+ * Decrypt the timestamp
+ */
+ status = ecb_crypt ((char *) &auth->ah_key, (char *) &verf.adv_xtimestamp,
+ sizeof (des_block), DES_DECRYPT | DES_HW);
+
+ if (DES_FAILED (status))
+ {
+ debug ("authdes_validate: DES decryption failure");
+ return FALSE;
+ }
+
+ /*
+ * xdr the decrypted timestamp
+ */
+ ixdr = (uint32_t *) verf.adv_xtimestamp.c;
+ verf.adv_timestamp.tv_sec = IXDR_GET_U_INT32 (ixdr) + 1;
+ verf.adv_timestamp.tv_usec = IXDR_GET_U_INT32 (ixdr);
+
+ /*
+ * validate
+ */
+ if (memcmp ((char *) &ad->ad_timestamp, (char *) &verf.adv_timestamp,
+ sizeof (struct rpc_timeval)) != 0)
+ {
+ debug ("authdes_validate: verifier mismatch\n");
+ return FALSE;
+ }
+
+ /*
+ * We have a nickname now, let's use it
+ */
+ ad->ad_nickname = verf.adv_nickname;
+ ad->ad_cred.adc_namekind = ADN_NICKNAME;
+ return TRUE;
+}
+
+/*
+ * 4. Refresh
+ */
+static bool_t
+authdes_refresh (AUTH *auth)
+{
+ netobj pkey;
+ struct ad_private *ad = AUTH_PRIVATE (auth);
+ struct authdes_cred *cred = &ad->ad_cred;
+
+ if (ad->ad_dosync && !synchronize (&ad->ad_syncaddr, &ad->ad_timediff))
+ {
+ /*
+ * Hope the clocks are synced!
+ */
+ ad->ad_timediff.tv_sec = ad->ad_timediff.tv_usec = 0;
+ debug ("authdes_refresh: unable to synchronize with server");
+ }
+ ad->ad_xkey = auth->ah_key;
+ pkey.n_bytes = (char *) (ad->ad_pkey);
+ pkey.n_len = strlen ((char *) ad->ad_pkey) + 1;
+ if (key_encryptsession_pk (ad->ad_servername, &pkey, &ad->ad_xkey) < 0)
+ {
+ debug ("authdes_create: unable to encrypt conversation key");
+ return FALSE;
+ }
+ cred->adc_fullname.key = ad->ad_xkey;
+ cred->adc_namekind = ADN_FULLNAME;
+ cred->adc_fullname.name = ad->ad_fullname;
+ return TRUE;
+}
+
+/*
+ * 5. Destroy
+ */
+static void
+authdes_destroy (AUTH *auth)
+{
+ struct ad_private *ad = AUTH_PRIVATE (auth);
+
+ FREE (ad->ad_fullname, ad->ad_fullnamelen + 1);
+ FREE (ad->ad_servername, ad->ad_servernamelen + 1);
+ FREE (ad, sizeof (struct ad_private));
+ FREE (auth, sizeof (AUTH));
+}
+
+/*
+ * Synchronize with the server at the given address, that is,
+ * adjust timep to reflect the delta between our clocks
+ */
+static bool_t
+internal_function
+synchronize (struct sockaddr *syncaddr, struct rpc_timeval *timep)
+{
+ struct timeval mytime;
+ struct rpc_timeval timeout;
+
+ timeout.tv_sec = RTIME_TIMEOUT;
+ timeout.tv_usec = 0;
+ if (rtime ((struct sockaddr_in *) syncaddr, timep, &timeout) < 0)
+ return FALSE;
+
+ __gettimeofday (&mytime, (struct timezone *) NULL);
+ timep->tv_sec -= mytime.tv_sec;
+ if (mytime.tv_usec > timep->tv_usec)
+ {
+ timep->tv_sec -= 1;
+ timep->tv_usec += MILLION;
+ }
+ timep->tv_usec -= mytime.tv_usec;
+ return TRUE;
+}
diff --git a/sunrpc/auth_none.c b/sunrpc/auth_none.c
new file mode 100644
index 0000000..faf999d
--- /dev/null
+++ b/sunrpc/auth_none.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * auth_none.c
+ * Creates a client authentication handle for passing "null"
+ * credentials and verifiers to remote systems.
+ */
+
+#include <rpc/rpc.h>
+#ifndef SYLIXOS
+#include <libc-lock.h>
+#endif
+
+#define MAX_MARSHAL_SIZE 20
+
+/*
+ * Authenticator operations routines
+ */
+static void authnone_verf (AUTH *);
+static void authnone_destroy (AUTH *);
+static bool_t authnone_marshal (AUTH *, XDR *);
+static bool_t authnone_validate (AUTH *, struct opaque_auth *);
+static bool_t authnone_refresh (AUTH *);
+
+static const struct auth_ops ops = {
+ authnone_verf,
+ authnone_marshal,
+ authnone_validate,
+ authnone_refresh,
+ authnone_destroy
+};
+
+/* Internal data and routines */
+
+struct authnone_private_s {
+ AUTH no_client;
+ char marshalled_client[MAX_MARSHAL_SIZE];
+ u_int mcnt;
+};
+
+static struct authnone_private_s authnone_private;
+__libc_once_define(static, authnone_private_guard);
+
+static void authnone_create_once (void);
+
+static void
+authnone_create_once (void)
+{
+ struct authnone_private_s *ap;
+ XDR xdr_stream;
+ XDR *xdrs;
+
+ ap = &authnone_private;
+
+ ap->no_client.ah_cred = ap->no_client.ah_verf = _null_auth;
+ ap->no_client.ah_ops = (struct auth_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);
+}
+
+AUTH *
+authnone_create (void)
+{
+ __libc_once (authnone_private_guard, authnone_create_once);
+ return &authnone_private.no_client;
+}
+libc_hidden_nolink_sunrpc (authnone_create, GLIBC_2_0)
+
+static bool_t
+authnone_marshal (AUTH *client, XDR *xdrs)
+{
+ struct authnone_private_s *ap;
+
+ /* authnone_create returned authnone_private->no_client, which is
+ the first field of struct authnone_private_s. */
+ ap = (struct authnone_private_s *) client;
+ if (ap == NULL)
+ return FALSE;
+ return (*xdrs->x_ops->x_putbytes) (xdrs, ap->marshalled_client, ap->mcnt);
+}
+
+static void
+authnone_verf (AUTH *auth)
+{
+}
+
+static bool_t
+authnone_validate (AUTH *auth, struct opaque_auth *oa)
+{
+ return TRUE;
+}
+
+static bool_t
+authnone_refresh (AUTH *auth)
+{
+ return FALSE;
+}
+
+static void
+authnone_destroy (AUTH *auth)
+{
+}
diff --git a/sunrpc/auth_unix.c b/sunrpc/auth_unix.c
new file mode 100644
index 0000000..726fc1e
--- /dev/null
+++ b/sunrpc/auth_unix.c
@@ -0,0 +1,358 @@
+/*
+ * Copyright (c) 2010, 2011, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * auth_unix.c, Implements UNIX style authentication parameters.
+ *
+ * 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.
+ */
+
+#include <errno.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#ifndef SYLIXOS
+#include <libintl.h>
+#endif
+#include <sys/param.h>
+#include <wchar.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 bool_t authunix_marshal (AUTH *, XDR *);
+static bool_t authunix_validate (AUTH *, struct opaque_auth *);
+static bool_t authunix_refresh (AUTH *);
+static void authunix_destroy (AUTH *);
+
+static const 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 bool_t marshal_new_auth (AUTH *) internal_function;
+
+
+/*
+ * Create a unix style authenticator.
+ * Returns an auth handle with the given stuff in it.
+ */
+AUTH *
+authunix_create (char *machname, uid_t uid, gid_t gid, int len,
+ gid_t *aup_gids)
+{
+ struct authunix_parms aup;
+ char mymem[MAX_AUTH_BYTES];
+ struct timeval now;
+ XDR xdrs;
+ AUTH *auth;
+ struct audata *au;
+
+ /*
+ * Allocate and set up auth handle
+ */
+ auth = (AUTH *) mem_alloc (sizeof (*auth));
+ au = (struct audata *) mem_alloc (sizeof (*au));
+ if (auth == NULL || au == NULL)
+ {
+no_memory:
+ (void) __fxprintf (NULL, "%s: %s", __func__, _("out of memory\n"));
+ mem_free (auth, sizeof (*auth));
+ mem_free (au, sizeof (*au));
+ return NULL;
+ }
+ auth->ah_ops = (struct auth_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;
+ 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;
+ au->au_origcred.oa_base = mem_alloc ((u_int) len);
+ if (au->au_origcred.oa_base == NULL)
+ goto no_memory;
+ 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;
+}
+libc_hidden_nolink_sunrpc (authunix_create, GLIBC_2_0)
+
+/*
+ * Returns an auth handle with parameters determined by doing lots of
+ * syscalls.
+ */
+AUTH *
+authunix_create_default (void)
+{
+ char machname[MAX_MACHINE_NAME + 1];
+
+ if (__gethostname (machname, MAX_MACHINE_NAME) == -1)
+ abort ();
+ machname[MAX_MACHINE_NAME] = 0;
+ uid_t uid = __geteuid ();
+ gid_t gid = __getegid ();
+
+ int max_nr_groups;
+ /* When we have to try a second time, do not use alloca() again. We
+ might have reached the stack limit already. */
+ bool retry = false;
+ again:
+ /* Ask the kernel how many groups there are exactly. Note that we
+ might have to redo all this if the number of groups has changed
+ between the two calls. */
+ max_nr_groups = __getgroups (0, NULL);
+
+ /* Just some random reasonable stack limit. */
+#define ALLOCA_LIMIT (1024 / sizeof (gid_t))
+ gid_t *gids = NULL;
+ if (max_nr_groups < ALLOCA_LIMIT && ! retry)
+ gids = (gid_t *) alloca (max_nr_groups * sizeof (gid_t));
+ else
+ {
+ gids = (gid_t *) malloc (max_nr_groups * sizeof (gid_t));
+ if (gids == NULL)
+ return NULL;
+ }
+
+ int len = __getgroups (max_nr_groups, gids);
+ if (len == -1)
+ {
+ if (errno == EINVAL)
+ {
+ /* New groups added in the meantime. Try again. */
+ if (max_nr_groups >= ALLOCA_LIMIT || retry)
+ free (gids);
+ retry = true;
+ goto again;
+ }
+ /* No other error can happen. */
+ abort ();
+ }
+
+ /* This braindamaged Sun code forces us here to truncate the
+ list of groups to NGRPS members since the code in
+ authuxprot.c transforms a fixed array. Grrr. */
+ AUTH *result = authunix_create (machname, uid, gid, MIN (NGRPS, len), gids);
+
+ if (max_nr_groups >= ALLOCA_LIMIT || retry)
+ free (gids);
+
+ return result;
+}
+#ifdef EXPORT_RPC_SYMBOLS
+libc_hidden_def (authunix_create_default)
+#else
+libc_hidden_nolink_sunrpc (authunix_create_default, GLIBC_2_0)
+#endif
+
+/*
+ * authunix operations
+ */
+
+static void
+authunix_nextverf (AUTH *auth)
+{
+ /* no action necessary */
+}
+
+static bool_t
+authunix_marshal (AUTH *auth, XDR *xdrs)
+{
+ struct audata *au = AUTH_PRIVATE (auth);
+
+ return XDR_PUTBYTES (xdrs, au->au_marshed, au->au_mpos);
+}
+
+static bool_t
+authunix_validate (AUTH *auth, struct opaque_auth *verf)
+{
+ 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 bool_t
+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 = (gid_t *) 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 bool_t
+internal_function
+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_unix.c: Fatal marshalling problem"));
+ else
+ au->au_mpos = XDR_GETPOS (xdrs);
+
+ XDR_DESTROY (xdrs);
+
+ return TRUE;
+}
diff --git a/sunrpc/authdes_prot.c b/sunrpc/authdes_prot.c
new file mode 100644
index 0000000..164c122
--- /dev/null
+++ b/sunrpc/authdes_prot.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * authdes_prot.c, XDR routines for DES authentication
+ */
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#include <rpc/auth_des.h>
+
+#define ATTEMPT(xdr_op) if (!(xdr_op)) return (FALSE)
+
+bool_t
+xdr_authdes_cred (XDR *xdrs, struct authdes_cred *cred)
+{
+ /*
+ * Unrolled xdr
+ */
+ ATTEMPT (xdr_enum (xdrs, (enum_t *) & cred->adc_namekind));
+ switch (cred->adc_namekind)
+ {
+ case ADN_FULLNAME:
+ ATTEMPT (xdr_string (xdrs, &cred->adc_fullname.name, MAXNETNAMELEN));
+ ATTEMPT (xdr_opaque (xdrs, (caddr_t) & cred->adc_fullname.key,
+ sizeof (des_block)));
+ ATTEMPT (xdr_opaque (xdrs, (caddr_t) & cred->adc_fullname.window,
+ sizeof (cred->adc_fullname.window)));
+ return (TRUE);
+ case ADN_NICKNAME:
+ ATTEMPT (xdr_opaque (xdrs, (caddr_t) & cred->adc_nickname,
+ sizeof (cred->adc_nickname)));
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+libc_hidden_nolink_sunrpc (xdr_authdes_cred, GLIBC_2_1)
+
+
+bool_t
+xdr_authdes_verf (register XDR *xdrs, register struct authdes_verf *verf)
+{
+ /*
+ * Unrolled xdr
+ */
+ ATTEMPT (xdr_opaque (xdrs, (caddr_t) & verf->adv_xtimestamp,
+ sizeof (des_block)));
+ ATTEMPT (xdr_opaque (xdrs, (caddr_t) & verf->adv_int_u,
+ sizeof (verf->adv_int_u)));
+ return TRUE;
+}
+libc_hidden_nolink_sunrpc (xdr_authdes_verf, GLIBC_2_1)
diff --git a/sunrpc/authuxprot.c b/sunrpc/authuxprot.c
new file mode 100644
index 0000000..d37faee
--- /dev/null
+++ b/sunrpc/authuxprot.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * authunix_prot.c
+ * XDR for UNIX style authentication parameters for RPC
+ */
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#include <rpc/auth_unix.h>
+
+/*
+ * XDR for unix authentication parameters.
+ * Unfortunately, none of these can be declared const.
+ */
+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)
+ && (sizeof (uid_t) == sizeof (short int)
+ ? xdr_u_short (xdrs, (u_short *) & (p->aup_uid))
+ : xdr_u_int (xdrs, (u_int *) & (p->aup_uid)))
+ && (sizeof (gid_t) == sizeof (short int)
+ ? xdr_u_short (xdrs, (u_short *) & (p->aup_gid))
+ : xdr_u_int (xdrs, (u_int *) & (p->aup_gid)))
+ && xdr_array (xdrs, (caddr_t *) & (p->aup_gids),
+ & (p->aup_len), NGRPS, sizeof (gid_t),
+ (sizeof (gid_t) == sizeof (short int)
+ ? (xdrproc_t) xdr_u_short
+ : (xdrproc_t) xdr_u_int)))
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+libc_hidden_nolink_sunrpc (xdr_authunix_parms, GLIBC_2_0)
diff --git a/sunrpc/bindrsvprt.c b/sunrpc/bindrsvprt.c
new file mode 100644
index 0000000..4c6b3f5
--- /dev/null
+++ b/sunrpc/bindrsvprt.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#ifndef SYLIXOS
+#include <libc-lock.h>
+#else
+#include <rpc/types.h>
+#endif
+
+/*
+ * Locks the static variables in this file.
+ */
+__libc_lock_define_initialized (static, lock);
+
+/*
+ * Bind a socket to a privileged IP port
+ */
+int
+bindresvport (int sd, struct sockaddr_in *sin)
+{
+ static short port;
+ struct sockaddr_in myaddr;
+ int i;
+
+#define STARTPORT 600
+#define LOWPORT 512
+#define ENDPORT (IPPORT_RESERVED - 1)
+#define NPORTS (ENDPORT - STARTPORT + 1)
+ static short startport = STARTPORT;
+
+ if (sin == (struct sockaddr_in *) 0)
+ {
+ sin = &myaddr;
+ __bzero (sin, sizeof (*sin));
+ sin->sin_family = AF_INET;
+ }
+ else if (sin->sin_family != AF_INET)
+ {
+ __set_errno (EAFNOSUPPORT);
+ return -1;
+ }
+
+ if (port == 0)
+ {
+ port = (__getpid () % NPORTS) + STARTPORT;
+ }
+
+ /* Initialize to make gcc happy. */
+ int res = -1;
+
+ int nports = ENDPORT - startport + 1;
+ int endport = ENDPORT;
+
+ __libc_lock_lock (lock);
+
+ again:
+ for (i = 0; i < nports; ++i)
+ {
+ sin->sin_port = htons (port++);
+ if (port > endport)
+ port = startport;
+ res = __bind (sd, sin, sizeof (struct sockaddr_in));
+ if (res >= 0 || errno != EADDRINUSE)
+ break;
+ }
+
+ if (i == nports && startport != LOWPORT)
+ {
+ startport = LOWPORT;
+ endport = STARTPORT - 1;
+ nports = STARTPORT - LOWPORT;
+ port = LOWPORT + port % (STARTPORT - LOWPORT);
+ goto again;
+ }
+
+ __libc_lock_unlock (lock);
+
+ return res;
+}
+libc_hidden_def (bindresvport)
diff --git a/sunrpc/clnt_gen.c b/sunrpc/clnt_gen.c
new file mode 100644
index 0000000..df34672
--- /dev/null
+++ b/sunrpc/clnt_gen.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <alloca.h>
+#include <errno.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <netdb.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, u_long prog, u_long vers,
+ const char *proto)
+{
+ struct hostent hostbuf, *h;
+ size_t hstbuflen;
+ char *hsttmpbuf;
+ struct protoent protobuf, *p;
+ size_t prtbuflen;
+ char *prttmpbuf;
+ struct sockaddr_in sin;
+ struct sockaddr_un sun;
+ int sock;
+ struct timeval tv;
+ CLIENT *client;
+ int herr;
+
+ if (strcmp (proto, "unix") == 0)
+ {
+ __bzero ((char *)&sun, sizeof (sun));
+ sun.sun_family = AF_UNIX;
+ strcpy (sun.sun_path, hostname);
+ sock = RPC_ANYSOCK;
+ client = clntunix_create (&sun, prog, vers, &sock, 0, 0);
+ if (client == NULL)
+ return NULL;
+#if 0
+ /* This is not wanted. This would disable the user from having
+ a timeout in the clnt_call() call. Only a call to cnlt_control()
+ by the user should set the timeout value. */
+ tv.tv_sec = 25;
+ tv.tv_usec = 0;
+ clnt_control (client, CLSET_TIMEOUT, (char *)&tv);
+#endif
+ return client;
+ }
+
+ hstbuflen = 1024;
+ hsttmpbuf = __alloca (hstbuflen);
+ while (__gethostbyname_r (hostname, &hostbuf, hsttmpbuf, hstbuflen,
+ &h, &herr) != 0
+ || h == NULL)
+ if (herr != NETDB_INTERNAL || errno != ERANGE)
+ {
+ get_rpc_createerr().cf_stat = RPC_UNKNOWNHOST;
+ return NULL;
+ }
+ else
+ {
+ /* Enlarge the buffer. */
+ hstbuflen *= 2;
+ hsttmpbuf = __alloca (hstbuflen);
+ }
+
+ if (h->h_addrtype != AF_INET)
+ {
+ /*
+ * Only support INET for now
+ */
+ struct rpc_createerr *ce = &get_rpc_createerr ();
+ ce->cf_stat = RPC_SYSTEMERROR;
+ ce->cf_error.re_errno = EAFNOSUPPORT;
+ return NULL;
+ }
+ sin.sin_family = h->h_addrtype;
+ sin.sin_port = 0;
+ __bzero (sin.sin_zero, sizeof (sin.sin_zero));
+ memcpy ((char *) &sin.sin_addr, h->h_addr, h->h_length);
+
+ prtbuflen = 1024;
+ prttmpbuf = __alloca (prtbuflen);
+ while (__getprotobyname_r (proto, &protobuf, prttmpbuf, prtbuflen, &p) != 0
+ || p == NULL)
+ if (errno != ERANGE)
+ {
+ struct rpc_createerr *ce = &get_rpc_createerr ();
+ ce->cf_stat = RPC_UNKNOWNPROTO;
+ ce->cf_error.re_errno = EPFNOSUPPORT;
+ return NULL;
+ }
+ else
+ {
+ /* Enlarge the buffer. */
+ prtbuflen *= 2;
+ prttmpbuf = __alloca (prtbuflen);
+ }
+
+ 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
+ /* This is not wanted. This would disable the user from having
+ a timeout in the clnt_call() call. Only a call to cnlt_control()
+ by the user should set the timeout value. */
+ tv.tv_sec = 25;
+ clnt_control (client, CLSET_TIMEOUT, (char *)&tv);
+#endif
+ break;
+ case IPPROTO_TCP:
+ client = clnttcp_create (&sin, prog, vers, &sock, 0, 0);
+ if (client == NULL)
+ {
+ return NULL;
+ }
+#if 0
+ /* This is not wanted. This would disable the user from having
+ a timeout in the clnt_call() call. Only a call to cnlt_control()
+ by the user should set the timeout value. */
+ tv.tv_sec = 25;
+ tv.tv_usec = 0;
+ clnt_control (client, CLSET_TIMEOUT, (char *)&tv);
+#endif
+ break;
+ default:
+ {
+ struct rpc_createerr *ce = &get_rpc_createerr ();
+ ce->cf_stat = RPC_SYSTEMERROR;
+ ce->cf_error.re_errno = EPFNOSUPPORT;
+ }
+ return (NULL);
+ }
+ return client;
+}
+#ifdef EXPORT_RPC_SYMBOLS
+libc_hidden_def (clnt_create)
+#else
+libc_hidden_nolink_sunrpc (clnt_create, GLIBC_2_0)
+#endif
diff --git a/sunrpc/clnt_perr.c b/sunrpc/clnt_perr.c
new file mode 100644
index 0000000..afc84ad
--- /dev/null
+++ b/sunrpc/clnt_perr.c
@@ -0,0 +1,401 @@
+/*
+ * clnt_perror.c
+ *
+ * Copyright (c) 2010, 2011, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <stdio.h>
+#include <string.h>
+#ifndef SYLIXOS
+#include <libintl.h>
+#endif
+#include <rpc/rpc.h>
+#include <wchar.h>
+#ifndef SYLIXOS
+#include <libio/iolibio.h>
+#endif
+
+static char *auth_errmsg (enum auth_stat stat) internal_function;
+
+#ifdef _RPC_THREAD_SAFE_
+/*
+ * Making buf a preprocessor macro requires renaming the local
+ * buf variable in a few functions. Overriding a global variable
+ * with a local variable of the same name is a bad idea, anyway.
+ */
+#define buf RPC_THREAD_VARIABLE(clnt_perr_buf_s)
+#else
+static char *buf;
+#endif
+
+/*
+ * Print reply error info
+ */
+char *
+clnt_sperror (CLIENT * rpch, const char *msg)
+{
+ struct rpc_err e;
+ CLNT_GETERR (rpch, &e);
+
+ const char *errstr = clnt_sperrno (e.re_status);
+
+ char chrbuf[1024];
+ char *str;
+ char *tmpstr;
+ int res;
+ 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:
+ res = __asprintf (&str, "%s: %s\n", msg, errstr);
+ break;
+
+ case RPC_CANTSEND:
+ case RPC_CANTRECV:
+ res = __asprintf (&str, "%s: %s; errno = %s\n",
+ msg, errstr, __strerror_r (e.re_errno,
+ chrbuf, sizeof chrbuf));
+ break;
+
+ case RPC_VERSMISMATCH:
+ res = __asprintf (&str,
+ _("%s: %s; low version = %lu, high version = %lu"),
+ msg, errstr, e.re_vers.low, e.re_vers.high);
+ break;
+
+ case RPC_AUTHERROR:
+ tmpstr = auth_errmsg (e.re_why);
+ if (tmpstr != NULL)
+ res = __asprintf (&str, _("%s: %s; why = %s\n"), msg, errstr, tmpstr);
+ else
+ res = __asprintf (&str, _("\
+%s: %s; why = (unknown authentication error - %d)\n"),
+ msg, errstr, (int) e.re_why);
+ break;
+
+ case RPC_PROGVERSMISMATCH:
+ res = __asprintf (&str,
+ _("%s: %s; low version = %lu, high version = %lu"),
+ msg, errstr, e.re_vers.low, e.re_vers.high);
+ break;
+
+ default: /* unknown */
+ res = __asprintf (&str, "%s: %s; s1 = %lu, s2 = %lu",
+ msg, errstr, e.re_lb.s1, e.re_lb.s2);
+ break;
+ }
+
+ if (res < 0)
+ return NULL;
+
+ char *oldbuf = buf;
+ buf = str;
+ free (oldbuf);
+
+ return str;
+}
+libc_hidden_nolink_sunrpc (clnt_sperror, GLIBC_2_0)
+
+void
+clnt_perror (CLIENT * rpch, const char *msg)
+{
+ (void) __fxprintf (NULL, "%s", clnt_sperror (rpch, msg));
+}
+#ifdef EXPORT_RPC_SYMBOLS
+libc_hidden_def (clnt_perror)
+#else
+libc_hidden_nolink_sunrpc (clnt_perror, GLIBC_2_0)
+#endif
+
+
+struct rpc_errtab
+{
+ enum clnt_stat status;
+ unsigned int message_off;
+};
+
+static const char rpc_errstr[] =
+{
+#define RPC_SUCCESS_IDX 0
+ N_("RPC: Success")
+ "\0"
+#define RPC_CANTENCODEARGS_IDX (RPC_SUCCESS_IDX + sizeof "RPC: Success")
+ N_("RPC: Can't encode arguments")
+ "\0"
+#define RPC_CANTDECODERES_IDX (RPC_CANTENCODEARGS_IDX \
+ + sizeof "RPC: Can't encode arguments")
+ N_("RPC: Can't decode result")
+ "\0"
+#define RPC_CANTSEND_IDX (RPC_CANTDECODERES_IDX \
+ + sizeof "RPC: Can't decode result")
+ N_("RPC: Unable to send")
+ "\0"
+#define RPC_CANTRECV_IDX (RPC_CANTSEND_IDX \
+ + sizeof "RPC: Unable to send")
+ N_("RPC: Unable to receive")
+ "\0"
+#define RPC_TIMEDOUT_IDX (RPC_CANTRECV_IDX \
+ + sizeof "RPC: Unable to receive")
+ N_("RPC: Timed out")
+ "\0"
+#define RPC_VERSMISMATCH_IDX (RPC_TIMEDOUT_IDX \
+ + sizeof "RPC: Timed out")
+ N_("RPC: Incompatible versions of RPC")
+ "\0"
+#define RPC_AUTHERROR_IDX (RPC_VERSMISMATCH_IDX \
+ + sizeof "RPC: Incompatible versions of RPC")
+ N_("RPC: Authentication error")
+ "\0"
+#define RPC_PROGUNAVAIL_IDX (RPC_AUTHERROR_IDX \
+ + sizeof "RPC: Authentication error")
+ N_("RPC: Program unavailable")
+ "\0"
+#define RPC_PROGVERSMISMATCH_IDX (RPC_PROGUNAVAIL_IDX \
+ + sizeof "RPC: Program unavailable")
+ N_("RPC: Program/version mismatch")
+ "\0"
+#define RPC_PROCUNAVAIL_IDX (RPC_PROGVERSMISMATCH_IDX \
+ + sizeof "RPC: Program/version mismatch")
+ N_("RPC: Procedure unavailable")
+ "\0"
+#define RPC_CANTDECODEARGS_IDX (RPC_PROCUNAVAIL_IDX \
+ + sizeof "RPC: Procedure unavailable")
+ N_("RPC: Server can't decode arguments")
+ "\0"
+#define RPC_SYSTEMERROR_IDX (RPC_CANTDECODEARGS_IDX \
+ + sizeof "RPC: Server can't decode arguments")
+ N_("RPC: Remote system error")
+ "\0"
+#define RPC_UNKNOWNHOST_IDX (RPC_SYSTEMERROR_IDX \
+ + sizeof "RPC: Remote system error")
+ N_("RPC: Unknown host")
+ "\0"
+#define RPC_UNKNOWNPROTO_IDX (RPC_UNKNOWNHOST_IDX \
+ + sizeof "RPC: Unknown host")
+ N_("RPC: Unknown protocol")
+ "\0"
+#define RPC_PMAPFAILURE_IDX (RPC_UNKNOWNPROTO_IDX \
+ + sizeof "RPC: Unknown protocol")
+ N_("RPC: Port mapper failure")
+ "\0"
+#define RPC_PROGNOTREGISTERED_IDX (RPC_PMAPFAILURE_IDX \
+ + sizeof "RPC: Port mapper failure")
+ N_("RPC: Program not registered")
+ "\0"
+#define RPC_FAILED_IDX (RPC_PROGNOTREGISTERED_IDX \
+ + sizeof "RPC: Program not registered")
+ N_("RPC: Failed (unspecified error)")
+};
+
+static const struct rpc_errtab rpc_errlist[] =
+{
+ { RPC_SUCCESS, RPC_SUCCESS_IDX },
+ { RPC_CANTENCODEARGS, RPC_CANTENCODEARGS_IDX },
+ { RPC_CANTDECODERES, RPC_CANTDECODERES_IDX },
+ { RPC_CANTSEND, RPC_CANTSEND_IDX },
+ { RPC_CANTRECV, RPC_CANTRECV_IDX },
+ { RPC_TIMEDOUT, RPC_TIMEDOUT_IDX },
+ { RPC_VERSMISMATCH, RPC_VERSMISMATCH_IDX },
+ { RPC_AUTHERROR, RPC_AUTHERROR_IDX },
+ { RPC_PROGUNAVAIL, RPC_PROGUNAVAIL_IDX },
+ { RPC_PROGVERSMISMATCH, RPC_PROGVERSMISMATCH_IDX },
+ { RPC_PROCUNAVAIL, RPC_PROCUNAVAIL_IDX },
+ { RPC_CANTDECODEARGS, RPC_CANTDECODEARGS_IDX },
+ { RPC_SYSTEMERROR, RPC_SYSTEMERROR_IDX },
+ { RPC_UNKNOWNHOST, RPC_UNKNOWNHOST_IDX },
+ { RPC_UNKNOWNPROTO, RPC_UNKNOWNPROTO_IDX },
+ { RPC_PMAPFAILURE, RPC_PMAPFAILURE_IDX },
+ { RPC_PROGNOTREGISTERED, RPC_PROGNOTREGISTERED_IDX },
+ { RPC_FAILED, RPC_FAILED_IDX }
+};
+
+
+/*
+ * This interface for use by clntrpc
+ */
+char *
+clnt_sperrno (enum clnt_stat stat)
+{
+ size_t i;
+
+ for (i = 0; i < sizeof (rpc_errlist) / sizeof (struct rpc_errtab); i++)
+ {
+ if (rpc_errlist[i].status == stat)
+ {
+ return _(rpc_errstr + rpc_errlist[i].message_off);
+ }
+ }
+ return _("RPC: (unknown error code)");
+}
+libc_hidden_def (clnt_sperrno)
+
+void
+clnt_perrno (enum clnt_stat num)
+{
+ (void) __fxprintf (NULL, "%s", clnt_sperrno (num));
+}
+#ifdef EXPORT_RPC_SYMBOLS
+libc_hidden_def (clnt_perrno)
+#else
+libc_hidden_nolink_sunrpc (clnt_perrno, GLIBC_2_0)
+#endif
+
+char *
+clnt_spcreateerror (const char *msg)
+{
+ struct rpc_createerr *ce = &get_rpc_createerr ();
+
+ char chrbuf[1024];
+ const char *connector = "";
+ const char *errstr = "";
+ switch (ce->cf_stat)
+ {
+ case RPC_PMAPFAILURE:
+ connector = " - ";
+ errstr = clnt_sperrno (ce->cf_error.re_status);
+ break;
+
+ case RPC_SYSTEMERROR:
+ connector = " - ";
+ errstr = __strerror_r (ce->cf_error.re_errno, chrbuf, sizeof chrbuf);
+ break;
+
+ default:
+ break;
+ }
+
+ char *str;
+ if (__asprintf (&str, "%s: %s%s%s\n",
+ msg, clnt_sperrno (ce->cf_stat), connector, errstr) < 0)
+ return NULL;
+
+ char *oldbuf = buf;
+ buf = str;
+ free (oldbuf);
+
+ return str;
+}
+libc_hidden_nolink_sunrpc (clnt_spcreateerror, GLIBC_2_0)
+
+void
+clnt_pcreateerror (const char *msg)
+{
+ (void) __fxprintf (NULL, "%s", clnt_spcreateerror (msg));
+}
+#ifdef EXPORT_RPC_SYMBOLS
+libc_hidden_def (clnt_pcreateerror)
+#else
+libc_hidden_nolink_sunrpc (clnt_pcreateerror, GLIBC_2_0)
+#endif
+
+struct auth_errtab
+{
+ enum auth_stat status;
+ unsigned int message_off;
+};
+
+static const char auth_errstr[] =
+{
+#define AUTH_OK_IDX 0
+ N_("Authentication OK")
+ "\0"
+#define AUTH_BADCRED_IDX (AUTH_OK_IDX + sizeof "Authentication OK")
+ N_("Invalid client credential")
+ "\0"
+#define AUTH_REJECTEDCRED_IDX (AUTH_BADCRED_IDX \
+ + sizeof "Invalid client credential")
+ N_("Server rejected credential")
+ "\0"
+#define AUTH_BADVERF_IDX (AUTH_REJECTEDCRED_IDX \
+ + sizeof "Server rejected credential")
+ N_("Invalid client verifier")
+ "\0"
+#define AUTH_REJECTEDVERF_IDX (AUTH_BADVERF_IDX \
+ + sizeof "Invalid client verifier")
+ N_("Server rejected verifier")
+ "\0"
+#define AUTH_TOOWEAK_IDX (AUTH_REJECTEDVERF_IDX \
+ + sizeof "Server rejected verifier")
+ N_("Client credential too weak")
+ "\0"
+#define AUTH_INVALIDRESP_IDX (AUTH_TOOWEAK_IDX \
+ + sizeof "Client credential too weak")
+ N_("Invalid server verifier")
+ "\0"
+#define AUTH_FAILED_IDX (AUTH_INVALIDRESP_IDX \
+ + sizeof "Invalid server verifier")
+ N_("Failed (unspecified error)")
+};
+
+static const struct auth_errtab auth_errlist[] =
+{
+ { AUTH_OK, AUTH_OK_IDX },
+ { AUTH_BADCRED, AUTH_BADCRED_IDX },
+ { AUTH_REJECTEDCRED, AUTH_REJECTEDCRED_IDX },
+ { AUTH_BADVERF, AUTH_BADVERF_IDX },
+ { AUTH_REJECTEDVERF, AUTH_REJECTEDVERF_IDX },
+ { AUTH_TOOWEAK, AUTH_TOOWEAK_IDX },
+ { AUTH_INVALIDRESP, AUTH_INVALIDRESP_IDX },
+ { AUTH_FAILED, AUTH_FAILED_IDX }
+};
+
+static char *
+internal_function
+auth_errmsg (enum auth_stat stat)
+{
+ size_t i;
+
+ for (i = 0; i < sizeof (auth_errlist) / sizeof (struct auth_errtab); i++)
+ {
+ if (auth_errlist[i].status == stat)
+ {
+ return _(auth_errstr + auth_errlist[i].message_off);
+ }
+ }
+ return NULL;
+}
+
+
+int libc_freeres_fn (void *free_mem)
+{
+ /* Not libc_freeres_ptr, since buf is a macro. */
+ free (buf);
+ return 0;
+}
diff --git a/sunrpc/clnt_raw.c b/sunrpc/clnt_raw.c
new file mode 100644
index 0000000..ba7abe0
--- /dev/null
+++ b/sunrpc/clnt_raw.c
@@ -0,0 +1,251 @@
+/*
+ * clnt_raw.c
+ *
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Memory based rpc for simple testing and timing.
+ * Interface to create an rpc client and server in the same process.
+ * This lets us simulate rpc and get round trip overhead, without
+ * any interference from the kernel.
+ */
+
+#include <rpc/rpc.h>
+#include <rpc/svc.h>
+#include <rpc/xdr.h>
+#ifndef SYLIXOS
+#include <libintl.h>
+#endif
+
+#define MCALL_MSG_SIZE 24
+
+/*
+ * This is the "network" we will be moving stuff over.
+ */
+struct clntraw_private_s
+ {
+ CLIENT client_object;
+ XDR xdr_stream;
+ char _raw_buf[UDPMSGSIZE];
+ union
+ {
+ char msg[MCALL_MSG_SIZE];
+ u_long rm_xid;
+ } mashl_callmsg;
+ u_int mcnt;
+ };
+#ifdef _RPC_THREAD_SAFE_
+#define clntraw_private RPC_THREAD_VARIABLE(clntraw_private_s)
+#else
+static struct clntraw_private_s *clntraw_private;
+#endif
+
+static enum clnt_stat clntraw_call (CLIENT *, u_long, xdrproc_t, caddr_t,
+ xdrproc_t, caddr_t, struct timeval);
+static void clntraw_abort (void);
+static void clntraw_geterr (CLIENT *, struct rpc_err *);
+static bool_t clntraw_freeres (CLIENT *, xdrproc_t, caddr_t);
+static bool_t clntraw_control (CLIENT *, int, char *);
+static void clntraw_destroy (CLIENT *);
+
+static const 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 clntraw_private_s *clp = clntraw_private;
+ struct rpc_msg call_msg;
+ XDR *xdrs;
+ CLIENT *client;
+
+ if (clp == 0)
+ {
+ clp = (struct clntraw_private_s *) calloc (1, sizeof (*clp));
+ if (clp == 0)
+ return (0);
+ clntraw_private = clp;
+ }
+ xdrs = &clp->xdr_stream;
+ client = &clp->client_object;
+ /*
+ * 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->mashl_callmsg.msg, 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 = (struct clnt_ops *) &client_ops;
+ client->cl_auth = authnone_create ();
+ return client;
+}
+libc_hidden_nolink_sunrpc (clntraw_create, GLIBC_2_0)
+
+static enum clnt_stat
+clntraw_call (CLIENT *h, u_long proc, xdrproc_t xargs, caddr_t argsp,
+ xdrproc_t xresults, caddr_t resultsp, struct timeval timeout)
+{
+ struct clntraw_private_s *clp = clntraw_private;
+ XDR *xdrs = &clp->xdr_stream;
+ struct rpc_msg msg;
+ enum clnt_stat status;
+ struct rpc_err error;
+
+ if (clp == NULL)
+ return RPC_FAILED;
+call_again:
+ /*
+ * send request
+ */
+ xdrs->x_op = XDR_ENCODE;
+ XDR_SETPOS (xdrs, 0);
+ /* Just checking the union definition to access rm_xid is correct. */
+ if (offsetof (struct rpc_msg, rm_xid) != 0)
+ abort ();
+ clp->mashl_callmsg.rm_xid++;
+ if ((!XDR_PUTBYTES (xdrs, clp->mashl_callmsg.msg, clp->mcnt)) ||
+ (!XDR_PUTLONG (xdrs, (long *) &proc)) ||
+ (!AUTH_MARSHALL (h->cl_auth, xdrs)) ||
+ (!(*xargs) (xdrs, argsp, 0)))
+ {
+ 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, caddr_t res_ptr)
+{
+ struct clntraw_private_s *clp = clntraw_private;
+ XDR *xdrs = &clp->xdr_stream;
+ bool_t rval;
+
+ if (clp == NULL)
+ {
+ rval = (bool_t) RPC_FAILED;
+ return rval;
+ }
+ xdrs->x_op = XDR_FREE;
+ return (*xdr_res) (xdrs, res_ptr, 0);
+}
+
+static void
+clntraw_abort (void)
+{
+}
+
+static bool_t
+clntraw_control (CLIENT *cl, int i, char *c)
+{
+ return FALSE;
+}
+
+static void
+clntraw_destroy (CLIENT *cl)
+{
+}
diff --git a/sunrpc/clnt_simp.c b/sunrpc/clnt_simp.c
new file mode 100644
index 0000000..d612df0
--- /dev/null
+++ b/sunrpc/clnt_simp.c
@@ -0,0 +1,156 @@
+/*
+ * clnt_simple.c
+ * Simplified front end to rpc.
+ *
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <alloca.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <string.h>
+
+struct callrpc_private_s
+ {
+ CLIENT *client;
+ int socket;
+ u_long oldprognum, oldversnum, valid;
+ char *oldhost;
+ };
+#ifdef _RPC_THREAD_SAFE_
+#define callrpc_private RPC_THREAD_VARIABLE(callrpc_private_s)
+#else
+static struct callrpc_private_s *callrpc_private;
+#endif
+
+int
+callrpc (const char *host, u_long prognum, u_long versnum, u_long procnum,
+ xdrproc_t inproc, const char *in, xdrproc_t outproc, char *out)
+{
+ struct callrpc_private_s *crp = callrpc_private;
+ struct sockaddr_in server_addr;
+ enum clnt_stat clnt_stat;
+ struct hostent hostbuf, *hp;
+ struct timeval timeout, tottimeout;
+
+ if (crp == 0)
+ {
+ crp = (struct callrpc_private_s *) calloc (1, sizeof (*crp));
+ if (crp == 0)
+ return 0;
+ callrpc_private = crp;
+ }
+ if (crp->oldhost == NULL)
+ {
+ crp->oldhost = malloc (256);
+ 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
+ {
+ size_t buflen;
+ char *buffer;
+ int herr;
+
+ crp->valid = 0;
+ if (crp->socket != RPC_ANYSOCK)
+ {
+ (void) __close (crp->socket);
+ crp->socket = RPC_ANYSOCK;
+ }
+ if (crp->client)
+ {
+ clnt_destroy (crp->client);
+ crp->client = NULL;
+ }
+
+ buflen = 1024;
+ buffer = __alloca (buflen);
+ while (__gethostbyname_r (host, &hostbuf, buffer, buflen,
+ &hp, &herr) != 0
+ || hp == NULL)
+ if (herr != NETDB_INTERNAL || errno != ERANGE)
+ return (int) RPC_UNKNOWNHOST;
+ else
+ {
+ /* Enlarge the buffer. */
+ buflen *= 2;
+ buffer = __alloca (buflen);
+ }
+
+ timeout.tv_usec = 0;
+ timeout.tv_sec = 5;
+ memcpy ((char *) &server_addr.sin_addr, hp->h_addr, hp->h_length);
+ 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) get_rpc_createerr().cf_stat;
+ crp->valid = 1;
+ crp->oldprognum = prognum;
+ crp->oldversnum = versnum;
+ (void) strncpy (crp->oldhost, host, 255);
+ crp->oldhost[255] = '\0';
+ }
+ tottimeout.tv_sec = 25;
+ tottimeout.tv_usec = 0;
+ clnt_stat = clnt_call (crp->client, procnum, inproc, (char *) in,
+ outproc, out, tottimeout);
+ /*
+ * if call failed, empty cache
+ */
+ if (clnt_stat != RPC_SUCCESS)
+ crp->valid = 0;
+ return (int) clnt_stat;
+}
+libc_hidden_nolink_sunrpc (callrpc, GLIBC_2_0)
+
+#ifdef _RPC_THREAD_SAFE_
+void
+__rpc_thread_clnt_cleanup (void)
+{
+ struct callrpc_private_s *rcp = RPC_THREAD_VARIABLE(callrpc_private_s);
+
+ if (rcp) {
+ if (rcp->client)
+ CLNT_DESTROY (rcp->client);
+ free (rcp);
+ }
+}
+#endif /* _RPC_THREAD_SAFE_ */
diff --git a/sunrpc/clnt_tcp.c b/sunrpc/clnt_tcp.c
new file mode 100644
index 0000000..bca0d10
--- /dev/null
+++ b/sunrpc/clnt_tcp.c
@@ -0,0 +1,531 @@
+/*
+ * clnt_tcp.c, Implements a TCP/IP based, client side RPC.
+ *
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.
+ */
+
+#include <netdb.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#ifndef SYLIXOS
+#include <libintl.h>
+#endif
+#include <rpc/rpc.h>
+#include <sys/poll.h>
+#include <sys/socket.h>
+#include <rpc/pmap_clnt.h>
+#include <wchar.h>
+
+extern u_long _create_xid (void);
+
+#define MCALL_MSG_SIZE 24
+
+struct ct_data
+ {
+ int ct_sock;
+ bool_t ct_closeit;
+ struct timeval ct_wait;
+ bool_t ct_waitset; /* wait set by clnt_control? */
+ struct sockaddr_in ct_addr;
+ struct rpc_err ct_error;
+ char ct_mcall[MCALL_MSG_SIZE]; /* marshalled callmsg */
+ u_int ct_mpos; /* pos after marshal */
+ XDR ct_xdrs;
+ };
+
+static int readtcp (char *, char *, int);
+static int writetcp (char *, char *, int);
+
+static enum clnt_stat clnttcp_call (CLIENT *, u_long, xdrproc_t, caddr_t,
+ xdrproc_t, caddr_t, struct timeval);
+static void clnttcp_abort (void);
+static void clnttcp_geterr (CLIENT *, struct rpc_err *);
+static bool_t clnttcp_freeres (CLIENT *, xdrproc_t, caddr_t);
+static bool_t clnttcp_control (CLIENT *, int, char *);
+static void clnttcp_destroy (CLIENT *);
+
+static const struct clnt_ops tcp_ops =
+{
+ clnttcp_call,
+ clnttcp_abort,
+ clnttcp_geterr,
+ clnttcp_freeres,
+ clnttcp_destroy,
+ clnttcp_control
+};
+
+/*
+ * 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, u_long vers,
+ int *sockp, u_int sendsz, u_int recvsz)
+{
+ CLIENT *h;
+ struct ct_data *ct;
+ struct rpc_msg call_msg;
+
+ h = (CLIENT *) mem_alloc (sizeof (*h));
+ ct = (struct ct_data *) mem_alloc (sizeof (*ct));
+ if (h == NULL || ct == NULL)
+ {
+ struct rpc_createerr *ce = &get_rpc_createerr ();
+ (void) __fxprintf (NULL, "%s: %s", __func__, _("out of memory\n"));
+ ce->cf_stat = RPC_SYSTEMERROR;
+ ce->cf_error.re_errno = ENOMEM;
+ 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))
+ {
+ struct rpc_createerr *ce = &get_rpc_createerr ();
+ ce->cf_stat = RPC_SYSTEMERROR;
+ ce->cf_error.re_errno = errno;
+ if (*sockp >= 0)
+ (void) __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
+ */
+ call_msg.rm_xid = _create_xid ();
+ 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_mcall, MCALL_MSG_SIZE, XDR_ENCODE);
+ if (!xdr_callhdr (&(ct->ct_xdrs), &call_msg))
+ {
+ if (ct->ct_closeit)
+ {
+ (void) __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 = (struct clnt_ops *) &tcp_ops;
+ h->cl_private = (caddr_t) ct;
+ h->cl_auth = authnone_create ();
+ return h;
+
+fooy:
+ /*
+ * Something goofed, free stuff and barf
+ */
+ mem_free ((caddr_t) ct, sizeof (struct ct_data));
+ mem_free ((caddr_t) h, sizeof (CLIENT));
+ return ((CLIENT *) NULL);
+}
+#ifdef EXPORT_RPC_SYMBOLS
+libc_hidden_def (clnttcp_create)
+#else
+libc_hidden_nolink_sunrpc (clnttcp_create, GLIBC_2_0)
+#endif
+
+static enum clnt_stat
+clnttcp_call (CLIENT *h, u_long proc, xdrproc_t xdr_args, caddr_t args_ptr,
+ xdrproc_t xdr_results, caddr_t 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_long x_id;
+ u_int32_t *msg_x_id = (u_int32_t *) (ct->ct_mcall); /* yuk */
+ bool_t shipnow;
+ int refreshes = 2;
+
+ if (!ct->ct_waitset)
+ {
+ ct->ct_wait = timeout;
+ }
+
+ shipnow =
+ (xdr_results == (xdrproc_t) 0 && ct->ct_wait.tv_sec == 0
+ && ct->ct_wait.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_mcall, ct->ct_mpos)) ||
+ (!XDR_PUTLONG (xdrs, (long *) &proc)) ||
+ (!AUTH_MARSHALL (h->cl_auth, xdrs)) ||
+ (!(*xdr_args) (xdrs, args_ptr, 0)))
+ {
+ 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 (ct->ct_wait.tv_sec == 0 && ct->ct_wait.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 ((u_int32_t) reply_msg.rm_xid == (u_int32_t) 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, 0))
+ {
+ 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 =
+ (struct ct_data *) h->cl_private;
+
+ *errp = ct->ct_error;
+}
+
+static bool_t
+clnttcp_freeres (CLIENT *cl, xdrproc_t xdr_res, caddr_t res_ptr)
+{
+ struct ct_data *ct = (struct ct_data *) cl->cl_private;
+ XDR *xdrs = &(ct->ct_xdrs);
+
+ xdrs->x_op = XDR_FREE;
+ return (*xdr_res) (xdrs, res_ptr, 0);
+}
+
+static void
+clnttcp_abort (void)
+{
+}
+
+static bool_t
+clnttcp_control (CLIENT *cl, int request, char *info)
+{
+ struct ct_data *ct = (struct ct_data *) cl->cl_private;
+ u_long ul;
+ u_int32_t ui32;
+
+
+ switch (request)
+ {
+ case CLSET_FD_CLOSE:
+ ct->ct_closeit = TRUE;
+ break;
+ case CLSET_FD_NCLOSE:
+ ct->ct_closeit = FALSE;
+ break;
+ case CLSET_TIMEOUT:
+ ct->ct_wait = *(struct timeval *) info;
+ ct->ct_waitset = TRUE;
+ break;
+ case CLGET_TIMEOUT:
+ *(struct timeval *) info = ct->ct_wait;
+ break;
+ case CLGET_SERVER_ADDR:
+ *(struct sockaddr_in *) info = ct->ct_addr;
+ break;
+ case CLGET_FD:
+ *(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
+ */
+ memcpy (&ui32, ct->ct_mcall, sizeof (ui32));
+ ul = ntohl (ui32);
+ memcpy (info, &ul, sizeof (ul));
+ break;
+ case CLSET_XID:
+ /* This will set the xid of the NEXT call */
+ memcpy (&ul, info, sizeof (ul));
+ ui32 = htonl (ul - 1);
+ memcpy (ct->ct_mcall, &ui32, sizeof (ui32));
+ /* decrement by 1 as clnttcp_call() increments once */
+ break;
+ case CLGET_VERS:
+ /*
+ * This RELIES on the information that, in the call body,
+ * the version number field is the fifth field from the
+ * beginning of the RPC header. MUST be changed if the
+ * call_struct is changed
+ */
+ memcpy (&ui32, ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT, sizeof (ui32));
+ ul = ntohl (ui32);
+ memcpy (info, &ul, sizeof (ul));
+ break;
+ case CLSET_VERS:
+ memcpy (&ul, info, sizeof (ul));
+ ui32 = htonl (ul);
+ memcpy (ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT, &ui32, sizeof (ui32));
+ break;
+ case CLGET_PROG:
+ /*
+ * This RELIES on the information that, in the call body,
+ * the program number field is the field from the
+ * beginning of the RPC header. MUST be changed if the
+ * call_struct is changed
+ */
+ memcpy (&ui32, ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT, sizeof (ui32));
+ ul = ntohl (ui32);
+ memcpy (info, &ul, sizeof (ul));
+ break;
+ case CLSET_PROG:
+ memcpy (&ul, info, sizeof (ul));
+ ui32 = htonl (ul);
+ memcpy (ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT, &ui32, sizeof (ui32));
+ break;
+ /* The following are only possible with TI-RPC */
+ 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) __close (ct->ct_sock);
+ }
+ XDR_DESTROY (&(ct->ct_xdrs));
+ mem_free ((caddr_t) ct, sizeof (struct ct_data));
+ mem_free ((caddr_t) 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 *ctptr, char *buf, int len)
+{
+ struct ct_data *ct = (struct ct_data *)ctptr;
+ struct pollfd fd;
+ int milliseconds = (ct->ct_wait.tv_sec * 1000) +
+ (ct->ct_wait.tv_usec / 1000);
+
+ if (len == 0)
+ return 0;
+
+ fd.fd = ct->ct_sock;
+ fd.events = POLLIN;
+ while (TRUE)
+ {
+ switch (__poll(&fd, 1, milliseconds))
+ {
+ case 0:
+ ct->ct_error.re_status = RPC_TIMEDOUT;
+ return -1;
+
+ case -1:
+ if (errno == EINTR)
+ continue;
+ ct->ct_error.re_status = RPC_CANTRECV;
+ ct->ct_error.re_errno = errno;
+ return -1;
+ }
+ break;
+ }
+ switch (len = __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 *ctptr, char *buf, int len)
+{
+ int i, cnt;
+ struct ct_data *ct = (struct ct_data*)ctptr;
+
+ for (cnt = len; cnt > 0; cnt -= i, buf += i)
+ {
+ if ((i = __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/sunrpc/clnt_udp.c b/sunrpc/clnt_udp.c
new file mode 100644
index 0000000..2d68c73
--- /dev/null
+++ b/sunrpc/clnt_udp.c
@@ -0,0 +1,632 @@
+/*
+ * clnt_udp.c, Implements a UDP/IP based, client side RPC.
+ *
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#ifndef SYLIXOS
+#include <libintl.h>
+#endif
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpc/clnt.h>
+#include <sys/poll.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <netdb.h>
+#include <errno.h>
+#include <stdint.h>
+#include <rpc/pmap_clnt.h>
+#include <net/if.h>
+#include <ifaddrs.h>
+#include <wchar.h>
+#include <fcntl.h>
+
+#ifdef IP_RECVERR
+#include <errqueue.h>
+#include <sys/uio.h>
+#endif
+
+#ifndef SYLIXOS
+#include <kernel-features.h>
+#endif
+
+extern u_long _create_xid (void);
+
+/*
+ * UDP bases client side rpc operations
+ */
+static enum clnt_stat clntudp_call (CLIENT *, u_long, xdrproc_t, caddr_t,
+ xdrproc_t, caddr_t, struct timeval);
+static void clntudp_abort (void);
+static void clntudp_geterr (CLIENT *, struct rpc_err *);
+static bool_t clntudp_freeres (CLIENT *, xdrproc_t, caddr_t);
+static bool_t clntudp_control (CLIENT *, int, char *);
+static void clntudp_destroy (CLIENT *);
+
+static const 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;
+ struct sockaddr_in cu_raddr;
+ int cu_rlen;
+ struct timeval cu_wait;
+ struct timeval cu_total;
+ struct rpc_err cu_error;
+ XDR cu_outxdrs;
+ u_int cu_xdrpos;
+ u_int cu_sendsz;
+ char *cu_outbuf;
+ u_int cu_recvsz;
+ char cu_inbuf[1];
+ };
+
+/*
+ * 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; retransmission occurs until the actual
+ * rpc call times out.
+ *
+ * sendsz and recvsz are the maximum allowable packet sizes that can be
+ * sent and received.
+ */
+CLIENT *
+__libc_clntudp_bufcreate (struct sockaddr_in *raddr, u_long program,
+ u_long version, struct timeval wait, int *sockp,
+ u_int sendsz, u_int recvsz, int flags)
+{
+ CLIENT *cl;
+ struct cu_data *cu = NULL;
+ struct rpc_msg call_msg;
+
+ cl = (CLIENT *) mem_alloc (sizeof (CLIENT));
+ sendsz = ((sendsz + 3) / 4) * 4;
+ recvsz = ((recvsz + 3) / 4) * 4;
+ cu = (struct cu_data *) mem_alloc (sizeof (*cu) + sendsz + recvsz);
+ if (cl == NULL || cu == NULL)
+ {
+ struct rpc_createerr *ce = &get_rpc_createerr ();
+ (void) __fxprintf (NULL, "%s: %s",
+ "clntudp_create", _("out of memory\n"));
+ ce->cf_stat = RPC_SYSTEMERROR;
+ ce->cf_error.re_errno = ENOMEM;
+ goto fooy;
+ }
+ cu->cu_outbuf = &cu->cu_inbuf[recvsz];
+
+ 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 = (struct clnt_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 = _create_xid ();
+ 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)
+ {
+ *sockp = __socket (AF_INET, SOCK_DGRAM|SOCK_NONBLOCK|flags, IPPROTO_UDP);
+ if (__glibc_unlikely (*sockp < 0))
+ {
+ struct rpc_createerr *ce = &get_rpc_createerr ();
+ ce->cf_stat = RPC_SYSTEMERROR;
+ ce->cf_error.re_errno = errno;
+ goto fooy;
+ }
+ /* attempt to bind to prov port */
+ (void) bindresvport (*sockp, (struct sockaddr_in *) 0);
+#ifdef IP_RECVERR
+ {
+ int on = 1;
+ __setsockopt (*sockp, SOL_IP, IP_RECVERR, &on, sizeof(on));
+ }
+#endif
+ 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;
+}
+#ifdef EXPORT_RPC_SYMBOLS
+libc_hidden_def (__libc_clntudp_bufcreate)
+#else
+libc_hidden_nolink_sunrpc (__libc_clntudp_bufcreate, GLIBC_PRIVATE)
+#endif
+
+CLIENT *
+clntudp_bufcreate (struct sockaddr_in *raddr, u_long program, u_long version,
+ struct timeval wait, int *sockp, u_int sendsz,
+ u_int recvsz)
+{
+ return __libc_clntudp_bufcreate (raddr, program, version, wait,
+ sockp, sendsz, recvsz, 0);
+}
+libc_hidden_nolink_sunrpc (clntudp_bufcreate, GLIBC_2_0)
+
+CLIENT *
+clntudp_create (struct sockaddr_in *raddr, u_long program, u_long version,
+ struct timeval wait, int *sockp)
+{
+ return __libc_clntudp_bufcreate (raddr, program, version, wait,
+ sockp, UDPMSGSIZE, UDPMSGSIZE, 0);
+}
+#ifdef EXPORT_RPC_SYMBOLS
+libc_hidden_def (clntudp_create)
+#else
+libc_hidden_nolink_sunrpc (clntudp_create, GLIBC_2_0)
+#endif
+
+static int
+is_network_up (int sock)
+{
+ struct ifaddrs *ifa;
+
+ if (getifaddrs (&ifa) != 0)
+ return 0;
+
+ struct ifaddrs *run = ifa;
+ while (run != NULL)
+ {
+ if ((run->ifa_flags & IFF_UP) != 0
+ && run->ifa_addr != NULL
+ && run->ifa_addr->sa_family == AF_INET)
+ break;
+
+ run = run->ifa_next;
+ }
+
+ freeifaddrs (ifa);
+
+ return run != NULL;
+}
+
+static enum clnt_stat
+clntudp_call (/* client handle */
+ CLIENT *cl,
+ /* procedure number */
+ u_long proc,
+ /* xdr routine for args */
+ xdrproc_t xargs,
+ /* pointer to args */
+ caddr_t argsp,
+ /* xdr routine for results */
+ xdrproc_t xresults,
+ /* pointer to results */
+ caddr_t resultsp,
+ /* seconds to wait before giving up */
+ struct timeval utimeout)
+{
+ struct cu_data *cu = (struct cu_data *) cl->cl_private;
+ XDR *xdrs;
+ int outlen = 0;
+ int inlen;
+ socklen_t fromlen;
+ struct pollfd fd;
+ int milliseconds = (cu->cu_wait.tv_sec * 1000) +
+ (cu->cu_wait.tv_usec / 1000);
+ struct sockaddr_in from;
+ struct rpc_msg reply_msg;
+ XDR reply_xdrs;
+ struct timeval time_waited;
+ bool_t ok;
+ int nrefreshes = 2; /* number of times to refresh cred */
+ struct timeval timeout;
+ int anyup; /* any network interface up */
+
+ if (cu->cu_total.tv_usec == -1)
+ {
+ timeout = utimeout; /* use supplied timeout */
+ }
+ else
+ {
+ timeout = cu->cu_total; /* use default timeout */
+ }
+
+ time_waited.tv_sec = 0;
+ time_waited.tv_usec = 0;
+call_again:
+ xdrs = &(cu->cu_outxdrs);
+ if (xargs == NULL)
+ goto get_reply;
+ xdrs->x_op = XDR_ENCODE;
+ XDR_SETPOS (xdrs, cu->cu_xdrpos);
+ /*
+ * the transaction is the first thing in the out buffer
+ */
+ (*(uint32_t *) (cu->cu_outbuf))++;
+ if ((!XDR_PUTLONG (xdrs, (long *) &proc)) ||
+ (!AUTH_MARSHALL (cl->cl_auth, xdrs)) ||
+ (!(*xargs) (xdrs, argsp, 0)))
+ return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
+ outlen = (int) 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;
+ return (cu->cu_error.re_status = RPC_CANTSEND);
+ }
+
+ /*
+ * Hack to provide rpc-based message passing
+ */
+ if (timeout.tv_sec == 0 && timeout.tv_usec == 0)
+ {
+ return (cu->cu_error.re_status = RPC_TIMEDOUT);
+ }
+ get_reply:
+ /*
+ * 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;
+ fd.fd = cu->cu_sock;
+ fd.events = POLLIN;
+ anyup = 0;
+ for (;;)
+ {
+ switch (__poll (&fd, 1, milliseconds))
+ {
+
+ case 0:
+ if (anyup == 0)
+ {
+ anyup = is_network_up (cu->cu_sock);
+ if (!anyup)
+ return (cu->cu_error.re_status = RPC_CANTRECV);
+ }
+
+ time_waited.tv_sec += cu->cu_wait.tv_sec;
+ time_waited.tv_usec += cu->cu_wait.tv_usec;
+ while (time_waited.tv_usec >= 1000000)
+ {
+ time_waited.tv_sec++;
+ time_waited.tv_usec -= 1000000;
+ }
+ if ((time_waited.tv_sec < timeout.tv_sec) ||
+ ((time_waited.tv_sec == timeout.tv_sec) &&
+ (time_waited.tv_usec < timeout.tv_usec)))
+ goto send_again;
+ return (cu->cu_error.re_status = RPC_TIMEDOUT);
+
+ /*
+ * buggy in other cases because time_waited is not being
+ * updated.
+ */
+ case -1:
+ if (errno == EINTR)
+ continue;
+ cu->cu_error.re_errno = errno;
+ return (cu->cu_error.re_status = RPC_CANTRECV);
+ }
+#ifdef IP_RECVERR
+ if (fd.revents & POLLERR)
+ {
+ struct msghdr msg;
+ struct cmsghdr *cmsg;
+ struct sock_extended_err *e;
+ struct sockaddr_in err_addr;
+ struct iovec iov;
+ char *cbuf = malloc (outlen + 256);
+ int ret;
+
+ if (cbuf == NULL)
+ {
+ cu->cu_error.re_errno = errno;
+ return (cu->cu_error.re_status = RPC_CANTRECV);
+ }
+
+ iov.iov_base = cbuf + 256;
+ iov.iov_len = outlen;
+ msg.msg_name = (void *) &err_addr;
+ msg.msg_namelen = sizeof (err_addr);
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_flags = 0;
+ msg.msg_control = cbuf;
+ msg.msg_controllen = 256;
+ ret = __recvmsg (cu->cu_sock, &msg, MSG_ERRQUEUE);
+ if (ret >= 0
+ && memcmp (cbuf + 256, cu->cu_outbuf, ret) == 0
+ && (msg.msg_flags & MSG_ERRQUEUE)
+ && ((msg.msg_namelen == 0
+ && ret >= 12)
+ || (msg.msg_namelen == sizeof (err_addr)
+ && err_addr.sin_family == AF_INET
+ && memcmp (&err_addr.sin_addr, &cu->cu_raddr.sin_addr,
+ sizeof (err_addr.sin_addr)) == 0
+ && err_addr.sin_port == cu->cu_raddr.sin_port)))
+ for (cmsg = CMSG_FIRSTHDR (&msg); cmsg;
+ cmsg = CMSG_NXTHDR (&msg, cmsg))
+ if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_RECVERR)
+ {
+ free (cbuf);
+ e = (struct sock_extended_err *) CMSG_DATA(cmsg);
+ cu->cu_error.re_errno = e->ee_errno;
+ return (cu->cu_error.re_status = RPC_CANTRECV);
+ }
+ free (cbuf);
+ }
+#endif
+ do
+ {
+ fromlen = sizeof (struct sockaddr);
+ inlen = __recvfrom (cu->cu_sock, cu->cu_inbuf,
+ (int) cu->cu_recvsz, MSG_DONTWAIT,
+ (struct sockaddr *) &from, &fromlen);
+ }
+ while (inlen < 0 && errno == EINTR);
+ if (inlen < 0)
+ {
+ if (errno == EWOULDBLOCK)
+ continue;
+ cu->cu_error.re_errno = errno;
+ return (cu->cu_error.re_status = RPC_CANTRECV);
+ }
+ if (inlen < 4)
+ continue;
+
+ /* see if reply transaction id matches sent id.
+ Don't do this if we only wait for a replay */
+ if (xargs != NULL
+ && memcmp (cu->cu_inbuf, cu->cu_outbuf, sizeof (u_int32_t)) != 0)
+ 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
+ {
+ cu->cu_error.re_status = RPC_CANTDECODERES;
+ }
+ 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, caddr_t 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, 0);
+}
+
+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;
+ u_long ul;
+ u_int32_t ui32;
+
+ switch (request)
+ {
+ case CLSET_FD_CLOSE:
+ cu->cu_closeit = TRUE;
+ break;
+ case CLSET_FD_NCLOSE:
+ cu->cu_closeit = FALSE;
+ break;
+ case CLSET_TIMEOUT:
+ cu->cu_total = *(struct timeval *) info;
+ break;
+ case CLGET_TIMEOUT:
+ *(struct timeval *) info = cu->cu_total;
+ break;
+ case CLSET_RETRY_TIMEOUT:
+ cu->cu_wait = *(struct timeval *) info;
+ break;
+ case CLGET_RETRY_TIMEOUT:
+ *(struct timeval *) info = cu->cu_wait;
+ break;
+ case CLGET_SERVER_ADDR:
+ *(struct sockaddr_in *) info = cu->cu_raddr;
+ break;
+ case CLGET_FD:
+ *(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
+ */
+ memcpy (&ui32, cu->cu_outbuf, sizeof (ui32));
+ ul = ntohl (ui32);
+ memcpy (info, &ul, sizeof (ul));
+ break;
+ case CLSET_XID:
+ /* This will set the xid of the NEXT call */
+ memcpy (&ul, info, sizeof (ul));
+ ui32 = htonl (ul - 1);
+ memcpy (cu->cu_outbuf, &ui32, sizeof (ui32));
+ /* decrement by 1 as clntudp_call() increments once */
+ break;
+ case CLGET_VERS:
+ /*
+ * This RELIES on the information that, in the call body,
+ * the version number field is the fifth field from the
+ * beginning of the RPC header. MUST be changed if the
+ * call_struct is changed
+ */
+ memcpy (&ui32, cu->cu_outbuf + 4 * BYTES_PER_XDR_UNIT, sizeof (ui32));
+ ul = ntohl (ui32);
+ memcpy (info, &ul, sizeof (ul));
+ break;
+ case CLSET_VERS:
+ memcpy (&ul, info, sizeof (ul));
+ ui32 = htonl (ul);
+ memcpy (cu->cu_outbuf + 4 * BYTES_PER_XDR_UNIT, &ui32, sizeof (ui32));
+ break;
+ case CLGET_PROG:
+ /*
+ * This RELIES on the information that, in the call body,
+ * the program number field is the field from the
+ * beginning of the RPC header. MUST be changed if the
+ * call_struct is changed
+ */
+ memcpy (&ui32, cu->cu_outbuf + 3 * BYTES_PER_XDR_UNIT, sizeof (ui32));
+ ul = ntohl (ui32);
+ memcpy (info, &ul, sizeof (ul));
+ break;
+ case CLSET_PROG:
+ memcpy (&ul, info, sizeof (ul));
+ ui32 = htonl (ul);
+ memcpy (cu->cu_outbuf + 3 * BYTES_PER_XDR_UNIT, &ui32, sizeof (ui32));
+ break;
+ /* The following are only possible with TI-RPC */
+ 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) __close (cu->cu_sock);
+ }
+ XDR_DESTROY (&(cu->cu_outxdrs));
+ mem_free ((caddr_t) cu, (sizeof (*cu) + cu->cu_sendsz + cu->cu_recvsz));
+ mem_free ((caddr_t) cl, sizeof (CLIENT));
+}
diff --git a/sunrpc/clnt_unix.c b/sunrpc/clnt_unix.c
new file mode 100644
index 0000000..f553ff7
--- /dev/null
+++ b/sunrpc/clnt_unix.c
@@ -0,0 +1,599 @@
+/*
+ * clnt_unix.c, Implements a TCP/IP based, client side RPC.
+ *
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.
+ */
+
+#include <netdb.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#ifndef SYLIXOS
+#include <libintl.h>
+#endif
+#include <rpc/rpc.h>
+#include <sys/uio.h>
+#include <sys/poll.h>
+#include <sys/socket.h>
+#include <rpc/pmap_clnt.h>
+#include <wchar.h>
+
+extern u_long _create_xid (void);
+
+#define MCALL_MSG_SIZE 24
+
+struct ct_data
+ {
+ int ct_sock;
+ bool_t ct_closeit;
+ struct timeval ct_wait;
+ bool_t ct_waitset; /* wait set by clnt_control? */
+ struct sockaddr_un ct_addr;
+ struct rpc_err ct_error;
+ char ct_mcall[MCALL_MSG_SIZE]; /* marshalled callmsg */
+ u_int ct_mpos; /* pos after marshal */
+ XDR ct_xdrs;
+ };
+
+static int readunix (char *, char *, int);
+static int writeunix (char *, char *, int);
+
+static enum clnt_stat clntunix_call (CLIENT *, u_long, xdrproc_t, caddr_t,
+ xdrproc_t, caddr_t, struct timeval);
+static void clntunix_abort (void);
+static void clntunix_geterr (CLIENT *, struct rpc_err *);
+static bool_t clntunix_freeres (CLIENT *, xdrproc_t, caddr_t);
+static bool_t clntunix_control (CLIENT *, int, char *);
+static void clntunix_destroy (CLIENT *);
+
+static const struct clnt_ops unix_ops =
+{
+ clntunix_call,
+ clntunix_abort,
+ clntunix_geterr,
+ clntunix_freeres,
+ clntunix_destroy,
+ clntunix_control
+};
+
+/*
+ * 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 *
+clntunix_create (struct sockaddr_un *raddr, u_long prog, u_long vers,
+ int *sockp, u_int sendsz, u_int recvsz)
+{
+ CLIENT *h;
+ struct ct_data *ct = (struct ct_data *) mem_alloc (sizeof (*ct));
+ struct rpc_msg call_msg;
+ int len;
+
+ h = (CLIENT *) mem_alloc (sizeof (*h));
+ if (h == NULL || ct == NULL)
+ {
+ struct rpc_createerr *ce = &get_rpc_createerr ();
+ (void) __fxprintf (NULL, "%s: %s", __func__, _("out of memory\n"));
+ ce->cf_stat = RPC_SYSTEMERROR;
+ ce->cf_error.re_errno = ENOMEM;
+ goto fooy;
+ }
+
+ /*
+ * If no socket given, open one
+ */
+ if (*sockp < 0)
+ {
+ *sockp = __socket (AF_UNIX, SOCK_STREAM, 0);
+ len = strlen (raddr->sun_path) + sizeof (raddr->sun_family) + 1;
+ if (*sockp < 0
+ || __connect (*sockp, (struct sockaddr *) raddr, len) < 0)
+ {
+ struct rpc_createerr *ce = &get_rpc_createerr ();
+ ce->cf_stat = RPC_SYSTEMERROR;
+ ce->cf_error.re_errno = errno;
+ if (*sockp != -1)
+ __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
+ */
+ call_msg.rm_xid = _create_xid ();
+ 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_mcall, MCALL_MSG_SIZE, XDR_ENCODE);
+ if (!xdr_callhdr (&(ct->ct_xdrs), &call_msg))
+ {
+ if (ct->ct_closeit)
+ __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, readunix, writeunix);
+ h->cl_ops = (struct clnt_ops *) &unix_ops;
+ h->cl_private = (caddr_t) ct;
+ h->cl_auth = authnone_create ();
+ return h;
+
+fooy:
+ /*
+ * Something goofed, free stuff and barf
+ */
+ mem_free ((caddr_t) ct, sizeof (struct ct_data));
+ mem_free ((caddr_t) h, sizeof (CLIENT));
+ return (CLIENT *) NULL;
+}
+libc_hidden_nolink_sunrpc (clntunix_create, GLIBC_2_1)
+
+static enum clnt_stat
+clntunix_call (CLIENT *h, u_long proc, xdrproc_t xdr_args, caddr_t args_ptr,
+ xdrproc_t xdr_results, caddr_t 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_long x_id;
+ u_int32_t *msg_x_id = (u_int32_t *) (ct->ct_mcall); /* yuk */
+ bool_t shipnow;
+ int refreshes = 2;
+
+ if (!ct->ct_waitset)
+ {
+ ct->ct_wait = timeout;
+ }
+
+ shipnow =
+ (xdr_results == (xdrproc_t) 0 && ct->ct_wait.tv_sec == 0
+ && ct->ct_wait.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_mcall, ct->ct_mpos)) ||
+ (!XDR_PUTLONG (xdrs, (long *) &proc)) ||
+ (!AUTH_MARSHALL (h->cl_auth, xdrs)) ||
+ (!(*xdr_args) (xdrs, args_ptr, 0)))
+ {
+ 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 (ct->ct_wait.tv_sec == 0 && ct->ct_wait.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, 0))
+ {
+ 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
+clntunix_geterr (CLIENT *h, struct rpc_err *errp)
+{
+ struct ct_data *ct = (struct ct_data *) h->cl_private;
+
+ *errp = ct->ct_error;
+}
+
+static bool_t
+clntunix_freeres (CLIENT *cl, xdrproc_t xdr_res, caddr_t res_ptr)
+{
+ struct ct_data *ct = (struct ct_data *) cl->cl_private;
+ XDR *xdrs = &(ct->ct_xdrs);
+
+ xdrs->x_op = XDR_FREE;
+ return (*xdr_res) (xdrs, res_ptr, 0);
+}
+
+static void
+clntunix_abort (void)
+{
+}
+
+static bool_t
+clntunix_control (CLIENT *cl, int request, char *info)
+{
+ struct ct_data *ct = (struct ct_data *) cl->cl_private;
+ u_long ul;
+ u_int32_t ui32;
+
+ switch (request)
+ {
+ case CLSET_FD_CLOSE:
+ ct->ct_closeit = TRUE;
+ break;
+ case CLSET_FD_NCLOSE:
+ ct->ct_closeit = FALSE;
+ break;
+ case CLSET_TIMEOUT:
+ ct->ct_wait = *(struct timeval *) info;
+ break;
+ case CLGET_TIMEOUT:
+ *(struct timeval *) info = ct->ct_wait;
+ break;
+ case CLGET_SERVER_ADDR:
+ *(struct sockaddr_un *) info = ct->ct_addr;
+ break;
+ case CLGET_FD:
+ *(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
+ */
+ memcpy (&ui32, ct->ct_mcall, sizeof (ui32));
+ ul = ntohl (ui32);
+ memcpy (info, &ul, sizeof (ul));
+ break;
+ case CLSET_XID:
+ /* This will set the xid of the NEXT call */
+ memcpy (&ul, info, sizeof (ul));
+ ui32 = htonl (ul - 1);
+ memcpy (ct->ct_mcall, &ui32, sizeof (ui32));
+ /* decrement by 1 as clntunix_call() increments once */
+ break;
+ case CLGET_VERS:
+ /*
+ * This RELIES on the information that, in the call body,
+ * the version number field is the fifth field from the
+ * beginning of the RPC header. MUST be changed if the
+ * call_struct is changed
+ */
+ memcpy (&ui32, ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT, sizeof (ui32));
+ ul = ntohl (ui32);
+ memcpy (info, &ul, sizeof (ul));
+ break;
+ case CLSET_VERS:
+ memcpy (&ul, info, sizeof (ul));
+ ui32 = htonl (ul);
+ memcpy (ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT, &ui32, sizeof (ui32));
+ break;
+ case CLGET_PROG:
+ /*
+ * This RELIES on the information that, in the call body,
+ * the program number field is the field from the
+ * beginning of the RPC header. MUST be changed if the
+ * call_struct is changed
+ */
+ memcpy (&ui32, ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT, sizeof (ui32));
+ ul = ntohl (ui32);
+ memcpy (info, &ul, sizeof (ul));
+ break;
+ case CLSET_PROG:
+ memcpy (&ul, info, sizeof (ul));
+ ui32 = htonl (ul);
+ memcpy (ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT, &ui32, sizeof (ui32));
+ break;
+ /* The following are only possible with TI-RPC */
+ 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
+clntunix_destroy (CLIENT *h)
+{
+ struct ct_data *ct =
+ (struct ct_data *) h->cl_private;
+
+ if (ct->ct_closeit)
+ {
+ (void) __close (ct->ct_sock);
+ }
+ XDR_DESTROY (&(ct->ct_xdrs));
+ mem_free ((caddr_t) ct, sizeof (struct ct_data));
+ mem_free ((caddr_t) h, sizeof (CLIENT));
+}
+
+static int
+__msgread (int sock, void *data, size_t cnt)
+{
+ struct iovec iov;
+ struct msghdr msg;
+#ifdef SCM_CREDENTIALS
+ static char cm[CMSG_SPACE(sizeof (struct ucred))];
+#endif
+ int len;
+
+ iov.iov_base = data;
+ iov.iov_len = cnt;
+
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+#ifdef SCM_CREDENTIALS
+ msg.msg_control = (caddr_t) &cm;
+ msg.msg_controllen = CMSG_SPACE(sizeof (struct ucred));
+#endif
+ msg.msg_flags = 0;
+
+#ifdef SO_PASSCRED
+ {
+ int on = 1;
+ if (__setsockopt (sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)))
+ return -1;
+ }
+#endif
+
+ restart:
+ len = __recvmsg (sock, &msg, 0);
+ if (len >= 0)
+ {
+ if (msg.msg_flags & MSG_CTRUNC || len == 0)
+ return 0;
+ else
+ return len;
+ }
+ if (errno == EINTR)
+ goto restart;
+ return -1;
+}
+
+static int
+__msgwrite (int sock, void *data, size_t cnt)
+{
+#ifndef SCM_CREDENTIALS
+ /* We cannot implement this reliably. */
+ __set_errno (ENOSYS);
+ return -1;
+#else
+ struct iovec iov;
+ struct msghdr msg;
+ struct cmsghdr *cmsg = alloca (CMSG_SPACE(sizeof (struct ucred)));
+ struct ucred cred;
+ int len;
+
+ /* XXX I'm not sure, if gete?id() is always correct, or if we should use
+ get?id(). But since keyserv needs geteuid(), we have no other chance.
+ It would be much better, if the kernel could pass both to the server. */
+ cred.pid = __getpid ();
+ cred.uid = __geteuid ();
+ cred.gid = __getegid ();
+
+ memcpy (CMSG_DATA(cmsg), &cred, sizeof (struct ucred));
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_CREDENTIALS;
+ cmsg->cmsg_len = sizeof(*cmsg) + sizeof(struct ucred);
+
+ iov.iov_base = data;
+ iov.iov_len = cnt;
+
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_control = cmsg;
+ msg.msg_controllen = CMSG_ALIGN(cmsg->cmsg_len);
+ msg.msg_flags = 0;
+
+ restart:
+ len = __sendmsg (sock, &msg, 0);
+ if (len >= 0)
+ return len;
+ if (errno == EINTR)
+ goto restart;
+ return -1;
+
+#endif
+}
+
+
+/*
+ * Interface between xdr serializer and unix connection.
+ * Behaves like the system calls, read & write, but keeps some error state
+ * around for the rpc level.
+ */
+static int
+readunix (char *ctptr, char *buf, int len)
+{
+ struct ct_data *ct = (struct ct_data *) ctptr;
+ struct pollfd fd;
+ int milliseconds = ((ct->ct_wait.tv_sec * 1000)
+ + (ct->ct_wait.tv_usec / 1000));
+
+ if (len == 0)
+ return 0;
+
+ fd.fd = ct->ct_sock;
+ fd.events = POLLIN;
+ while (TRUE)
+ {
+ switch (__poll (&fd, 1, milliseconds))
+ {
+ case 0:
+ ct->ct_error.re_status = RPC_TIMEDOUT;
+ return -1;
+
+ case -1:
+ if (errno == EINTR)
+ continue;
+ ct->ct_error.re_status = RPC_CANTRECV;
+ ct->ct_error.re_errno = errno;
+ return -1;
+ }
+ break;
+ }
+ switch (len = __msgread (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
+writeunix (char *ctptr, char *buf, int len)
+{
+ int i, cnt;
+ struct ct_data *ct = (struct ct_data *) ctptr;
+
+ for (cnt = len; cnt > 0; cnt -= i, buf += i)
+ {
+ if ((i = __msgwrite (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/sunrpc/create_xid.c b/sunrpc/create_xid.c
new file mode 100644
index 0000000..2f132a1
--- /dev/null
+++ b/sunrpc/create_xid.c
@@ -0,0 +1,72 @@
+/* Copyright (c) 1998-2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#ifndef SYLIXOS
+#include <libc-lock.h>
+#endif
+#include <kernrpc/rpc.h>
+
+/* The RPC code is not threadsafe, but new code should be threadsafe. */
+
+__libc_lock_define_initialized (static, createxid_lock)
+
+static pid_t is_initialized;
+#ifndef SYLIXOS
+static struct drand48_data __rpc_lrand48_data;
+#endif
+
+static int getktid (void)
+{
+ return ((int)API_ThreadIdSelf() & 0xffff);
+}
+
+unsigned long
+_create_xid (void)
+{
+ long int res;
+
+ __libc_lock_lock (createxid_lock);
+
+ pid_t pid = (pid_t)getktid ();
+ if (is_initialized != pid)
+ {
+ struct timeval now;
+
+ __gettimeofday (&now, (struct timezone *) 0);
+#ifndef SYLIXOS
+ __srand48_r (now.tv_sec ^ now.tv_usec ^ pid,
+ &__rpc_lrand48_data);
+#else
+ srand48(now.tv_sec ^ now.tv_usec ^ pid);
+#endif
+ is_initialized = pid;
+ }
+
+#ifndef SYLIXOS
+ lrand48_r (&__rpc_lrand48_data, &res);
+#else
+ res = lib_lrand48();
+#endif
+
+ __libc_lock_unlock (createxid_lock);
+
+ return res;
+}
diff --git a/sunrpc/des.h b/sunrpc/des.h
new file mode 100644
index 0000000..8196e54
--- /dev/null
+++ b/sunrpc/des.h
@@ -0,0 +1 @@
+#include <rpc/rpc_des.h>
diff --git a/sunrpc/des_crypt.c b/sunrpc/des_crypt.c
new file mode 100644
index 0000000..1b131bf
--- /dev/null
+++ b/sunrpc/des_crypt.c
@@ -0,0 +1,120 @@
+/*
+ * des_crypt.c, DES encryption library routines
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <rpc/des_crypt.h>
+#ifndef SYLIXOS
+#include <abi-versions.h>
+#endif
+#include "des.h"
+
+extern int _des_crypt (char *, unsigned, struct desparams *);
+
+/*
+ * Copy 8 bytes
+ */
+#define COPY8(src, dst) { \
+ register char *a = (char *) dst; \
+ register char *b = (char *) src; \
+ *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
+ *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
+}
+
+/*
+ * Copy multiple of 8 bytes
+ */
+#define DESCOPY(src, dst, len) { \
+ register char *a = (char *) dst; \
+ register char *b = (char *) src; \
+ register int i; \
+ for (i = (int) len; i > 0; i -= 8) { \
+ *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
+ *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; \
+ } \
+}
+
+/*
+ * Common code to cbc_crypt() & ecb_crypt()
+ */
+static int
+common_crypt (char *key, char *buf, register unsigned len,
+ unsigned mode, register struct desparams *desp)
+{
+ register int desdev;
+
+ if ((len % 8) != 0 || len > DES_MAXDATA)
+ return DESERR_BADPARAM;
+
+ desp->des_dir =
+ ((mode & DES_DIRMASK) == DES_ENCRYPT) ? ENCRYPT : DECRYPT;
+
+ desdev = mode & DES_DEVMASK;
+ COPY8 (key, desp->des_key);
+ /*
+ * software
+ */
+ if (!_des_crypt (buf, len, desp))
+ return DESERR_HWERROR;
+
+ return desdev == DES_SW ? DESERR_NONE : DESERR_NOHWDEVICE;
+}
+
+/*
+ * CBC mode encryption
+ */
+int
+cbc_crypt (char *key, char *buf, unsigned int len, unsigned int mode,
+ char *ivec)
+{
+ int err;
+ struct desparams dp;
+
+ dp.des_mode = CBC;
+ COPY8 (ivec, dp.des_ivec);
+ err = common_crypt (key, buf, len, mode, &dp);
+ COPY8 (dp.des_ivec, ivec);
+ return err;
+}
+libc_hidden_nolink_sunrpc (cbc_crypt, GLIBC_2_1)
+
+/*
+ * ECB mode encryption
+ */
+int
+ecb_crypt (char *key, char *buf, unsigned int len, unsigned int mode)
+{
+ struct desparams dp;
+
+ dp.des_mode = ECB;
+ return common_crypt (key, buf, len, mode, &dp);
+}
+libc_hidden_nolink_sunrpc (ecb_crypt, GLIBC_2_1)
diff --git a/sunrpc/des_impl.c b/sunrpc/des_impl.c
new file mode 100644
index 0000000..1757dc1
--- /dev/null
+++ b/sunrpc/des_impl.c
@@ -0,0 +1,596 @@
+/* Copyright (C) 1992 Eric Young */
+/* Collected from libdes and modified for SECURE RPC by Martin Kuck 1994 */
+/* This file is distributed under the terms of the GNU Lesser General */
+/* Public License, version 2.1 or later - see the file COPYING.LIB for details.*/
+/* If you did not receive a copy of the license with this program, please*/
+/* see <http://www.gnu.org/licenses/> to obtain a copy. */
+#include <string.h>
+#include <stdint.h>
+#include "des.h"
+
+
+static const uint32_t des_SPtrans[8][64] =
+{
+ { /* nibble 0 */
+ 0x00820200, 0x00020000, 0x80800000, 0x80820200,
+ 0x00800000, 0x80020200, 0x80020000, 0x80800000,
+ 0x80020200, 0x00820200, 0x00820000, 0x80000200,
+ 0x80800200, 0x00800000, 0x00000000, 0x80020000,
+ 0x00020000, 0x80000000, 0x00800200, 0x00020200,
+ 0x80820200, 0x00820000, 0x80000200, 0x00800200,
+ 0x80000000, 0x00000200, 0x00020200, 0x80820000,
+ 0x00000200, 0x80800200, 0x80820000, 0x00000000,
+ 0x00000000, 0x80820200, 0x00800200, 0x80020000,
+ 0x00820200, 0x00020000, 0x80000200, 0x00800200,
+ 0x80820000, 0x00000200, 0x00020200, 0x80800000,
+ 0x80020200, 0x80000000, 0x80800000, 0x00820000,
+ 0x80820200, 0x00020200, 0x00820000, 0x80800200,
+ 0x00800000, 0x80000200, 0x80020000, 0x00000000,
+ 0x00020000, 0x00800000, 0x80800200, 0x00820200,
+ 0x80000000, 0x80820000, 0x00000200, 0x80020200},
+
+ { /* nibble 1 */
+ 0x10042004, 0x00000000, 0x00042000, 0x10040000,
+ 0x10000004, 0x00002004, 0x10002000, 0x00042000,
+ 0x00002000, 0x10040004, 0x00000004, 0x10002000,
+ 0x00040004, 0x10042000, 0x10040000, 0x00000004,
+ 0x00040000, 0x10002004, 0x10040004, 0x00002000,
+ 0x00042004, 0x10000000, 0x00000000, 0x00040004,
+ 0x10002004, 0x00042004, 0x10042000, 0x10000004,
+ 0x10000000, 0x00040000, 0x00002004, 0x10042004,
+ 0x00040004, 0x10042000, 0x10002000, 0x00042004,
+ 0x10042004, 0x00040004, 0x10000004, 0x00000000,
+ 0x10000000, 0x00002004, 0x00040000, 0x10040004,
+ 0x00002000, 0x10000000, 0x00042004, 0x10002004,
+ 0x10042000, 0x00002000, 0x00000000, 0x10000004,
+ 0x00000004, 0x10042004, 0x00042000, 0x10040000,
+ 0x10040004, 0x00040000, 0x00002004, 0x10002000,
+ 0x10002004, 0x00000004, 0x10040000, 0x00042000},
+
+ { /* nibble 2 */
+ 0x41000000, 0x01010040, 0x00000040, 0x41000040,
+ 0x40010000, 0x01000000, 0x41000040, 0x00010040,
+ 0x01000040, 0x00010000, 0x01010000, 0x40000000,
+ 0x41010040, 0x40000040, 0x40000000, 0x41010000,
+ 0x00000000, 0x40010000, 0x01010040, 0x00000040,
+ 0x40000040, 0x41010040, 0x00010000, 0x41000000,
+ 0x41010000, 0x01000040, 0x40010040, 0x01010000,
+ 0x00010040, 0x00000000, 0x01000000, 0x40010040,
+ 0x01010040, 0x00000040, 0x40000000, 0x00010000,
+ 0x40000040, 0x40010000, 0x01010000, 0x41000040,
+ 0x00000000, 0x01010040, 0x00010040, 0x41010000,
+ 0x40010000, 0x01000000, 0x41010040, 0x40000000,
+ 0x40010040, 0x41000000, 0x01000000, 0x41010040,
+ 0x00010000, 0x01000040, 0x41000040, 0x00010040,
+ 0x01000040, 0x00000000, 0x41010000, 0x40000040,
+ 0x41000000, 0x40010040, 0x00000040, 0x01010000},
+
+ { /* nibble 3 */
+ 0x00100402, 0x04000400, 0x00000002, 0x04100402,
+ 0x00000000, 0x04100000, 0x04000402, 0x00100002,
+ 0x04100400, 0x04000002, 0x04000000, 0x00000402,
+ 0x04000002, 0x00100402, 0x00100000, 0x04000000,
+ 0x04100002, 0x00100400, 0x00000400, 0x00000002,
+ 0x00100400, 0x04000402, 0x04100000, 0x00000400,
+ 0x00000402, 0x00000000, 0x00100002, 0x04100400,
+ 0x04000400, 0x04100002, 0x04100402, 0x00100000,
+ 0x04100002, 0x00000402, 0x00100000, 0x04000002,
+ 0x00100400, 0x04000400, 0x00000002, 0x04100000,
+ 0x04000402, 0x00000000, 0x00000400, 0x00100002,
+ 0x00000000, 0x04100002, 0x04100400, 0x00000400,
+ 0x04000000, 0x04100402, 0x00100402, 0x00100000,
+ 0x04100402, 0x00000002, 0x04000400, 0x00100402,
+ 0x00100002, 0x00100400, 0x04100000, 0x04000402,
+ 0x00000402, 0x04000000, 0x04000002, 0x04100400},
+
+ { /* nibble 4 */
+ 0x02000000, 0x00004000, 0x00000100, 0x02004108,
+ 0x02004008, 0x02000100, 0x00004108, 0x02004000,
+ 0x00004000, 0x00000008, 0x02000008, 0x00004100,
+ 0x02000108, 0x02004008, 0x02004100, 0x00000000,
+ 0x00004100, 0x02000000, 0x00004008, 0x00000108,
+ 0x02000100, 0x00004108, 0x00000000, 0x02000008,
+ 0x00000008, 0x02000108, 0x02004108, 0x00004008,
+ 0x02004000, 0x00000100, 0x00000108, 0x02004100,
+ 0x02004100, 0x02000108, 0x00004008, 0x02004000,
+ 0x00004000, 0x00000008, 0x02000008, 0x02000100,
+ 0x02000000, 0x00004100, 0x02004108, 0x00000000,
+ 0x00004108, 0x02000000, 0x00000100, 0x00004008,
+ 0x02000108, 0x00000100, 0x00000000, 0x02004108,
+ 0x02004008, 0x02004100, 0x00000108, 0x00004000,
+ 0x00004100, 0x02004008, 0x02000100, 0x00000108,
+ 0x00000008, 0x00004108, 0x02004000, 0x02000008},
+
+ { /* nibble 5 */
+ 0x20000010, 0x00080010, 0x00000000, 0x20080800,
+ 0x00080010, 0x00000800, 0x20000810, 0x00080000,
+ 0x00000810, 0x20080810, 0x00080800, 0x20000000,
+ 0x20000800, 0x20000010, 0x20080000, 0x00080810,
+ 0x00080000, 0x20000810, 0x20080010, 0x00000000,
+ 0x00000800, 0x00000010, 0x20080800, 0x20080010,
+ 0x20080810, 0x20080000, 0x20000000, 0x00000810,
+ 0x00000010, 0x00080800, 0x00080810, 0x20000800,
+ 0x00000810, 0x20000000, 0x20000800, 0x00080810,
+ 0x20080800, 0x00080010, 0x00000000, 0x20000800,
+ 0x20000000, 0x00000800, 0x20080010, 0x00080000,
+ 0x00080010, 0x20080810, 0x00080800, 0x00000010,
+ 0x20080810, 0x00080800, 0x00080000, 0x20000810,
+ 0x20000010, 0x20080000, 0x00080810, 0x00000000,
+ 0x00000800, 0x20000010, 0x20000810, 0x20080800,
+ 0x20080000, 0x00000810, 0x00000010, 0x20080010},
+
+ { /* nibble 6 */
+ 0x00001000, 0x00000080, 0x00400080, 0x00400001,
+ 0x00401081, 0x00001001, 0x00001080, 0x00000000,
+ 0x00400000, 0x00400081, 0x00000081, 0x00401000,
+ 0x00000001, 0x00401080, 0x00401000, 0x00000081,
+ 0x00400081, 0x00001000, 0x00001001, 0x00401081,
+ 0x00000000, 0x00400080, 0x00400001, 0x00001080,
+ 0x00401001, 0x00001081, 0x00401080, 0x00000001,
+ 0x00001081, 0x00401001, 0x00000080, 0x00400000,
+ 0x00001081, 0x00401000, 0x00401001, 0x00000081,
+ 0x00001000, 0x00000080, 0x00400000, 0x00401001,
+ 0x00400081, 0x00001081, 0x00001080, 0x00000000,
+ 0x00000080, 0x00400001, 0x00000001, 0x00400080,
+ 0x00000000, 0x00400081, 0x00400080, 0x00001080,
+ 0x00000081, 0x00001000, 0x00401081, 0x00400000,
+ 0x00401080, 0x00000001, 0x00001001, 0x00401081,
+ 0x00400001, 0x00401080, 0x00401000, 0x00001001},
+
+ { /* nibble 7 */
+ 0x08200020, 0x08208000, 0x00008020, 0x00000000,
+ 0x08008000, 0x00200020, 0x08200000, 0x08208020,
+ 0x00000020, 0x08000000, 0x00208000, 0x00008020,
+ 0x00208020, 0x08008020, 0x08000020, 0x08200000,
+ 0x00008000, 0x00208020, 0x00200020, 0x08008000,
+ 0x08208020, 0x08000020, 0x00000000, 0x00208000,
+ 0x08000000, 0x00200000, 0x08008020, 0x08200020,
+ 0x00200000, 0x00008000, 0x08208000, 0x00000020,
+ 0x00200000, 0x00008000, 0x08000020, 0x08208020,
+ 0x00008020, 0x08000000, 0x00000000, 0x00208000,
+ 0x08200020, 0x08008020, 0x08008000, 0x00200020,
+ 0x08208000, 0x00000020, 0x00200020, 0x08008000,
+ 0x08208020, 0x00200000, 0x08200000, 0x08000020,
+ 0x00208000, 0x00008020, 0x08008020, 0x08200000,
+ 0x00000020, 0x08208000, 0x00208020, 0x00000000,
+ 0x08000000, 0x08200020, 0x00008000, 0x00208020}};
+
+static const uint32_t des_skb[8][64] =
+{
+ { /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
+ 0x00000000, 0x00000010, 0x20000000, 0x20000010,
+ 0x00010000, 0x00010010, 0x20010000, 0x20010010,
+ 0x00000800, 0x00000810, 0x20000800, 0x20000810,
+ 0x00010800, 0x00010810, 0x20010800, 0x20010810,
+ 0x00000020, 0x00000030, 0x20000020, 0x20000030,
+ 0x00010020, 0x00010030, 0x20010020, 0x20010030,
+ 0x00000820, 0x00000830, 0x20000820, 0x20000830,
+ 0x00010820, 0x00010830, 0x20010820, 0x20010830,
+ 0x00080000, 0x00080010, 0x20080000, 0x20080010,
+ 0x00090000, 0x00090010, 0x20090000, 0x20090010,
+ 0x00080800, 0x00080810, 0x20080800, 0x20080810,
+ 0x00090800, 0x00090810, 0x20090800, 0x20090810,
+ 0x00080020, 0x00080030, 0x20080020, 0x20080030,
+ 0x00090020, 0x00090030, 0x20090020, 0x20090030,
+ 0x00080820, 0x00080830, 0x20080820, 0x20080830,
+ 0x00090820, 0x00090830, 0x20090820, 0x20090830},
+ { /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
+ 0x00000000, 0x02000000, 0x00002000, 0x02002000,
+ 0x00200000, 0x02200000, 0x00202000, 0x02202000,
+ 0x00000004, 0x02000004, 0x00002004, 0x02002004,
+ 0x00200004, 0x02200004, 0x00202004, 0x02202004,
+ 0x00000400, 0x02000400, 0x00002400, 0x02002400,
+ 0x00200400, 0x02200400, 0x00202400, 0x02202400,
+ 0x00000404, 0x02000404, 0x00002404, 0x02002404,
+ 0x00200404, 0x02200404, 0x00202404, 0x02202404,
+ 0x10000000, 0x12000000, 0x10002000, 0x12002000,
+ 0x10200000, 0x12200000, 0x10202000, 0x12202000,
+ 0x10000004, 0x12000004, 0x10002004, 0x12002004,
+ 0x10200004, 0x12200004, 0x10202004, 0x12202004,
+ 0x10000400, 0x12000400, 0x10002400, 0x12002400,
+ 0x10200400, 0x12200400, 0x10202400, 0x12202400,
+ 0x10000404, 0x12000404, 0x10002404, 0x12002404,
+ 0x10200404, 0x12200404, 0x10202404, 0x12202404},
+ { /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
+ 0x00000000, 0x00000001, 0x00040000, 0x00040001,
+ 0x01000000, 0x01000001, 0x01040000, 0x01040001,
+ 0x00000002, 0x00000003, 0x00040002, 0x00040003,
+ 0x01000002, 0x01000003, 0x01040002, 0x01040003,
+ 0x00000200, 0x00000201, 0x00040200, 0x00040201,
+ 0x01000200, 0x01000201, 0x01040200, 0x01040201,
+ 0x00000202, 0x00000203, 0x00040202, 0x00040203,
+ 0x01000202, 0x01000203, 0x01040202, 0x01040203,
+ 0x08000000, 0x08000001, 0x08040000, 0x08040001,
+ 0x09000000, 0x09000001, 0x09040000, 0x09040001,
+ 0x08000002, 0x08000003, 0x08040002, 0x08040003,
+ 0x09000002, 0x09000003, 0x09040002, 0x09040003,
+ 0x08000200, 0x08000201, 0x08040200, 0x08040201,
+ 0x09000200, 0x09000201, 0x09040200, 0x09040201,
+ 0x08000202, 0x08000203, 0x08040202, 0x08040203,
+ 0x09000202, 0x09000203, 0x09040202, 0x09040203},
+ { /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
+ 0x00000000, 0x00100000, 0x00000100, 0x00100100,
+ 0x00000008, 0x00100008, 0x00000108, 0x00100108,
+ 0x00001000, 0x00101000, 0x00001100, 0x00101100,
+ 0x00001008, 0x00101008, 0x00001108, 0x00101108,
+ 0x04000000, 0x04100000, 0x04000100, 0x04100100,
+ 0x04000008, 0x04100008, 0x04000108, 0x04100108,
+ 0x04001000, 0x04101000, 0x04001100, 0x04101100,
+ 0x04001008, 0x04101008, 0x04001108, 0x04101108,
+ 0x00020000, 0x00120000, 0x00020100, 0x00120100,
+ 0x00020008, 0x00120008, 0x00020108, 0x00120108,
+ 0x00021000, 0x00121000, 0x00021100, 0x00121100,
+ 0x00021008, 0x00121008, 0x00021108, 0x00121108,
+ 0x04020000, 0x04120000, 0x04020100, 0x04120100,
+ 0x04020008, 0x04120008, 0x04020108, 0x04120108,
+ 0x04021000, 0x04121000, 0x04021100, 0x04121100,
+ 0x04021008, 0x04121008, 0x04021108, 0x04121108},
+ { /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
+ 0x00000000, 0x10000000, 0x00010000, 0x10010000,
+ 0x00000004, 0x10000004, 0x00010004, 0x10010004,
+ 0x20000000, 0x30000000, 0x20010000, 0x30010000,
+ 0x20000004, 0x30000004, 0x20010004, 0x30010004,
+ 0x00100000, 0x10100000, 0x00110000, 0x10110000,
+ 0x00100004, 0x10100004, 0x00110004, 0x10110004,
+ 0x20100000, 0x30100000, 0x20110000, 0x30110000,
+ 0x20100004, 0x30100004, 0x20110004, 0x30110004,
+ 0x00001000, 0x10001000, 0x00011000, 0x10011000,
+ 0x00001004, 0x10001004, 0x00011004, 0x10011004,
+ 0x20001000, 0x30001000, 0x20011000, 0x30011000,
+ 0x20001004, 0x30001004, 0x20011004, 0x30011004,
+ 0x00101000, 0x10101000, 0x00111000, 0x10111000,
+ 0x00101004, 0x10101004, 0x00111004, 0x10111004,
+ 0x20101000, 0x30101000, 0x20111000, 0x30111000,
+ 0x20101004, 0x30101004, 0x20111004, 0x30111004},
+ { /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
+ 0x00000000, 0x08000000, 0x00000008, 0x08000008,
+ 0x00000400, 0x08000400, 0x00000408, 0x08000408,
+ 0x00020000, 0x08020000, 0x00020008, 0x08020008,
+ 0x00020400, 0x08020400, 0x00020408, 0x08020408,
+ 0x00000001, 0x08000001, 0x00000009, 0x08000009,
+ 0x00000401, 0x08000401, 0x00000409, 0x08000409,
+ 0x00020001, 0x08020001, 0x00020009, 0x08020009,
+ 0x00020401, 0x08020401, 0x00020409, 0x08020409,
+ 0x02000000, 0x0A000000, 0x02000008, 0x0A000008,
+ 0x02000400, 0x0A000400, 0x02000408, 0x0A000408,
+ 0x02020000, 0x0A020000, 0x02020008, 0x0A020008,
+ 0x02020400, 0x0A020400, 0x02020408, 0x0A020408,
+ 0x02000001, 0x0A000001, 0x02000009, 0x0A000009,
+ 0x02000401, 0x0A000401, 0x02000409, 0x0A000409,
+ 0x02020001, 0x0A020001, 0x02020009, 0x0A020009,
+ 0x02020401, 0x0A020401, 0x02020409, 0x0A020409},
+ { /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
+ 0x00000000, 0x00000100, 0x00080000, 0x00080100,
+ 0x01000000, 0x01000100, 0x01080000, 0x01080100,
+ 0x00000010, 0x00000110, 0x00080010, 0x00080110,
+ 0x01000010, 0x01000110, 0x01080010, 0x01080110,
+ 0x00200000, 0x00200100, 0x00280000, 0x00280100,
+ 0x01200000, 0x01200100, 0x01280000, 0x01280100,
+ 0x00200010, 0x00200110, 0x00280010, 0x00280110,
+ 0x01200010, 0x01200110, 0x01280010, 0x01280110,
+ 0x00000200, 0x00000300, 0x00080200, 0x00080300,
+ 0x01000200, 0x01000300, 0x01080200, 0x01080300,
+ 0x00000210, 0x00000310, 0x00080210, 0x00080310,
+ 0x01000210, 0x01000310, 0x01080210, 0x01080310,
+ 0x00200200, 0x00200300, 0x00280200, 0x00280300,
+ 0x01200200, 0x01200300, 0x01280200, 0x01280300,
+ 0x00200210, 0x00200310, 0x00280210, 0x00280310,
+ 0x01200210, 0x01200310, 0x01280210, 0x01280310},
+ { /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
+ 0x00000000, 0x04000000, 0x00040000, 0x04040000,
+ 0x00000002, 0x04000002, 0x00040002, 0x04040002,
+ 0x00002000, 0x04002000, 0x00042000, 0x04042000,
+ 0x00002002, 0x04002002, 0x00042002, 0x04042002,
+ 0x00000020, 0x04000020, 0x00040020, 0x04040020,
+ 0x00000022, 0x04000022, 0x00040022, 0x04040022,
+ 0x00002020, 0x04002020, 0x00042020, 0x04042020,
+ 0x00002022, 0x04002022, 0x00042022, 0x04042022,
+ 0x00000800, 0x04000800, 0x00040800, 0x04040800,
+ 0x00000802, 0x04000802, 0x00040802, 0x04040802,
+ 0x00002800, 0x04002800, 0x00042800, 0x04042800,
+ 0x00002802, 0x04002802, 0x00042802, 0x04042802,
+ 0x00000820, 0x04000820, 0x00040820, 0x04040820,
+ 0x00000822, 0x04000822, 0x00040822, 0x04040822,
+ 0x00002820, 0x04002820, 0x00042820, 0x04042820,
+ 0x00002822, 0x04002822, 0x00042822, 0x04042822},
+};
+
+#define c2l(c,l) (l =((unsigned long)(*((c)++))) , \
+ l|=((unsigned long)(*((c)++)))<< 8, \
+ l|=((unsigned long)(*((c)++)))<<16, \
+ l|=((unsigned long)(*((c)++)))<<24)
+
+#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
+ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>24)&0xff))
+
+/*
+ * IP and FP
+ * The problem is more of a geometric problem that random bit fiddling.
+ * 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6
+ * 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4
+ * 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2
+ * 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0
+ *
+ * 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7
+ * 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5
+ * 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3
+ * 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1
+ *
+ * The output has been subject to swaps of the form
+ * 0 1 -> 3 1 but the odd and even bits have been put into
+ * 2 3 2 0
+ * different words. The main trick is to remember that
+ * t=((l>>size)^r)&(mask);
+ * r^=t;
+ * l^=(t<<size);
+ * can be used to swap and move bits between words.
+ *
+ * So l = 0 1 2 3 r = 16 17 18 19
+ * 4 5 6 7 20 21 22 23
+ * 8 9 10 11 24 25 26 27
+ * 12 13 14 15 28 29 30 31
+ * becomes (for size == 2 and mask == 0x3333)
+ * t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19
+ * 6^20 7^21 -- -- 4 5 20 21 6 7 22 23
+ * 10^24 11^25 -- -- 8 9 24 25 10 11 24 25
+ * 14^28 15^29 -- -- 12 13 28 29 14 15 28 29
+ *
+ * Thanks for hints from Richard Outerbridge - he told me IP&FP
+ * could be done in 15 xor, 10 shifts and 5 ands.
+ * When I finally started to think of the problem in 2D
+ * I first got ~42 operations without xors. When I remembered
+ * how to use xors :-) I got it to its final state.
+ */
+
+#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
+ (b)^=(t),\
+ (a)^=((t)<<(n)))
+
+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
+ (a)=(a)^(t)^(t>>(16-(n))))
+
+
+#define D_ENCRYPT(L,R,S) \
+ u=(R^s[S ]); \
+ t=R^s[S+1]; \
+ t=((t>>4)+(t<<28)); \
+ L^= des_SPtrans[1][(t )&0x3f]| \
+ des_SPtrans[3][(t>> 8)&0x3f]| \
+ des_SPtrans[5][(t>>16)&0x3f]| \
+ des_SPtrans[7][(t>>24)&0x3f]| \
+ des_SPtrans[0][(u )&0x3f]| \
+ des_SPtrans[2][(u>> 8)&0x3f]| \
+ des_SPtrans[4][(u>>16)&0x3f]| \
+ des_SPtrans[6][(u>>24)&0x3f];
+
+#define ITERATIONS 16
+
+static const char shifts2[16] =
+{0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0};
+
+static void des_set_key (unsigned char *, unsigned long *) internal_function;
+static void des_encrypt (unsigned long *, unsigned long *, int)
+ internal_function;
+int _des_crypt (char *, unsigned, struct desparams *);
+
+static void
+internal_function
+des_set_key (unsigned char *key, unsigned long *schedule)
+{
+ register unsigned long c, d, t, s;
+ register unsigned char *in;
+ register unsigned long *k;
+ register int i;
+
+ k = (unsigned long *) schedule;
+ in = key;
+
+ c2l (in, c);
+ c2l (in, d);
+
+ /* I now do it in 47 simple operations :-)
+ * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
+ * for the inspiration. :-) */
+ PERM_OP (d, c, t, 4, 0x0f0f0f0f);
+ HPERM_OP (c, t, -2, 0xcccc0000);
+ HPERM_OP (d, t, -2, 0xcccc0000);
+ PERM_OP (d, c, t, 1, 0x55555555);
+ PERM_OP (c, d, t, 8, 0x00ff00ff);
+ PERM_OP (d, c, t, 1, 0x55555555);
+ d = (((d & 0x000000ff) << 16) | (d & 0x0000ff00) |
+ ((d & 0x00ff0000) >> 16) | ((c & 0xf0000000) >> 4));
+ c &= 0x0fffffff;
+
+ for (i = 0; i < ITERATIONS; i++)
+ {
+ if (shifts2[i])
+ {
+ c = ((c >> 2) | (c << 26));
+ d = ((d >> 2) | (d << 26));
+ }
+ else
+ {
+ c = ((c >> 1) | (c << 27));
+ d = ((d >> 1) | (d << 27));
+ }
+ c &= 0x0fffffff;
+ d &= 0x0fffffff;
+ /* could be a few less shifts but I am to lazy at this
+ * point in time to investigate */
+ s = des_skb[0][(c) & 0x3f] |
+ des_skb[1][((c >> 6) & 0x03) | ((c >> 7) & 0x3c)] |
+ des_skb[2][((c >> 13) & 0x0f) | ((c >> 14) & 0x30)] |
+ des_skb[3][((c >> 20) & 0x01) | ((c >> 21) & 0x06) | ((c >> 22) & 0x38)];
+ t = des_skb[4][(d) & 0x3f] |
+ des_skb[5][((d >> 7) & 0x03) | ((d >> 8) & 0x3c)] |
+ des_skb[6][(d >> 15) & 0x3f] |
+ des_skb[7][((d >> 21) & 0x0f) | ((d >> 22) & 0x30)];
+
+ /* table contained 0213 4657 */
+ *(k++) = ((t << 16) | (s & 0x0000ffff)) & 0xffffffff;
+ s = ((s >> 16) | (t & 0xffff0000));
+
+ s = (s << 4) | (s >> 28);
+ *(k++) = s & 0xffffffff;
+ }
+}
+
+
+static void
+internal_function
+des_encrypt (unsigned long *buf, unsigned long *schedule, int encrypt)
+{
+ register unsigned long l, r, t, u;
+ register int i;
+ register unsigned long *s;
+
+ l = buf[0];
+ r = buf[1];
+
+ /* do IP */
+ PERM_OP (r, l, t, 4, 0x0f0f0f0f);
+ PERM_OP (l, r, t, 16, 0x0000ffff);
+ PERM_OP (r, l, t, 2, 0x33333333);
+ PERM_OP (l, r, t, 8, 0x00ff00ff);
+ PERM_OP (r, l, t, 1, 0x55555555);
+ /* r and l are reversed - remember that :-) - fix
+ * it in the next step */
+
+ /* Things have been modified so that the initial rotate is
+ * done outside the loop. This required the
+ * des_SPtrans values in sp.h to be rotated 1 bit to the right.
+ * One perl script later and things have a 5% speed up on a sparc2.
+ * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
+ * for pointing this out. */
+ t = (r << 1) | (r >> 31);
+ r = (l << 1) | (l >> 31);
+ l = t;
+
+ /* clear the top bits on machines with 8byte longs */
+ l &= 0xffffffff;
+ r &= 0xffffffff;
+
+ s = (unsigned long *) schedule;
+ /* I don't know if it is worth the effort of loop unrolling the
+ * inner loop */
+ if (encrypt)
+ {
+ for (i = 0; i < 32; i += 4)
+ {
+ D_ENCRYPT (l, r, i + 0); /* 1 */
+ D_ENCRYPT (r, l, i + 2); /* 2 */
+ }
+ }
+ else
+ {
+ for (i = 30; i > 0; i -= 4)
+ {
+ D_ENCRYPT (l, r, i - 0); /* 16 */
+ D_ENCRYPT (r, l, i - 2); /* 15 */
+ }
+ }
+ l = (l >> 1) | (l << 31);
+ r = (r >> 1) | (r << 31);
+ /* clear the top bits on machines with 8byte longs */
+ l &= 0xffffffff;
+ r &= 0xffffffff;
+
+ /* swap l and r
+ * we will not do the swap so just remember they are
+ * reversed for the rest of the subroutine
+ * luckily FP fixes this problem :-) */
+
+ PERM_OP (r, l, t, 1, 0x55555555);
+ PERM_OP (l, r, t, 8, 0x00ff00ff);
+ PERM_OP (r, l, t, 2, 0x33333333);
+ PERM_OP (l, r, t, 16, 0x0000ffff);
+ PERM_OP (r, l, t, 4, 0x0f0f0f0f);
+
+ buf[0] = l;
+ buf[1] = r;
+
+ l = r = t = u = 0;
+}
+
+
+int
+_des_crypt (char *buf, unsigned len, struct desparams *desp)
+{
+ unsigned long schedule[32];
+ register unsigned long tin0, tin1;
+ register unsigned long tout0, tout1, xor0, xor1;
+ register unsigned char *in, *out;
+ unsigned long tbuf[2];
+ unsigned char *iv, *oiv;
+ int cbc_mode;
+
+ cbc_mode = (desp->des_mode == CBC) ? 1 : 0;
+
+ in = (unsigned char *) buf;
+ out = (unsigned char *) buf;
+ oiv = iv = (unsigned char *) desp->des_ivec;
+
+ des_set_key (desp->des_key, schedule);
+
+ tin0 = tin1 = 0; /* For GCC */
+ if (desp->des_dir == ENCRYPT)
+ {
+ c2l (iv, tout0);
+ c2l (iv, tout1);
+ for (; len > 0; len -= 8)
+ {
+ c2l (in, tin0);
+ c2l (in, tin1);
+ if (cbc_mode)
+ {
+ tin0 ^= tout0;
+ tin1 ^= tout1;
+ }
+ tbuf[0] = tin0;
+ tbuf[1] = tin1;
+ des_encrypt (tbuf, schedule, 1);
+ tout0 = tbuf[0];
+ tout1 = tbuf[1];
+ l2c (tout0, out);
+ l2c (tout1, out);
+ }
+ l2c (tout0, oiv);
+ l2c (tout1, oiv);
+ }
+ else
+ {
+ c2l (iv, xor0);
+ c2l (iv, xor1);
+ for (; len > 0; len -= 8)
+ {
+ c2l (in, tin0);
+ c2l (in, tin1);
+ tbuf[0] = tin0;
+ tbuf[1] = tin1;
+ des_encrypt (tbuf, schedule, 0);
+ if (cbc_mode)
+ {
+ tout0 = tbuf[0] ^ xor0;
+ tout1 = tbuf[1] ^ xor1;
+ xor0 = tin0;
+ xor1 = tin1;
+ }
+ else
+ {
+ tout0 = tbuf[0];
+ tout1 = tbuf[1];
+ }
+ l2c (tout0, out);
+ l2c (tout1, out);
+ }
+ l2c (tin0, oiv);
+ l2c (tin1, oiv);
+ }
+ tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
+ tbuf[0] = tbuf[1] = 0;
+ __bzero (schedule, sizeof (schedule));
+
+ return (1);
+}
diff --git a/sunrpc/des_soft.c b/sunrpc/des_soft.c
new file mode 100644
index 0000000..ca4c626
--- /dev/null
+++ b/sunrpc/des_soft.c
@@ -0,0 +1,78 @@
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)des_soft.c 2.2 88/08/10 4.0 RPCSRC; from 1.13 88/02/08 SMI";
+#endif
+/*
+ * Copyright (c) 2010, Oracle America, Inc.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <rpc/des_crypt.h>
+#ifndef SYLIXOS
+#include <abi-versions.h>
+#else
+#include <rpc/types.h>
+#endif
+
+/*
+ * Table giving odd parity in the low bit for ASCII characters
+ */
+static const char partab[128] =
+{
+ 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x07, 0x07,
+ 0x08, 0x08, 0x0b, 0x0b, 0x0d, 0x0d, 0x0e, 0x0e,
+ 0x10, 0x10, 0x13, 0x13, 0x15, 0x15, 0x16, 0x16,
+ 0x19, 0x19, 0x1a, 0x1a, 0x1c, 0x1c, 0x1f, 0x1f,
+ 0x20, 0x20, 0x23, 0x23, 0x25, 0x25, 0x26, 0x26,
+ 0x29, 0x29, 0x2a, 0x2a, 0x2c, 0x2c, 0x2f, 0x2f,
+ 0x31, 0x31, 0x32, 0x32, 0x34, 0x34, 0x37, 0x37,
+ 0x38, 0x38, 0x3b, 0x3b, 0x3d, 0x3d, 0x3e, 0x3e,
+ 0x40, 0x40, 0x43, 0x43, 0x45, 0x45, 0x46, 0x46,
+ 0x49, 0x49, 0x4a, 0x4a, 0x4c, 0x4c, 0x4f, 0x4f,
+ 0x51, 0x51, 0x52, 0x52, 0x54, 0x54, 0x57, 0x57,
+ 0x58, 0x58, 0x5b, 0x5b, 0x5d, 0x5d, 0x5e, 0x5e,
+ 0x61, 0x61, 0x62, 0x62, 0x64, 0x64, 0x67, 0x67,
+ 0x68, 0x68, 0x6b, 0x6b, 0x6d, 0x6d, 0x6e, 0x6e,
+ 0x70, 0x70, 0x73, 0x73, 0x75, 0x75, 0x76, 0x76,
+ 0x79, 0x79, 0x7a, 0x7a, 0x7c, 0x7c, 0x7f, 0x7f,
+};
+
+/*
+ * Add odd parity to low bit of 8 byte key
+ */
+void
+des_setparity (char *p)
+{
+ int i;
+
+ for (i = 0; i < 8; i++)
+ {
+ *p = partab[*p & 0x7f];
+ p++;
+ }
+}
+libc_hidden_nolink_sunrpc (des_setparity, GLIBC_2_1)
diff --git a/sunrpc/etc.rpc b/sunrpc/etc.rpc
new file mode 100644
index 0000000..e099ebb
--- /dev/null
+++ b/sunrpc/etc.rpc
@@ -0,0 +1,70 @@
+#ident "@(#)rpc 1.11 95/07/14 SMI" /* SVr4.0 1.2 */
+#
+# rpc
+#
+portmapper 100000 portmap sunrpc rpcbind
+rstatd 100001 rstat rup perfmeter rstat_svc
+rusersd 100002 rusers
+nfs 100003 nfsprog
+ypserv 100004 ypprog
+mountd 100005 mount showmount
+ypbind 100007
+walld 100008 rwall shutdown
+yppasswdd 100009 yppasswd
+etherstatd 100010 etherstat
+rquotad 100011 rquotaprog quota rquota
+sprayd 100012 spray
+3270_mapper 100013
+rje_mapper 100014
+selection_svc 100015 selnsvc
+database_svc 100016
+rexd 100017 rex
+alis 100018
+sched 100019
+llockmgr 100020
+nlockmgr 100021
+x25.inr 100022
+statmon 100023
+status 100024
+bootparam 100026
+ypupdated 100028 ypupdate
+keyserv 100029 keyserver
+sunlink_mapper 100033
+tfsd 100037
+nsed 100038
+nsemntd 100039
+showfhd 100043 showfh
+ioadmd 100055 rpc.ioadmd
+NETlicense 100062
+sunisamd 100065
+debug_svc 100066 dbsrv
+ypxfrd 100069 rpc.ypxfrd
+bugtraqd 100071
+kerbd 100078
+event 100101 na.event # SunNet Manager
+logger 100102 na.logger # SunNet Manager
+sync 100104 na.sync
+hostperf 100107 na.hostperf
+activity 100109 na.activity # SunNet Manager
+hostmem 100112 na.hostmem
+sample 100113 na.sample
+x25 100114 na.x25
+ping 100115 na.ping
+rpcnfs 100116 na.rpcnfs
+hostif 100117 na.hostif
+etherif 100118 na.etherif
+iproutes 100120 na.iproutes
+layers 100121 na.layers
+snmp 100122 na.snmp snmp-cmc snmp-synoptics snmp-unisys snmp-utk
+traffic 100123 na.traffic
+nfs_acl 100227
+sadmind 100232
+nisd 100300 rpc.nisd
+nispasswd 100303 rpc.nispasswdd
+ufsd 100233 ufsd
+fedfs_admin 100418
+pcnfsd 150001 pcnfs
+amd 300019 amq
+sgi_fam 391002 fam
+bwnfsd 545580417
+fypxfrd 600100069 freebsd-ypxfrd
diff --git a/sunrpc/get_myaddr.c b/sunrpc/get_myaddr.c
new file mode 100644
index 0000000..e9a29d1
--- /dev/null
+++ b/sunrpc/get_myaddr.c
@@ -0,0 +1,105 @@
+/*
+ * get_myaddress.c
+ *
+ * Get client's IP address via ioctl. This avoids using the yellowpages.
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <rpc/types.h>
+#include <rpc/clnt.h>
+#include <rpc/pmap_prot.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <unistd.h>
+#ifndef SYLIXOS
+#include <libintl.h>
+#endif
+#include <net/if.h>
+#include <ifaddrs.h>
+#include <sys/ioctl.h>
+/* Order of following two #includes reversed by roland@gnu */
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+/*
+ * 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.
+ */
+void
+get_myaddress (struct sockaddr_in *addr)
+{
+ struct ifaddrs *ifa;
+
+ if (getifaddrs (&ifa) != 0)
+ {
+ perror ("get_myaddress: getifaddrs");
+ exit (1);
+ }
+
+ int loopback = 0;
+ struct ifaddrs *run;
+
+ again:
+ run = ifa;
+ while (run != NULL)
+ {
+ if ((run->ifa_flags & IFF_UP)
+ && run->ifa_addr != NULL
+ && run->ifa_addr->sa_family == AF_INET
+ && (!(run->ifa_flags & IFF_LOOPBACK)
+ || (loopback == 1 && (run->ifa_flags & IFF_LOOPBACK))))
+ {
+ *addr = *((struct sockaddr_in *) run->ifa_addr);
+ addr->sin_port = htons (PMAPPORT);
+ goto out;
+ }
+
+ run = run->ifa_next;
+ }
+
+ if (loopback == 0)
+ {
+ loopback = 1;
+ goto again;
+ }
+ out:
+ freeifaddrs (ifa);
+
+ /* The function is horribly specified. It does not return any error
+ if no interface is up. Probably this won't happen (at least
+ loopback is there) but still... */
+}
+#ifdef EXPORT_RPC_SYMBOLS
+libc_hidden_def (get_myaddress)
+#else
+libc_hidden_nolink_sunrpc (get_myaddress, GLIBC_2_0)
+#endif
diff --git a/sunrpc/getprotobyname.c b/sunrpc/getprotobyname.c
new file mode 100644
index 0000000..7dd906d
--- /dev/null
+++ b/sunrpc/getprotobyname.c
@@ -0,0 +1,52 @@
+/* $NetBSD: getprotobyname_r.c,v 1.3 2005/04/18 19:39:45 kleink Exp $ */
+
+/*
+ * Copyright (c) 1983, 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.
+ */
+
+#include <sys/cdefs.h>
+#include <endian.h>
+
+#include <assert.h>
+#include <netdb.h>
+#include <string.h>
+
+int __getprotobyname_r (const char *__name,
+ struct protoent *__result_buf,
+ char *__buf, size_t __buflen,
+ struct protoent **__result)
+{
+ if (strcmp(__name, "udp") == 0) {
+ __result_buf->p_proto = IPPROTO_UDP;
+ } else {
+ __result_buf->p_proto = IPPROTO_TCP;
+ }
+ *__result = __result_buf;
+
+ return 0;
+}
diff --git a/sunrpc/getrpcbyname.c b/sunrpc/getrpcbyname.c
new file mode 100644
index 0000000..5a13055
--- /dev/null
+++ b/sunrpc/getrpcbyname.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 1996-2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <rpc/netdb.h>
+
+
+#define LOOKUP_TYPE struct rpcent
+#define FUNCTION_NAME getrpcbyname
+#define DATABASE_NAME rpc
+#define ADD_PARAMS const char *name
+#define ADD_VARIABLES name
+#define BUFLEN 1024
+
+/* There is no nscd support for the rpc file. */
+#undef USE_NSCD
+
+#include "../nss/getXXbyYY.c"
diff --git a/sunrpc/getrpcbyname_r.c b/sunrpc/getrpcbyname_r.c
new file mode 100644
index 0000000..f71a255
--- /dev/null
+++ b/sunrpc/getrpcbyname_r.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1996-2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <rpc/netdb.h>
+
+
+#define LOOKUP_TYPE struct rpcent
+#define FUNCTION_NAME getrpcbyname
+#define DATABASE_NAME rpc
+#define ADD_PARAMS const char *name
+#define ADD_VARIABLES name
+
+/* There is no nscd support for the rpc file. */
+#undef USE_NSCD
+
+#include "../nss/getXXbyYY_r.c"
diff --git a/sunrpc/getrpcbynumber.c b/sunrpc/getrpcbynumber.c
new file mode 100644
index 0000000..0905ad8
--- /dev/null
+++ b/sunrpc/getrpcbynumber.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 1996-2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <rpc/netdb.h>
+
+
+#define LOOKUP_TYPE struct rpcent
+#define FUNCTION_NAME getrpcbynumber
+#define DATABASE_NAME rpc
+#define ADD_PARAMS int number
+#define ADD_VARIABLES number
+#define BUFLEN 1024
+
+/* There is no nscd support for the rpc file. */
+#undef USE_NSCD
+
+#include "../nss/getXXbyYY.c"
diff --git a/sunrpc/getrpcbynumber_r.c b/sunrpc/getrpcbynumber_r.c
new file mode 100644
index 0000000..d82bfa3
--- /dev/null
+++ b/sunrpc/getrpcbynumber_r.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1996-2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <rpc/netdb.h>
+
+
+#define LOOKUP_TYPE struct rpcent
+#define FUNCTION_NAME getrpcbynumber
+#define DATABASE_NAME rpc
+#define ADD_PARAMS int number
+#define ADD_VARIABLES number
+
+/* There is no nscd support for the rpc file. */
+#undef USE_NSCD
+
+#include "../nss/getXXbyYY_r.c"
diff --git a/sunrpc/getrpcent.c b/sunrpc/getrpcent.c
new file mode 100644
index 0000000..04fad25
--- /dev/null
+++ b/sunrpc/getrpcent.c
@@ -0,0 +1,28 @@
+/* Copyright (C) 1996-2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <rpc/netdb.h>
+
+
+#define LOOKUP_TYPE struct rpcent
+#define GETFUNC_NAME getrpcent
+#define BUFLEN 1024
+
+/* There is no nscd support for the rpc file. */
+#undef USE_NSCD
+
+#include "../nss/getXXent.c"
diff --git a/sunrpc/getrpcent_r.c b/sunrpc/getrpcent_r.c
new file mode 100644
index 0000000..cb40cb3
--- /dev/null
+++ b/sunrpc/getrpcent_r.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 1996-2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <netdb.h>
+
+
+#define LOOKUP_TYPE struct rpcent
+#define SETFUNC_NAME setrpcent
+#define GETFUNC_NAME getrpcent
+#define ENDFUNC_NAME endrpcent
+#define DATABASE_NAME rpc
+#define STAYOPEN int stayopen
+#define STAYOPEN_VAR stayopen
+
+/* There is no nscd support for the rpc file. */
+#undef USE_NSCD
+
+#include "../nss/getXXent_r.c"
diff --git a/sunrpc/getrpcport.c b/sunrpc/getrpcport.c
new file mode 100644
index 0000000..885fe08
--- /dev/null
+++ b/sunrpc/getrpcport.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef SYLIXOS
+#include <alloca.h>
+#endif
+#include <errno.h>
+#include <stdio.h>
+#include <netdb.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <rpc/clnt.h>
+#include <rpc/pmap_clnt.h>
+#include <sys/socket.h>
+
+int
+getrpcport (const char *host, u_long prognum, u_long versnum, u_int proto)
+{
+ struct sockaddr_in addr;
+ struct hostent hostbuf, *hp;
+ size_t buflen;
+ char *buffer;
+ int herr;
+
+ buflen = 1024;
+ buffer = __alloca (buflen);
+ while (__gethostbyname_r (host, &hostbuf, buffer, buflen, &hp, &herr) != 0
+ || hp == NULL)
+ if (herr != NETDB_INTERNAL || errno != ERANGE)
+ return 0;
+ else
+ {
+ /* Enlarge the buffer. */
+ buflen *= 2;
+ buffer = __alloca (buflen);
+ }
+
+ memcpy ((char *) &addr.sin_addr, hp->h_addr, hp->h_length);
+ addr.sin_family = AF_INET;
+ addr.sin_port = 0;
+ return pmap_getport (&addr, prognum, versnum, proto);
+}
diff --git a/sunrpc/key_call.c b/sunrpc/key_call.c
new file mode 100644
index 0000000..7959325
--- /dev/null
+++ b/sunrpc/key_call.c
@@ -0,0 +1,577 @@
+/*
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * The original source is from the RPCSRC 4.0 package from Sun Microsystems.
+ * The Interface to keyserver protocoll 2, RPC over AF_UNIX and Linux/doors
+ * was added by Thorsten Kukuk <kukuk@suse.de>
+ * Since the Linux/doors project was stopped, I doubt that this code will
+ * ever be useful <kukuk@suse.de>.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <unistd.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <rpc/auth.h>
+#include <sys/wait.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <rpc/key_prot.h>
+#ifndef SYLIXOS
+#include <libc-lock.h>
+#endif
+
+#define KEY_TIMEOUT 5 /* per-try timeout in seconds */
+#define KEY_NRETRY 12 /* number of retries */
+
+#define debug(msg) /* turn off debugging */
+
+#ifndef SO_PASSCRED
+extern int _openchild (const char *command, FILE **fto, FILE **ffrom);
+#endif
+
+static int key_call (u_long, xdrproc_t xdr_arg, char *,
+ xdrproc_t xdr_rslt, char *) internal_function;
+
+static const struct timeval trytimeout = {KEY_TIMEOUT, 0};
+static const struct timeval tottimeout = {KEY_TIMEOUT *KEY_NRETRY, 0};
+
+int
+key_setsecret (char *secretkey)
+{
+ keystatus status;
+
+ if (!key_call ((u_long) KEY_SET, (xdrproc_t) xdr_keybuf, secretkey,
+ (xdrproc_t) xdr_keystatus, (char *) &status))
+ return -1;
+ if (status != KEY_SUCCESS)
+ {
+ debug ("set status is nonzero");
+ return -1;
+ }
+ return 0;
+}
+libc_hidden_nolink_sunrpc (key_setsecret, GLIBC_2_1)
+
+/* key_secretkey_is_set() returns 1 if the keyserver has a secret key
+ * stored for the caller's effective uid; it returns 0 otherwise
+ *
+ * N.B.: The KEY_NET_GET key call is undocumented. Applications shouldn't
+ * be using it, because it allows them to get the user's secret key.
+ */
+int
+key_secretkey_is_set (void)
+{
+ struct key_netstres kres;
+
+ memset (&kres, 0, sizeof (kres));
+ if (key_call ((u_long) KEY_NET_GET, (xdrproc_t) xdr_void,
+ (char *) NULL, (xdrproc_t) xdr_key_netstres,
+ (char *) &kres) &&
+ (kres.status == KEY_SUCCESS) &&
+ (kres.key_netstres_u.knet.st_priv_key[0] != 0))
+ {
+ /* avoid leaving secret key in memory */
+ memset (kres.key_netstres_u.knet.st_priv_key, 0, HEXKEYBYTES);
+ return 1;
+ }
+ return 0;
+}
+#ifdef EXPORT_RPC_SYMBOLS
+libc_hidden_def (key_secretkey_is_set)
+#else
+libc_hidden_nolink_sunrpc (key_secretkey_is_set, GLIBC_2_1)
+#endif
+
+int
+key_encryptsession (char *remotename, des_block *deskey)
+{
+ cryptkeyarg arg;
+ cryptkeyres res;
+
+ arg.remotename = remotename;
+ arg.deskey = *deskey;
+ if (!key_call ((u_long) KEY_ENCRYPT, (xdrproc_t) xdr_cryptkeyarg,
+ (char *) &arg, (xdrproc_t) xdr_cryptkeyres,
+ (char *) &res))
+ return -1;
+
+ if (res.status != KEY_SUCCESS)
+ {
+ debug ("encrypt status is nonzero");
+ return -1;
+ }
+ *deskey = res.cryptkeyres_u.deskey;
+ return 0;
+}
+libc_hidden_nolink_sunrpc (key_encryptsession, GLIBC_2_1)
+
+int
+key_decryptsession (char *remotename, des_block *deskey)
+{
+ cryptkeyarg arg;
+ cryptkeyres res;
+
+ arg.remotename = remotename;
+ arg.deskey = *deskey;
+ if (!key_call ((u_long) KEY_DECRYPT, (xdrproc_t) xdr_cryptkeyarg,
+ (char *) &arg, (xdrproc_t) xdr_cryptkeyres,
+ (char *) &res))
+ return -1;
+ if (res.status != KEY_SUCCESS)
+ {
+ debug ("decrypt status is nonzero");
+ return -1;
+ }
+ *deskey = res.cryptkeyres_u.deskey;
+ return 0;
+}
+libc_hidden_nolink_sunrpc (key_decryptsession, GLIBC_2_1)
+
+int
+key_encryptsession_pk (char *remotename, netobj *remotekey,
+ des_block *deskey)
+{
+ cryptkeyarg2 arg;
+ cryptkeyres res;
+
+ arg.remotename = remotename;
+ arg.remotekey = *remotekey;
+ arg.deskey = *deskey;
+ if (!key_call ((u_long) KEY_ENCRYPT_PK, (xdrproc_t) xdr_cryptkeyarg2,
+ (char *) &arg, (xdrproc_t) xdr_cryptkeyres,
+ (char *) &res))
+ return -1;
+
+ if (res.status != KEY_SUCCESS)
+ {
+ debug ("encrypt status is nonzero");
+ return -1;
+ }
+ *deskey = res.cryptkeyres_u.deskey;
+ return 0;
+}
+libc_hidden_nolink_sunrpc (key_encryptsession_pk, GLIBC_2_1)
+
+int
+key_decryptsession_pk (char *remotename, netobj *remotekey,
+ des_block *deskey)
+{
+ cryptkeyarg2 arg;
+ cryptkeyres res;
+
+ arg.remotename = remotename;
+ arg.remotekey = *remotekey;
+ arg.deskey = *deskey;
+ if (!key_call ((u_long) KEY_DECRYPT_PK, (xdrproc_t) xdr_cryptkeyarg2,
+ (char *) &arg, (xdrproc_t) xdr_cryptkeyres,
+ (char *) &res))
+ return -1;
+
+ if (res.status != KEY_SUCCESS)
+ {
+ debug ("decrypt status is nonzero");
+ return -1;
+ }
+ *deskey = res.cryptkeyres_u.deskey;
+ return 0;
+}
+libc_hidden_nolink_sunrpc (key_decryptsession_pk, GLIBC_2_1)
+
+int
+key_gendes (des_block *key)
+{
+ struct sockaddr_in sin;
+ CLIENT *client;
+ int socket;
+ enum clnt_stat stat;
+
+ sin.sin_family = AF_INET;
+ sin.sin_port = 0;
+ sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+ __bzero (sin.sin_zero, sizeof (sin.sin_zero));
+ socket = RPC_ANYSOCK;
+ client = clntudp_bufcreate (&sin, (u_long) KEY_PROG, (u_long) KEY_VERS,
+ trytimeout, &socket, RPCSMALLMSGSIZE,
+ RPCSMALLMSGSIZE);
+ if (client == NULL)
+ return -1;
+
+ stat = clnt_call (client, KEY_GEN, (xdrproc_t) xdr_void, NULL,
+ (xdrproc_t) xdr_des_block, (caddr_t) key,
+ tottimeout);
+ clnt_destroy (client);
+ __close (socket);
+ if (stat != RPC_SUCCESS)
+ return -1;
+
+ return 0;
+}
+#ifdef EXPORT_RPC_SYMBOLS
+libc_hidden_def (key_gendes)
+#else
+libc_hidden_nolink_sunrpc (key_gendes, GLIBC_2_1)
+#endif
+
+int
+key_setnet (struct key_netstarg *arg)
+{
+ keystatus status;
+
+ if (!key_call ((u_long) KEY_NET_PUT, (xdrproc_t) xdr_key_netstarg,
+ (char *) arg,(xdrproc_t) xdr_keystatus,
+ (char *) &status))
+ return -1;
+
+ if (status != KEY_SUCCESS)
+ {
+ debug ("key_setnet status is nonzero");
+ return -1;
+ }
+ return 1;
+}
+libc_hidden_nolink_sunrpc (key_setnet, GLIBC_2_1)
+
+int
+key_get_conv (char *pkey, des_block *deskey)
+{
+ cryptkeyres res;
+
+ if (!key_call ((u_long) KEY_GET_CONV, (xdrproc_t) xdr_keybuf, pkey,
+ (xdrproc_t) xdr_cryptkeyres, (char *) &res))
+ return -1;
+
+ if (res.status != KEY_SUCCESS)
+ {
+ debug ("get_conv status is nonzero");
+ return -1;
+ }
+ *deskey = res.cryptkeyres_u.deskey;
+ return 0;
+}
+libc_hidden_nolink_sunrpc (key_get_conv, GLIBC_2_1)
+
+/*
+ * Hack to allow the keyserver to use AUTH_DES (for authenticated
+ * NIS+ calls, for example). The only functions that get called
+ * are key_encryptsession_pk, key_decryptsession_pk, and key_gendes.
+ *
+ * The approach is to have the keyserver fill in pointers to local
+ * implementations of these functions, and to call those in key_call().
+ */
+
+cryptkeyres *(*__key_encryptsession_pk_LOCAL) (uid_t, char *);
+cryptkeyres *(*__key_decryptsession_pk_LOCAL) (uid_t, char *);
+des_block *(*__key_gendes_LOCAL) (uid_t, char *);
+
+#ifndef SO_PASSCRED
+static int
+internal_function
+key_call_keyenvoy (u_long proc, xdrproc_t xdr_arg, char *arg,
+ xdrproc_t xdr_rslt, char *rslt)
+{
+ XDR xdrargs;
+ XDR xdrrslt;
+ FILE *fargs;
+ FILE *frslt;
+ sigset_t oldmask, mask;
+ int status;
+ int pid;
+ int success;
+ uid_t ruid;
+ uid_t euid;
+ static const char MESSENGER[] = "/usr/etc/keyenvoy";
+
+ success = 1;
+ sigemptyset (&mask);
+ sigaddset (&mask, SIGCHLD);
+ __sigprocmask (SIG_BLOCK, &mask, &oldmask);
+
+ /*
+ * We are going to exec a set-uid program which makes our effective uid
+ * zero, and authenticates us with our real uid. We need to make the
+ * effective uid be the real uid for the setuid program, and
+ * the real uid be the effective uid so that we can change things back.
+ */
+ euid = __geteuid ();
+ ruid = __getuid ();
+ __setreuid (euid, ruid);
+ pid = _openchild (MESSENGER, &fargs, &frslt);
+ __setreuid (ruid, euid);
+ if (pid < 0)
+ {
+ debug ("open_streams");
+ __sigprocmask (SIG_SETMASK, &oldmask, NULL);
+ return (0);
+ }
+ xdrstdio_create (&xdrargs, fargs, XDR_ENCODE);
+ xdrstdio_create (&xdrrslt, frslt, XDR_DECODE);
+
+ if (!xdr_u_long (&xdrargs, &proc) || !(*xdr_arg) (&xdrargs, arg))
+ {
+ debug ("xdr args");
+ success = 0;
+ }
+ fclose (fargs);
+
+ if (success && !(*xdr_rslt) (&xdrrslt, rslt))
+ {
+ debug ("xdr rslt");
+ success = 0;
+ }
+ fclose(frslt);
+
+ wait_again:
+ if (__wait4 (pid, &status, 0, NULL) < 0)
+ {
+ if (errno == EINTR)
+ goto wait_again;
+ debug ("wait4");
+ if (errno == ECHILD || errno == ESRCH)
+ perror ("wait");
+ else
+ success = 0;
+ }
+ else
+ if (status != 0)
+ {
+ debug ("wait4 1");
+ success = 0;
+ }
+ __sigprocmask (SIG_SETMASK, &oldmask, NULL);
+
+ return success;
+}
+#endif
+
+struct key_call_private {
+ CLIENT *client; /* Client handle */
+ pid_t pid; /* process-id at moment of creation */
+ uid_t uid; /* user-id at last authorization */
+};
+#ifdef _RPC_THREAD_SAFE_
+#define key_call_private_main RPC_THREAD_VARIABLE(key_call_private_s)
+#else
+static struct key_call_private *key_call_private_main;
+#endif
+__libc_lock_define_initialized (static, keycall_lock)
+
+/*
+ * Keep the handle cached. This call may be made quite often.
+ */
+static CLIENT *
+getkeyserv_handle (int vers)
+{
+ struct key_call_private *kcp = key_call_private_main;
+ struct timeval wait_time;
+ int fd;
+ struct sockaddr_un name;
+ socklen_t namelen = sizeof(struct sockaddr_un);
+
+#define TOTAL_TIMEOUT 30 /* total timeout talking to keyserver */
+#define TOTAL_TRIES 5 /* Number of tries */
+
+ if (kcp == (struct key_call_private *)NULL)
+ {
+ kcp = (struct key_call_private *)malloc (sizeof (*kcp));
+ if (kcp == (struct key_call_private *)NULL)
+ return (CLIENT *) NULL;
+
+ key_call_private_main = kcp;
+ kcp->client = NULL;
+ }
+
+ /* if pid has changed, destroy client and rebuild */
+ if (kcp->client != NULL && kcp->pid != __getpid ())
+ {
+ auth_destroy (kcp->client->cl_auth);
+ clnt_destroy (kcp->client);
+ kcp->client = NULL;
+ }
+
+ if (kcp->client != NULL)
+ {
+ /* if other side closed socket, build handle again */
+ clnt_control (kcp->client, CLGET_FD, (char *)&fd);
+ if (__getpeername (fd,(struct sockaddr *)&name,&namelen) == -1)
+ {
+ auth_destroy (kcp->client->cl_auth);
+ clnt_destroy (kcp->client);
+ kcp->client = NULL;
+ }
+ }
+
+ if (kcp->client != NULL)
+ {
+ /* if uid has changed, build client handle again */
+ if (kcp->uid != __geteuid ())
+ {
+ kcp->uid = __geteuid ();
+ auth_destroy (kcp->client->cl_auth);
+ kcp->client->cl_auth =
+ authunix_create ((char *)"", kcp->uid, 0, 0, NULL);
+ if (kcp->client->cl_auth == NULL)
+ {
+ clnt_destroy (kcp->client);
+ kcp->client = NULL;
+ return ((CLIENT *) NULL);
+ }
+ }
+ /* Change the version number to the new one */
+ clnt_control (kcp->client, CLSET_VERS, (void *)&vers);
+ return kcp->client;
+ }
+
+ if ((kcp->client == (CLIENT *) NULL))
+ /* Use the AF_UNIX transport */
+ kcp->client = clnt_create ("/var/run/keyservsock", KEY_PROG, vers, "unix");
+
+ if (kcp->client == (CLIENT *) NULL)
+ return (CLIENT *) NULL;
+
+ kcp->uid = __geteuid ();
+ kcp->pid = __getpid ();
+ kcp->client->cl_auth = authunix_create ((char *)"", kcp->uid, 0, 0, NULL);
+ if (kcp->client->cl_auth == NULL)
+ {
+ clnt_destroy (kcp->client);
+ kcp->client = NULL;
+ return (CLIENT *) NULL;
+ }
+
+ wait_time.tv_sec = TOTAL_TIMEOUT/TOTAL_TRIES;
+ wait_time.tv_usec = 0;
+ clnt_control (kcp->client, CLSET_RETRY_TIMEOUT,
+ (char *)&wait_time);
+ if (clnt_control (kcp->client, CLGET_FD, (char *)&fd))
+ __fcntl (fd, F_SETFD, FD_CLOEXEC); /* make it "close on exec" */
+
+ return kcp->client;
+}
+
+/* returns 0 on failure, 1 on success */
+static int
+internal_function
+key_call_socket (u_long proc, xdrproc_t xdr_arg, char *arg,
+ xdrproc_t xdr_rslt, char *rslt)
+{
+ CLIENT *clnt;
+ struct timeval wait_time;
+ int result = 0;
+
+ __libc_lock_lock (keycall_lock);
+ if ((proc == KEY_ENCRYPT_PK) || (proc == KEY_DECRYPT_PK) ||
+ (proc == KEY_NET_GET) || (proc == KEY_NET_PUT) ||
+ (proc == KEY_GET_CONV))
+ clnt = getkeyserv_handle(2); /* talk to version 2 */
+ else
+ clnt = getkeyserv_handle(1); /* talk to version 1 */
+
+ if (clnt != NULL)
+ {
+ wait_time.tv_sec = TOTAL_TIMEOUT;
+ wait_time.tv_usec = 0;
+
+ if (clnt_call (clnt, proc, xdr_arg, arg, xdr_rslt, rslt,
+ wait_time) == RPC_SUCCESS)
+ result = 1;
+ }
+
+ __libc_lock_unlock (keycall_lock);
+
+ return result;
+}
+
+
+/* returns 0 on failure, 1 on success */
+static int
+internal_function
+key_call (u_long proc, xdrproc_t xdr_arg, char *arg,
+ xdrproc_t xdr_rslt, char *rslt)
+{
+#ifndef SO_PASSCRED
+ static int use_keyenvoy;
+#endif
+
+ if (proc == KEY_ENCRYPT_PK && __key_encryptsession_pk_LOCAL)
+ {
+ cryptkeyres *res;
+ res = (*__key_encryptsession_pk_LOCAL) (__geteuid (), arg);
+ *(cryptkeyres *) rslt = *res;
+ return 1;
+ }
+ else if (proc == KEY_DECRYPT_PK && __key_decryptsession_pk_LOCAL)
+ {
+ cryptkeyres *res;
+ res = (*__key_decryptsession_pk_LOCAL) (__geteuid (), arg);
+ *(cryptkeyres *) rslt = *res;
+ return 1;
+ }
+ else if (proc == KEY_GEN && __key_gendes_LOCAL)
+ {
+ des_block *res;
+ res = (*__key_gendes_LOCAL) (__geteuid (), 0);
+ *(des_block *) rslt = *res;
+ return 1;
+ }
+
+#ifdef SO_PASSCRED
+ return key_call_socket (proc, xdr_arg, arg, xdr_rslt, rslt);
+#else
+ if (!use_keyenvoy)
+ {
+ if (key_call_socket (proc, xdr_arg, arg, xdr_rslt, rslt))
+ return 1;
+ use_keyenvoy = 1;
+ }
+ return key_call_keyenvoy (proc, xdr_arg, arg, xdr_rslt, rslt);
+#endif
+}
+
+#ifdef _RPC_THREAD_SAFE_
+void
+__rpc_thread_key_cleanup (void)
+{
+ struct key_call_private *kcp = RPC_THREAD_VARIABLE(key_call_private_s);
+
+ if (kcp) {
+ if (kcp->client) {
+ if (kcp->client->cl_auth)
+ auth_destroy (kcp->client->cl_auth);
+ clnt_destroy(kcp->client);
+ }
+ free (kcp);
+ }
+}
+#endif /* _RPC_THREAD_SAFE_ */
diff --git a/sunrpc/key_prot.c b/sunrpc/key_prot.c
new file mode 100644
index 0000000..2899c9a
--- /dev/null
+++ b/sunrpc/key_prot.c
@@ -0,0 +1,169 @@
+/* Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <rpc/key_prot.h>
+
+bool_t
+xdr_keystatus (XDR * xdrs, keystatus * objp)
+{
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+
+ return TRUE;
+}
+libc_hidden_nolink_sunrpc (xdr_keystatus, GLIBC_2_0)
+
+bool_t
+xdr_keybuf (XDR * xdrs, keybuf objp)
+{
+ if (!xdr_opaque (xdrs, objp, HEXKEYBYTES))
+ return FALSE;
+
+ return TRUE;
+}
+libc_hidden_nolink_sunrpc (xdr_keybuf, GLIBC_2_0)
+
+bool_t
+xdr_netnamestr (XDR * xdrs, netnamestr * objp)
+{
+ if (!xdr_string (xdrs, objp, MAXNETNAMELEN))
+ return FALSE;
+
+ return TRUE;
+}
+libc_hidden_nolink_sunrpc (xdr_netnamestr, GLIBC_2_1)
+
+bool_t
+xdr_cryptkeyarg (XDR * xdrs, cryptkeyarg * objp)
+{
+ if (!xdr_netnamestr (xdrs, &objp->remotename))
+ return FALSE;
+
+ if (!xdr_des_block (xdrs, &objp->deskey))
+ return FALSE;
+
+ return TRUE;
+}
+libc_hidden_nolink_sunrpc (xdr_cryptkeyarg, GLIBC_2_0)
+
+bool_t
+xdr_cryptkeyarg2 (XDR * xdrs, cryptkeyarg2 * objp)
+{
+ if (!xdr_netnamestr (xdrs, &objp->remotename))
+ return FALSE;
+ if (!xdr_netobj (xdrs, &objp->remotekey))
+ return FALSE;
+ if (!xdr_des_block (xdrs, &objp->deskey))
+ return FALSE;
+ return TRUE;
+}
+libc_hidden_nolink_sunrpc (xdr_cryptkeyarg2, GLIBC_2_0)
+
+bool_t
+xdr_cryptkeyres (XDR * xdrs, cryptkeyres * objp)
+{
+ if (!xdr_keystatus (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status)
+ {
+ case KEY_SUCCESS:
+ if (!xdr_des_block (xdrs, &objp->cryptkeyres_u.deskey))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+libc_hidden_nolink_sunrpc (xdr_cryptkeyres, GLIBC_2_0)
+
+bool_t
+xdr_unixcred (XDR * xdrs, unixcred * objp)
+{
+ if (!xdr_u_int (xdrs, &objp->uid))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->gid))
+ return FALSE;
+ if (!xdr_array (xdrs, (void *) &objp->gids.gids_val,
+ (u_int *) & objp->gids.gids_len, MAXGIDS,
+ sizeof (u_int), (xdrproc_t) xdr_u_int))
+ return FALSE;
+ return TRUE;
+}
+libc_hidden_nolink_sunrpc (xdr_unixcred, GLIBC_2_1)
+
+bool_t
+xdr_getcredres (XDR * xdrs, getcredres * objp)
+{
+ if (!xdr_keystatus (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status)
+ {
+ case KEY_SUCCESS:
+ if (!xdr_unixcred (xdrs, &objp->getcredres_u.cred))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+libc_hidden_nolink_sunrpc (xdr_getcredres, GLIBC_2_1)
+
+bool_t
+xdr_key_netstarg (XDR * xdrs, key_netstarg * objp)
+{
+ if (!xdr_keybuf (xdrs, objp->st_priv_key))
+ return FALSE;
+ if (!xdr_keybuf (xdrs, objp->st_pub_key))
+ return FALSE;
+ if (!xdr_netnamestr (xdrs, &objp->st_netname))
+ return FALSE;
+ return TRUE;
+}
+libc_hidden_nolink_sunrpc (xdr_key_netstarg, GLIBC_2_0)
+
+bool_t
+xdr_key_netstres (XDR * xdrs, key_netstres * objp)
+{
+ if (!xdr_keystatus (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status)
+ {
+ case KEY_SUCCESS:
+ if (!xdr_key_netstarg (xdrs, &objp->key_netstres_u.knet))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+libc_hidden_nolink_sunrpc (xdr_key_netstres, GLIBC_2_0)
diff --git a/sunrpc/netname.c b/sunrpc/netname.c
new file mode 100644
index 0000000..376d6ff
--- /dev/null
+++ b/sunrpc/netname.c
@@ -0,0 +1,217 @@
+/* Copyright (C) 1997-2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <rpc/rpc.h>
+
+#include "nsswitch.h"
+
+#define OPSYS_LEN 4
+#define MAXIPRINT (11) /* max length of printed integer */
+static const char OPSYS[] = "unix";
+
+int
+user2netname (char netname[MAXNETNAMELEN + 1], const uid_t uid,
+ const char *domain)
+{
+ char dfltdom[MAXNETNAMELEN + 1];
+ size_t i;
+
+ if (domain == NULL)
+ {
+ if (getdomainname (dfltdom, sizeof (dfltdom)) < 0)
+ return 0;
+ }
+ else
+ {
+ strncpy (dfltdom, domain, MAXNETNAMELEN);
+ dfltdom[MAXNETNAMELEN] = '\0';
+ }
+
+ if ((strlen (dfltdom) + OPSYS_LEN + 3 + MAXIPRINT) > (size_t) MAXNETNAMELEN)
+ return 0;
+
+ sprintf (netname, "%s.%d@%s", OPSYS, uid, dfltdom);
+ i = strlen (netname);
+ if (netname[i - 1] == '.')
+ netname[i - 1] = '\0';
+ return 1;
+}
+libc_hidden_nolink_sunrpc (user2netname, GLIBC_2_1)
+
+int
+host2netname (char netname[MAXNETNAMELEN + 1], const char *host,
+ const char *domain)
+{
+ char *p;
+ char hostname[MAXHOSTNAMELEN + 1];
+ char domainname[MAXHOSTNAMELEN + 1];
+ char *dot_in_host;
+ size_t i;
+
+ netname[0] = '\0'; /* make null first (no need for memset) */
+
+ if (host == NULL)
+ __gethostname (hostname, MAXHOSTNAMELEN);
+ else
+ {
+ strncpy (hostname, host, MAXHOSTNAMELEN);
+ hostname[MAXHOSTNAMELEN] = '\0';
+ }
+
+ dot_in_host = strchr (hostname, '.');
+ if (domain == NULL)
+ {
+ p = dot_in_host;
+ if (p)
+ {
+ ++p;
+ strncpy (domainname, p, MAXHOSTNAMELEN);
+ domainname[MAXHOSTNAMELEN] = '\0';
+ }
+ else
+ {
+ domainname[0] = 0;
+ getdomainname (domainname, MAXHOSTNAMELEN);
+ }
+ }
+ else
+ {
+ strncpy (domainname, domain, MAXHOSTNAMELEN);
+ domainname[MAXHOSTNAMELEN] = '\0';
+ }
+
+ i = strlen (domainname);
+ if (i == 0)
+ /* No domainname */
+ return 0;
+ if (domainname[i - 1] == '.')
+ domainname[i - 1] = 0;
+
+ if (dot_in_host) /* strip off rest of name */
+ *dot_in_host = '\0';
+
+ if ((strlen (domainname) + strlen (hostname) + OPSYS_LEN + 3)
+ > MAXNETNAMELEN)
+ return 0;
+
+ sprintf (netname, "%s.%s@%s", OPSYS, hostname, domainname);
+ return 1;
+}
+#ifdef EXPORT_RPC_SYMBOLS
+libc_hidden_def (host2netname)
+#else
+libc_hidden_nolink_sunrpc (host2netname, GLIBC_2_1)
+#endif
+
+int
+getnetname (char name[MAXNETNAMELEN + 1])
+{
+ uid_t uid;
+ int dummy;
+
+ uid = __geteuid ();
+ if (uid == 0)
+ dummy = host2netname (name, NULL, NULL);
+ else
+ dummy = user2netname (name, uid, NULL);
+ return (dummy);
+}
+libc_hidden_nolink_sunrpc (getnetname, GLIBC_2_1)
+
+/* Type of the lookup function for netname2user. */
+typedef int (*netname2user_function) (const char netname[MAXNETNAMELEN + 1],
+ uid_t *, gid_t *, int *, gid_t *);
+/* The lookup function for the first entry of this service. */
+extern int __nss_publickey_lookup (service_user ** nip, const char *name,
+ void **fctp) internal_function;
+
+int
+netname2user (const char netname[MAXNETNAMELEN + 1], uid_t * uidp, gid_t * gidp,
+ int *gidlenp, gid_t * gidlist)
+{
+ static service_user *startp;
+ static netname2user_function start_fct;
+ service_user *nip;
+ union
+ {
+ netname2user_function f;
+ void *ptr;
+ } fct;
+ enum nss_status status = NSS_STATUS_UNAVAIL;
+ int no_more;
+
+ if (startp == NULL)
+ {
+ no_more = __nss_publickey_lookup (&nip, "netname2user", &fct.ptr);
+ if (no_more)
+ startp = (service_user *) - 1;
+ else
+ {
+ startp = nip;
+ start_fct = fct.f;
+ }
+ }
+ else
+ {
+ fct.f = start_fct;
+ no_more = (nip = startp) == (service_user *) - 1;
+ }
+
+ while (!no_more)
+ {
+ status = (*fct.f) (netname, uidp, gidp, gidlenp, gidlist);
+
+ no_more = __nss_next2 (&nip, "netname2user", NULL, &fct.ptr, status, 0);
+ }
+
+ return status == NSS_STATUS_SUCCESS;
+}
+#ifdef EXPORT_RPC_SYMBOLS
+libc_hidden_def (netname2user)
+#else
+libc_hidden_nolink_sunrpc (netname2user, GLIBC_2_1)
+#endif
+
+int
+netname2host (const char netname[MAXNETNAMELEN + 1], char *hostname,
+ const int hostlen)
+{
+ char *p1, *p2;
+
+ p1 = strchr (netname, '.');
+ if (p1 == NULL)
+ return 0;
+ p1++;
+
+ p2 = strchr (p1, '@');
+ if (p2 == NULL)
+ return 0;
+ *p2 = '\0';
+
+ if (hostlen > MAXNETNAMELEN)
+ return 0;
+
+ strncpy (hostname, p1, hostlen);
+ hostname[hostlen] = '\0';
+
+ return 1;
+}
+libc_hidden_nolink_sunrpc (netname2host, GLIBC_2_1)
diff --git a/sunrpc/openchild.c b/sunrpc/openchild.c
new file mode 100644
index 0000000..29f274a
--- /dev/null
+++ b/sunrpc/openchild.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Open two pipes to a child process, one for reading, one for writing.
+ * The pipes are accessed by FILE pointers. This is NOT a public
+ * interface, but for internal use only!
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <rpc/clnt.h>
+
+#include <libio/iolibio.h>
+#define fflush(s) _IO_fflush (s)
+#define __fdopen(fd,m) _IO_fdopen (fd,m)
+
+/*
+ * returns pid, or -1 for failure
+ */
+int
+_openchild (const char *command, FILE ** fto, FILE ** ffrom)
+{
+ int i;
+ int pid;
+ int pdto[2];
+ int pdfrom[2];
+
+ if (__pipe (pdto) < 0)
+ goto error1;
+ if (__pipe (pdfrom) < 0)
+ goto error2;
+ switch (pid = __fork ())
+ {
+ case -1:
+ goto error3;
+
+ case 0:
+ /*
+ * child: read from pdto[0], write into pdfrom[1]
+ */
+ __close (0);
+ __dup (pdto[0]);
+ __close (1);
+ __dup (pdfrom[1]);
+ fflush (stderr);
+ for (i = _rpc_dtablesize () - 1; i >= 3; i--)
+ __close (i);
+ fflush (stderr);
+ execlp (command, command, NULL);
+ perror ("exec");
+ _exit (~0);
+
+ default:
+ /*
+ * parent: write into pdto[1], read from pdfrom[0]
+ */
+ *fto = __fdopen (pdto[1], "w");
+ __close (pdto[0]);
+ *ffrom = __fdopen (pdfrom[0], "r");
+ __close (pdfrom[1]);
+ break;
+ }
+ return pid;
+
+ /*
+ * error cleanup and return
+ */
+error3:
+ __close (pdfrom[0]);
+ __close (pdfrom[1]);
+error2:
+ __close (pdto[0]);
+ __close (pdto[1]);
+error1:
+ return -1;
+}
diff --git a/sunrpc/pm_getmaps.c b/sunrpc/pm_getmaps.c
new file mode 100644
index 0000000..1200c52
--- /dev/null
+++ b/sunrpc/pm_getmaps.c
@@ -0,0 +1,90 @@
+/*
+ * pmap_getmap.c
+ * Client interface to pmap rpc service.
+ * contains pmap_getmaps, which is only tcp service involved
+ *
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <errno.h>
+#ifndef SYLIXOS
+#include <libintl.h>
+#endif
+#include <unistd.h>
+#ifndef SYLIXOS
+#include <not-cancel.h>
+#endif
+
+/*
+ * 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 = (struct pmaplist *) NULL;
+ struct timeval minutetimeout;
+ CLIENT *client;
+ bool closeit = false;
+
+ minutetimeout.tv_sec = 60;
+ minutetimeout.tv_usec = 0;
+ address->sin_port = htons (PMAPPORT);
+
+ /* Don't need a reserved port to get ports from the portmapper. */
+ int socket = __get_socket (address);
+ if (socket != -1)
+ closeit = true;
+
+ client = clnttcp_create (address, PMAPPROG, PMAPVERS, &socket, 50, 500);
+ if (client != (CLIENT *) NULL)
+ {
+ if (CLNT_CALL (client, PMAPPROC_DUMP, (xdrproc_t)xdr_void, NULL,
+ (xdrproc_t)xdr_pmaplist, (caddr_t)&head,
+ minutetimeout) != RPC_SUCCESS)
+ {
+ clnt_perror (client, _("pmap_getmaps.c: rpc problem"));
+ }
+ CLNT_DESTROY (client);
+ }
+ /* We only need to close the socket here if we opened it. */
+ if (closeit)
+ close_not_cancel (socket);
+ address->sin_port = 0;
+ return head;
+}
+libc_hidden_nolink_sunrpc (pmap_getmaps, GLIBC_2_0)
diff --git a/sunrpc/pm_getport.c b/sunrpc/pm_getport.c
new file mode 100644
index 0000000..000a01f
--- /dev/null
+++ b/sunrpc/pm_getport.c
@@ -0,0 +1,155 @@
+/*
+ * pmap_getport.c
+ * Client interface to pmap rpc service.
+ *
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdbool.h>
+#include <unistd.h>
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#include <sys/socket.h>
+
+/*
+ * Create a socket that is locally bound to a non-reserve port. For
+ * any failures, -1 is returned which will cause the RPC code to
+ * create the socket.
+ */
+int
+internal_function
+__get_socket (struct sockaddr_in *saddr)
+{
+ int so = __socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (so < 0)
+ return -1;
+
+ struct sockaddr_in laddr;
+ socklen_t namelen = sizeof (laddr);
+ laddr.sin_family = AF_INET;
+ laddr.sin_port = 0;
+ laddr.sin_addr.s_addr = htonl (INADDR_ANY);
+
+ int cc = __bind (so, (struct sockaddr *) &laddr, namelen);
+ if (__glibc_unlikely (cc < 0))
+ {
+ fail:
+ __close (so);
+ return -1;
+ }
+
+ cc = __connect (so, (struct sockaddr *) saddr, namelen);
+ if (__glibc_unlikely (cc < 0))
+ goto fail;
+
+ return so;
+}
+
+
+/*
+ * Find the mapped port for program,version.
+ * Internal version with additional parameters.
+ * Calls the pmap service remotely to do the lookup.
+ * Returns 0 if no map exists.
+ */
+u_short
+internal_function
+__libc_rpc_getport (struct sockaddr_in *address, u_long program,
+ u_long version, u_int protocol, time_t timeout_sec,
+ time_t tottimeout_sec)
+{
+ const struct timeval timeout = {timeout_sec, 0};
+ const struct timeval tottimeout = {tottimeout_sec, 0};
+
+ u_short port = 0;
+ int socket = -1;
+ CLIENT *client;
+ struct pmap parms;
+ bool closeit = false;
+
+ address->sin_port = htons (PMAPPORT);
+ if (protocol == IPPROTO_TCP)
+ {
+ /* Don't need a reserved port to get ports from the portmapper. */
+ socket = __get_socket(address);
+ if (socket != -1)
+ closeit = true;
+ client = clnttcp_create (address, PMAPPROG, PMAPVERS, &socket,
+ RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
+ }
+ else
+ client = clntudp_bufcreate (address, PMAPPROG, PMAPVERS, timeout,
+ &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
+ if (client != (CLIENT *) NULL)
+ {
+ struct rpc_createerr *ce = &get_rpc_createerr ();
+ parms.pm_prog = program;
+ parms.pm_vers = version;
+ parms.pm_prot = protocol;
+ parms.pm_port = 0; /* not needed or used */
+ if (CLNT_CALL (client, PMAPPROC_GETPORT, (xdrproc_t)xdr_pmap,
+ (caddr_t)&parms, (xdrproc_t)xdr_u_short,
+ (caddr_t)&port, tottimeout) != RPC_SUCCESS)
+ {
+ ce->cf_stat = RPC_PMAPFAILURE;
+ clnt_geterr (client, &ce->cf_error);
+ }
+ else if (port == 0)
+ {
+ ce->cf_stat = RPC_PROGNOTREGISTERED;
+ }
+ CLNT_DESTROY (client);
+ }
+ /* We only need to close the socket here if we opened it. */
+ if (closeit)
+ (void) __close (socket);
+ address->sin_port = 0;
+ return port;
+}
+#ifdef EXPORT_RPC_SYMBOLS
+libc_hidden_def (__libc_rpc_getport)
+#else
+libc_hidden_nolink_sunrpc (__libc_rpc_getport, GLIBC_PRIVATE)
+#endif
+
+
+/*
+ * 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)
+{
+ return __libc_rpc_getport (address, program, version, protocol, 5, 60);
+}
+libc_hidden_nolink_sunrpc (pmap_getport, GLIBC_2_0)
diff --git a/sunrpc/pmap_clnt.c b/sunrpc/pmap_clnt.c
new file mode 100644
index 0000000..0e2c16b
--- /dev/null
+++ b/sunrpc/pmap_clnt.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * pmap_clnt.c
+ * Client interface to pmap rpc service.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#ifndef SYLIXOS
+#include <libintl.h>
+#endif
+#include <net/if.h>
+#include <ifaddrs.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+
+/*
+ * Same as get_myaddress, but we try to use the loopback
+ * interface. portmap caches interfaces, and on DHCP clients,
+ * it could be that only loopback is started at this time.
+ */
+static bool_t
+__get_myaddress (struct sockaddr_in *addr)
+{
+ struct ifaddrs *ifa;
+
+ if (getifaddrs (&ifa) != 0)
+ {
+ perror ("get_myaddress: getifaddrs");
+ exit (1);
+ }
+
+ int loopback = 1;
+ struct ifaddrs *run;
+
+ again:
+ run = ifa;
+ while (run != NULL)
+ {
+ if ((run->ifa_flags & IFF_UP)
+ && run->ifa_addr != NULL
+ && run->ifa_addr->sa_family == AF_INET
+ && ((run->ifa_flags & IFF_LOOPBACK) || loopback == 0))
+ {
+ *addr = *((struct sockaddr_in *) run->ifa_addr);
+ addr->sin_port = htons (PMAPPORT);
+ goto out;
+ }
+
+ run = run->ifa_next;
+ }
+
+ if (loopback == 1)
+ {
+ loopback = 0;
+ goto again;
+ }
+ out:
+ freeifaddrs (ifa);
+
+ return run == NULL ? FALSE : TRUE;
+}
+
+
+static const struct timeval timeout = {5, 0};
+static const struct timeval tottimeout = {60, 0};
+
+/*
+ * 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, u_short port)
+{
+ struct sockaddr_in myaddress;
+ int socket = -1;
+ CLIENT *client;
+ struct pmap parms;
+ bool_t rslt;
+
+ if (!__get_myaddress (&myaddress))
+ return FALSE;
+ 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,
+ (caddr_t)&parms, (xdrproc_t)xdr_bool, (caddr_t)&rslt,
+ tottimeout) != RPC_SUCCESS)
+ {
+ clnt_perror (client, _("Cannot register service"));
+ rslt = FALSE;
+ }
+ CLNT_DESTROY (client);
+ /* (void)close(socket); CLNT_DESTROY closes it */
+ return rslt;
+}
+libc_hidden_nolink_sunrpc (pmap_set, GLIBC_2_0)
+
+/*
+ * 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;
+ CLIENT *client;
+ struct pmap parms;
+ bool_t rslt;
+
+ if (!__get_myaddress (&myaddress))
+ return FALSE;
+ 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,
+ (caddr_t)&parms, (xdrproc_t)xdr_bool, (caddr_t)&rslt,
+ tottimeout);
+ CLNT_DESTROY (client);
+ /* (void)close(socket); CLNT_DESTROY already closed it */
+ return rslt;
+}
+libc_hidden_nolink_sunrpc (pmap_unset, GLIBC_2_0)
diff --git a/sunrpc/pmap_prot.c b/sunrpc/pmap_prot.c
new file mode 100644
index 0000000..0919d09
--- /dev/null
+++ b/sunrpc/pmap_prot.c
@@ -0,0 +1,50 @@
+/*
+ * pmap_prot.c
+ * Protocol for the local binder service, or pmap.
+ *
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#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;
+}
+libc_hidden_nolink_sunrpc (xdr_pmap, GLIBC_2_0)
diff --git a/sunrpc/pmap_prot2.c b/sunrpc/pmap_prot2.c
new file mode 100644
index 0000000..01f158d
--- /dev/null
+++ b/sunrpc/pmap_prot2.c
@@ -0,0 +1,111 @@
+/*
+ * pmap_prot2.c
+ * Protocol for the local binder service, or pmap.
+ *
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#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;
+ int freeing = (xdrs->x_op == XDR_FREE);
+ 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);
+ }
+}
+libc_hidden_nolink_sunrpc (xdr_pmaplist, GLIBC_2_0)
diff --git a/sunrpc/pmap_rmt.c b/sunrpc/pmap_rmt.c
new file mode 100644
index 0000000..faf662a
--- /dev/null
+++ b/sunrpc/pmap_rmt.c
@@ -0,0 +1,394 @@
+/*
+ * pmap_rmt.c
+ * Client interface to pmap rpc service.
+ * remote call and broadcast service
+ *
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <unistd.h>
+#include <string.h>
+#ifndef SYLIXOS
+#include <libintl.h>
+#endif
+#include <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#include <rpc/pmap_rmt.h>
+#include <sys/poll.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <errno.h>
+#undef _POSIX_SOURCE /* Ultrix <sys/param.h> needs --roland@gnu */
+#include <sys/param.h> /* Ultrix needs before net/if --roland@gnu */
+#include <net/if.h>
+#include <ifaddrs.h>
+#include <sys/ioctl.h>
+#include <arpa/inet.h>
+#define MAX_BROADCAST_SIZE 1400
+
+extern u_long _create_xid (void);
+
+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 socket = -1;
+ CLIENT *client;
+ struct rmtcallargs a;
+ struct rmtcallres r;
+ enum clnt_stat stat;
+
+ addr->sin_port = htons (PMAPPORT);
+ client = clntudp_create (addr, PMAPPROG, PMAPVERS, timeout, &socket);
+ if (client != (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, PMAPPROC_CALLIT,
+ (xdrproc_t)xdr_rmtcall_args,
+ (caddr_t)&a, (xdrproc_t)xdr_rmtcallres,
+ (caddr_t)&r, tout);
+ CLNT_DESTROY (client);
+ }
+ else
+ {
+ stat = RPC_FAILED;
+ }
+ /* (void)__close(socket); CLNT_DESTROY already closed it */
+ addr->sin_port = 0;
+ return stat;
+}
+libc_hidden_nolink_sunrpc (pmap_rmtcall, GLIBC_2_0)
+
+
+/*
+ * 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;
+
+ if (xdr_u_long (xdrs, &(cap->prog)) &&
+ xdr_u_long (xdrs, &(cap->vers)) &&
+ xdr_u_long (xdrs, &(cap->proc)))
+ {
+ u_long dummy_arglen = 0;
+ lenposition = XDR_GETPOS (xdrs);
+ if (!xdr_u_long (xdrs, &dummy_arglen))
+ return FALSE;
+ argposition = XDR_GETPOS (xdrs);
+ if (!(*(cap->xdr_args)) (xdrs, cap->args_ptr, 0))
+ 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;
+}
+libc_hidden_nolink_sunrpc (xdr_rmtcall_args, GLIBC_2_0)
+
+/*
+ * XDR remote call results
+ * written for XDR_DECODE direction only
+ */
+bool_t
+xdr_rmtcallres (XDR *xdrs, struct rmtcallres *crp)
+{
+ caddr_t port_ptr;
+
+ port_ptr = (caddr_t) 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 *) port_ptr;
+ return (*(crp->xdr_results)) (xdrs, crp->results_ptr, 0);
+ }
+ return FALSE;
+}
+libc_hidden_nolink_sunrpc (xdr_rmtcallres, GLIBC_2_0)
+
+
+/*
+ * 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
+internal_function
+getbroadcastnets (struct in_addr *addrs, int naddrs)
+{
+ struct ifaddrs *ifa;
+
+ if (getifaddrs (&ifa) != 0)
+ {
+ perror ("broadcast: getifaddrs");
+ return 0;
+ }
+
+ int i = 0;
+ struct ifaddrs *run = ifa;
+ while (run != NULL && i < naddrs)
+ {
+ if ((run->ifa_flags & IFF_BROADCAST) != 0
+ && (run->ifa_flags & IFF_UP) != 0
+ && run->ifa_addr != NULL
+ && run->ifa_addr->sa_family == AF_INET)
+ /* Copy the broadcast address. */
+ addrs[i++] = ((struct sockaddr_in *) run->ifa_broadaddr)->sin_addr;
+
+ run = run->ifa_next;
+ }
+
+ freeifaddrs (ifa);
+
+ return i;
+}
+
+
+enum clnt_stat
+clnt_broadcast (/* program number */
+ u_long prog,
+ /* version number */
+ u_long vers,
+ /* procedure number */
+ u_long proc,
+ /* xdr routine for args */
+ xdrproc_t xargs,
+ /* pointer to args */
+ caddr_t argsp,
+ /* xdr routine for results */
+ xdrproc_t xresults,
+ /* pointer to results */
+ caddr_t resultsp,
+ /* call with each result obtained */
+ resultproc_t eachresult)
+{
+ enum clnt_stat stat = RPC_FAILED;
+ AUTH *unix_auth = authunix_create_default ();
+ XDR xdr_stream;
+ XDR *xdrs = &xdr_stream;
+ struct timeval t;
+ int outlen, inlen, nets;
+ socklen_t fromlen;
+ int sock;
+ int on = 1;
+ struct pollfd fd;
+ int milliseconds;
+ int i;
+ bool_t done = FALSE;
+ 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;
+ char outbuf[MAX_BROADCAST_SIZE], inbuf[UDPMSGSIZE];
+
+ /*
+ * 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 */
+ fd.fd = sock;
+ fd.events = POLLIN;
+ nets = getbroadcastnets (addrs, sizeof (addrs) / sizeof (addrs[0]));
+ __bzero ((char *) &baddr, sizeof (baddr));
+ baddr.sin_family = AF_INET;
+ baddr.sin_port = htons (PMAPPORT);
+ baddr.sin_addr.s_addr = htonl (INADDR_ANY);
+/* baddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); */
+ msg.rm_xid = xid = _create_xid ();
+ 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.
+ */
+ 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;
+ milliseconds = t.tv_sec * 1000 + t.tv_usec / 1000;
+ switch (__poll(&fd, 1, milliseconds))
+ {
+
+ case 0: /* timed out */
+ stat = RPC_TIMEDOUT;
+ continue;
+
+ case -1: /* some kind of error */
+ if (errno == EINTR)
+ goto recv_again;
+ perror (_("Broadcast poll problem"));
+ stat = RPC_CANTRECV;
+ goto done_broad;
+
+ } /* end of poll 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 ((size_t) inlen < sizeof (u_long))
+ 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 (((u_int32_t) msg.rm_xid == (u_int32_t) 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 ... */
+ }
+ else
+ {
+#ifdef notdef
+ /* some kind of deserialization problem ... */
+ if ((u_int32_t) msg.rm_xid == (u_int32_t) xid)
+ fprintf (stderr, "Broadcast deserialization problem");
+ /* otherwise, just random garbage */
+#endif
+ }
+ xdrs->x_op = XDR_FREE;
+ msg.acpted_rply.ar_results.proc = (xdrproc_t)xdr_void;
+ (void) xdr_replymsg (xdrs, &msg);
+ (void) (*xresults) (xdrs, resultsp, 0);
+ xdr_destroy (xdrs);
+ if (done)
+ {
+ stat = RPC_SUCCESS;
+ goto done_broad;
+ }
+ else
+ {
+ goto recv_again;
+ }
+ }
+done_broad:
+ (void) __close (sock);
+ AUTH_DESTROY (unix_auth);
+ return stat;
+}
+libc_hidden_nolink_sunrpc (clnt_broadcast, GLIBC_2_0)
diff --git a/sunrpc/proto.h b/sunrpc/proto.h
new file mode 100644
index 0000000..ea28565
--- /dev/null
+++ b/sunrpc/proto.h
@@ -0,0 +1,65 @@
+/****** rpc_clntout.c ******/
+
+void write_stubs(void);
+void printarglist(proc_list *proc, const char *result,
+ const char *addargname, const char *addargtype);
+
+/****** rpc_cout.c ******/
+
+void emit (definition *def);
+
+/****** rpc_hout.c ******/
+
+void print_datadef(definition *def);
+void print_funcdef(definition *def);
+void pxdrfuncdecl(const char *name, int pointerp);
+void pprocdef(proc_list *proc, version_list *vp,
+ const char *addargtype, int server_p, int mode);
+void pdeclaration(const char *name, declaration *dec, int tab,
+ const char *separator);
+void print_xdr_func_def (char* name, int pointerp, int i);
+
+/****** rpc_main.c ******/
+ /* nil */
+
+/****** rpc_parse.c ******/
+definition *get_definition(void);
+
+/****** rpc_sample.c ******/
+void write_sample_svc(definition *def);
+int write_sample_clnt(definition *def);
+void add_sample_msg(void);
+void write_sample_clnt_main(void);
+
+/****** rpc_scan.c ******/
+ /* see rpc_scan.h */
+
+/****** rpc_svcout.c ******/
+int nullproc(const proc_list *proc);
+void write_svc_aux(int nomain);
+void write_msg_out(void);
+
+/****** rpc_tblout.c ******/
+void write_tables(void);
+
+/****** rpc_util.c ******/
+void reinitialize(void);
+int streq(const char *a, const char *b);
+void error(const char *msg) __attribute__ ((noreturn));
+void crash(void) __attribute__ ((noreturn));
+void tabify(FILE *f, int tab);
+char *make_argname(const char *pname, const char *vname);
+void add_type(int len, const char *type);
+
+/* This header is the last one included in all rpc_*.c files,
+ so we define stuff for cross-rpcgen here to avoid conflicts with
+ $build's C library and $host's glibc. */
+
+#ifdef IS_IN_build
+
+/* Disable translated messages when built for $build and used in
+ building glibc. */
+#define _(X) (X)
+#define textdomain(X) ((void) 0)
+
+#endif
diff --git a/sunrpc/publickey.c b/sunrpc/publickey.c
new file mode 100644
index 0000000..a1883af
--- /dev/null
+++ b/sunrpc/publickey.c
@@ -0,0 +1,121 @@
+/* Get public or secret key from key server.
+ Copyright (C) 1996-2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <rpc/netdb.h>
+#include <rpc/auth_des.h>
+
+#include "nsswitch.h"
+
+
+/* Type of the lookup function for the public key. */
+typedef int (*public_function) (const char *, char *, int *);
+
+/* Type of the lookup function for the secret key. */
+typedef int (*secret_function) (const char *, char *, const char *, int *);
+
+/* The lookup function for the first entry of this service. */
+extern int __nss_publickey_lookup (service_user **nip, const char *name,
+ void **fctp) internal_function;
+
+
+int
+getpublickey (const char *name, char *key)
+{
+ static service_user *startp;
+ static public_function start_fct;
+ service_user *nip;
+ union
+ {
+ public_function f;
+ void *ptr;
+ } fct;
+ enum nss_status status = NSS_STATUS_UNAVAIL;
+ int no_more;
+
+ if (startp == NULL)
+ {
+ no_more = __nss_publickey_lookup (&nip, "getpublickey", &fct.ptr);
+ if (no_more)
+ startp = (service_user *) -1;
+ else
+ {
+ startp = nip;
+ start_fct = fct.f;
+ }
+ }
+ else
+ {
+ fct.f = start_fct;
+ no_more = (nip = startp) == (service_user *) -1;
+ }
+
+ while (! no_more)
+ {
+ status = (*fct.f) (name, key, &errno);
+
+ no_more = __nss_next2 (&nip, "getpublickey", NULL, &fct.ptr, status, 0);
+ }
+
+ return status == NSS_STATUS_SUCCESS;
+}
+libc_hidden_nolink_sunrpc (getpublickey, GLIBC_2_0)
+
+
+int
+getsecretkey (const char *name, char *key, const char *passwd)
+{
+ static service_user *startp;
+ static secret_function start_fct;
+ service_user *nip;
+ union
+ {
+ secret_function f;
+ void *ptr;
+ } fct;
+ enum nss_status status = NSS_STATUS_UNAVAIL;
+ int no_more;
+
+ if (startp == NULL)
+ {
+ no_more = __nss_publickey_lookup (&nip, "getsecretkey", &fct.ptr);
+ if (no_more)
+ startp = (service_user *) -1;
+ else
+ {
+ startp = nip;
+ start_fct = fct.f;
+ }
+ }
+ else
+ {
+ fct.f = start_fct;
+ no_more = (nip = startp) == (service_user *) -1;
+ }
+
+ while (! no_more)
+ {
+ status = (*fct.f) (name, key, passwd, &errno);
+
+ no_more = __nss_next2 (&nip, "getsecretkey", NULL, &fct.ptr, status, 0);
+ }
+
+ return status == NSS_STATUS_SUCCESS;
+}
+libc_hidden_nolink_sunrpc (getsecretkey, GLIBC_2_0)
diff --git a/sunrpc/rpc/auth.h b/sunrpc/rpc/auth.h
new file mode 100644
index 0000000..c147382
--- /dev/null
+++ b/sunrpc/rpc/auth.h
@@ -0,0 +1,212 @@
+/*
+ * auth.h, Authentication interface.
+ *
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The data structures are completely opaque to the client. The client
+ * is required to pass a AUTH * to routines that create rpc
+ * "sessions".
+ */
+
+#ifndef _RPC_AUTH_H
+
+#define _RPC_AUTH_H 1
+#ifndef SYLIXOS
+#include <features.h>
+#endif
+#include <rpc/xdr.h>
+
+__BEGIN_DECLS
+
+#define MAX_AUTH_BYTES 400
+#define MAXNETNAMELEN 255 /* maximum length of network user's name */
+
+/*
+ * Status returned from authentication check
+ */
+enum auth_stat {
+ AUTH_OK=0,
+ /*
+ * failed at remote end
+ */
+ AUTH_BADCRED=1, /* bogus credentials (seal broken) */
+ AUTH_REJECTEDCRED=2, /* client should begin new session */
+ AUTH_BADVERF=3, /* bogus verifier (seal broken) */
+ AUTH_REJECTEDVERF=4, /* verifier expired or was replayed */
+ AUTH_TOOWEAK=5, /* rejected due to security reasons */
+ /*
+ * failed locally
+ */
+ AUTH_INVALIDRESP=6, /* bogus response verifier */
+ AUTH_FAILED=7 /* some unknown reason */
+};
+
+union des_block {
+ struct {
+ u_int32_t high;
+ u_int32_t low;
+ } key;
+ char c[8];
+};
+typedef union des_block des_block;
+extern bool_t xdr_des_block (XDR *__xdrs, des_block *__blkp) __THROW;
+
+/*
+ * Authentication info. Opaque to client.
+ */
+struct opaque_auth {
+ enum_t oa_flavor; /* flavor of auth */
+ caddr_t oa_base; /* address of more auth stuff */
+ u_int oa_length; /* not to exceed MAX_AUTH_BYTES */
+};
+
+/*
+ * Auth handle, interface to client side authenticators.
+ */
+typedef struct AUTH AUTH;
+struct AUTH {
+ struct opaque_auth ah_cred;
+ struct opaque_auth ah_verf;
+ union des_block ah_key;
+ struct auth_ops {
+ void (*ah_nextverf) (AUTH *);
+ int (*ah_marshal) (AUTH *, XDR *); /* nextverf & serialize */
+ int (*ah_validate) (AUTH *, struct opaque_auth *);
+ /* validate verifier */
+ int (*ah_refresh) (AUTH *); /* refresh credentials */
+ void (*ah_destroy) (AUTH *); /* destroy this structure */
+ } *ah_ops;
+ caddr_t ah_private;
+};
+
+
+/*
+ * Authentication ops.
+ * The ops and the auth handle provide the interface to the authenticators.
+ *
+ * AUTH *auth;
+ * XDR *xdrs;
+ * struct opaque_auth verf;
+ */
+#define AUTH_NEXTVERF(auth) \
+ ((*((auth)->ah_ops->ah_nextverf))(auth))
+#define auth_nextverf(auth) \
+ ((*((auth)->ah_ops->ah_nextverf))(auth))
+
+#define AUTH_MARSHALL(auth, xdrs) \
+ ((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
+#define auth_marshall(auth, xdrs) \
+ ((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
+
+#define AUTH_VALIDATE(auth, verfp) \
+ ((*((auth)->ah_ops->ah_validate))((auth), verfp))
+#define auth_validate(auth, verfp) \
+ ((*((auth)->ah_ops->ah_validate))((auth), verfp))
+
+#define AUTH_REFRESH(auth) \
+ ((*((auth)->ah_ops->ah_refresh))(auth))
+#define auth_refresh(auth) \
+ ((*((auth)->ah_ops->ah_refresh))(auth))
+
+#define AUTH_DESTROY(auth) \
+ ((*((auth)->ah_ops->ah_destroy))(auth))
+#define auth_destroy(auth) \
+ ((*((auth)->ah_ops->ah_destroy))(auth))
+
+
+extern struct opaque_auth _null_auth;
+
+
+/*
+ * These are the various implementations of client side authenticators.
+ */
+
+/*
+ * Unix style authentication
+ * AUTH *authunix_create(machname, uid, gid, len, aup_gids)
+ * char *machname;
+ * int uid;
+ * int gid;
+ * int len;
+ * int *aup_gids;
+ */
+extern AUTH *authunix_create (char *__machname, __uid_t __uid, __gid_t __gid,
+ int __len, __gid_t *__aup_gids);
+extern AUTH *authunix_create_default (void);
+extern AUTH *authnone_create (void) __THROW;
+extern AUTH *authdes_create (const char *__servername, u_int __window,
+ struct sockaddr *__syncaddr, des_block *__ckey)
+ __THROW;
+extern AUTH *authdes_pk_create (const char *, netobj *, u_int,
+ struct sockaddr *, des_block *) __THROW;
+
+
+#define AUTH_NONE 0 /* no authentication */
+#define AUTH_NULL 0 /* backward compatibility */
+#define AUTH_SYS 1 /* unix style (uid, gids) */
+#define AUTH_UNIX AUTH_SYS
+#define AUTH_SHORT 2 /* short hand unix style */
+#define AUTH_DES 3 /* des style (encrypted timestamps) */
+#define AUTH_DH AUTH_DES /* Diffie-Hellman (this is DES) */
+#define AUTH_KERB 4 /* kerberos style */
+
+/*
+ * Netname manipulating functions
+ *
+ */
+extern int getnetname (char *) __THROW;
+extern int host2netname (char *, const char *, const char *) __THROW;
+extern int user2netname (char *, const uid_t, const char *) __THROW;
+extern int netname2user (const char *, uid_t *, gid_t *, int *, gid_t *)
+ __THROW;
+extern int netname2host (const char *, char *, const int) __THROW;
+
+/*
+ *
+ * These routines interface to the keyserv daemon
+ *
+ */
+extern int key_decryptsession (char *, des_block *);
+extern int key_decryptsession_pk (char *, netobj *, des_block *);
+extern int key_encryptsession (char *, des_block *);
+extern int key_encryptsession_pk (char *, netobj *, des_block *);
+extern int key_gendes (des_block *);
+extern int key_setsecret (char *);
+extern int key_secretkey_is_set (void);
+extern int key_get_conv (char *, des_block *);
+
+/*
+ * XDR an opaque authentication struct.
+ */
+extern bool_t xdr_opaque_auth (XDR *, struct opaque_auth *) __THROW;
+
+__END_DECLS
+
+#endif /* rpc/auth.h */
diff --git a/sunrpc/rpc/auth_des.h b/sunrpc/rpc/auth_des.h
new file mode 100644
index 0000000..2c9f2f4
--- /dev/null
+++ b/sunrpc/rpc/auth_des.h
@@ -0,0 +1,111 @@
+/* Copyright (C) 1996-2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _RPC_AUTH_DES_H
+#define _RPC_AUTH_DES_H 1
+
+#include <sys/cdefs.h>
+#include <rpc/auth.h>
+
+__BEGIN_DECLS
+
+/* There are two kinds of "names": fullnames and nicknames */
+enum authdes_namekind
+ {
+ ADN_FULLNAME,
+ ADN_NICKNAME
+ };
+
+/* A fullname contains the network name of the client,
+ a conversation key and the window */
+struct authdes_fullname
+ {
+ char *name; /* network name of client, up to MAXNETNAMELEN */
+ des_block key; /* conversation key */
+ uint32_t window; /* associated window */
+ };
+
+/* A credential */
+struct authdes_cred
+ {
+ enum authdes_namekind adc_namekind;
+ struct authdes_fullname adc_fullname;
+ uint32_t adc_nickname;
+ };
+
+/* A timeval replacement for !32bit platforms */
+struct rpc_timeval
+ {
+ uint32_t tv_sec; /* Seconds. */
+ uint32_t tv_usec; /* Microseconds. */
+ };
+
+/* A des authentication verifier */
+struct authdes_verf
+ {
+ union
+ {
+ struct rpc_timeval adv_ctime; /* clear time */
+ des_block adv_xtime; /* crypt time */
+ }
+ adv_time_u;
+ uint32_t adv_int_u;
+ };
+
+/* des authentication verifier: client variety
+
+ adv_timestamp is the current time.
+ adv_winverf is the credential window + 1.
+ Both are encrypted using the conversation key. */
+#define adv_timestamp adv_time_u.adv_ctime
+#define adv_xtimestamp adv_time_u.adv_xtime
+#define adv_winverf adv_int_u
+
+/* des authentication verifier: server variety
+
+ adv_timeverf is the client's timestamp + client's window
+ adv_nickname is the server's nickname for the client.
+ adv_timeverf is encrypted using the conversation key. */
+#define adv_timeverf adv_time_u.adv_ctime
+#define adv_xtimeverf adv_time_u.adv_xtime
+#define adv_nickname adv_int_u
+
+/* Map a des credential into a unix cred. */
+extern int authdes_getucred (const struct authdes_cred * __adc,
+ uid_t * __uid, gid_t * __gid,
+ short *__grouplen, gid_t * __groups) __THROW;
+
+/* Get the public key for NAME and place it in KEY. NAME can only be
+ up to MAXNETNAMELEN bytes long and the destination buffer KEY should
+ have HEXKEYBYTES + 1 bytes long to fit all characters from the key. */
+extern int getpublickey (const char *__name, char *__key) __THROW;
+
+/* Get the secret key for NAME and place it in KEY. PASSWD is used to
+ decrypt the encrypted key stored in the database. NAME can only be
+ up to MAXNETNAMELEN bytes long and the destination buffer KEY
+ should have HEXKEYBYTES + 1 bytes long to fit all characters from
+ the key. */
+extern int getsecretkey (const char *__name, char *__key,
+ const char *__passwd) __THROW;
+
+extern int rtime (struct sockaddr_in *__addrp, struct rpc_timeval *__timep,
+ struct rpc_timeval *__timeout) __THROW;
+
+__END_DECLS
+
+
+#endif /* rpc/auth_des.h */
diff --git a/sunrpc/rpc/auth_unix.h b/sunrpc/rpc/auth_unix.h
new file mode 100644
index 0000000..06e10cc
--- /dev/null
+++ b/sunrpc/rpc/auth_unix.h
@@ -0,0 +1,88 @@
+/*
+ * auth_unix.h, Protocol for UNIX style authentication parameters for RPC
+ *
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * The system is very weak. The client uses no encryption for it
+ * 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.
+ */
+
+#ifndef _RPC_AUTH_UNIX_H
+#define _RPC_AUTH_UNIX_H 1
+
+#ifndef SYLIXOS
+#include <features.h>
+#endif
+#include <sys/types.h>
+#include <rpc/types.h>
+#include <rpc/auth.h>
+#include <rpc/xdr.h>
+
+__BEGIN_DECLS
+
+/* The machine name is part of a credential; it may not exceed 255 bytes */
+#define MAX_MACHINE_NAME 255
+
+/* gids compose part of a credential; there may not be more than 16 of them */
+#define NGRPS 16
+
+/*
+ * Unix style credentials.
+ */
+struct authunix_parms
+ {
+ u_long aup_time;
+ char *aup_machname;
+ __uid_t aup_uid;
+ __gid_t aup_gid;
+ u_int aup_len;
+ __gid_t *aup_gids;
+ };
+
+extern bool_t xdr_authunix_parms (XDR *__xdrs, struct authunix_parms *__p)
+ __THROW;
+
+/*
+ * If a response verifier has flavor AUTH_SHORT,
+ * then the body of the response verifier encapsulates the following structure;
+ * again it is serialized in the obvious fashion.
+ */
+struct short_hand_verf
+ {
+ struct opaque_auth new_cred;
+ };
+
+__END_DECLS
+
+#endif /* rpc/auth_unix.h */
diff --git a/sunrpc/rpc/clnt.h b/sunrpc/rpc/clnt.h
new file mode 100644
index 0000000..67ae890
--- /dev/null
+++ b/sunrpc/rpc/clnt.h
@@ -0,0 +1,427 @@
+/*
+ * clnt.h - Client side remote procedure call interface.
+ *
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RPC_CLNT_H
+#define _RPC_CLNT_H 1
+
+#ifndef SYLIXOS
+#include <features.h>
+#endif
+#include <sys/types.h>
+#include <rpc/types.h>
+#include <rpc/auth.h>
+#include <sys/un.h>
+
+__BEGIN_DECLS
+
+/*
+ * Rpc calls return an enum clnt_stat. This should be looked at more,
+ * since each implementation is required to live with this (implementation
+ * independent) list of errors.
+ */
+enum clnt_stat {
+ RPC_SUCCESS=0, /* call succeeded */
+ /*
+ * local errors
+ */
+ RPC_CANTENCODEARGS=1, /* can't encode arguments */
+ RPC_CANTDECODERES=2, /* can't decode results */
+ RPC_CANTSEND=3, /* failure in sending call */
+ RPC_CANTRECV=4, /* failure in receiving result */
+ RPC_TIMEDOUT=5, /* call timed out */
+ /*
+ * remote errors
+ */
+ RPC_VERSMISMATCH=6, /* rpc versions not compatible */
+ RPC_AUTHERROR=7, /* authentication error */
+ RPC_PROGUNAVAIL=8, /* program not available */
+ RPC_PROGVERSMISMATCH=9, /* program version mismatched */
+ RPC_PROCUNAVAIL=10, /* procedure unavailable */
+ RPC_CANTDECODEARGS=11, /* decode arguments error */
+ RPC_SYSTEMERROR=12, /* generic "other problem" */
+ RPC_NOBROADCAST = 21, /* Broadcasting not supported */
+ /*
+ * callrpc & clnt_create errors
+ */
+ RPC_UNKNOWNHOST=13, /* unknown host name */
+ RPC_UNKNOWNPROTO=17, /* unknown protocol */
+ RPC_UNKNOWNADDR = 19, /* Remote address unknown */
+
+ /*
+ * rpcbind errors
+ */
+ RPC_RPCBFAILURE=14, /* portmapper failed in its call */
+#define RPC_PMAPFAILURE RPC_RPCBFAILURE
+ RPC_PROGNOTREGISTERED=15, /* remote program is not registered */
+ RPC_N2AXLATEFAILURE = 22, /* Name to addr translation failed */
+ /*
+ * unspecified error
+ */
+ RPC_FAILED=16,
+ RPC_INTR=18,
+ RPC_TLIERROR=20,
+ RPC_UDERROR=23,
+ /*
+ * asynchronous errors
+ */
+ RPC_INPROGRESS = 24,
+ RPC_STALERACHANDLE = 25
+};
+
+
+/*
+ * Error info.
+ */
+struct rpc_err {
+ enum clnt_stat re_status;
+ union {
+ int RE_errno; /* related system error */
+ enum auth_stat RE_why; /* why the auth error occurred */
+ struct {
+ u_long low; /* lowest verion supported */
+ u_long high; /* highest verion supported */
+ } RE_vers;
+ struct { /* maybe meaningful if RPC_FAILED */
+ long s1;
+ long s2;
+ } RE_lb; /* life boot & debugging only */
+ } ru;
+#define re_errno ru.RE_errno
+#define re_why ru.RE_why
+#define re_vers ru.RE_vers
+#define re_lb ru.RE_lb
+};
+
+
+/*
+ * Client rpc handle.
+ * Created by individual implementations, see e.g. rpc_udp.c.
+ * Client is responsible for initializing auth, see e.g. auth_none.c.
+ */
+typedef struct CLIENT CLIENT;
+struct CLIENT {
+ AUTH *cl_auth; /* authenticator */
+ struct clnt_ops {
+ enum clnt_stat (*cl_call) (CLIENT *, u_long, xdrproc_t, caddr_t, xdrproc_t,
+ caddr_t, struct timeval);
+ /* call remote procedure */
+ void (*cl_abort) (void); /* abort a call */
+ void (*cl_geterr) (CLIENT *, struct rpc_err *);
+ /* get specific error code */
+ bool_t (*cl_freeres) (CLIENT *, xdrproc_t, caddr_t);
+ /* frees results */
+ void (*cl_destroy) (CLIENT *); /* destroy this structure */
+ bool_t (*cl_control) (CLIENT *, int, char *);
+ /* the ioctl() of rpc */
+ } *cl_ops;
+ caddr_t cl_private; /* private stuff */
+};
+
+
+/*
+ * client side rpc interface ops
+ *
+ * Parameter types are:
+ *
+ */
+
+/*
+ * enum clnt_stat
+ * CLNT_CALL(rh, proc, xargs, argsp, xres, resp, timeout)
+ * CLIENT *rh;
+ * u_long proc;
+ * xdrproc_t xargs;
+ * caddr_t argsp;
+ * xdrproc_t xres;
+ * caddr_t resp;
+ * struct timeval timeout;
+ */
+#define CLNT_CALL(rh, proc, xargs, argsp, xres, resp, secs) \
+ ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs))
+#define clnt_call(rh, proc, xargs, argsp, xres, resp, secs) \
+ ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs))
+
+/*
+ * void
+ * CLNT_ABORT(rh);
+ * CLIENT *rh;
+ */
+#define CLNT_ABORT(rh) ((*(rh)->cl_ops->cl_abort)(rh))
+#define clnt_abort(rh) ((*(rh)->cl_ops->cl_abort)(rh))
+
+/*
+ * struct rpc_err
+ * CLNT_GETERR(rh);
+ * CLIENT *rh;
+ */
+#define CLNT_GETERR(rh,errp) ((*(rh)->cl_ops->cl_geterr)(rh, errp))
+#define clnt_geterr(rh,errp) ((*(rh)->cl_ops->cl_geterr)(rh, errp))
+
+
+/*
+ * bool_t
+ * CLNT_FREERES(rh, xres, resp);
+ * CLIENT *rh;
+ * xdrproc_t xres;
+ * caddr_t resp;
+ */
+#define CLNT_FREERES(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp))
+#define clnt_freeres(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp))
+
+/*
+ * bool_t
+ * CLNT_CONTROL(cl, request, info)
+ * CLIENT *cl;
+ * u_int request;
+ * char *info;
+ */
+#define CLNT_CONTROL(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in))
+#define clnt_control(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in))
+
+/*
+ * control operations that apply to all transports
+ *
+ * Note: options marked XXX are no-ops in this implementation of RPC.
+ * The are present in TI-RPC but can't be implemented here since they
+ * depend on the presence of STREAMS/TLI, which we don't have.
+ */
+#define CLSET_TIMEOUT 1 /* set timeout (timeval) */
+#define CLGET_TIMEOUT 2 /* get timeout (timeval) */
+#define CLGET_SERVER_ADDR 3 /* get server's address (sockaddr) */
+#define CLGET_FD 6 /* get connections file descriptor */
+#define CLGET_SVC_ADDR 7 /* get server's address (netbuf) XXX */
+#define CLSET_FD_CLOSE 8 /* close fd while clnt_destroy */
+#define CLSET_FD_NCLOSE 9 /* Do not close fd while clnt_destroy*/
+#define CLGET_XID 10 /* Get xid */
+#define CLSET_XID 11 /* Set xid */
+#define CLGET_VERS 12 /* Get version number */
+#define CLSET_VERS 13 /* Set version number */
+#define CLGET_PROG 14 /* Get program number */
+#define CLSET_PROG 15 /* Set program number */
+#define CLSET_SVC_ADDR 16 /* get server's address (netbuf) XXX */
+#define CLSET_PUSH_TIMOD 17 /* push timod if not already present XXX */
+#define CLSET_POP_TIMOD 18 /* pop timod XXX */
+/*
+ * Connectionless only control operations
+ */
+#define CLSET_RETRY_TIMEOUT 4 /* set retry timeout (timeval) */
+#define CLGET_RETRY_TIMEOUT 5 /* get retry timeout (timeval) */
+
+/*
+ * void
+ * CLNT_DESTROY(rh);
+ * CLIENT *rh;
+ */
+#define CLNT_DESTROY(rh) ((*(rh)->cl_ops->cl_destroy)(rh))
+#define clnt_destroy(rh) ((*(rh)->cl_ops->cl_destroy)(rh))
+
+
+/*
+ * RPCTEST is a test program which is accessible on every rpc
+ * transport/port. It is used for testing, performance evaluation,
+ * and network administration.
+ */
+
+#define RPCTEST_PROGRAM ((u_long)1)
+#define RPCTEST_VERSION ((u_long)1)
+#define RPCTEST_NULL_PROC ((u_long)2)
+#define RPCTEST_NULL_BATCH_PROC ((u_long)3)
+
+/*
+ * By convention, procedure 0 takes null arguments and returns them
+ */
+
+#define NULLPROC ((u_long)0)
+
+/*
+ * Below are the client handle creation routines for the various
+ * implementations of client side rpc. They can return NULL if a
+ * creation failure occurs.
+ */
+
+/*
+ * Memory based rpc (for speed check and testing)
+ * CLIENT *
+ * clntraw_create(prog, vers)
+ * u_long prog;
+ * u_long vers;
+ */
+extern CLIENT *clntraw_create (const u_long __prog, const u_long __vers)
+ __THROW;
+
+
+/*
+ * Generic client creation routine. Supported protocols are "udp", "tcp" and
+ * "unix"
+ * CLIENT *
+ * clnt_create(host, prog, vers, prot)
+ * char *host; -- hostname
+ * u_long prog; -- program number
+ * u_ong vers; -- version number
+ * char *prot; -- protocol
+ */
+extern CLIENT *clnt_create (const char *__host, const u_long __prog,
+ const u_long __vers, const char *__prot)
+ __THROW;
+
+
+/*
+ * TCP based rpc
+ * CLIENT *
+ * clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
+ * struct sockaddr_in *raddr;
+ * u_long prog;
+ * u_long version;
+ * register int *sockp;
+ * u_int sendsz;
+ * u_int recvsz;
+ */
+extern CLIENT *clnttcp_create (struct sockaddr_in *__raddr, u_long __prog,
+ u_long __version, int *__sockp, u_int __sendsz,
+ u_int __recvsz) __THROW;
+
+/*
+ * UDP based rpc.
+ * CLIENT *
+ * clntudp_create(raddr, program, version, wait, sockp)
+ * struct sockaddr_in *raddr;
+ * u_long program;
+ * u_long version;
+ * struct timeval wait_resend;
+ * int *sockp;
+ *
+ * Same as above, but you specify max packet sizes.
+ * CLIENT *
+ * clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
+ * struct sockaddr_in *raddr;
+ * u_long program;
+ * u_long version;
+ * struct timeval wait_resend;
+ * int *sockp;
+ * u_int sendsz;
+ * u_int recvsz;
+ */
+extern CLIENT *clntudp_create (struct sockaddr_in *__raddr, u_long __program,
+ u_long __version, struct timeval __wait_resend,
+ int *__sockp) __THROW;
+extern CLIENT *clntudp_bufcreate (struct sockaddr_in *__raddr,
+ u_long __program, u_long __version,
+ struct timeval __wait_resend, int *__sockp,
+ u_int __sendsz, u_int __recvsz) __THROW;
+
+
+
+
+/*
+ * AF_UNIX based rpc
+ * CLIENT *
+ * clntunix_create(raddr, prog, vers, sockp, sendsz, recvsz)
+ * struct sockaddr_un *raddr;
+ * u_long prog;
+ * u_long version;
+ * register int *sockp;
+ * u_int sendsz;
+ * u_int recvsz;
+ */
+extern CLIENT *clntunix_create (struct sockaddr_un *__raddr, u_long __program,
+ u_long __version, int *__sockp,
+ u_int __sendsz, u_int __recvsz) __THROW;
+
+
+extern int callrpc (const char *__host, const u_long __prognum,
+ const u_long __versnum, const u_long __procnum,
+ const xdrproc_t __inproc, const char *__in,
+ const xdrproc_t __outproc, char *__out) __THROW;
+extern int _rpc_dtablesize (void) __THROW;
+
+/*
+ * Print why creation failed
+ */
+extern void clnt_pcreateerror (const char *__msg); /* stderr */
+extern char *clnt_spcreateerror(const char *__msg) __THROW; /* string */
+
+/*
+ * Like clnt_perror(), but is more verbose in its output
+ */
+extern void clnt_perrno (enum clnt_stat __num); /* stderr */
+
+/*
+ * Print an English error message, given the client error code
+ */
+extern void clnt_perror (CLIENT *__clnt, const char *__msg);
+ /* stderr */
+extern char *clnt_sperror (CLIENT *__clnt, const char *__msg) __THROW;
+ /* string */
+
+/*
+ * If a creation fails, the following allows the user to figure out why.
+ */
+struct rpc_createerr {
+ enum clnt_stat cf_stat;
+ struct rpc_err cf_error; /* useful when cf_stat == RPC_PMAPFAILURE */
+};
+
+extern struct rpc_createerr rpc_createerr;
+
+
+
+/*
+ * Copy error message to buffer.
+ */
+extern char *clnt_sperrno (enum clnt_stat __num) __THROW; /* string */
+
+/*
+ * get the port number on the host for the rpc program,version and proto
+ */
+extern int getrpcport (const char * __host, u_long __prognum,
+ u_long __versnum, u_int __proto) __THROW;
+
+/*
+ * get the local host's IP address without consulting
+ * name service library functions
+ */
+extern void get_myaddress (struct sockaddr_in *) __THROW;
+
+#ifndef __SYLIXOS_LITE
+#define UDPMSGSIZE 8800 /* rpc imposed limit on udp msg size */
+#define RPCSMALLMSGSIZE 400 /* a more reasonable packet size */
+#define TCPMSGSIZE (32 * 1024) /* reasonably sized RPC/TCP msg */
+#else
+#define UDPMSGSIZE 1200 /* rpc imposed limit on udp msg size */
+#define RPCSMALLMSGSIZE 400 /* a more reasonable packet size */
+#define TCPMSGSIZE 1200 /* reasonably sized RPC/TCP msg */
+#endif
+
+__END_DECLS
+
+#endif /* rpc/clnt.h */
diff --git a/sunrpc/rpc/des_crypt.h b/sunrpc/rpc/des_crypt.h
new file mode 100644
index 0000000..d728f53
--- /dev/null
+++ b/sunrpc/rpc/des_crypt.h
@@ -0,0 +1,100 @@
+/*
+ * @(#)des_crypt.h 2.1 88/08/11 4.0 RPCSRC
+ *
+ * des_crypt.h, des library routine interface
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __DES_CRYPT_H__
+#define __DES_CRYPT_H__ 1
+
+#ifndef SYLIXOS
+#include <features.h>
+#else
+#include <sys/cdefs.h>
+#endif
+
+__BEGIN_DECLS
+
+#define DES_MAXDATA 8192 /* max bytes encrypted in one call */
+#define DES_DIRMASK (1 << 0)
+#define DES_ENCRYPT (0*DES_DIRMASK) /* Encrypt */
+#define DES_DECRYPT (1*DES_DIRMASK) /* Decrypt */
+
+
+#define DES_DEVMASK (1 << 1)
+#define DES_HW (0*DES_DEVMASK) /* Use hardware device */
+#define DES_SW (1*DES_DEVMASK) /* Use software device */
+
+
+#define DESERR_NONE 0 /* succeeded */
+#define DESERR_NOHWDEVICE 1 /* succeeded, but hw device not available */
+#define DESERR_HWERROR 2 /* failed, hardware/driver error */
+#define DESERR_BADPARAM 3 /* failed, bad parameter to call */
+
+#define DES_FAILED(err) \
+ ((err) > DESERR_NOHWDEVICE)
+
+/*
+ * cbc_crypt()
+ * ecb_crypt()
+ *
+ * Encrypt (or decrypt) len bytes of a buffer buf.
+ * The length must be a multiple of eight.
+ * The key should have odd parity in the low bit of each byte.
+ * ivec is the input vector, and is updated to the new one (cbc only).
+ * The mode is created by oring together the appropriate parameters.
+ * DESERR_NOHWDEVICE is returned if DES_HW was specified but
+ * there was no hardware to do it on (the data will still be
+ * encrypted though, in software).
+ */
+
+
+/*
+ * Cipher Block Chaining mode
+ */
+extern int cbc_crypt (char *__key, char *__buf, unsigned __len,
+ unsigned __mode, char *__ivec) __THROW;
+
+/*
+ * Electronic Code Book mode
+ */
+extern int ecb_crypt (char *__key, char *__buf, unsigned __len,
+ unsigned __mode) __THROW;
+
+/*
+ * Set des parity for a key.
+ * DES parity is odd and in the low bit of each byte
+ */
+extern void des_setparity (char *__key) __THROW;
+
+__END_DECLS
+
+#endif
diff --git a/sunrpc/rpc/key_prot.h b/sunrpc/rpc/key_prot.h
new file mode 100644
index 0000000..74627e6
--- /dev/null
+++ b/sunrpc/rpc/key_prot.h
@@ -0,0 +1,343 @@
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#ifndef _KEY_PROT_H_RPCGEN
+#define _KEY_PROT_H_RPCGEN
+
+#include <rpc/rpc.h>
+
+/* Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Compiled from key_prot.x using rpcgen.
+ * DO NOT EDIT THIS FILE!
+ * This is NOT source code!
+ */
+#define PROOT 3
+#define HEXMODULUS "d4a0ba0250b6fd2ec626e7efd637df76c716e22d0944b88b"
+#define HEXKEYBYTES 48
+#define KEYSIZE 192
+#define KEYBYTES 24
+#define KEYCHECKSUMSIZE 16
+
+enum keystatus {
+ KEY_SUCCESS = 0,
+ KEY_NOSECRET = 1,
+ KEY_UNKNOWN = 2,
+ KEY_SYSTEMERR = 3,
+};
+typedef enum keystatus keystatus;
+#ifdef __cplusplus
+extern "C" bool_t xdr_keystatus(XDR *, keystatus*);
+#elif __STDC__
+extern bool_t xdr_keystatus(XDR *, keystatus*);
+#else /* Old Style C */
+bool_t xdr_keystatus();
+#endif /* Old Style C */
+
+
+typedef char keybuf[HEXKEYBYTES];
+#ifdef __cplusplus
+extern "C" bool_t xdr_keybuf(XDR *, keybuf);
+#elif __STDC__
+extern bool_t xdr_keybuf(XDR *, keybuf);
+#else /* Old Style C */
+bool_t xdr_keybuf();
+#endif /* Old Style C */
+
+
+typedef char *netnamestr;
+#ifdef __cplusplus
+extern "C" bool_t xdr_netnamestr(XDR *, netnamestr*);
+#elif __STDC__
+extern bool_t xdr_netnamestr(XDR *, netnamestr*);
+#else /* Old Style C */
+bool_t xdr_netnamestr();
+#endif /* Old Style C */
+
+
+struct cryptkeyarg {
+ netnamestr remotename;
+ des_block deskey;
+};
+typedef struct cryptkeyarg cryptkeyarg;
+#ifdef __cplusplus
+extern "C" bool_t xdr_cryptkeyarg(XDR *, cryptkeyarg*);
+#elif __STDC__
+extern bool_t xdr_cryptkeyarg(XDR *, cryptkeyarg*);
+#else /* Old Style C */
+bool_t xdr_cryptkeyarg();
+#endif /* Old Style C */
+
+
+struct cryptkeyarg2 {
+ netnamestr remotename;
+ netobj remotekey;
+ des_block deskey;
+};
+typedef struct cryptkeyarg2 cryptkeyarg2;
+#ifdef __cplusplus
+extern "C" bool_t xdr_cryptkeyarg2(XDR *, cryptkeyarg2*);
+#elif __STDC__
+extern bool_t xdr_cryptkeyarg2(XDR *, cryptkeyarg2*);
+#else /* Old Style C */
+bool_t xdr_cryptkeyarg2();
+#endif /* Old Style C */
+
+
+struct cryptkeyres {
+ keystatus status;
+ union {
+ des_block deskey;
+ } cryptkeyres_u;
+};
+typedef struct cryptkeyres cryptkeyres;
+#ifdef __cplusplus
+extern "C" bool_t xdr_cryptkeyres(XDR *, cryptkeyres*);
+#elif __STDC__
+extern bool_t xdr_cryptkeyres(XDR *, cryptkeyres*);
+#else /* Old Style C */
+bool_t xdr_cryptkeyres();
+#endif /* Old Style C */
+
+#define MAXGIDS 16
+
+struct unixcred {
+ u_int uid;
+ u_int gid;
+ struct {
+ u_int gids_len;
+ u_int *gids_val;
+ } gids;
+};
+typedef struct unixcred unixcred;
+#ifdef __cplusplus
+extern "C" bool_t xdr_unixcred(XDR *, unixcred*);
+#elif __STDC__
+extern bool_t xdr_unixcred(XDR *, unixcred*);
+#else /* Old Style C */
+bool_t xdr_unixcred();
+#endif /* Old Style C */
+
+
+struct getcredres {
+ keystatus status;
+ union {
+ unixcred cred;
+ } getcredres_u;
+};
+typedef struct getcredres getcredres;
+#ifdef __cplusplus
+extern "C" bool_t xdr_getcredres(XDR *, getcredres*);
+#elif __STDC__
+extern bool_t xdr_getcredres(XDR *, getcredres*);
+#else /* Old Style C */
+bool_t xdr_getcredres();
+#endif /* Old Style C */
+
+
+struct key_netstarg {
+ keybuf st_priv_key;
+ keybuf st_pub_key;
+ netnamestr st_netname;
+};
+typedef struct key_netstarg key_netstarg;
+#ifdef __cplusplus
+extern "C" bool_t xdr_key_netstarg(XDR *, key_netstarg*);
+#elif __STDC__
+extern bool_t xdr_key_netstarg(XDR *, key_netstarg*);
+#else /* Old Style C */
+bool_t xdr_key_netstarg();
+#endif /* Old Style C */
+
+
+struct key_netstres {
+ keystatus status;
+ union {
+ key_netstarg knet;
+ } key_netstres_u;
+};
+typedef struct key_netstres key_netstres;
+#ifdef __cplusplus
+extern "C" bool_t xdr_key_netstres(XDR *, key_netstres*);
+#elif __STDC__
+extern bool_t xdr_key_netstres(XDR *, key_netstres*);
+#else /* Old Style C */
+bool_t xdr_key_netstres();
+#endif /* Old Style C */
+
+
+#ifndef opaque
+#define opaque char
+#endif
+
+
+#define KEY_PROG ((u_long)100029)
+#define KEY_VERS ((u_long)1)
+
+#ifdef __cplusplus
+#define KEY_SET ((u_long)1)
+extern "C" keystatus * key_set_1(opaque *, CLIENT *);
+extern "C" keystatus * key_set_1_svc(opaque *, struct svc_req *);
+#define KEY_ENCRYPT ((u_long)2)
+extern "C" cryptkeyres * key_encrypt_1(cryptkeyarg *, CLIENT *);
+extern "C" cryptkeyres * key_encrypt_1_svc(cryptkeyarg *, struct svc_req *);
+#define KEY_DECRYPT ((u_long)3)
+extern "C" cryptkeyres * key_decrypt_1(cryptkeyarg *, CLIENT *);
+extern "C" cryptkeyres * key_decrypt_1_svc(cryptkeyarg *, struct svc_req *);
+#define KEY_GEN ((u_long)4)
+extern "C" des_block * key_gen_1(void *, CLIENT *);
+extern "C" des_block * key_gen_1_svc(void *, struct svc_req *);
+#define KEY_GETCRED ((u_long)5)
+extern "C" getcredres * key_getcred_1(netnamestr *, CLIENT *);
+extern "C" getcredres * key_getcred_1_svc(netnamestr *, struct svc_req *);
+
+#elif __STDC__
+#define KEY_SET ((u_long)1)
+extern keystatus * key_set_1(opaque *, CLIENT *);
+extern keystatus * key_set_1_svc(opaque *, struct svc_req *);
+#define KEY_ENCRYPT ((u_long)2)
+extern cryptkeyres * key_encrypt_1(cryptkeyarg *, CLIENT *);
+extern cryptkeyres * key_encrypt_1_svc(cryptkeyarg *, struct svc_req *);
+#define KEY_DECRYPT ((u_long)3)
+extern cryptkeyres * key_decrypt_1(cryptkeyarg *, CLIENT *);
+extern cryptkeyres * key_decrypt_1_svc(cryptkeyarg *, struct svc_req *);
+#define KEY_GEN ((u_long)4)
+extern des_block * key_gen_1(void *, CLIENT *);
+extern des_block * key_gen_1_svc(void *, struct svc_req *);
+#define KEY_GETCRED ((u_long)5)
+extern getcredres * key_getcred_1(netnamestr *, CLIENT *);
+extern getcredres * key_getcred_1_svc(netnamestr *, struct svc_req *);
+
+#else /* Old Style C */
+#define KEY_SET ((u_long)1)
+extern keystatus * key_set_1();
+extern keystatus * key_set_1_svc();
+#define KEY_ENCRYPT ((u_long)2)
+extern cryptkeyres * key_encrypt_1();
+extern cryptkeyres * key_encrypt_1_svc();
+#define KEY_DECRYPT ((u_long)3)
+extern cryptkeyres * key_decrypt_1();
+extern cryptkeyres * key_decrypt_1_svc();
+#define KEY_GEN ((u_long)4)
+extern des_block * key_gen_1();
+extern des_block * key_gen_1_svc();
+#define KEY_GETCRED ((u_long)5)
+extern getcredres * key_getcred_1();
+extern getcredres * key_getcred_1_svc();
+#endif /* Old Style C */
+#define KEY_VERS2 ((u_long)2)
+
+#ifdef __cplusplus
+extern "C" keystatus * key_set_2(opaque *, CLIENT *);
+extern "C" keystatus * key_set_2_svc(opaque *, struct svc_req *);
+extern "C" cryptkeyres * key_encrypt_2(cryptkeyarg *, CLIENT *);
+extern "C" cryptkeyres * key_encrypt_2_svc(cryptkeyarg *, struct svc_req *);
+extern "C" cryptkeyres * key_decrypt_2(cryptkeyarg *, CLIENT *);
+extern "C" cryptkeyres * key_decrypt_2_svc(cryptkeyarg *, struct svc_req *);
+extern "C" des_block * key_gen_2(void *, CLIENT *);
+extern "C" des_block * key_gen_2_svc(void *, struct svc_req *);
+extern "C" getcredres * key_getcred_2(netnamestr *, CLIENT *);
+extern "C" getcredres * key_getcred_2_svc(netnamestr *, struct svc_req *);
+#define KEY_ENCRYPT_PK ((u_long)6)
+extern "C" cryptkeyres * key_encrypt_pk_2(cryptkeyarg2 *, CLIENT *);
+extern "C" cryptkeyres * key_encrypt_pk_2_svc(cryptkeyarg2 *, struct svc_req *);
+#define KEY_DECRYPT_PK ((u_long)7)
+extern "C" cryptkeyres * key_decrypt_pk_2(cryptkeyarg2 *, CLIENT *);
+extern "C" cryptkeyres * key_decrypt_pk_2_svc(cryptkeyarg2 *, struct svc_req *);
+#define KEY_NET_PUT ((u_long)8)
+extern "C" keystatus * key_net_put_2(key_netstarg *, CLIENT *);
+extern "C" keystatus * key_net_put_2_svc(key_netstarg *, struct svc_req *);
+#define KEY_NET_GET ((u_long)9)
+extern "C" key_netstres * key_net_get_2(void *, CLIENT *);
+extern "C" key_netstres * key_net_get_2_svc(void *, struct svc_req *);
+#define KEY_GET_CONV ((u_long)10)
+extern "C" cryptkeyres * key_get_conv_2(opaque *, CLIENT *);
+extern "C" cryptkeyres * key_get_conv_2_svc(opaque *, struct svc_req *);
+
+#elif __STDC__
+extern keystatus * key_set_2(opaque *, CLIENT *);
+extern keystatus * key_set_2_svc(opaque *, struct svc_req *);
+extern cryptkeyres * key_encrypt_2(cryptkeyarg *, CLIENT *);
+extern cryptkeyres * key_encrypt_2_svc(cryptkeyarg *, struct svc_req *);
+extern cryptkeyres * key_decrypt_2(cryptkeyarg *, CLIENT *);
+extern cryptkeyres * key_decrypt_2_svc(cryptkeyarg *, struct svc_req *);
+extern des_block * key_gen_2(void *, CLIENT *);
+extern des_block * key_gen_2_svc(void *, struct svc_req *);
+extern getcredres * key_getcred_2(netnamestr *, CLIENT *);
+extern getcredres * key_getcred_2_svc(netnamestr *, struct svc_req *);
+#define KEY_ENCRYPT_PK ((u_long)6)
+extern cryptkeyres * key_encrypt_pk_2(cryptkeyarg2 *, CLIENT *);
+extern cryptkeyres * key_encrypt_pk_2_svc(cryptkeyarg2 *, struct svc_req *);
+#define KEY_DECRYPT_PK ((u_long)7)
+extern cryptkeyres * key_decrypt_pk_2(cryptkeyarg2 *, CLIENT *);
+extern cryptkeyres * key_decrypt_pk_2_svc(cryptkeyarg2 *, struct svc_req *);
+#define KEY_NET_PUT ((u_long)8)
+extern keystatus * key_net_put_2(key_netstarg *, CLIENT *);
+extern keystatus * key_net_put_2_svc(key_netstarg *, struct svc_req *);
+#define KEY_NET_GET ((u_long)9)
+extern key_netstres * key_net_get_2(void *, CLIENT *);
+extern key_netstres * key_net_get_2_svc(void *, struct svc_req *);
+#define KEY_GET_CONV ((u_long)10)
+extern cryptkeyres * key_get_conv_2(opaque *, CLIENT *);
+extern cryptkeyres * key_get_conv_2_svc(opaque *, struct svc_req *);
+
+#else /* Old Style C */
+extern keystatus * key_set_2();
+extern keystatus * key_set_2_svc();
+extern cryptkeyres * key_encrypt_2();
+extern cryptkeyres * key_encrypt_2_svc();
+extern cryptkeyres * key_decrypt_2();
+extern cryptkeyres * key_decrypt_2_svc();
+extern des_block * key_gen_2();
+extern des_block * key_gen_2_svc();
+extern getcredres * key_getcred_2();
+extern getcredres * key_getcred_2_svc();
+#define KEY_ENCRYPT_PK ((u_long)6)
+extern cryptkeyres * key_encrypt_pk_2();
+extern cryptkeyres * key_encrypt_pk_2_svc();
+#define KEY_DECRYPT_PK ((u_long)7)
+extern cryptkeyres * key_decrypt_pk_2();
+extern cryptkeyres * key_decrypt_pk_2_svc();
+#define KEY_NET_PUT ((u_long)8)
+extern keystatus * key_net_put_2();
+extern keystatus * key_net_put_2_svc();
+#define KEY_NET_GET ((u_long)9)
+extern key_netstres * key_net_get_2();
+extern key_netstres * key_net_get_2_svc();
+#define KEY_GET_CONV ((u_long)10)
+extern cryptkeyres * key_get_conv_2();
+extern cryptkeyres * key_get_conv_2_svc();
+#endif /* Old Style C */
+
+#endif /* !_KEY_PROT_H_RPCGEN */
diff --git a/sunrpc/rpc/netdb.h b/sunrpc/rpc/netdb.h
new file mode 100644
index 0000000..31482e1
--- /dev/null
+++ b/sunrpc/rpc/netdb.h
@@ -0,0 +1,76 @@
+/* @(#)netdb.h 2.1 88/07/29 3.9 RPCSRC */
+/*
+ * Copyright (c) 2010, Oracle America, Inc.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Cleaned up for GNU C library roland@gnu.ai.mit.edu:
+ added multiple inclusion protection and use of <sys/cdefs.h>.
+ In GNU this file is #include'd by <netdb.h>. */
+
+#ifndef _RPC_NETDB_H
+#define _RPC_NETDB_H 1
+
+#ifndef SYLIXOS
+#include <features.h>
+#endif
+
+#define __need_size_t
+#include <stddef.h>
+
+__BEGIN_DECLS
+
+struct rpcent
+{
+ char *r_name; /* Name of server for this rpc program. */
+ char **r_aliases; /* Alias list. */
+ int r_number; /* RPC program number. */
+};
+
+extern void setrpcent (int __stayopen) __THROW;
+extern void endrpcent (void) __THROW;
+extern struct rpcent *getrpcbyname (const char *__name) __THROW;
+extern struct rpcent *getrpcbynumber (int __number) __THROW;
+extern struct rpcent *getrpcent (void) __THROW;
+
+#ifdef __USE_MISC
+extern int getrpcbyname_r (const char *__name, struct rpcent *__result_buf,
+ char *__buffer, size_t __buflen,
+ struct rpcent **__result) __THROW;
+
+extern int getrpcbynumber_r (int __number, struct rpcent *__result_buf,
+ char *__buffer, size_t __buflen,
+ struct rpcent **__result) __THROW;
+
+extern int getrpcent_r (struct rpcent *__result_buf, char *__buffer,
+ size_t __buflen, struct rpcent **__result) __THROW;
+#endif
+
+__END_DECLS
+
+#endif /* rpc/netdb.h */
diff --git a/sunrpc/rpc/pmap_clnt.h b/sunrpc/rpc/pmap_clnt.h
new file mode 100644
index 0000000..7fe9d8b
--- /dev/null
+++ b/sunrpc/rpc/pmap_clnt.h
@@ -0,0 +1,97 @@
+/*
+ * pmap_clnt.h
+ * Supplies C routines to get to portmap services.
+ *
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RPC_PMAP_CLNT_H
+#define _RPC_PMAP_CLNT_H 1
+
+#ifndef SYLIXOS
+#include <features.h>
+#endif
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/clnt.h>
+
+__BEGIN_DECLS
+
+typedef bool_t (*resultproc_t) (caddr_t __resp, struct sockaddr_in *__raddr);
+
+/*
+ * Usage:
+ * success = pmap_set(program, version, protocol, port);
+ * success = pmap_unset(program, version);
+ * port = pmap_getport(address, program, version, protocol);
+ * head = pmap_getmaps(address);
+ * clnt_stat = pmap_rmtcall(address, program, version, procedure,
+ * xdrargs, argsp, xdrres, resp, tout, port_ptr)
+ * (works for udp only.)
+ * clnt_stat = clnt_broadcast(program, version, procedure,
+ * xdrargs, argsp, xdrres, resp, eachresult)
+ * (like pmap_rmtcall, except the call is broadcasted to all
+ * locally connected nets. For each valid response received,
+ * the procedure eachresult is called. Its form is:
+ * done = eachresult(resp, raddr)
+ * bool_t done;
+ * caddr_t resp;
+ * struct sockaddr_in raddr;
+ * where resp points to the results of the call and raddr is the
+ * address if the responder to the broadcast.
+ */
+
+extern bool_t pmap_set (const u_long __program, const u_long __vers,
+ int __protocol, u_short __port) __THROW;
+extern bool_t pmap_unset (const u_long __program, const u_long __vers)
+ __THROW;
+extern struct pmaplist *pmap_getmaps (struct sockaddr_in *__address) __THROW;
+extern enum clnt_stat pmap_rmtcall (struct sockaddr_in *__addr,
+ const u_long __prog,
+ const u_long __vers,
+ const u_long __proc,
+ xdrproc_t __xdrargs,
+ caddr_t __argsp, xdrproc_t __xdrres,
+ caddr_t __resp, struct timeval __tout,
+ u_long *__port_ptr) __THROW;
+extern enum clnt_stat clnt_broadcast (const u_long __prog,
+ const u_long __vers,
+ const u_long __proc, xdrproc_t __xargs,
+ caddr_t __argsp, xdrproc_t __xresults,
+ caddr_t __resultsp,
+ resultproc_t __eachresult) __THROW;
+extern u_short pmap_getport (struct sockaddr_in *__address,
+ const u_long __program,
+ const u_long __version, u_int __protocol)
+ __THROW;
+
+__END_DECLS
+
+#endif /* rpc/pmap_clnt.h */
diff --git a/sunrpc/rpc/pmap_prot.h b/sunrpc/rpc/pmap_prot.h
new file mode 100644
index 0000000..a83a84a
--- /dev/null
+++ b/sunrpc/rpc/pmap_prot.h
@@ -0,0 +1,107 @@
+/*
+ * pmap_prot.h
+ * Protocol for the local binder service, or pmap.
+ *
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RPC_PMAP_PROT_H
+#define _RPC_PMAP_PROT_H 1
+
+#ifndef SYLIXOS
+#include <features.h>
+#endif
+
+#include <rpc/xdr.h>
+
+__BEGIN_DECLS
+
+/* 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 *)
+ *
+ * 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.
+ */
+
+#define PMAPPORT ((u_short)111)
+#define PMAPPROG ((u_long)100000)
+#define PMAPVERS ((u_long)2)
+#define PMAPVERS_PROTO ((u_long)2)
+#define PMAPVERS_ORIG ((u_long)1)
+#define PMAPPROC_NULL ((u_long)0)
+#define PMAPPROC_SET ((u_long)1)
+#define PMAPPROC_UNSET ((u_long)2)
+#define PMAPPROC_GETPORT ((u_long)3)
+#define PMAPPROC_DUMP ((u_long)4)
+#define PMAPPROC_CALLIT ((u_long)5)
+
+struct pmap {
+ long unsigned pm_prog;
+ long unsigned pm_vers;
+ long unsigned pm_prot;
+ long unsigned pm_port;
+};
+
+extern bool_t xdr_pmap (XDR *__xdrs, struct pmap *__regs) __THROW;
+
+struct pmaplist {
+ struct pmap pml_map;
+ struct pmaplist *pml_next;
+};
+
+extern bool_t xdr_pmaplist (XDR *__xdrs, struct pmaplist **__rp) __THROW;
+
+__END_DECLS
+
+#endif /* rpc/pmap_prot.h */
diff --git a/sunrpc/rpc/pmap_rmt.h b/sunrpc/rpc/pmap_rmt.h
new file mode 100644
index 0000000..c7e1a79
--- /dev/null
+++ b/sunrpc/rpc/pmap_rmt.h
@@ -0,0 +1,67 @@
+/*
+ * Structures and XDR routines for parameters to and replies from
+ * the portmapper remote-call-service.
+ *
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RPC_PMAP_RMT_H
+#define _RPC_PMAP_RMT_H 1
+
+#ifndef SYLIXOS
+#include <features.h>
+#endif
+#include <sys/types.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+__BEGIN_DECLS
+
+struct rmtcallargs {
+ u_long prog, vers, proc, arglen;
+ caddr_t args_ptr;
+ xdrproc_t xdr_args;
+};
+
+extern bool_t xdr_rmtcall_args (XDR *__xdrs, struct rmtcallargs *__crp)
+ __THROW;
+
+struct rmtcallres {
+ u_long *port_ptr;
+ u_long resultslen;
+ caddr_t results_ptr;
+ xdrproc_t xdr_results;
+};
+
+extern bool_t xdr_rmtcallres (XDR *__xdrs, struct rmtcallres *__crp) __THROW;
+
+__END_DECLS
+
+#endif /* rpc/pmap_rmt.h */
diff --git a/sunrpc/rpc/rpc.h b/sunrpc/rpc/rpc.h
new file mode 100644
index 0000000..acfe26a
--- /dev/null
+++ b/sunrpc/rpc/rpc.h
@@ -0,0 +1,102 @@
+/*
+ * rpc.h, Just includes the billions of rpc header files necessary to
+ * do remote procedure calling.
+ *
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RPC_RPC_H
+#define _RPC_RPC_H 1
+
+#include <rpc/types.h> /* some typedefs */
+#include <netinet/in.h>
+
+/* external data representation interfaces */
+#include <rpc/xdr.h> /* generic (de)serializer */
+
+/* Client side only authentication */
+#include <rpc/auth.h> /* generic authenticator (client side) */
+
+/* Client side (mostly) remote procedure call */
+#include <rpc/clnt.h> /* generic rpc stuff */
+
+/* semi-private protocol headers */
+#include <rpc/rpc_msg.h> /* protocol for rpc messages */
+#include <rpc/auth_unix.h> /* protocol for unix style cred */
+#include <rpc/auth_des.h> /* protocol for des style cred */
+
+/* Server side only remote procedure callee */
+#include <rpc/svc.h> /* service manager and multiplexer */
+#include <rpc/svc_auth.h> /* service side authenticator */
+
+/*
+ * COMMENT OUT THE NEXT INCLUDE IF RUNNING ON SUN OS OR ON A VERSION
+ * OF UNIX BASED ON NFSSRC. These systems will already have the structures
+ * defined by <rpc/netdb.h> included in <netdb.h>.
+ */
+/* routines for parsing /etc/rpc */
+#include <rpc/netdb.h> /* structures and routines to parse /etc/rpc */
+
+__BEGIN_DECLS
+
+#ifdef _RPC_THREAD_SAFE_
+/* Global variables, protected for multi-threaded applications. */
+extern fd_set *__rpc_thread_svc_fdset (void) __attribute__ ((__const__));
+#define svc_fdset (*__rpc_thread_svc_fdset ())
+
+extern struct rpc_createerr *__rpc_thread_createerr (void)
+ __attribute__ ((__const__));
+#define get_rpc_createerr() (*__rpc_thread_createerr ())
+/* The people who "engineered" RPC should bee punished for naming the
+ data structure and the variable the same. We cannot always define the
+ macro 'rpc_createerr' because this would prevent people from defining
+ object of type 'struct rpc_createerr'. So we leave it up to the user
+ to select transparent replacement also of this variable. */
+#ifdef _RPC_MT_VARS
+# define rpc_createerr (*__rpc_thread_createerr ())
+#endif
+
+extern struct pollfd **__rpc_thread_svc_pollfd (void)
+ __attribute__ ((__const__));
+#define svc_pollfd (*__rpc_thread_svc_pollfd ())
+
+extern int *__rpc_thread_svc_max_pollfd (void) __attribute__ ((__const__));
+#define svc_max_pollfd (*__rpc_thread_svc_max_pollfd ())
+#else
+extern fd_set svc_fdset;
+extern struct rpc_createerr rpc_createerr;
+#define get_rpc_createerr() rpc_createerr
+extern struct pollfd *svc_pollfd;
+extern int svc_max_pollfd;
+#endif
+
+__END_DECLS
+
+#endif /* rpc/rpc.h */
diff --git a/sunrpc/rpc/rpc_des.h b/sunrpc/rpc/rpc_des.h
new file mode 100644
index 0000000..8f4a2e2
--- /dev/null
+++ b/sunrpc/rpc/rpc_des.h
@@ -0,0 +1,72 @@
+/*
+ * Generic DES driver interface
+ * Keep this file hardware independent!
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DES_H
+#define _DES_H
+
+#include <sys/types.h>
+#include <rpc/types.h>
+
+#define DES_MAXLEN 65536 /* maximum # of bytes to encrypt */
+#define DES_QUICKLEN 16 /* maximum # of bytes to encrypt quickly */
+
+enum desdir
+ {
+ ENCRYPT, DECRYPT
+ };
+enum desmode
+ {
+ CBC, ECB
+ };
+
+/*
+ * parameters to ioctl call
+ */
+struct desparams
+ {
+ u_char des_key[8]; /* key (with low bit parity) */
+ enum desdir des_dir; /* direction */
+ enum desmode des_mode; /* mode */
+ u_char des_ivec[8]; /* input vector */
+ unsigned des_len; /* number of bytes to crypt */
+ union
+ {
+ u_char UDES_data[DES_QUICKLEN];
+ u_char *UDES_buf;
+ }
+ UDES;
+#define des_data UDES.UDES_data /* direct data here if quick */
+#define des_buf UDES.UDES_buf /* otherwise, pointer to data */
+ };
+
+#endif
diff --git a/sunrpc/rpc/rpc_msg.h b/sunrpc/rpc/rpc_msg.h
new file mode 100644
index 0000000..273b187
--- /dev/null
+++ b/sunrpc/rpc/rpc_msg.h
@@ -0,0 +1,198 @@
+/*
+ * rpc_msg.h
+ * rpc message definition
+ *
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RPC_MSG_H
+#define _RPC_MSG_H 1
+
+#include <sys/cdefs.h>
+
+#include <rpc/xdr.h>
+#include <rpc/clnt.h>
+
+#define RPC_MSG_VERSION ((u_long) 2)
+#define RPC_SERVICE_PORT ((u_short) 2048)
+
+__BEGIN_DECLS
+
+/*
+ * Bottom up definition of an rpc message.
+ * NOTE: call and reply use the same overall struct but
+ * different parts of unions within it.
+ */
+
+enum msg_type {
+ CALL=0,
+ REPLY=1
+};
+
+enum reply_stat {
+ MSG_ACCEPTED=0,
+ MSG_DENIED=1
+};
+
+enum accept_stat {
+ SUCCESS=0,
+ PROG_UNAVAIL=1,
+ PROG_MISMATCH=2,
+ PROC_UNAVAIL=3,
+ GARBAGE_ARGS=4,
+ SYSTEM_ERR=5
+};
+
+enum reject_stat {
+ RPC_MISMATCH=0,
+ AUTH_ERROR=1
+};
+
+/*
+ * Reply part of an rpc exchange
+ */
+
+/*
+ * Reply to an rpc request that was accepted by the server.
+ * Note: there could be an error even though the request was
+ * accepted.
+ */
+struct accepted_reply {
+ struct opaque_auth ar_verf;
+ enum accept_stat ar_stat;
+ union {
+ struct {
+ u_long low;
+ u_long high;
+ } AR_versions;
+ struct {
+ caddr_t where;
+ xdrproc_t proc;
+ } AR_results;
+ /* and many other null cases */
+ } ru;
+#define ar_results ru.AR_results
+#define ar_vers ru.AR_versions
+};
+
+/*
+ * Reply to an rpc request that was rejected by the server.
+ */
+struct rejected_reply {
+ enum reject_stat rj_stat;
+ union {
+ struct {
+ u_long low;
+ u_long high;
+ } RJ_versions;
+ enum auth_stat RJ_why; /* why authentication did not work */
+ } ru;
+#define rj_vers ru.RJ_versions
+#define rj_why ru.RJ_why
+};
+
+/*
+ * Body of a reply to an rpc request.
+ */
+struct reply_body {
+ enum reply_stat rp_stat;
+ union {
+ struct accepted_reply RP_ar;
+ struct rejected_reply RP_dr;
+ } ru;
+#define rp_acpt ru.RP_ar
+#define rp_rjct ru.RP_dr
+};
+
+/*
+ * Body of an rpc request call.
+ */
+struct call_body {
+ u_long cb_rpcvers; /* must be equal to two */
+ u_long cb_prog;
+ u_long cb_vers;
+ u_long cb_proc;
+ struct opaque_auth cb_cred;
+ struct opaque_auth cb_verf; /* protocol specific - provided by client */
+};
+
+/*
+ * The rpc message
+ */
+struct rpc_msg {
+ u_long rm_xid;
+ enum msg_type rm_direction;
+ union {
+ struct call_body RM_cmb;
+ struct reply_body RM_rmb;
+ } ru;
+#define rm_call ru.RM_cmb
+#define rm_reply ru.RM_rmb
+};
+#define acpted_rply ru.RM_rmb.ru.RP_ar
+#define rjcted_rply ru.RM_rmb.ru.RP_dr
+
+
+/*
+ * XDR routine to handle a rpc message.
+ * xdr_callmsg(xdrs, cmsg)
+ * XDR *xdrs;
+ * struct rpc_msg *cmsg;
+ */
+extern bool_t xdr_callmsg (XDR *__xdrs, struct rpc_msg *__cmsg) __THROW;
+
+/*
+ * XDR routine to pre-serialize the static part of a rpc message.
+ * xdr_callhdr(xdrs, cmsg)
+ * XDR *xdrs;
+ * struct rpc_msg *cmsg;
+ */
+extern bool_t xdr_callhdr (XDR *__xdrs, struct rpc_msg *__cmsg) __THROW;
+
+/*
+ * XDR routine to handle a rpc reply.
+ * xdr_replymsg(xdrs, rmsg)
+ * XDR *xdrs;
+ * struct rpc_msg *rmsg;
+ */
+extern bool_t xdr_replymsg (XDR *__xdrs, struct rpc_msg *__rmsg) __THROW;
+
+/*
+ * Fills in the error part of a reply message.
+ * _seterr_reply(msg, error)
+ * struct rpc_msg *msg;
+ * struct rpc_err *error;
+ */
+extern void _seterr_reply (struct rpc_msg *__msg, struct rpc_err *__error)
+ __THROW;
+
+__END_DECLS
+
+#endif /* rpc/rpc_msg.h */
diff --git a/sunrpc/rpc/rpc_sylixos.h b/sunrpc/rpc/rpc_sylixos.h
new file mode 100644
index 0000000..be7cf07
--- /dev/null
+++ b/sunrpc/rpc/rpc_sylixos.h
@@ -0,0 +1,116 @@
+/**
+ * @file
+ * rpc SylixOS porting file.
+ */
+
+/*
+ * Copyright (c) 2006-2017 SylixOS Group.
+ * 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.
+ *
+ * Author: Jiao.JinXing
+ *
+ */
+
+#ifndef _RPC_SYLIXOS_H
+#define _RPC_SYLIXOS_H 1
+
+#include <pthread.h>
+#include <stdio.h>
+
+typedef gid_t __gid_t;
+typedef uid_t __uid_t;
+
+#define internal_function
+
+#define libc_hidden_nolink_sunrpc(...)
+#define libc_sunrpc_symbol(...)
+#define libc_hidden_def(a)
+
+#define __libc_once_define(filed, var) filed pthread_once_t var = PTHREAD_ONCE_INIT
+#define __libc_once(var, func) pthread_once(&var, func)
+
+#define __libc_lock_define_initialized(filed, var) filed pthread_mutex_t var = PTHREAD_MUTEX_INITIALIZER;
+#define __libc_lock_lock(var) pthread_mutex_lock(&var)
+#define __libc_lock_unlock(var) pthread_mutex_unlock(&var)
+
+#define __glibc_unlikely(x) (x)
+
+#define __FLOAT_WORD_ORDER __BYTE_ORDER
+
+#ifndef IPPORT_TIMESERVER
+#define IPPORT_TIMESERVER 37
+#endif
+
+#define _(str) str
+#define N_(str) str
+
+void __svc_accept_failed (void);
+
+struct sockaddr_in;
+int bindresvport (int sd, struct sockaddr_in *sin);
+int internal_function __get_socket (struct sockaddr_in *saddr);
+
+struct protoent;
+extern int __getprotobyname_r (const char *__name,
+ struct protoent *__result_buf,
+ char *__buf, size_t __buflen,
+ struct protoent **__result);
+
+#define ffsl ffs
+#define __getdtablesize() sysconf(_SC_OPEN_MAX)
+#define __fxprintf(fp, fmt, ...) fprintf(((fp) ? (fp) : stderr), fmt, __VA_ARGS__)
+#define __asprintf asprintf
+#define __fcntl fcntl
+#define __lseek lseek
+#define __gettimeofday gettimeofday
+#define __nanosleep nanosleep
+#define __socket socket
+#define __bind(sock, addr, len) bind(sock, (struct sockaddr *)addr, len)
+#define __getsockname getsockname
+#define __listen listen
+#define __close close
+#define __setsockopt setsockopt
+#define __recvmsg recvmsg
+#define __sendmsg sendmsg
+#define __sendto sendto
+#define __recvfrom recvfrom
+#define __connect connect
+#define __poll poll
+#define __read read
+#define __write write
+#define close_not_cancel close
+#define __getpid getpid
+#define __geteuid geteuid
+#define __getegid getegid
+#define __getgroups getgroups
+#define __bzero bzero
+#define __set_errno(num) errno = (num)
+#define __getpeername getpeername
+#define __alloca alloca
+#define __gethostbyname_r gethostbyname_r
+#define __gethostname gethostname
+#define __strerror_r(num, buf, len) (strerror_r(num, buf, len) == 0 ? (buf) : NULL)
+
+#endif /* _RPC_SYLIXOS_H */
diff --git a/sunrpc/rpc/svc.h b/sunrpc/rpc/svc.h
new file mode 100644
index 0000000..9cb46d9
--- /dev/null
+++ b/sunrpc/rpc/svc.h
@@ -0,0 +1,338 @@
+/*
+ * svc.h, Server-side remote procedure call interface.
+ *
+ * Copyright (C) 2012-2016 Free Software Foundation, Inc.
+ * This file is part of the GNU C Library.
+ *
+ * The GNU C Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * The GNU C Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the GNU C Library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RPC_SVC_H
+#define _RPC_SVC_H 1
+
+#ifndef SYLIXOS
+#include <features.h>
+#endif
+#include <rpc/rpc_msg.h>
+
+__BEGIN_DECLS
+
+/*
+ * This interface must manage two items concerning remote procedure calling:
+ *
+ * 1) An arbitrary number of transport connections upon which rpc requests
+ * are received. The two most notable transports are TCP and UDP; they are
+ * created and registered by routines in svc_tcp.c and svc_udp.c, respectively;
+ * they in turn call xprt_register and xprt_unregister.
+ *
+ * 2) An arbitrary number of locally registered services. Services are
+ * described by the following four data: program number, version number,
+ * "service dispatch" function, a transport handle, and a boolean that
+ * indicates whether or not the exported program should be registered with a
+ * local binder service; if true the program's number and version and the
+ * port number from the transport handle are registered with the binder.
+ * These data are registered with the rpc svc system via svc_register.
+ *
+ * A service's dispatch function is called whenever an rpc request comes in
+ * on a transport. The request's program and version numbers must match
+ * those of the registered service. The dispatch function is passed two
+ * parameters, struct svc_req * and SVCXPRT *, defined below.
+ */
+
+enum xprt_stat {
+ XPRT_DIED,
+ XPRT_MOREREQS,
+ XPRT_IDLE
+};
+
+/*
+ * Server side transport handle
+ */
+typedef struct SVCXPRT SVCXPRT;
+struct SVCXPRT {
+ int xp_sock;
+ u_short xp_port; /* associated port number */
+ const struct xp_ops {
+ bool_t (*xp_recv) (SVCXPRT *__xprt, struct rpc_msg *__msg);
+ /* receive incoming requests */
+ enum xprt_stat (*xp_stat) (SVCXPRT *__xprt);
+ /* get transport status */
+ bool_t (*xp_getargs) (SVCXPRT *__xprt, xdrproc_t __xdr_args,
+ caddr_t __args_ptr); /* get arguments */
+ bool_t (*xp_reply) (SVCXPRT *__xprt, struct rpc_msg *__msg);
+ /* send reply */
+ bool_t (*xp_freeargs) (SVCXPRT *__xprt, xdrproc_t __xdr_args,
+ caddr_t __args_ptr);
+ /* free mem allocated for args */
+ void (*xp_destroy) (SVCXPRT *__xprt);
+ /* destroy this struct */
+ } *xp_ops;
+ int xp_addrlen; /* length of remote address */
+ struct sockaddr_in xp_raddr; /* remote address */
+ struct opaque_auth xp_verf; /* raw response verifier */
+ caddr_t xp_p1; /* private */
+ caddr_t xp_p2; /* private */
+ char xp_pad [256]; /* padding, internal use */
+};
+
+/*
+ * Approved way of getting address of caller
+ */
+#define svc_getcaller(x) (&(x)->xp_raddr)
+
+/*
+ * Operations defined on an SVCXPRT handle
+ *
+ * SVCXPRT *xprt;
+ * struct rpc_msg *msg;
+ * xdrproc_t xargs;
+ * caddr_t argsp;
+ */
+#define SVC_RECV(xprt, msg) \
+ (*(xprt)->xp_ops->xp_recv)((xprt), (msg))
+#define svc_recv(xprt, msg) \
+ (*(xprt)->xp_ops->xp_recv)((xprt), (msg))
+
+#define SVC_STAT(xprt) \
+ (*(xprt)->xp_ops->xp_stat)(xprt)
+#define svc_stat(xprt) \
+ (*(xprt)->xp_ops->xp_stat)(xprt)
+
+#define SVC_GETARGS(xprt, xargs, argsp) \
+ (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp))
+#define svc_getargs(xprt, xargs, argsp) \
+ (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp))
+
+#define SVC_REPLY(xprt, msg) \
+ (*(xprt)->xp_ops->xp_reply) ((xprt), (msg))
+#define svc_reply(xprt, msg) \
+ (*(xprt)->xp_ops->xp_reply) ((xprt), (msg))
+
+#define SVC_FREEARGS(xprt, xargs, argsp) \
+ (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp))
+#define svc_freeargs(xprt, xargs, argsp) \
+ (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp))
+
+#define SVC_DESTROY(xprt) \
+ (*(xprt)->xp_ops->xp_destroy)(xprt)
+#define svc_destroy(xprt) \
+ (*(xprt)->xp_ops->xp_destroy)(xprt)
+
+
+/*
+ * Service request
+ */
+struct svc_req {
+ rpcprog_t rq_prog; /* service program number */
+ rpcvers_t rq_vers; /* service protocol version */
+ rpcproc_t rq_proc; /* the desired procedure */
+ struct opaque_auth rq_cred; /* raw creds from the wire */
+ caddr_t rq_clntcred; /* read only cooked cred */
+ SVCXPRT *rq_xprt; /* associated transport */
+};
+
+#ifndef __DISPATCH_FN_T
+#define __DISPATCH_FN_T
+typedef void (*__dispatch_fn_t) (struct svc_req*, SVCXPRT*);
+#endif
+
+/*
+ * Service registration
+ *
+ * svc_register(xprt, prog, vers, dispatch, protocol)
+ * SVCXPRT *xprt;
+ * rpcprog_t prog;
+ * rpcvers_t vers;
+ * void (*dispatch)(struct svc_req*, SVCXPRT*);
+ * rpcprot_t protocol; like TCP or UDP, zero means do not register
+ */
+extern bool_t svc_register (SVCXPRT *__xprt, rpcprog_t __prog,
+ rpcvers_t __vers, __dispatch_fn_t __dispatch,
+ rpcprot_t __protocol) __THROW;
+
+/*
+ * Service un-registration
+ *
+ * svc_unregister(prog, vers)
+ * rpcprog_t prog;
+ * rpcvers_t vers;
+ */
+extern void svc_unregister (rpcprog_t __prog, rpcvers_t __vers) __THROW;
+
+/*
+ * Transport registration.
+ *
+ * xprt_register(xprt)
+ * SVCXPRT *xprt;
+ */
+extern void xprt_register (SVCXPRT *__xprt) __THROW;
+
+/*
+ * Transport un-register
+ *
+ * xprt_unregister(xprt)
+ * SVCXPRT *xprt;
+ */
+extern void xprt_unregister (SVCXPRT *__xprt) __THROW;
+
+
+/*
+ * When the service routine is called, it must first check to see if it
+ * knows about the procedure; if not, it should call svcerr_noproc
+ * and return. If so, it should deserialize its arguments via
+ * SVC_GETARGS (defined above). If the deserialization does not work,
+ * svcerr_decode should be called followed by a return. Successful
+ * decoding of the arguments should be followed the execution of the
+ * procedure's code and a call to svc_sendreply.
+ *
+ * Also, if the service refuses to execute the procedure due to too-
+ * weak authentication parameters, svcerr_weakauth should be called.
+ * Note: do not confuse access-control failure with weak authentication!
+ *
+ * NB: In pure implementations of rpc, the caller always waits for a reply
+ * msg. This message is sent when svc_sendreply is called.
+ * Therefore pure service implementations should always call
+ * svc_sendreply even if the function logically returns void; use
+ * xdr.h - xdr_void for the xdr routine. HOWEVER, tcp based rpc allows
+ * for the abuse of pure rpc via batched calling or pipelining. In the
+ * case of a batched call, svc_sendreply should NOT be called since
+ * this would send a return message, which is what batching tries to avoid.
+ * It is the service/protocol writer's responsibility to know which calls are
+ * batched and which are not. Warning: responding to batch calls may
+ * deadlock the caller and server processes!
+ */
+
+extern bool_t svc_sendreply (SVCXPRT *__xprt, xdrproc_t __xdr_results,
+ caddr_t __xdr_location) __THROW;
+
+extern void svcerr_decode (SVCXPRT *__xprt) __THROW;
+
+extern void svcerr_weakauth (SVCXPRT *__xprt) __THROW;
+
+extern void svcerr_noproc (SVCXPRT *__xprt) __THROW;
+
+extern void svcerr_progvers (SVCXPRT *__xprt, rpcvers_t __low_vers,
+ rpcvers_t __high_vers) __THROW;
+
+extern void svcerr_auth (SVCXPRT *__xprt, enum auth_stat __why) __THROW;
+
+extern void svcerr_noprog (SVCXPRT *__xprt) __THROW;
+
+extern void svcerr_systemerr (SVCXPRT *__xprt) __THROW;
+
+/*
+ * Lowest level dispatching -OR- who owns this process anyway.
+ * Somebody has to wait for incoming requests and then call the correct
+ * service routine. The routine svc_run does infinite waiting; i.e.,
+ * svc_run never returns.
+ * Since another (coexistent) package may wish to selectively wait for
+ * incoming calls or other events outside of the rpc architecture, the
+ * routine svc_getreq is provided. It must be passed readfds, the
+ * "in-place" results of a select system call (see select, section 2).
+ */
+
+/*
+ * Global keeper of rpc service descriptors in use
+ * dynamic; must be inspected before each call to select
+ */
+
+extern struct pollfd *svc_pollfd;
+extern int svc_max_pollfd;
+extern fd_set svc_fdset;
+#define svc_fds svc_fdset.fds_bits[0] /* compatibility */
+
+/*
+ * a small program implemented by the svc_rpc implementation itself;
+ * also see clnt.h for protocol numbers.
+ */
+extern void svc_getreq (int __rdfds) __THROW;
+extern void svc_getreq_common (const int __fd) __THROW;
+extern void svc_getreqset (fd_set *__readfds) __THROW;
+extern void svc_getreq_poll (struct pollfd *, const int) __THROW;
+extern void svc_exit (void) __THROW;
+extern void svc_run (void) __THROW;
+
+/*
+ * Socket to use on svcxxx_create call to get default socket
+ */
+#define RPC_ANYSOCK -1
+
+/*
+ * These are the existing service side transport implementations
+ */
+
+/*
+ * Memory based rpc for testing and timing.
+ */
+extern SVCXPRT *svcraw_create (void) __THROW;
+
+/*
+ * Udp based rpc.
+ */
+extern SVCXPRT *svcudp_create (int __sock) __THROW;
+extern SVCXPRT *svcudp_bufcreate (int __sock, u_int __sendsz, u_int __recvsz)
+ __THROW;
+
+/*
+ * Tcp based rpc.
+ */
+extern SVCXPRT *svctcp_create (int __sock, u_int __sendsize, u_int __recvsize)
+ __THROW;
+
+/*
+ * FD based rpc.
+ */
+extern SVCXPRT *svcfd_create (int __sock, u_int __sendsize, u_int __recvsize)
+ __THROW;
+
+/*
+ * Unix based rpc.
+ */
+extern SVCXPRT *svcunix_create (int __sock, u_int __sendsize, u_int __recvsize,
+ char *__path) __THROW;
+
+
+__END_DECLS
+
+#endif /* rpc/svc.h */
diff --git a/sunrpc/rpc/svc_auth.h b/sunrpc/rpc/svc_auth.h
new file mode 100644
index 0000000..895dc62
--- /dev/null
+++ b/sunrpc/rpc/svc_auth.h
@@ -0,0 +1,52 @@
+/*
+ * svc_auth.h, Service side of rpc authentication.
+ *
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RPC_SVC_AUTH_H
+#define _RPC_SVC_AUTH_H 1
+
+#ifndef SYLIXOS
+#include <features.h>
+#endif
+#include <rpc/svc.h>
+
+__BEGIN_DECLS
+
+/*
+ * Server side authenticator
+ */
+extern enum auth_stat _authenticate (struct svc_req *__rqst,
+ struct rpc_msg *__msg) __THROW;
+
+__END_DECLS
+
+#endif /* rpc/svc_auth.h */
diff --git a/sunrpc/rpc/types.h b/sunrpc/rpc/types.h
new file mode 100644
index 0000000..d5dbc6e
--- /dev/null
+++ b/sunrpc/rpc/types.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2010, Oracle America, Inc.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/* fixincludes should not add extern "C" to this file */
+/*
+ * Rpc additions to <sys/types.h>
+ */
+#ifndef _RPC_TYPES_H
+#define _RPC_TYPES_H 1
+
+typedef int bool_t;
+typedef int enum_t;
+/* This needs to be changed to uint32_t in the future */
+typedef unsigned long rpcprog_t;
+typedef unsigned long rpcvers_t;
+typedef unsigned long rpcproc_t;
+typedef unsigned long rpcprot_t;
+typedef unsigned long rpcport_t;
+
+#define __dontcare__ -1
+
+#ifndef FALSE
+# define FALSE (0)
+#endif
+
+#ifndef TRUE
+# define TRUE (1)
+#endif
+
+#ifndef NULL
+# define NULL 0
+#endif
+
+#include <stdlib.h> /* For malloc decl. */
+#define mem_alloc(bsize) malloc(bsize)
+/*
+ * XXX: This must not use the second argument, or code in xdr_array.c needs
+ * to be modified.
+ */
+#define mem_free(ptr, bsize) free(ptr)
+
+#ifndef makedev /* ie, we haven't already included it */
+#include <sys/types.h>
+#endif
+
+#if defined __APPLE_CC__ || defined __FreeBSD__ || SYLIXOS
+# define __u_char_defined
+# define __daddr_t_defined
+#endif
+
+#if defined SYLIXOS
+#include "rpc_sylixos.h"
+#endif
+
+#ifndef __u_char_defined
+typedef __u_char u_char;
+typedef __u_short u_short;
+typedef __u_int u_int;
+typedef __u_long u_long;
+typedef __quad_t quad_t;
+typedef __u_quad_t u_quad_t;
+typedef __fsid_t fsid_t;
+# define __u_char_defined
+#endif
+#ifndef __daddr_t_defined
+typedef __daddr_t daddr_t;
+typedef __caddr_t caddr_t;
+# define __daddr_t_defined
+#endif
+
+#include <sys/time.h>
+#include <sys/param.h>
+
+#include <netinet/in.h>
+
+#ifndef INADDR_LOOPBACK
+#define INADDR_LOOPBACK (u_long)0x7F000001
+#endif
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 64
+#endif
+
+#endif /* rpc/types.h */
diff --git a/sunrpc/rpc/xdr.h b/sunrpc/rpc/xdr.h
new file mode 100644
index 0000000..eb02843
--- /dev/null
+++ b/sunrpc/rpc/xdr.h
@@ -0,0 +1,379 @@
+/*
+ * xdr.h, External Data Representation Serialization Routines.
+ *
+ * Copyright (c) 2010, 2012, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RPC_XDR_H
+#define _RPC_XDR_H 1
+
+#ifndef SYLIXOS
+#include <features.h>
+#endif
+#include <sys/types.h>
+#include <rpc/types.h>
+
+/* We need FILE. */
+#include <stdio.h>
+
+__BEGIN_DECLS
+
+/*
+ * XDR provides a conventional way for converting between C data
+ * types and an external bit-string representation. Library supplied
+ * routines provide for the conversion on built-in C data types. These
+ * routines and utility routines defined here are used to help implement
+ * a type encode/decode routine for each user-defined type.
+ *
+ * Each data type provides a single procedure which takes two arguments:
+ *
+ * bool_t
+ * xdrproc(xdrs, argresp)
+ * XDR *xdrs;
+ * <type> *argresp;
+ *
+ * xdrs is an instance of a XDR handle, to which or from which the data
+ * type is to be converted. argresp is a pointer to the structure to be
+ * converted. The XDR handle contains an operation field which indicates
+ * which of the operations (ENCODE, DECODE * or FREE) is to be performed.
+ *
+ * XDR_DECODE may allocate space if the pointer argresp is null. This
+ * data can be freed with the XDR_FREE operation.
+ *
+ * We write only one procedure per data type to make it easy
+ * to keep the encode and decode procedures for a data type consistent.
+ * In many cases the same code performs all operations on a user defined type,
+ * because all the hard work is done in the component type routines.
+ * decode as a series of calls on the nested data types.
+ */
+
+/*
+ * Xdr operations. XDR_ENCODE causes the type to be encoded into the
+ * stream. XDR_DECODE causes the type to be extracted from the stream.
+ * XDR_FREE can be used to release the space allocated by an XDR_DECODE
+ * request.
+ */
+enum xdr_op {
+ XDR_ENCODE = 0,
+ XDR_DECODE = 1,
+ XDR_FREE = 2
+};
+
+/*
+ * This is the number of bytes per unit of external data.
+ */
+#define BYTES_PER_XDR_UNIT (4)
+/*
+ * This only works if the above is a power of 2. But it's defined to be
+ * 4 by the appropriate RFCs. So it will work. And it's normally quicker
+ * than the old routine.
+ */
+#if 1
+#define RNDUP(x) (((x) + BYTES_PER_XDR_UNIT - 1) & ~(BYTES_PER_XDR_UNIT - 1))
+#else /* this is the old routine */
+#define RNDUP(x) ((((x) + BYTES_PER_XDR_UNIT - 1) / BYTES_PER_XDR_UNIT) \
+ * BYTES_PER_XDR_UNIT)
+#endif
+
+/*
+ * The XDR handle.
+ * Contains operation which is being applied to the stream,
+ * an operations vector for the particular implementation (e.g. see xdr_mem.c),
+ * and two private fields for the use of the particular implementation.
+ */
+typedef struct XDR XDR;
+struct XDR
+ {
+ enum xdr_op x_op; /* operation; fast additional param */
+ struct xdr_ops
+ {
+ bool_t (*x_getlong) (XDR *__xdrs, long *__lp);
+ /* get a long from underlying stream */
+ bool_t (*x_putlong) (XDR *__xdrs, const long *__lp);
+ /* put a long to " */
+ bool_t (*x_getbytes) (XDR *__xdrs, caddr_t __addr, u_int __len);
+ /* get some bytes from " */
+ bool_t (*x_putbytes) (XDR *__xdrs, const char *__addr, u_int __len);
+ /* put some bytes to " */
+ u_int (*x_getpostn) (const XDR *__xdrs);
+ /* returns bytes off from beginning */
+ bool_t (*x_setpostn) (XDR *__xdrs, u_int __pos);
+ /* lets you reposition the stream */
+ int32_t *(*x_inline) (XDR *__xdrs, u_int __len);
+ /* buf quick ptr to buffered data */
+ void (*x_destroy) (XDR *__xdrs);
+ /* free privates of this xdr_stream */
+ bool_t (*x_getint32) (XDR *__xdrs, int32_t *__ip);
+ /* get a int from underlying stream */
+ bool_t (*x_putint32) (XDR *__xdrs, const int32_t *__ip);
+ /* put a int to " */
+ }
+ *x_ops;
+ caddr_t x_public; /* users' data */
+ caddr_t x_private; /* pointer to private data */
+ caddr_t x_base; /* private used for position info */
+ u_int x_handy; /* extra private word */
+ };
+
+/*
+ * A xdrproc_t exists for each data type which is to be encoded or decoded.
+ *
+ * The second argument to the xdrproc_t is a pointer to an opaque pointer.
+ * The opaque pointer generally points to a structure of the data type
+ * to be decoded. If this pointer is 0, then the type routines should
+ * allocate dynamic storage of the appropriate size and return it.
+ * bool_t (*xdrproc_t)(XDR *, caddr_t *);
+ */
+typedef bool_t (*xdrproc_t) (XDR *, void *, int);
+
+
+/*
+ * Operations defined on a XDR handle
+ *
+ * XDR *xdrs;
+ * int32_t *int32p;
+ * long *longp;
+ * caddr_t addr;
+ * u_int len;
+ * u_int pos;
+ */
+#define XDR_GETINT32(xdrs, int32p) \
+ (*(xdrs)->x_ops->x_getint32)(xdrs, int32p)
+#define xdr_getint32(xdrs, int32p) \
+ (*(xdrs)->x_ops->x_getint32)(xdrs, int32p)
+
+#define XDR_PUTINT32(xdrs, int32p) \
+ (*(xdrs)->x_ops->x_putint32)(xdrs, int32p)
+#define xdr_putint32(xdrs, int32p) \
+ (*(xdrs)->x_ops->x_putint32)(xdrs, int32p)
+
+#define XDR_GETLONG(xdrs, longp) \
+ (*(xdrs)->x_ops->x_getlong)(xdrs, longp)
+#define xdr_getlong(xdrs, longp) \
+ (*(xdrs)->x_ops->x_getlong)(xdrs, longp)
+
+#define XDR_PUTLONG(xdrs, longp) \
+ (*(xdrs)->x_ops->x_putlong)(xdrs, longp)
+#define xdr_putlong(xdrs, longp) \
+ (*(xdrs)->x_ops->x_putlong)(xdrs, longp)
+
+#define XDR_GETBYTES(xdrs, addr, len) \
+ (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
+#define xdr_getbytes(xdrs, addr, len) \
+ (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
+
+#define XDR_PUTBYTES(xdrs, addr, len) \
+ (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
+#define xdr_putbytes(xdrs, addr, len) \
+ (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
+
+#define XDR_GETPOS(xdrs) \
+ (*(xdrs)->x_ops->x_getpostn)(xdrs)
+#define xdr_getpos(xdrs) \
+ (*(xdrs)->x_ops->x_getpostn)(xdrs)
+
+#define XDR_SETPOS(xdrs, pos) \
+ (*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
+#define xdr_setpos(xdrs, pos) \
+ (*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
+
+#define XDR_INLINE(xdrs, len) \
+ (*(xdrs)->x_ops->x_inline)(xdrs, len)
+#define xdr_inline(xdrs, len) \
+ (*(xdrs)->x_ops->x_inline)(xdrs, len)
+
+#define XDR_DESTROY(xdrs) \
+ do { \
+ if ((xdrs)->x_ops->x_destroy) \
+ (*(xdrs)->x_ops->x_destroy)(xdrs); \
+ } while (0)
+#define xdr_destroy(xdrs) \
+ do { \
+ if ((xdrs)->x_ops->x_destroy) \
+ (*(xdrs)->x_ops->x_destroy)(xdrs); \
+ } while (0)
+
+/*
+ * Support struct for discriminated unions.
+ * You create an array of xdrdiscrim structures, terminated with
+ * an entry with a null procedure pointer. The xdr_union routine gets
+ * the discriminant value and then searches the array of structures
+ * for a matching value. If a match is found the associated xdr routine
+ * is called to handle that part of the union. If there is
+ * no match, then a default routine may be called.
+ * If there is no match and no default routine it is an error.
+ */
+#define NULL_xdrproc_t ((xdrproc_t)0)
+struct xdr_discrim
+{
+ int value;
+ xdrproc_t proc;
+};
+
+/*
+ * Inline routines for fast encode/decode of primitive data types.
+ * Caveat emptor: these use single memory cycles to get the
+ * data from the underlying buffer, and will fail to operate
+ * properly if the data is not aligned. The standard way to use these
+ * is to say:
+ * if ((buf = XDR_INLINE(xdrs, count)) == NULL)
+ * return (FALSE);
+ * <<< macro calls >>>
+ * where ``count'' is the number of bytes of data occupied
+ * by the primitive data types.
+ *
+ * N.B. and frozen for all time: each data type here uses 4 bytes
+ * of external representation.
+ */
+
+#define IXDR_GET_INT32(buf) ((int32_t)ntohl((uint32_t)*(buf)++))
+#define IXDR_PUT_INT32(buf, v) (*(buf)++ = (int32_t)htonl((uint32_t)(v)))
+#define IXDR_GET_U_INT32(buf) ((uint32_t)IXDR_GET_INT32(buf))
+#define IXDR_PUT_U_INT32(buf, v) IXDR_PUT_INT32(buf, (int32_t)(v))
+
+/* WARNING: The IXDR_*_LONG defines are removed by Sun for new platforms
+ * and shouldn't be used any longer. Code which use this defines or longs
+ * in the RPC code will not work on 64bit Solaris platforms !
+ */
+#define IXDR_GET_LONG(buf) ((long)IXDR_GET_U_INT32(buf))
+#define IXDR_PUT_LONG(buf, v) ((long)IXDR_PUT_INT32(buf, (long)(v)))
+#define IXDR_GET_U_LONG(buf) ((u_long)IXDR_GET_LONG(buf))
+#define IXDR_PUT_U_LONG(buf, v) IXDR_PUT_LONG(buf, (long)(v))
+
+
+#define IXDR_GET_BOOL(buf) ((bool_t)IXDR_GET_LONG(buf))
+#define IXDR_GET_ENUM(buf, t) ((t)IXDR_GET_LONG(buf))
+#define IXDR_GET_SHORT(buf) ((short)IXDR_GET_LONG(buf))
+#define IXDR_GET_U_SHORT(buf) ((u_short)IXDR_GET_LONG(buf))
+
+#define IXDR_PUT_BOOL(buf, v) IXDR_PUT_LONG(buf, (long)(v))
+#define IXDR_PUT_ENUM(buf, v) IXDR_PUT_LONG(buf, (long)(v))
+#define IXDR_PUT_SHORT(buf, v) IXDR_PUT_LONG(buf, (long)(v))
+#define IXDR_PUT_U_SHORT(buf, v) IXDR_PUT_LONG(buf, (long)(v))
+
+/*
+ * These are the "generic" xdr routines.
+ * None of these can have const applied because it's not possible to
+ * know whether the call is a read or a write to the passed parameter
+ * also, the XDR structure is always updated by some of these calls.
+ */
+extern bool_t xdr_void (void) __THROW;
+extern bool_t xdr_short (XDR *__xdrs, short *__sp) __THROW;
+extern bool_t xdr_u_short (XDR *__xdrs, u_short *__usp) __THROW;
+extern bool_t xdr_int (XDR *__xdrs, int *__ip) __THROW;
+extern bool_t xdr_u_int (XDR *__xdrs, u_int *__up) __THROW;
+extern bool_t xdr_long (XDR *__xdrs, long *__lp) __THROW;
+extern bool_t xdr_u_long (XDR *__xdrs, u_long *__ulp) __THROW;
+extern bool_t xdr_hyper (XDR *__xdrs, quad_t *__llp) __THROW;
+extern bool_t xdr_u_hyper (XDR *__xdrs, u_quad_t *__ullp) __THROW;
+extern bool_t xdr_longlong_t (XDR *__xdrs, quad_t *__llp) __THROW;
+extern bool_t xdr_u_longlong_t (XDR *__xdrs, u_quad_t *__ullp) __THROW;
+extern bool_t xdr_int8_t (XDR *__xdrs, int8_t *__ip) __THROW;
+extern bool_t xdr_uint8_t (XDR *__xdrs, uint8_t *__up) __THROW;
+extern bool_t xdr_int16_t (XDR *__xdrs, int16_t *__ip) __THROW;
+extern bool_t xdr_uint16_t (XDR *__xdrs, uint16_t *__up) __THROW;
+extern bool_t xdr_int32_t (XDR *__xdrs, int32_t *__ip) __THROW;
+extern bool_t xdr_uint32_t (XDR *__xdrs, uint32_t *__up) __THROW;
+extern bool_t xdr_int64_t (XDR *__xdrs, int64_t *__ip) __THROW;
+extern bool_t xdr_uint64_t (XDR *__xdrs, uint64_t *__up) __THROW;
+extern bool_t xdr_quad_t (XDR *__xdrs, quad_t *__ip) __THROW;
+extern bool_t xdr_u_quad_t (XDR *__xdrs, u_quad_t *__up) __THROW;
+extern bool_t xdr_bool (XDR *__xdrs, bool_t *__bp) __THROW;
+extern bool_t xdr_enum (XDR *__xdrs, enum_t *__ep) __THROW;
+extern bool_t xdr_array (XDR * _xdrs, caddr_t *__addrp, u_int *__sizep,
+ u_int __maxsize, u_int __elsize, xdrproc_t __elproc)
+ __THROW;
+extern bool_t xdr_bytes (XDR *__xdrs, char **__cpp, u_int *__sizep,
+ u_int __maxsize) __THROW;
+extern bool_t xdr_opaque (XDR *__xdrs, caddr_t __cp, u_int __cnt) __THROW;
+extern bool_t xdr_string (XDR *__xdrs, char **__cpp, u_int __maxsize) __THROW;
+extern bool_t xdr_union (XDR *__xdrs, enum_t *__dscmp, char *__unp,
+ const struct xdr_discrim *__choices,
+ xdrproc_t __dfault) __THROW;
+extern bool_t xdr_char (XDR *__xdrs, char *__cp) __THROW;
+extern bool_t xdr_u_char (XDR *__xdrs, u_char *__cp) __THROW;
+extern bool_t xdr_vector (XDR *__xdrs, char *__basep, u_int __nelem,
+ u_int __elemsize, xdrproc_t __xdr_elem) __THROW;
+extern bool_t xdr_float (XDR *__xdrs, float *__fp) __THROW;
+extern bool_t xdr_double (XDR *__xdrs, double *__dp) __THROW;
+extern bool_t xdr_reference (XDR *__xdrs, caddr_t *__xpp, u_int __size,
+ xdrproc_t __proc) __THROW;
+extern bool_t xdr_pointer (XDR *__xdrs, char **__objpp,
+ u_int __obj_size, xdrproc_t __xdr_obj) __THROW;
+extern bool_t xdr_wrapstring (XDR *__xdrs, char **__cpp) __THROW;
+extern u_long xdr_sizeof (xdrproc_t, void *) __THROW;
+
+/*
+ * Common opaque bytes objects used by many rpc protocols;
+ * declared here due to commonality.
+ */
+#define MAX_NETOBJ_SZ 1024
+struct netobj
+{
+ u_int n_len;
+ char *n_bytes;
+};
+typedef struct netobj netobj;
+extern bool_t xdr_netobj (XDR *__xdrs, struct netobj *__np) __THROW;
+
+/*
+ * These are the public routines for the various implementations of
+ * xdr streams.
+ */
+
+/* XDR using memory buffers */
+extern void xdrmem_create (XDR *__xdrs, const caddr_t __addr,
+ u_int __size, enum xdr_op __xop) __THROW;
+
+/* XDR using stdio library */
+extern void xdrstdio_create (XDR *__xdrs, FILE *__file, enum xdr_op __xop)
+ __THROW;
+
+/* XDR pseudo records for tcp */
+extern void xdrrec_create (XDR *__xdrs, u_int __sendsize,
+ u_int __recvsize, caddr_t __tcp_handle,
+ int (*__readit) (char *, char *, int),
+ int (*__writeit) (char *, char *, int)) __THROW;
+
+/* make end of xdr record */
+extern bool_t xdrrec_endofrecord (XDR *__xdrs, bool_t __sendnow) __THROW;
+
+/* move to beginning of next record */
+extern bool_t xdrrec_skiprecord (XDR *__xdrs) __THROW;
+
+/* true if no more input */
+extern bool_t xdrrec_eof (XDR *__xdrs) __THROW;
+
+/* free memory buffers for xdr */
+extern void xdr_free (xdrproc_t __proc, char *__objp) __THROW;
+
+__END_DECLS
+
+#endif /* rpc/xdr.h */
diff --git a/sunrpc/rpc_clntout.c b/sunrpc/rpc_clntout.c
new file mode 100644
index 0000000..ce4d2a4
--- /dev/null
+++ b/sunrpc/rpc_clntout.c
@@ -0,0 +1,333 @@
+/*
+ * rpc_clntout.c, Client-stub outputter for the RPC protocol compiler
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <stdio.h>
+#include <string.h>
+#include "rpc/types.h"
+#include "rpc_parse.h"
+#include "rpc_util.h"
+#include "proto.h"
+
+#define DEFAULT_TIMEOUT 25 /* in seconds */
+static const char RESULT[] = "clnt_res";
+
+static void write_program (definition * def);
+static void printbody (proc_list * proc);
+static const char *ampr (const char *type);
+static void printbody (proc_list * proc);
+
+
+void
+write_stubs (void)
+{
+ list *l;
+ definition *def;
+
+ fprintf (fout,
+ "\n/* Default timeout can be changed using clnt_control() */\n");
+ fprintf (fout, "static struct timeval TIMEOUT = { %d, 0 };\n",
+ DEFAULT_TIMEOUT);
+ for (l = defined; l != NULL; l = l->next)
+ {
+ def = (definition *) l->val;
+ if (def->def_kind == DEF_PROGRAM)
+ {
+ write_program (def);
+ }
+ }
+}
+
+static void
+write_program (definition * def)
+{
+ version_list *vp;
+ proc_list *proc;
+
+ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next)
+ {
+ for (proc = vp->procs; proc != NULL; proc = proc->next)
+ {
+ fprintf (fout, "\n");
+ if (mtflag == 0)
+ {
+ ptype (proc->res_prefix, proc->res_type, 1);
+ fprintf (fout, "*\n");
+ pvname (proc->proc_name, vp->vers_num);
+ printarglist (proc, RESULT, "clnt", "CLIENT *");
+ }
+ else
+ {
+ fprintf (fout, "enum clnt_stat \n");
+ pvname (proc->proc_name, vp->vers_num);
+ printarglist (proc, RESULT, "clnt", "CLIENT *");
+ }
+ fprintf (fout, "{\n");
+ printbody (proc);
+ fprintf (fout, "}\n");
+ }
+ }
+}
+
+/* Writes out declarations of procedure's argument list.
+ In either ANSI C style, in one of old rpcgen style (pass by reference),
+ or new rpcgen style (multiple arguments, pass by value);
+ */
+
+/* sample addargname = "clnt"; sample addargtype = "CLIENT * " */
+
+void
+printarglist (proc_list * proc, const char *result,
+ const char *addargname, const char *addargtype)
+{
+
+ decl_list *l;
+
+ if (!newstyle)
+ { /* old style: always pass argument by reference */
+ if (Cflag)
+ { /* C++ style heading */
+ fprintf (fout, "(");
+ ptype (proc->args.decls->decl.prefix,
+ proc->args.decls->decl.type, 1);
+
+ if (mtflag)
+ {/* Generate result field */
+ fprintf (fout, "*argp, ");
+ ptype(proc->res_prefix, proc->res_type, 1);
+ fprintf (fout, "*%s, %s%s)\n", result, addargtype, addargname);
+ }
+ else
+ fprintf (fout, "*argp, %s%s)\n", addargtype, addargname);
+ }
+ else
+ {
+ if (!mtflag)
+ fprintf (fout, "(argp, %s)\n", addargname);
+ else
+ fprintf (fout, "(argp, %s, %s)\n", result, addargname);
+ fprintf (fout, "\t");
+ ptype (proc->args.decls->decl.prefix,
+ proc->args.decls->decl.type, 1);
+ fprintf (fout, "*argp;\n");
+ if (mtflag)
+ {
+ fprintf (fout, "\t");
+ ptype (proc->res_prefix, proc->res_type, 1);
+ fprintf (fout, "*%s;\n", result);
+ }
+ }
+ }
+ else if (streq (proc->args.decls->decl.type, "void"))
+ {
+ /* newstyle, 0 argument */
+ if (mtflag)
+ {
+ fprintf (fout, "(");
+ if (Cflag)
+ {
+ ptype(proc->res_prefix, proc->res_type, 1);
+ fprintf (fout, "*%s, %s%s)\n", result, addargtype, addargname);
+ }
+ else
+ fprintf (fout, "(%s)\n", addargname);
+ }
+ else if (Cflag)
+ fprintf (fout, "(%s%s)\n", addargtype, addargname);
+ else
+ fprintf (fout, "(%s)\n", addargname);
+ }
+ else
+ {
+ /* new style, 1 or multiple arguments */
+ if (!Cflag)
+ {
+ fprintf (fout, "(");
+ for (l = proc->args.decls; l != NULL; l = l->next)
+ fprintf (fout, "%s, ", l->decl.name);
+ if (mtflag)
+ fprintf (fout, "%s, ", result);
+ fprintf (fout, "%s)\n", addargname);
+ for (l = proc->args.decls; l != NULL; l = l->next)
+ {
+ pdeclaration (proc->args.argname, &l->decl, 1, ";\n");
+ }
+ if (mtflag)
+ {
+ fprintf (fout, "\t");
+ ptype (proc->res_prefix, proc->res_type, 1);
+ fprintf (fout, "*%s;\n", result);
+ }
+ }
+ else
+ { /* C++ style header */
+ fprintf (fout, "(");
+ for (l = proc->args.decls; l != NULL; l = l->next)
+ {
+ pdeclaration (proc->args.argname, &l->decl, 0, ", ");
+ }
+ if (mtflag)
+ {
+ ptype (proc->res_prefix, proc->res_type, 1);
+ fprintf (fout, "*%s, ", result);
+ }
+ fprintf (fout, " %s%s)\n", addargtype, addargname);
+ }
+ }
+
+ if (!Cflag)
+ fprintf (fout, "\t%s%s;\n", addargtype, addargname);
+}
+
+
+static
+const char *
+ampr (const char *type)
+{
+ if (isvectordef (type, REL_ALIAS))
+ {
+ return "";
+ }
+ else
+ {
+ return "&";
+ }
+}
+
+static void
+printbody (proc_list * proc)
+{
+ decl_list *l;
+ bool_t args2 = (proc->arg_num > 1);
+/* int i; */
+
+ /* For new style with multiple arguments, need a structure in which
+ to stuff the arguments. */
+ if (newstyle && args2)
+ {
+ fprintf (fout, "\t%s", proc->args.argname);
+ fprintf (fout, " arg;\n");
+ }
+ if (!mtflag)
+ {
+ fprintf (fout, "\tstatic ");
+ if (streq (proc->res_type, "void"))
+ {
+ fprintf (fout, "char ");
+ }
+ else
+ {
+ ptype (proc->res_prefix, proc->res_type, 0);
+ }
+ fprintf (fout, "%s;\n", RESULT);
+ fprintf (fout, "\n");
+ fprintf (fout, "\tmemset((char *)%s%s, 0, sizeof(%s));\n",
+ ampr (proc->res_type), RESULT, RESULT);
+ }
+ if (newstyle && !args2 && (streq (proc->args.decls->decl.type, "void")))
+ {
+ /* newstyle, 0 arguments */
+ if (mtflag)
+ fprintf (fout, "\t return ");
+ else
+ fprintf (fout, "\t if ");
+ fprintf (fout,
+ "(clnt_call (clnt, %s, (xdrproc_t) xdr_void, ", proc->proc_name);
+
+ fprintf (fout,
+ "(caddr_t) NULL,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,",
+ stringfix(proc->res_type), (mtflag)?"":ampr(proc->res_type),
+ RESULT);
+ if (mtflag)
+ fprintf (fout, "\n\t\tTIMEOUT));\n\n");
+ else
+ fprintf (fout, "\n\t\tTIMEOUT) != RPC_SUCCESS) {\n");
+ }
+ else if (newstyle && args2)
+ {
+ /* newstyle, multiple arguments: stuff arguments into structure */
+ for (l = proc->args.decls; l != NULL; l = l->next)
+ {
+ fprintf (fout, "\targ.%s = %s;\n",
+ l->decl.name, l->decl.name);
+ }
+ if (mtflag)
+ fprintf (fout, "\treturn ");
+ else
+ fprintf (fout, "\tif ");
+
+ fprintf (fout,
+ "(clnt_call (clnt, %s, (xdrproc_t) xdr_%s", proc->proc_name,
+ proc->args.argname);
+ fprintf (fout,
+ ", (caddr_t) &arg,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,",
+ stringfix(proc->res_type), (mtflag)?"":ampr(proc->res_type),
+ RESULT);
+ if (mtflag)
+ fprintf (fout, "\n\t\tTIMEOUT));\n");
+ else
+ fprintf (fout, "\n\t\tTIMEOUT) != RPC_SUCCESS) {\n");
+ }
+ else
+ { /* single argument, new or old style */
+ if (!mtflag)
+ fprintf (fout,
+ "\tif (clnt_call (clnt, %s,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,\n\t\tTIMEOUT) != RPC_SUCCESS) {\n",
+ proc->proc_name,
+ stringfix (proc->args.decls->decl.type),
+ (newstyle ? "&" : ""),
+ (newstyle ? proc->args.decls->decl.name : "argp"),
+ stringfix (proc->res_type), ampr (proc->res_type),
+ RESULT);
+ else
+ fprintf(fout,
+ "\treturn (clnt_call(clnt, %s,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,\n\t\t(xdrproc_t) xdr_%s, (caddr_t) %s%s,\n\t\tTIMEOUT));\n",
+ proc->proc_name,
+ stringfix (proc->args.decls->decl.type),
+ (newstyle ? "&" : ""),
+ (newstyle ? proc->args.decls->decl.name : "argp"),
+ stringfix (proc->res_type), "",
+ RESULT);
+ }
+ if (!mtflag)
+ {
+ fprintf (fout, "\t\treturn (NULL);\n");
+ fprintf (fout, "\t}\n");
+ if (streq (proc->res_type, "void"))
+ {
+ fprintf (fout, "\treturn ((void *)%s%s);\n",
+ ampr (proc->res_type), RESULT);
+ }
+ else
+ {
+ fprintf (fout, "\treturn (%s%s);\n", ampr (proc->res_type), RESULT);
+ }
+ }
+}
diff --git a/sunrpc/rpc_cmsg.c b/sunrpc/rpc_cmsg.c
new file mode 100644
index 0000000..62d95fc
--- /dev/null
+++ b/sunrpc/rpc_cmsg.c
@@ -0,0 +1,197 @@
+/*
+ * rpc_callmsg.c
+ *
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <sys/param.h>
+#include <rpc/rpc.h>
+
+/*
+ * XDR a call message
+ */
+bool_t
+xdr_callmsg (XDR *xdrs, struct rpc_msg *cmsg)
+{
+ int32_t *buf;
+ 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)
+ {
+ (void) IXDR_PUT_LONG (buf, cmsg->rm_xid);
+ (void) IXDR_PUT_ENUM (buf, cmsg->rm_direction);
+ if (cmsg->rm_direction != CALL)
+ return FALSE;
+ (void) IXDR_PUT_LONG (buf, cmsg->rm_call.cb_rpcvers);
+ if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION)
+ return FALSE;
+ (void) IXDR_PUT_LONG (buf, cmsg->rm_call.cb_prog);
+ (void) IXDR_PUT_LONG (buf, cmsg->rm_call.cb_vers);
+ (void) IXDR_PUT_LONG (buf, cmsg->rm_call.cb_proc);
+ oa = &cmsg->rm_call.cb_cred;
+ (void) IXDR_PUT_ENUM (buf, oa->oa_flavor);
+ (void) IXDR_PUT_INT32 (buf, oa->oa_length);
+ if (oa->oa_length)
+ {
+ memcpy ((caddr_t) buf, oa->oa_base, oa->oa_length);
+ buf = (int32_t *) ((char *) buf + RNDUP (oa->oa_length));
+ }
+ oa = &cmsg->rm_call.cb_verf;
+ (void) IXDR_PUT_ENUM (buf, oa->oa_flavor);
+ (void) IXDR_PUT_INT32 (buf, oa->oa_length);
+ if (oa->oa_length)
+ {
+ memcpy ((caddr_t) buf, oa->oa_base, oa->oa_length);
+ /* no real need....
+ buf = (long *) ((char *) buf + RNDUP(oa->oa_length));
+ */
+ }
+ 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_INT32 (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 = (long *) ((char *) buf
+ + RNDUP(oa->oa_length));
+ */
+ }
+ }
+ 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_INT32 (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 = (long *) ((char *) buf
+ + RNDUP(oa->oa_length));
+ */
+ }
+ }
+ return TRUE;
+ }
+ }
+ if (
+ xdr_u_long (xdrs, &(cmsg->rm_xid)) &&
+ xdr_enum (xdrs, (enum_t *) & (cmsg->rm_direction)) &&
+ (cmsg->rm_direction == CALL) &&
+ xdr_u_long (xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
+ (cmsg->rm_call.cb_rpcvers == RPC_MSG_VERSION) &&
+ xdr_u_long (xdrs, &(cmsg->rm_call.cb_prog)) &&
+ xdr_u_long (xdrs, &(cmsg->rm_call.cb_vers)) &&
+ xdr_u_long (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;
+}
+libc_hidden_nolink_sunrpc (xdr_callmsg, GLIBC_2_0)
diff --git a/sunrpc/rpc_common.c b/sunrpc/rpc_common.c
new file mode 100644
index 0000000..608170b
--- /dev/null
+++ b/sunrpc/rpc_common.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, Oracle America, Inc.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <rpc/rpc.h>
+#ifndef SYLIXOS
+#include <shlib-compat.h>
+#endif
+
+#ifdef _RPC_THREAD_SAFE_
+#undef svc_fdset
+#undef rpc_createerr
+#undef svc_pollfd
+#undef svc_max_pollfd
+#endif /* _RPC_THREAD_SAFE_ */
+
+/*
+ * This file should only contain common data (global data) that is exported
+ * by public interfaces
+ */
+/* We are very tricky here. We want to have _null_auth in a read-only
+ section but we cannot add const to the type because this isn't how
+ the variable is declared. So we use the section attribute. */
+struct opaque_auth _null_auth __attribute__ ((nocommon));
+libc_hidden_nolink_sunrpc (_null_auth, GLIBC_2_0)
+fd_set svc_fdset;
+struct rpc_createerr rpc_createerr;
+struct pollfd *svc_pollfd;
+int svc_max_pollfd;
diff --git a/sunrpc/rpc_cout.c b/sunrpc/rpc_cout.c
new file mode 100644
index 0000000..db7b571
--- /dev/null
+++ b/sunrpc/rpc_cout.c
@@ -0,0 +1,811 @@
+/*
+ * From: @(#)rpc_cout.c 1.13 89/02/22
+ *
+ * Copyright (c) 2010, Oracle America, Inc.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * rpc_cout.c, XDR routine outputter for the RPC protocol compiler
+ */
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include "rpc_parse.h"
+#include "rpc_util.h"
+#include "proto.h"
+
+static void emit_enum (definition * def);
+static void emit_program (const definition * def);
+static void emit_union (const definition * def);
+static void emit_struct (definition * def);
+static void emit_typedef (const definition * def);
+static void emit_inline (int indent, declaration * decl, int flag);
+static void emit_single_in_line (int indent, declaration *decl, int flag,
+ relation rel);
+static int findtype (const definition * def, const char *type);
+static int undefined (const char *type);
+static void print_generic_header (const char *procname, int pointerp);
+static void print_ifopen (int indent, const char *name);
+static void print_ifarg (const char *arg);
+static void print_ifsizeof (int indent, const char *prefix, const char *type);
+static void print_ifclose (int indent);
+static void print_ifstat (int indent, const char *prefix, const char *type,
+ relation rel, const char *amax,
+ const char *objname, const char *name);
+static void print_stat (int indent, const declaration * dec);
+static void print_header (const definition * def);
+static void print_trailer (void);
+static char *upcase (const char *str);
+
+/*
+ * Emit the C-routine for the given definition
+ */
+void
+emit (definition * def)
+{
+ if (def->def_kind == DEF_CONST)
+ {
+ return;
+ }
+ if (def->def_kind == DEF_PROGRAM)
+ {
+ emit_program (def);
+ return;
+ }
+ if (def->def_kind == DEF_TYPEDEF)
+ {
+ /* now we need to handle declarations like
+ struct typedef foo foo;
+ since we don't want this to be expanded
+ into 2 calls to xdr_foo */
+
+ if (strcmp (def->def.ty.old_type, def->def_name) == 0)
+ return;
+ };
+
+ print_header (def);
+ switch (def->def_kind)
+ {
+ case DEF_UNION:
+ emit_union (def);
+ break;
+ case DEF_ENUM:
+ emit_enum (def);
+ break;
+ case DEF_STRUCT:
+ emit_struct (def);
+ break;
+ case DEF_TYPEDEF:
+ emit_typedef (def);
+ break;
+ default:
+ /* can't happen */
+ break;
+ }
+ print_trailer ();
+}
+
+static int
+findtype (const definition * def, const char *type)
+{
+ if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST)
+ {
+ return 0;
+ }
+ else
+ {
+ return (streq (def->def_name, type));
+ }
+}
+
+static int
+undefined (const char *type)
+{
+ definition *def;
+ def = (definition *) FINDVAL (defined, type, findtype);
+ return (def == NULL);
+}
+
+
+static void
+print_generic_header (const char *procname, int pointerp)
+{
+ f_print (fout, "\n");
+ f_print (fout, "bool_t\n");
+ if (Cflag)
+ {
+ f_print (fout, "xdr_%s (", procname);
+ f_print (fout, "XDR *xdrs, ");
+ f_print (fout, "%s ", procname);
+ if (pointerp)
+ f_print (fout, "*");
+ f_print (fout, "objp)\n{\n");
+ }
+ else
+ {
+ f_print (fout, "xdr_%s (xdrs, objp)\n", procname);
+ f_print (fout, "\tXDR *xdrs;\n");
+ f_print (fout, "\t%s ", procname);
+ if (pointerp)
+ f_print (fout, "*");
+ f_print (fout, "objp;\n{\n");
+ }
+}
+
+static void
+print_header (const definition * def)
+{
+ print_generic_header (def->def_name,
+ def->def_kind != DEF_TYPEDEF ||
+ !isvectordef (def->def.ty.old_type,
+ def->def.ty.rel));
+
+ /* Now add Inline support */
+
+ if (inlineflag == 0)
+ return;
+ /*May cause lint to complain. but ... */
+ f_print (fout, "\tregister int32_t *buf;\n\n");
+}
+
+static void
+print_prog_header (const proc_list * plist)
+{
+ print_generic_header (plist->args.argname, 1);
+}
+
+static void
+print_trailer (void)
+{
+ f_print (fout, "\treturn TRUE;\n");
+ f_print (fout, "}\n");
+}
+
+
+static void
+print_ifopen (int indent, const char *name)
+{
+ tabify (fout, indent);
+ f_print (fout, " if (!xdr_%s (xdrs", name);
+}
+
+static void
+print_ifarg (const char *arg)
+{
+ f_print (fout, ", %s", arg);
+}
+
+static void
+print_ifsizeof (int indent, const char *prefix, const char *type)
+{
+ if (indent)
+ {
+ fprintf (fout, ",\n");
+ tabify (fout, indent);
+ }
+ else
+ fprintf (fout, ", ");
+
+ if (streq (type, "bool"))
+ fprintf (fout, "sizeof (bool_t), (xdrproc_t) xdr_bool");
+ else
+ {
+ fprintf (fout, "sizeof (");
+ if (undefined (type) && prefix)
+ {
+ f_print (fout, "%s ", prefix);
+ }
+ fprintf (fout, "%s), (xdrproc_t) xdr_%s", type, type);
+ }
+}
+
+static void
+print_ifclose (int indent)
+{
+ f_print (fout, "))\n");
+ tabify (fout, indent);
+ f_print (fout, "\t return FALSE;\n");
+}
+
+static void
+print_ifstat (int indent, const char *prefix, const char *type, relation rel,
+ const char *amax, const char *objname, const char *name)
+{
+ const char *alt = NULL;
+
+ switch (rel)
+ {
+ case REL_POINTER:
+ print_ifopen (indent, "pointer");
+ print_ifarg ("(char **)");
+ f_print (fout, "%s", objname);
+ print_ifsizeof (0, prefix, type);
+ break;
+ case REL_VECTOR:
+ if (streq (type, "string"))
+ {
+ alt = "string";
+ }
+ else if (streq (type, "opaque"))
+ {
+ alt = "opaque";
+ }
+ if (alt)
+ {
+ print_ifopen (indent, alt);
+ print_ifarg (objname);
+ }
+ else
+ {
+ print_ifopen (indent, "vector");
+ print_ifarg ("(char *)");
+ f_print (fout, "%s", objname);
+ }
+ print_ifarg (amax);
+ if (!alt)
+ {
+ print_ifsizeof (indent + 1, prefix, type);
+ }
+ break;
+ case REL_ARRAY:
+ if (streq (type, "string"))
+ {
+ alt = "string";
+ }
+ else if (streq (type, "opaque"))
+ {
+ alt = "bytes";
+ }
+ if (streq (type, "string"))
+ {
+ print_ifopen (indent, alt);
+ print_ifarg (objname);
+ }
+ else
+ {
+ if (alt)
+ {
+ print_ifopen (indent, alt);
+ }
+ else
+ {
+ print_ifopen (indent, "array");
+ }
+ print_ifarg ("(char **)");
+ if (*objname == '&')
+ {
+ f_print (fout, "%s.%s_val, (u_int *) %s.%s_len",
+ objname, name, objname, name);
+ }
+ else
+ {
+ f_print (fout, "&%s->%s_val, (u_int *) &%s->%s_len",
+ objname, name, objname, name);
+ }
+ }
+ print_ifarg (amax);
+ if (!alt)
+ {
+ print_ifsizeof (indent + 1, prefix, type);
+ }
+ break;
+ case REL_ALIAS:
+ print_ifopen (indent, type);
+ print_ifarg (objname);
+ break;
+ }
+ print_ifclose (indent);
+}
+
+static void
+emit_enum (definition * def)
+{
+ (void) def;
+
+ print_ifopen (1, "enum");
+ print_ifarg ("(enum_t *) objp");
+ print_ifclose (1);
+}
+
+static void
+emit_program (const definition * def)
+{
+ decl_list *dl;
+ version_list *vlist;
+ proc_list *plist;
+
+ for (vlist = def->def.pr.versions; vlist != NULL; vlist = vlist->next)
+ for (plist = vlist->procs; plist != NULL; plist = plist->next)
+ {
+ if (!newstyle || plist->arg_num < 2)
+ continue; /* old style, or single argument */
+ print_prog_header (plist);
+ for (dl = plist->args.decls; dl != NULL;
+ dl = dl->next)
+ print_stat (1, &dl->decl);
+ print_trailer ();
+ }
+}
+
+static void
+emit_union (const definition * def)
+{
+ declaration *dflt;
+ case_list *cl;
+ declaration *cs;
+ char *object;
+ const char *vecformat = "objp->%s_u.%s";
+ const char *format = "&objp->%s_u.%s";
+
+ print_stat (1, &def->def.un.enum_decl);
+ f_print (fout, "\tswitch (objp->%s) {\n", def->def.un.enum_decl.name);
+ for (cl = def->def.un.cases; cl != NULL; cl = cl->next)
+ {
+
+ f_print (fout, "\tcase %s:\n", cl->case_name);
+ if (cl->contflag == 1) /* a continued case statement */
+ continue;
+ cs = &cl->case_decl;
+ if (!streq (cs->type, "void"))
+ {
+ object = alloc (strlen (def->def_name) + strlen (format) +
+ strlen (cs->name) + 1);
+ if (isvectordef (cs->type, cs->rel))
+ {
+ s_print (object, vecformat, def->def_name,
+ cs->name);
+ }
+ else
+ {
+ s_print (object, format, def->def_name,
+ cs->name);
+ }
+ print_ifstat (2, cs->prefix, cs->type, cs->rel, cs->array_max,
+ object, cs->name);
+ free (object);
+ }
+ f_print (fout, "\t\tbreak;\n");
+ }
+ dflt = def->def.un.default_decl;
+ if (dflt != NULL)
+ {
+ if (!streq (dflt->type, "void"))
+ {
+ f_print (fout, "\tdefault:\n");
+ object = alloc (strlen (def->def_name) + strlen (format) +
+ strlen (dflt->name) + 1);
+ if (isvectordef (dflt->type, dflt->rel))
+ {
+ s_print (object, vecformat, def->def_name,
+ dflt->name);
+ }
+ else
+ {
+ s_print (object, format, def->def_name,
+ dflt->name);
+ }
+
+ print_ifstat (2, dflt->prefix, dflt->type, dflt->rel,
+ dflt->array_max, object, dflt->name);
+ free (object);
+ f_print (fout, "\t\tbreak;\n");
+ }
+ else
+ {
+ f_print (fout, "\tdefault:\n");
+ f_print (fout, "\t\tbreak;\n");
+ }
+ }
+ else
+ {
+ f_print (fout, "\tdefault:\n");
+ f_print (fout, "\t\treturn FALSE;\n");
+ }
+
+ f_print (fout, "\t}\n");
+}
+
+static void
+inline_struct (definition *def, int flag)
+{
+ decl_list *dl;
+ int i, size;
+ decl_list *cur = NULL;
+ decl_list *psav;
+ bas_type *ptr;
+ char *sizestr;
+ const char *plus;
+ char ptemp[256];
+ int indent = 1;
+
+ if (flag == PUT)
+ f_print (fout, "\n\tif (xdrs->x_op == XDR_ENCODE) {\n");
+ else
+ f_print (fout,
+ "\t\treturn TRUE;\n\t} else if (xdrs->x_op == XDR_DECODE) {\n");
+
+ i = 0;
+ size = 0;
+ sizestr = NULL;
+ for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
+ { /* xxx */
+ /* now walk down the list and check for basic types */
+ if ((dl->decl.prefix == NULL) &&
+ ((ptr = find_type (dl->decl.type)) != NULL) &&
+ ((dl->decl.rel == REL_ALIAS) || (dl->decl.rel == REL_VECTOR)))
+ {
+ if (i == 0)
+ cur = dl;
+ ++i;
+
+ if (dl->decl.rel == REL_ALIAS)
+ size += ptr->length;
+ else
+ {
+ /* this is required to handle arrays */
+ if (sizestr == NULL)
+ plus = "";
+ else
+ plus = "+ ";
+
+ if (ptr->length != 1)
+ s_print (ptemp, " %s %s * %d", plus, dl->decl.array_max,
+ ptr->length);
+ else
+ s_print (ptemp, " %s%s ", plus, dl->decl.array_max);
+
+ /*now concatenate to sizestr !!!! */
+ if (sizestr == NULL)
+ sizestr = strdup (ptemp);
+ else
+ {
+ sizestr = realloc (sizestr, strlen (sizestr) +
+ strlen (ptemp) + 1);
+ if (sizestr == NULL)
+ {
+ f_print (stderr, "Fatal error : no memory \n");
+ crash ();
+ };
+ sizestr = strcat (sizestr, ptemp);
+ /*build up length of array */
+ }
+ }
+ }
+ else
+ {
+ if (i > 0)
+ {
+ if (sizestr == NULL && size < inlineflag)
+ {
+ /* don't expand into inline code if size < inlineflag */
+ while (cur != dl)
+ {
+ print_stat (indent + 1, &cur->decl);
+ cur = cur->next;
+ }
+ }
+ else
+ {
+ /* were already looking at a xdr_inlineable structure */
+ tabify (fout, indent + 1);
+ if (sizestr == NULL)
+ f_print (fout, "buf = XDR_INLINE (xdrs, %d * BYTES_PER_XDR_UNIT);", size);
+ else if (size == 0)
+ f_print (fout,
+ "buf = XDR_INLINE (xdrs, (%s) * BYTES_PER_XDR_UNIT);",
+ sizestr);
+ else
+ f_print (fout,
+ "buf = XDR_INLINE (xdrs, (%d + (%s)) * BYTES_PER_XDR_UNIT);",
+ size, sizestr);
+ f_print (fout, "\n");
+ tabify (fout, indent + 1);
+ fprintf (fout, "if (buf == NULL) {\n");
+ psav = cur;
+ while (cur != dl)
+ {
+ print_stat (indent + 2, &cur->decl);
+ cur = cur->next;
+ }
+
+ f_print (fout, "\n\t\t} else {\n");
+ cur = psav;
+ while (cur != dl)
+ {
+ emit_inline (indent + 1, &cur->decl, flag);
+ cur = cur->next;
+ }
+ tabify (fout, indent + 1);
+ f_print (fout, "}\n");
+ }
+ }
+ size = 0;
+ i = 0;
+ free (sizestr);
+ sizestr = NULL;
+ print_stat (indent + 1, &dl->decl);
+ }
+ }
+ if (i > 0)
+ {
+ if (sizestr == NULL && size < inlineflag)
+ {
+ /* don't expand into inline code if size < inlineflag */
+ while (cur != dl)
+ {
+ print_stat (indent + 1, &cur->decl);
+ cur = cur->next;
+ }
+ }
+ else
+ {
+ /* were already looking at a xdr_inlineable structure */
+ if (sizestr == NULL)
+ f_print (fout,
+ "\t\tbuf = XDR_INLINE (xdrs, %d * BYTES_PER_XDR_UNIT);",
+ size);
+ else if (size == 0)
+ f_print (fout,
+ "\t\tbuf = XDR_INLINE (xdrs, (%s) * BYTES_PER_XDR_UNIT);",
+ sizestr);
+ else
+ f_print (fout,
+ "\t\tbuf = XDR_INLINE (xdrs, (%d + %s)* BYTES_PER_XDR_UNIT);",
+ size, sizestr);
+ f_print (fout, "\n\t\tif (buf == NULL) {\n");
+ psav = cur;
+ while (cur != NULL)
+ {
+ print_stat (indent + 2, &cur->decl);
+ cur = cur->next;
+ }
+ f_print (fout, "\t\t} else {\n");
+
+ cur = psav;
+ while (cur != dl)
+ {
+ emit_inline (indent + 2, &cur->decl, flag);
+ cur = cur->next;
+ }
+ f_print (fout, "\t\t}\n");
+ }
+ }
+}
+
+/* this may be const. i haven't traced this one through yet. */
+
+static void
+emit_struct (definition * def)
+{
+ decl_list *dl;
+ int j, size, flag;
+ bas_type *ptr;
+ int can_inline;
+
+
+ if (inlineflag == 0)
+ {
+ /* No xdr_inlining at all */
+ for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
+ print_stat (1, &dl->decl);
+ return;
+ }
+
+ for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
+ if (dl->decl.rel == REL_VECTOR)
+ {
+ f_print (fout, "\tint i;\n");
+ break;
+ }
+
+ size = 0;
+ can_inline = 0;
+ /*
+ * Make a first pass and see if inling is possible.
+ */
+ for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
+ if ((dl->decl.prefix == NULL) &&
+ ((ptr = find_type (dl->decl.type)) != NULL) &&
+ ((dl->decl.rel == REL_ALIAS) || (dl->decl.rel == REL_VECTOR)))
+ {
+ if (dl->decl.rel == REL_ALIAS)
+ size += ptr->length;
+ else
+ {
+ can_inline = 1;
+ break; /* can be inlined */
+ }
+ }
+ else
+ {
+ if (size >= inlineflag)
+ {
+ can_inline = 1;
+ break; /* can be inlined */
+ }
+ size = 0;
+ }
+ if (size > inlineflag)
+ can_inline = 1;
+
+ if (can_inline == 0)
+ { /* can not inline, drop back to old mode */
+ for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
+ print_stat (1, &dl->decl);
+ return;
+ };
+
+ flag = PUT;
+ for (j = 0; j < 2; j++)
+ {
+ inline_struct (def, flag);
+ if (flag == PUT)
+ flag = GET;
+ }
+
+ f_print (fout, "\t return TRUE;\n\t}\n\n");
+
+ /* now take care of XDR_FREE case */
+
+ for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
+ print_stat (1, &dl->decl);
+}
+
+static void
+emit_typedef (const definition * def)
+{
+ const char *prefix = def->def.ty.old_prefix;
+ const char *type = def->def.ty.old_type;
+ const char *amax = def->def.ty.array_max;
+ relation rel = def->def.ty.rel;
+
+ print_ifstat (1, prefix, type, rel, amax, "objp", def->def_name);
+}
+
+static void
+print_stat (int indent, const declaration * dec)
+{
+ const char *prefix = dec->prefix;
+ const char *type = dec->type;
+ const char *amax = dec->array_max;
+ relation rel = dec->rel;
+ char name[256];
+
+ if (isvectordef (type, rel))
+ {
+ s_print (name, "objp->%s", dec->name);
+ }
+ else
+ {
+ s_print (name, "&objp->%s", dec->name);
+ }
+ print_ifstat (indent, prefix, type, rel, amax, name, dec->name);
+}
+
+
+static void
+emit_inline (int indent, declaration * decl, int flag)
+{
+ switch (decl->rel)
+ {
+ case REL_ALIAS:
+ emit_single_in_line (indent, decl, flag, REL_ALIAS);
+ break;
+ case REL_VECTOR:
+ tabify (fout, indent);
+ f_print (fout, "{\n");
+ tabify (fout, indent + 1);
+ f_print (fout, "register %s *genp;\n\n", decl->type);
+ tabify (fout, indent + 1);
+ f_print (fout,
+ "for (i = 0, genp = objp->%s;\n", decl->name);
+ tabify (fout, indent + 2);
+ f_print (fout, "i < %s; ++i) {\n", decl->array_max);
+ emit_single_in_line (indent + 2, decl, flag, REL_VECTOR);
+ tabify (fout, indent + 1);
+ f_print (fout, "}\n");
+ tabify (fout, indent);
+ f_print (fout, "}\n");
+ break;
+ default:
+ break;
+ /* ?... do nothing I guess */
+ }
+}
+
+static void
+emit_single_in_line (int indent, declaration *decl, int flag, relation rel)
+{
+ char *upp_case;
+ int freed = 0;
+
+ tabify (fout, indent);
+ if (flag == PUT)
+ f_print (fout, "IXDR_PUT_");
+ else
+ {
+ if (rel == REL_ALIAS)
+ f_print (fout, "objp->%s = IXDR_GET_", decl->name);
+ else
+ f_print (fout, "*genp++ = IXDR_GET_");
+ }
+
+ upp_case = upcase (decl->type);
+
+ /* hack - XX */
+ if (!strcmp (upp_case, "INT"))
+ {
+ free (upp_case);
+ freed = 1;
+ /* Casting is safe since the `freed' flag is set. */
+ upp_case = (char *) "LONG";
+ }
+
+ if (!strcmp (upp_case, "U_INT"))
+ {
+ free (upp_case);
+ freed = 1;
+ /* Casting is safe since the `freed' flag is set. */
+ upp_case = (char *) "U_LONG";
+ }
+
+ if (flag == PUT)
+ {
+ if (rel == REL_ALIAS)
+ f_print (fout, "%s(buf, objp->%s);\n", upp_case, decl->name);
+ else
+ f_print (fout, "%s(buf, *genp++);\n", upp_case);
+ }
+ else
+ {
+ f_print (fout, "%s(buf);\n", upp_case);
+ }
+
+ if (!freed)
+ free (upp_case);
+}
+
+
+static char *
+upcase (const char *str)
+{
+ char *ptr, *hptr;
+ ptr = malloc (strlen (str) + 1);
+ if (ptr == NULL)
+ {
+ f_print (stderr, "malloc failed\n");
+ exit (1);
+ }
+ hptr = ptr;
+ while (*str != '\0')
+ *ptr++ = toupper (*str++);
+
+ *ptr = '\0';
+ return hptr;
+}
diff --git a/sunrpc/rpc_dtable.c b/sunrpc/rpc_dtable.c
new file mode 100644
index 0000000..81ddf8f
--- /dev/null
+++ b/sunrpc/rpc_dtable.c
@@ -0,0 +1,49 @@
+/* @(#)rpc_dtablesize.c 2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Copyright (c) 2010, Oracle America, Inc.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <unistd.h>
+#include <rpc/clnt.h>
+
+/*
+ * Cache the result of getdtablesize(), so we don't have to do an
+ * expensive system call every time.
+ */
+int
+_rpc_dtablesize (void)
+{
+ static int size;
+
+ if (size == 0)
+ size = __getdtablesize ();
+
+ return size;
+}
+libc_hidden_nolink_sunrpc (_rpc_dtablesize, GLIBC_2_0)
diff --git a/sunrpc/rpc_hout.c b/sunrpc/rpc_hout.c
new file mode 100644
index 0000000..10f793d
--- /dev/null
+++ b/sunrpc/rpc_hout.c
@@ -0,0 +1,607 @@
+/*
+ * From: @(#)rpc_hout.c 1.12 89/02/22
+ *
+ * Copyright (c) 2010, Oracle America, Inc.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * rpc_hout.c, Header file outputter for the RPC protocol compiler
+ */
+#include <stdio.h>
+#include <ctype.h>
+#include "rpc_parse.h"
+#include "rpc_util.h"
+#include "proto.h"
+
+static void pconstdef (definition * def);
+static void pargdef (definition * def);
+static void pstructdef (definition * def);
+static void puniondef (definition * def);
+static void pdefine (const char *name, const char *num);
+static int define_printed (proc_list * stop, version_list * start);
+static void pprogramdef (definition * def);
+static void parglist (proc_list * proc, const char *addargtype);
+static void penumdef (definition * def);
+static void ptypedef (definition * def);
+static int undefined2 (const char *type, const char *stop);
+
+/* store away enough information to allow the XDR functions to be spat
+ out at the end of the file */
+
+static void
+storexdrfuncdecl (const char *name, int pointerp)
+{
+ xdrfunc * xdrptr;
+
+ xdrptr = (xdrfunc *) malloc(sizeof (struct xdrfunc));
+
+ xdrptr->name = (char *)name;
+ xdrptr->pointerp = pointerp;
+ xdrptr->next = NULL;
+
+ if (xdrfunc_tail == NULL)
+ {
+ xdrfunc_head = xdrptr;
+ xdrfunc_tail = xdrptr;
+ }
+ else
+ {
+ xdrfunc_tail->next = xdrptr;
+ xdrfunc_tail = xdrptr;
+ }
+}
+
+/*
+ * Print the C-version of an xdr definition
+ */
+void
+print_datadef (definition *def)
+{
+
+ if (def->def_kind == DEF_PROGRAM) /* handle data only */
+ return;
+
+ if (def->def_kind != DEF_CONST)
+ {
+ f_print (fout, "\n");
+ }
+ switch (def->def_kind)
+ {
+ case DEF_STRUCT:
+ pstructdef (def);
+ break;
+ case DEF_UNION:
+ puniondef (def);
+ break;
+ case DEF_ENUM:
+ penumdef (def);
+ break;
+ case DEF_TYPEDEF:
+ ptypedef (def);
+ break;
+ case DEF_PROGRAM:
+ pprogramdef (def);
+ break;
+ case DEF_CONST:
+ pconstdef (def);
+ break;
+ }
+ if (def->def_kind != DEF_PROGRAM && def->def_kind != DEF_CONST)
+ {
+ storexdrfuncdecl(def->def_name,
+ def->def_kind != DEF_TYPEDEF ||
+ !isvectordef(def->def.ty.old_type,
+ def->def.ty.rel));
+ }
+}
+
+
+void
+print_funcdef (definition *def)
+{
+ switch (def->def_kind)
+ {
+ case DEF_PROGRAM:
+ f_print (fout, "\n");
+ pprogramdef (def);
+ break;
+ default:
+ break;
+ /* ?... shouldn't happen I guess */
+ }
+}
+
+void
+print_xdr_func_def (char *name, int pointerp, int i)
+{
+ if (i == 2)
+ {
+ f_print (fout, "extern bool_t xdr_%s ();\n", name);
+ return;
+ }
+ else
+ f_print(fout, "extern bool_t xdr_%s (XDR *, %s%s);\n", name,
+ name, pointerp ? "*" : "");
+}
+
+static void
+pconstdef (definition *def)
+{
+ pdefine (def->def_name, def->def.co);
+}
+
+/* print out the definitions for the arguments of functions in the
+ header file
+ */
+static void
+pargdef (definition * def)
+{
+ decl_list *l;
+ version_list *vers;
+ const char *name;
+ proc_list *plist;
+
+ for (vers = def->def.pr.versions; vers != NULL; vers = vers->next)
+ {
+ for (plist = vers->procs; plist != NULL;
+ plist = plist->next)
+ {
+
+ if (!newstyle || plist->arg_num < 2)
+ {
+ continue; /* old style or single args */
+ }
+ name = plist->args.argname;
+ f_print (fout, "struct %s {\n", name);
+ for (l = plist->args.decls;
+ l != NULL; l = l->next)
+ {
+ pdeclaration (name, &l->decl, 1, ";\n");
+ }
+ f_print (fout, "};\n");
+ f_print (fout, "typedef struct %s %s;\n", name, name);
+ storexdrfuncdecl (name, 1);
+ f_print (fout, "\n");
+ }
+ }
+
+}
+
+static void
+pstructdef (definition *def)
+{
+ decl_list *l;
+ const char *name = def->def_name;
+
+ f_print (fout, "struct %s {\n", name);
+ for (l = def->def.st.decls; l != NULL; l = l->next)
+ {
+ pdeclaration (name, &l->decl, 1, ";\n");
+ }
+ f_print (fout, "};\n");
+ f_print (fout, "typedef struct %s %s;\n", name, name);
+}
+
+static void
+puniondef (definition *def)
+{
+ case_list *l;
+ const char *name = def->def_name;
+ declaration *decl;
+
+ f_print (fout, "struct %s {\n", name);
+ decl = &def->def.un.enum_decl;
+ if (streq (decl->type, "bool"))
+ {
+ f_print (fout, "\tbool_t %s;\n", decl->name);
+ }
+ else
+ {
+ f_print (fout, "\t%s %s;\n", decl->type, decl->name);
+ }
+ f_print (fout, "\tunion {\n");
+ for (l = def->def.un.cases; l != NULL; l = l->next)
+ {
+ if (l->contflag == 0)
+ pdeclaration (name, &l->case_decl, 2, ";\n");
+ }
+ decl = def->def.un.default_decl;
+ if (decl && !streq (decl->type, "void"))
+ {
+ pdeclaration (name, decl, 2, ";\n");
+ }
+ f_print (fout, "\t} %s_u;\n", name);
+ f_print (fout, "};\n");
+ f_print (fout, "typedef struct %s %s;\n", name, name);
+}
+
+static void
+pdefine (const char *name, const char *num)
+{
+ f_print (fout, "#define %s %s\n", name, num);
+}
+
+static int
+define_printed (proc_list *stop, version_list *start)
+{
+ version_list *vers;
+ proc_list *proc;
+
+ for (vers = start; vers != NULL; vers = vers->next)
+ {
+ for (proc = vers->procs; proc != NULL; proc = proc->next)
+ {
+ if (proc == stop)
+ {
+ return 0;
+ }
+ else if (streq (proc->proc_name, stop->proc_name))
+ {
+ return 1;
+ }
+ }
+ }
+ abort ();
+ /* NOTREACHED */
+}
+
+static void
+pfreeprocdef (const char *name, const char *vers, int mode)
+{
+ f_print (fout, "extern int ");
+ pvname (name, vers);
+ if (mode == 1)
+ f_print (fout,"_freeresult (SVCXPRT *, xdrproc_t, caddr_t);\n");
+ else
+ f_print (fout,"_freeresult ();\n");
+}
+
+static void
+pprogramdef (definition *def)
+{
+ version_list *vers;
+ proc_list *proc;
+ int i;
+ const char *ext;
+
+ pargdef (def);
+
+ pdefine (def->def_name, def->def.pr.prog_num);
+ for (vers = def->def.pr.versions; vers != NULL; vers = vers->next)
+ {
+ if (tblflag)
+ {
+ f_print (fout, "extern struct rpcgen_table %s_%s_table[];\n",
+ locase (def->def_name), vers->vers_num);
+ f_print (fout, "extern %s_%s_nproc;\n",
+ locase (def->def_name), vers->vers_num);
+ }
+ pdefine (vers->vers_name, vers->vers_num);
+
+ /*
+ * Print out 2 definitions, one for ANSI-C, another for
+ * old K & R C
+ */
+
+ if(!Cflag)
+ {
+ ext = "extern ";
+ for (proc = vers->procs; proc != NULL;
+ proc = proc->next)
+ {
+ if (!define_printed(proc, def->def.pr.versions))
+ {
+ pdefine (proc->proc_name, proc->proc_num);
+ }
+ f_print (fout, "%s", ext);
+ pprocdef (proc, vers, NULL, 0, 2);
+
+ if (mtflag)
+ {
+ f_print(fout, "%s", ext);
+ pprocdef (proc, vers, NULL, 1, 2);
+ }
+ }
+ pfreeprocdef (def->def_name, vers->vers_num, 2);
+ }
+ else
+ {
+ for (i = 1; i < 3; i++)
+ {
+ if (i == 1)
+ {
+ f_print (fout, "\n#if defined(__STDC__) || defined(__cplusplus)\n");
+ ext = "extern ";
+ }
+ else
+ {
+ f_print (fout, "\n#else /* K&R C */\n");
+ ext = "extern ";
+ }
+
+ for (proc = vers->procs; proc != NULL; proc = proc->next)
+ {
+ if (!define_printed(proc, def->def.pr.versions))
+ {
+ pdefine(proc->proc_name, proc->proc_num);
+ }
+ f_print (fout, "%s", ext);
+ pprocdef (proc, vers, "CLIENT *", 0, i);
+ f_print (fout, "%s", ext);
+ pprocdef (proc, vers, "struct svc_req *", 1, i);
+ }
+ pfreeprocdef (def->def_name, vers->vers_num, i);
+ }
+ f_print (fout, "#endif /* K&R C */\n");
+ }
+ }
+}
+
+void
+pprocdef (proc_list * proc, version_list * vp,
+ const char *addargtype, int server_p, int mode)
+{
+ if (mtflag)
+ {/* Print MT style stubs */
+ if (server_p)
+ f_print (fout, "bool_t ");
+ else
+ f_print (fout, "enum clnt_stat ");
+ }
+ else
+ {
+ ptype (proc->res_prefix, proc->res_type, 1);
+ f_print (fout, "* ");
+ }
+ if (server_p)
+ pvname_svc (proc->proc_name, vp->vers_num);
+ else
+ pvname (proc->proc_name, vp->vers_num);
+
+ /*
+ * mode 1 = ANSI-C, mode 2 = K&R C
+ */
+ if (mode == 1)
+ parglist (proc, addargtype);
+ else
+ f_print (fout, "();\n");
+}
+
+/* print out argument list of procedure */
+static void
+parglist (proc_list *proc, const char *addargtype)
+{
+ decl_list *dl;
+
+ f_print(fout,"(");
+ if (proc->arg_num < 2 && newstyle &&
+ streq (proc->args.decls->decl.type, "void"))
+ {
+ /* 0 argument in new style: do nothing */
+ }
+ else
+ {
+ for (dl = proc->args.decls; dl != NULL; dl = dl->next)
+ {
+ ptype (dl->decl.prefix, dl->decl.type, 1);
+ if (!newstyle)
+ f_print (fout, "*"); /* old style passes by reference */
+
+ f_print (fout, ", ");
+ }
+ }
+ if (mtflag)
+ {
+ ptype(proc->res_prefix, proc->res_type, 1);
+ f_print(fout, "*, ");
+ }
+
+ f_print (fout, "%s);\n", addargtype);
+}
+
+static void
+penumdef (definition *def)
+{
+ const char *name = def->def_name;
+ enumval_list *l;
+ const char *last = NULL;
+ int count = 0;
+
+ f_print (fout, "enum %s {\n", name);
+ for (l = def->def.en.vals; l != NULL; l = l->next)
+ {
+ f_print (fout, "\t%s", l->name);
+ if (l->assignment)
+ {
+ f_print (fout, " = %s", l->assignment);
+ last = l->assignment;
+ count = 1;
+ }
+ else
+ {
+ if (last == NULL)
+ {
+ f_print (fout, " = %d", count++);
+ }
+ else
+ {
+ f_print (fout, " = %s + %d", last, count++);
+ }
+ }
+ f_print (fout, ",\n");
+ }
+ f_print (fout, "};\n");
+ f_print (fout, "typedef enum %s %s;\n", name, name);
+}
+
+static void
+ptypedef (definition *def)
+{
+ const char *name = def->def_name;
+ const char *old = def->def.ty.old_type;
+ char prefix[8]; /* enough to contain "struct ", including NUL */
+ relation rel = def->def.ty.rel;
+
+ if (!streq (name, old))
+ {
+ if (streq (old, "string"))
+ {
+ old = "char";
+ rel = REL_POINTER;
+ }
+ else if (streq (old, "opaque"))
+ {
+ old = "char";
+ }
+ else if (streq (old, "bool"))
+ {
+ old = "bool_t";
+ }
+ if (undefined2 (old, name) && def->def.ty.old_prefix)
+ {
+ s_print (prefix, "%s ", def->def.ty.old_prefix);
+ }
+ else
+ {
+ prefix[0] = 0;
+ }
+ f_print (fout, "typedef ");
+ switch (rel)
+ {
+ case REL_ARRAY:
+ f_print (fout, "struct {\n");
+ f_print (fout, "\tu_int %s_len;\n", name);
+ f_print (fout, "\t%s%s *%s_val;\n", prefix, old, name);
+ f_print (fout, "} %s", name);
+ break;
+ case REL_POINTER:
+ f_print (fout, "%s%s *%s", prefix, old, name);
+ break;
+ case REL_VECTOR:
+ f_print (fout, "%s%s %s[%s]", prefix, old, name,
+ def->def.ty.array_max);
+ break;
+ case REL_ALIAS:
+ f_print (fout, "%s%s %s", prefix, old, name);
+ break;
+ }
+ f_print (fout, ";\n");
+ }
+}
+
+void
+pdeclaration (const char *name, declaration * dec, int tab,
+ const char *separator)
+{
+ char buf[8]; /* enough to hold "struct ", include NUL */
+ const char *prefix;
+ const char *type;
+
+ if (streq (dec->type, "void"))
+ {
+ return;
+ }
+ tabify (fout, tab);
+ if (streq (dec->type, name) && !dec->prefix)
+ {
+ f_print (fout, "struct ");
+ }
+ if (streq (dec->type, "string"))
+ {
+ f_print (fout, "char *%s", dec->name);
+ }
+ else
+ {
+ prefix = "";
+ if (streq (dec->type, "bool"))
+ {
+ type = "bool_t";
+ }
+ else if (streq (dec->type, "opaque"))
+ {
+ type = "char";
+ }
+ else
+ {
+ if (dec->prefix)
+ {
+ s_print (buf, "%s ", dec->prefix);
+ prefix = buf;
+ }
+ type = dec->type;
+ }
+ switch (dec->rel)
+ {
+ case REL_ALIAS:
+ f_print (fout, "%s%s %s", prefix, type, dec->name);
+ break;
+ case REL_VECTOR:
+ f_print (fout, "%s%s %s[%s]", prefix, type, dec->name,
+ dec->array_max);
+ break;
+ case REL_POINTER:
+ f_print (fout, "%s%s *%s", prefix, type, dec->name);
+ break;
+ case REL_ARRAY:
+ f_print (fout, "struct {\n");
+ tabify (fout, tab);
+ f_print (fout, "\tu_int %s_len;\n", dec->name);
+ tabify (fout, tab);
+ f_print (fout, "\t%s%s *%s_val;\n", prefix, type, dec->name);
+ tabify (fout, tab);
+ f_print (fout, "} %s", dec->name);
+ break;
+ }
+ }
+ f_print (fout, "%s", separator);
+}
+
+static int
+undefined2 (const char *type, const char *stop)
+{
+ list *l;
+ definition *def;
+
+ for (l = defined; l != NULL; l = l->next)
+ {
+ def = (definition *) l->val;
+ if (def->def_kind != DEF_PROGRAM)
+ {
+ if (streq (def->def_name, stop))
+ {
+ return 1;
+ }
+ else if (streq (def->def_name, type))
+ {
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
diff --git a/sunrpc/rpc_main.c b/sunrpc/rpc_main.c
new file mode 100644
index 0000000..0a51e2c
--- /dev/null
+++ b/sunrpc/rpc_main.c
@@ -0,0 +1,1460 @@
+/*
+ * From @(#)rpc_main.c 1.30 89/03/30
+ *
+ * Copyright (c) 2010, Oracle America, Inc.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * rpc_main.c, Top level of the RPC protocol compiler.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <libintl.h>
+#include <locale.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include "rpc_parse.h"
+#include "rpc_util.h"
+#include "rpc_scan.h"
+#include "proto.h"
+
+#include "../version.h"
+#define PACKAGE _libc_intl_domainname
+
+#define EXTEND 1 /* alias for TRUE */
+#define DONT_EXTEND 0 /* alias for FALSE */
+
+struct commandline
+ {
+ int cflag; /* xdr C routines */
+ int hflag; /* header file */
+ int lflag; /* client side stubs */
+ int mflag; /* server side stubs */
+ int nflag; /* netid flag */
+ int sflag; /* server stubs for the given transport */
+ int tflag; /* dispatch Table file */
+ int Ssflag; /* produce server sample code */
+ int Scflag; /* produce client sample code */
+ int makefileflag; /* Generate a template Makefile */
+ const char *infile; /* input module name */
+ const char *outfile; /* output module name */
+ };
+
+
+static const char *cmdname;
+
+static const char *svcclosetime = "120";
+static int cppDefined; /* explicit path for C preprocessor */
+static const char *CPP = "/lib/cpp";
+static const char CPPFLAGS[] = "-C";
+static char *pathbuf;
+static int cpp_pid;
+static const char *allv[] =
+{
+ "rpcgen", "-s", "udp", "-s", "tcp"
+};
+static int allc = sizeof (allv) / sizeof (allv[0]);
+static const char *allnv[] =
+{
+ "rpcgen", "-s", "netpath",
+};
+static int allnc = sizeof (allnv) / sizeof (allnv[0]);
+
+/*
+ * machinations for handling expanding argument list
+ */
+static void addarg (const char *); /* add another argument to the list */
+static void putarg (int, const char *); /* put argument at specified location */
+static void clear_args (void); /* clear argument list */
+static void checkfiles (const char *, const char *);
+ /* check if out file already exists */
+
+static void clear_args (void);
+static char *extendfile (const char *file, const char *ext);
+static void open_output (const char *infile, const char *outfile);
+static void add_warning (void);
+static void clear_args (void);
+static void find_cpp (void);
+static void open_input (const char *infile, const char *define);
+static int check_nettype (const char *name, const char *list_to_check[]);
+static void c_output (const char *infile, const char *define,
+ int extend, const char *outfile);
+static void h_output (const char *infile, const char *define,
+ int extend, const char *outfile);
+static void s_output (int argc, const char *argv[], const char *infile,
+ const char *define, int extend,
+ const char *outfile, int nomain, int netflag);
+static void l_output (const char *infile, const char *define,
+ int extend, const char *outfile);
+static void t_output (const char *infile, const char *define,
+ int extend, const char *outfile);
+static void svc_output (const char *infile, const char *define,
+ int extend, const char *outfile);
+static void clnt_output (const char *infile, const char *define,
+ int extend, const char *outfile);
+static void mkfile_output (struct commandline *cmd);
+static int do_registers (int argc, const char *argv[]);
+static void addarg (const char *cp);
+static void putarg (int whereto, const char *cp);
+static void checkfiles (const char *infile, const char *outfile);
+static int parseargs (int argc, const char *argv[], struct commandline *cmd);
+static void usage (FILE *stream, int status) __attribute__ ((noreturn));
+static void options_usage (FILE *stream, int status) __attribute__ ((noreturn));
+static void print_version (void);
+static void c_initialize (void);
+static char *generate_guard (const char *pathname);
+
+
+#define ARGLISTLEN 20
+#define FIXEDARGS 2
+
+static const char *arglist[ARGLISTLEN];
+static int argcount = FIXEDARGS;
+
+
+int nonfatalerrors; /* errors */
+int inetdflag /* = 1 */ ; /* Support for inetd *//* is now the default */
+int pmflag; /* Support for port monitors */
+int logflag; /* Use syslog instead of fprintf for errors */
+int tblflag; /* Support for dispatch table file */
+int mtflag; /* Support for MT */
+
+#define INLINE 3
+/*length at which to start doing an inline */
+
+int inlineflag = INLINE; /* length at which to start doing an inline. 3 = default
+ if 0, no xdr_inline code */
+
+int indefinitewait; /* If started by port monitors, hang till it wants */
+int exitnow; /* If started by port monitors, exit after the call */
+int timerflag; /* TRUE if !indefinite && !exitnow */
+int newstyle; /* newstyle of passing arguments (by value) */
+int Cflag = 1; /* ANSI C syntax */
+int CCflag; /* C++ files */
+static int allfiles; /* generate all files */
+int tirpcflag; /* generating code for tirpc, by default */
+xdrfunc *xdrfunc_head; /* xdr function list */
+xdrfunc *xdrfunc_tail; /* xdr function list */
+
+int
+main (int argc, const char *argv[])
+{
+ struct commandline cmd;
+
+ setlocale (LC_ALL, "");
+ textdomain (_libc_intl_domainname);
+
+ (void) memset ((char *) &cmd, 0, sizeof (struct commandline));
+ clear_args ();
+ if (!parseargs (argc, argv, &cmd))
+ usage (stderr, 1);
+
+ if (cmd.cflag || cmd.hflag || cmd.lflag || cmd.tflag || cmd.sflag ||
+ cmd.mflag || cmd.nflag || cmd.Ssflag || cmd.Scflag)
+ {
+ checkfiles (cmd.infile, cmd.outfile);
+ }
+ else
+ checkfiles (cmd.infile, NULL);
+
+ if (cmd.cflag)
+ c_output (cmd.infile, "-DRPC_XDR", DONT_EXTEND, cmd.outfile);
+ else if (cmd.hflag)
+ h_output (cmd.infile, "-DRPC_HDR", DONT_EXTEND, cmd.outfile);
+ else if (cmd.lflag)
+ l_output (cmd.infile, "-DRPC_CLNT", DONT_EXTEND, cmd.outfile);
+ else if (cmd.sflag || cmd.mflag || (cmd.nflag))
+ s_output (argc, argv, cmd.infile, "-DRPC_SVC", DONT_EXTEND,
+ cmd.outfile, cmd.mflag, cmd.nflag);
+ else if (cmd.tflag)
+ t_output (cmd.infile, "-DRPC_TBL", DONT_EXTEND, cmd.outfile);
+ else if (cmd.Ssflag)
+ svc_output (cmd.infile, "-DRPC_SERVER", DONT_EXTEND, cmd.outfile);
+ else if (cmd.Scflag)
+ clnt_output (cmd.infile, "-DRPC_CLIENT", DONT_EXTEND, cmd.outfile);
+ else if (cmd.makefileflag)
+ mkfile_output (&cmd);
+ else
+ {
+ /* the rescans are required, since cpp may effect input */
+ c_output (cmd.infile, "-DRPC_XDR", EXTEND, "_xdr.c");
+ reinitialize ();
+ h_output (cmd.infile, "-DRPC_HDR", EXTEND, ".h");
+ reinitialize ();
+ l_output (cmd.infile, "-DRPC_CLNT", EXTEND, "_clnt.c");
+ reinitialize ();
+ if (inetdflag || !tirpcflag)
+ s_output (allc, allv, cmd.infile, "-DRPC_SVC", EXTEND,
+ "_svc.c", cmd.mflag, cmd.nflag);
+ else
+ s_output (allnc, allnv, cmd.infile, "-DRPC_SVC",
+ EXTEND, "_svc.c", cmd.mflag, cmd.nflag);
+ if (tblflag)
+ {
+ reinitialize ();
+ t_output (cmd.infile, "-DRPC_TBL", EXTEND, "_tbl.i");
+ }
+ if (allfiles)
+ {
+ reinitialize ();
+ svc_output (cmd.infile, "-DRPC_SERVER", EXTEND, "_server.c");
+ reinitialize ();
+ clnt_output (cmd.infile, "-DRPC_CLIENT", EXTEND, "_client.c");
+ }
+ if (allfiles || (cmd.makefileflag == 1))
+ {
+ reinitialize ();
+ mkfile_output (&cmd);
+ }
+ }
+
+ return nonfatalerrors;
+}
+
+/*
+ * add extension to filename
+ */
+static char *
+extendfile (const char *file, const char *ext)
+{
+ char *res;
+ const char *p;
+
+ res = alloc (strlen (file) + strlen (ext) + 1);
+ if (res == NULL)
+ abort ();
+ p = strrchr (file, '.');
+ if (p == NULL)
+ p = file + strlen (file);
+ strcpy (res, file);
+ strcpy (res + (p - file), ext);
+ return res;
+}
+
+/*
+ * Open output file with given extension
+ */
+static void
+open_output (const char *infile, const char *outfile)
+{
+ if (outfile == NULL)
+ {
+ fout = stdout;
+ return;
+ }
+
+ if (infile != NULL && streq (outfile, infile))
+ {
+ fprintf (stderr, _ ("%s: output would overwrite %s\n"), cmdname,
+ infile);
+ crash ();
+ }
+ fout = fopen (outfile, "w");
+ if (fout == NULL)
+ {
+ fprintf (stderr, _ ("%s: unable to open %s: %m\n"), cmdname, outfile);
+ crash ();
+ }
+ record_open (outfile);
+}
+
+/* Close the output file and check for write errors. */
+static void
+close_output (const char *outfile)
+{
+ if (fclose (fout) == EOF)
+ {
+ fprintf (stderr, _("%s: while writing output %s: %m"), cmdname,
+ outfile ?: "<stdout>");
+ crash ();
+ }
+}
+
+static void
+add_warning (void)
+{
+ fprintf (fout, "/*\n");
+ fprintf (fout, " * Please do not edit this file.\n");
+ fprintf (fout, " * It was generated using rpcgen.\n");
+ fprintf (fout, " */\n\n");
+}
+
+/* clear list of arguments */
+static void
+clear_args (void)
+{
+ int i;
+ for (i = FIXEDARGS; i < ARGLISTLEN; ++i)
+ arglist[i] = NULL;
+ argcount = FIXEDARGS;
+}
+
+/* make sure that a CPP exists */
+static void
+find_cpp (void)
+{
+ struct stat64 buf;
+
+ if (stat64 (CPP, &buf) == 0)
+ return;
+
+ if (cppDefined) /* user specified cpp but it does not exist */
+ {
+ fprintf (stderr, _ ("cannot find C preprocessor: %s\n"), CPP);
+ crash ();
+ }
+
+ /* fall back to system CPP */
+ CPP = "cpp";
+}
+
+/*
+ * Open input file with given define for C-preprocessor
+ */
+static void
+open_input (const char *infile, const char *define)
+{
+ int pd[2];
+
+ infilename = (infile == NULL) ? "<stdin>" : infile;
+ if (pipe (pd) != 0)
+ {
+ perror ("pipe");
+ exit (1);
+ }
+ cpp_pid = fork ();
+ switch (cpp_pid)
+ {
+ case 0:
+ find_cpp ();
+ putarg (0, CPP);
+ putarg (1, CPPFLAGS);
+ addarg (define);
+ if (infile)
+ addarg (infile);
+ addarg ((char *) NULL);
+ close (1);
+ dup2 (pd[1], 1);
+ close (pd[0]);
+ execvp (arglist[0], (char **) arglist);
+ if (errno == ENOENT)
+ {
+ fprintf (stderr, _ ("cannot find C preprocessor: %s\n"), CPP);
+ exit (1);
+ }
+ perror ("execvp");
+ exit (1);
+ case -1:
+ perror ("fork");
+ exit (1);
+ }
+ close (pd[1]);
+ fin = fdopen (pd[0], "r");
+ if (fin == NULL)
+ {
+ fprintf (stderr, "%s: ", cmdname);
+ perror (infilename);
+ crash ();
+ }
+}
+
+/* Close the connection to the C-preprocessor and check for successfull
+ termination. */
+static void
+close_input (void)
+{
+ int status;
+
+ fclose (fin);
+ /* Check the termination status. */
+ if (waitpid (cpp_pid, &status, 0) < 0)
+ {
+ perror ("waitpid");
+ crash ();
+ }
+ if (WIFSIGNALED (status) || WEXITSTATUS (status) != 0)
+ {
+ if (WIFSIGNALED (status))
+ fprintf (stderr, _("%s: C preprocessor failed with signal %d\n"),
+ cmdname, WTERMSIG (status));
+ else
+ fprintf (stderr, _("%s: C preprocessor failed with exit code %d\n"),
+ cmdname, WEXITSTATUS (status));
+ crash ();
+ }
+}
+
+/* valid tirpc nettypes */
+static const char *valid_ti_nettypes[] =
+{
+ "netpath",
+ "visible",
+ "circuit_v",
+ "datagram_v",
+ "circuit_n",
+ "datagram_n",
+ "udp",
+ "tcp",
+ "raw",
+ NULL
+};
+
+/* valid inetd nettypes */
+static const char *valid_i_nettypes[] =
+{
+ "udp",
+ "tcp",
+ NULL
+};
+
+static int
+check_nettype (const char *name, const char *list_to_check[])
+{
+ int i;
+ for (i = 0; list_to_check[i] != NULL; i++)
+ {
+ if (strcmp (name, list_to_check[i]) == 0)
+ {
+ return 1;
+ }
+ }
+ fprintf (stderr, _ ("illegal nettype: `%s'\n"), name);
+ return 0;
+}
+
+/*
+ * Compile into an XDR routine output file
+ */
+
+static void
+c_output (const char *infile, const char *define, int extend,
+ const char *outfile)
+{
+ definition *def;
+ char *include;
+ const char *outfilename;
+ long tell;
+
+ c_initialize ();
+ open_input (infile, define);
+ outfilename = extend ? extendfile (infile, outfile) : outfile;
+ open_output (infile, outfilename);
+ add_warning ();
+ if (infile && (include = extendfile (infile, ".h")))
+ {
+ fprintf (fout, "#include \"%s\"\n", include);
+ free (include);
+ /* .h file already contains rpc/rpc.h */
+ }
+ else
+ fprintf (fout, "#include <rpc/rpc.h>\n");
+ tell = ftell (fout);
+ while ((def = get_definition ()) != NULL)
+ emit (def);
+
+ if (extend && tell == ftell (fout))
+ unlink (outfilename);
+ close_input ();
+ close_output (outfilename);
+}
+
+void
+c_initialize (void)
+{
+
+ /* add all the starting basic types */
+
+ add_type (1, "int");
+ add_type (1, "long");
+ add_type (1, "short");
+ add_type (1, "bool");
+
+ add_type (1, "u_int");
+ add_type (1, "u_long");
+ add_type (1, "u_short");
+
+}
+
+char rpcgen_table_dcl[] = "struct rpcgen_table {\n\
+ char *(*proc)();\n\
+ xdrproc_t xdr_arg;\n\
+ unsigned len_arg;\n\
+ xdrproc_t xdr_res;\n\
+ unsigned len_res;\n\
+};\n";
+
+
+static char *
+generate_guard (const char *pathname)
+{
+ const char *filename;
+ char *guard, *tmp;
+
+ filename = strrchr (pathname, '/'); /* find last component */
+ filename = ((filename == NULL) ? pathname : filename + 1);
+ guard = extendfile (filename, "_H_RPCGEN");
+ /* convert to upper case */
+ tmp = guard;
+ while (*tmp)
+ {
+ if (islower (*tmp))
+ *tmp = toupper (*tmp);
+ tmp++;
+ }
+
+ return guard;
+}
+
+/*
+ * Compile into an XDR header file
+ */
+
+
+static void
+h_output (const char *infile, const char *define, int extend,
+ const char *outfile)
+{
+ xdrfunc *xdrfuncp;
+ definition *def;
+ const char *ifilename;
+ const char *outfilename;
+ long tell;
+ char *guard;
+ list *l;
+
+ open_input (infile, define);
+ outfilename = extend ? extendfile (infile, outfile) : outfile;
+ open_output (infile, outfilename);
+ add_warning ();
+ ifilename = (infile == NULL) ? "STDIN" : infile;
+ guard = generate_guard (outfilename ? outfilename : ifilename);
+
+ fprintf (fout, "#ifndef _%s\n#define _%s\n\n", guard,
+ guard);
+
+ fprintf (fout, "#include <rpc/rpc.h>\n\n");
+
+ if (mtflag)
+ {
+ fprintf (fout, "#include <pthread.h>\n");
+ }
+
+ /* put the C++ support */
+ if (Cflag && !CCflag)
+ {
+ fprintf (fout, "\n#ifdef __cplusplus\n");
+ fprintf (fout, "extern \"C\" {\n");
+ fprintf (fout, "#endif\n\n");
+ }
+
+ tell = ftell (fout);
+ /* print data definitions */
+ while ((def = get_definition ()) != NULL)
+ {
+ print_datadef (def);
+ }
+
+ /* print function declarations.
+ Do this after data definitions because they might be used as
+ arguments for functions */
+ for (l = defined; l != NULL; l = l->next)
+ {
+ print_funcdef (l->val);
+ }
+ /* Now print all xdr func declarations */
+ if (xdrfunc_head != NULL)
+ {
+ fprintf (fout, "\n/* the xdr functions */\n");
+ if (CCflag)
+ {
+ fprintf (fout, "\n#ifdef __cplusplus\n");
+ fprintf (fout, "extern \"C\" {\n");
+ fprintf (fout, "#endif\n");
+ }
+ if (!Cflag)
+ {
+ xdrfuncp = xdrfunc_head;
+ while (xdrfuncp != NULL)
+ {
+ print_xdr_func_def (xdrfuncp->name,
+ xdrfuncp->pointerp, 2);
+ xdrfuncp = xdrfuncp->next;
+ }
+ }
+ else
+ {
+ int i;
+
+ for (i = 1; i < 3; ++i)
+ {
+ if (i == 1)
+ fprintf (fout, "\n#if defined(__STDC__) || defined(__cplusplus)\n");
+ else
+ fprintf (fout, "\n#else /* K&R C */\n");
+
+ xdrfuncp = xdrfunc_head;
+ while (xdrfuncp != NULL)
+ {
+ print_xdr_func_def (xdrfuncp->name,
+ xdrfuncp->pointerp, i);
+ xdrfuncp = xdrfuncp->next;
+ }
+ }
+ fprintf (fout, "\n#endif /* K&R C */\n");
+ }
+ }
+
+ if (extend && tell == ftell (fout))
+ {
+ unlink (outfilename);
+ }
+ else if (tblflag)
+ {
+ fprintf (fout, "%s", rpcgen_table_dcl);
+ }
+
+ if (Cflag)
+ {
+ fprintf (fout, "\n#ifdef __cplusplus\n");
+ fprintf (fout, "}\n");
+ fprintf (fout, "#endif\n");
+ }
+
+ fprintf (fout, "\n#endif /* !_%s */\n", guard);
+ free (guard);
+ close_input ();
+ close_output (outfilename);
+}
+
+/*
+ * Compile into an RPC service
+ */
+static void
+s_output (int argc, const char *argv[], const char *infile, const char *define,
+ int extend, const char *outfile, int nomain, int netflag)
+{
+ char *include;
+ definition *def;
+ int foundprogram = 0;
+ const char *outfilename;
+
+ open_input (infile, define);
+ outfilename = extend ? extendfile (infile, outfile) : outfile;
+ open_output (infile, outfilename);
+ add_warning ();
+ if (infile && (include = extendfile (infile, ".h")))
+ {
+ fprintf (fout, "#include \"%s\"\n", include);
+ free (include);
+ }
+ else
+ fprintf (fout, "#include <rpc/rpc.h>\n");
+
+ fprintf (fout, "#include <stdio.h>\n");
+ fprintf (fout, "#include <stdlib.h>\n");
+ fprintf (fout, "#include <rpc/pmap_clnt.h>\n");
+ if (Cflag)
+ fprintf (fout, "#include <string.h>\n");
+ if (strcmp (svcclosetime, "-1") == 0)
+ indefinitewait = 1;
+ else if (strcmp (svcclosetime, "0") == 0)
+ exitnow = 1;
+ else if (inetdflag || pmflag)
+ {
+ fprintf (fout, "#include <signal.h>\n");
+ timerflag = 1;
+ }
+
+ if (!tirpcflag && inetdflag)
+ fprintf (fout, "#include <sys/ioctl.h> /* ioctl, TIOCNOTTY */\n");
+ if (Cflag && (inetdflag || pmflag))
+ {
+ fprintf (fout, "#include <sys/types.h> /* open */\n");
+ fprintf (fout, "#include <sys/stat.h> /* open */\n");
+ fprintf (fout, "#include <fcntl.h> /* open */\n");
+ fprintf (fout, "#include <unistd.h> /* getdtablesize */\n");
+ }
+ if (tirpcflag && !(Cflag && (inetdflag || pmflag)))
+ fprintf (fout, "#include <sys/types.h>\n");
+
+ fprintf (fout, "#include <memory.h>\n");
+ if (inetdflag || !tirpcflag)
+ {
+ fprintf (fout, "#include <sys/socket.h>\n");
+ fprintf (fout, "#include <netinet/in.h>\n");
+ }
+
+ if ((netflag || pmflag) && tirpcflag && !nomain)
+ {
+ fprintf (fout, "#include <netconfig.h>\n");
+ }
+ if ( /*timerflag && */ tirpcflag)
+ fprintf (fout, "#include <sys/resource.h> /* rlimit */\n");
+ if (logflag || inetdflag || pmflag)
+ {
+ fprintf (fout, "#include <syslog.h>\n");
+ }
+
+ /* for ANSI-C */
+ if (Cflag)
+ fprintf (fout, "\n#ifndef SIG_PF\n#define SIG_PF void(*)(int)\n#endif\n");
+
+ if (timerflag)
+ fprintf (fout, "\n#define _RPCSVC_CLOSEDOWN %s\n", svcclosetime);
+ while ((def = get_definition ()) != NULL)
+ {
+ foundprogram |= (def->def_kind == DEF_PROGRAM);
+ }
+ if (extend && !foundprogram)
+ {
+ unlink (outfilename);
+ return;
+ }
+ write_most (infile, netflag, nomain);
+ if (!nomain)
+ {
+ if (!do_registers (argc, argv))
+ {
+ if (outfilename)
+ unlink (outfilename);
+ usage (stderr, 1);
+ }
+ write_rest ();
+ }
+ close_input ();
+ close_output (outfilename);
+}
+
+/*
+ * generate client side stubs
+ */
+static void
+l_output (const char *infile, const char *define, int extend,
+ const char *outfile)
+{
+ char *include;
+ definition *def;
+ int foundprogram = 0;
+ const char *outfilename;
+
+ open_input (infile, define);
+ outfilename = extend ? extendfile (infile, outfile) : outfile;
+ open_output (infile, outfilename);
+ add_warning ();
+ if (Cflag)
+ fprintf (fout, "#include <memory.h> /* for memset */\n");
+ if (infile && (include = extendfile (infile, ".h")))
+ {
+ fprintf (fout, "#include \"%s\"\n", include);
+ free (include);
+ }
+ else
+ fprintf (fout, "#include <rpc/rpc.h>\n");
+ while ((def = get_definition ()) != NULL)
+ {
+ foundprogram |= (def->def_kind == DEF_PROGRAM);
+ }
+ if (extend && !foundprogram)
+ {
+ unlink (outfilename);
+ return;
+ }
+ write_stubs ();
+ close_input ();
+ close_output (outfilename);
+}
+
+/*
+ * generate the dispatch table
+ */
+static void
+t_output (const char *infile, const char *define, int extend,
+ const char *outfile)
+{
+ definition *def;
+ int foundprogram = 0;
+ const char *outfilename;
+
+ open_input (infile, define);
+ outfilename = extend ? extendfile (infile, outfile) : outfile;
+ open_output (infile, outfilename);
+ add_warning ();
+ while ((def = get_definition ()) != NULL)
+ {
+ foundprogram |= (def->def_kind == DEF_PROGRAM);
+ }
+ if (extend && !foundprogram)
+ {
+ unlink (outfilename);
+ return;
+ }
+ write_tables ();
+ close_input ();
+ close_output (outfilename);
+}
+
+/* sample routine for the server template */
+static void
+svc_output (const char *infile, const char *define, int extend,
+ const char *outfile)
+{
+ definition *def;
+ char *include;
+ const char *outfilename;
+ long tell;
+
+ open_input (infile, define);
+ outfilename = extend ? extendfile (infile, outfile) : outfile;
+ checkfiles (infile, outfilename);
+ /*check if outfile already exists.
+ if so, print an error message and exit */
+ open_output (infile, outfilename);
+ add_sample_msg ();
+
+ if (infile && (include = extendfile (infile, ".h")))
+ {
+ fprintf (fout, "#include \"%s\"\n", include);
+ free (include);
+ }
+ else
+ fprintf (fout, "#include <rpc/rpc.h>\n");
+
+ tell = ftell (fout);
+ while ((def = get_definition ()) != NULL)
+ {
+ write_sample_svc (def);
+ }
+ if (extend && tell == ftell (fout))
+ {
+ unlink (outfilename);
+ }
+ close_input ();
+ close_output (outfilename);
+}
+
+
+/* sample main routine for client */
+static void
+clnt_output (const char *infile, const char *define, int extend,
+ const char *outfile)
+{
+ definition *def;
+ char *include;
+ const char *outfilename;
+ long tell;
+ int has_program = 0;
+
+ open_input (infile, define);
+ outfilename = extend ? extendfile (infile, outfile) : outfile;
+ checkfiles (infile, outfilename);
+ /*check if outfile already exists.
+ if so, print an error message and exit */
+
+ open_output (infile, outfilename);
+ add_sample_msg ();
+ if (infile && (include = extendfile (infile, ".h")))
+ {
+ fprintf (fout, "#include \"%s\"\n", include);
+ free (include);
+ }
+ else
+ fprintf (fout, "#include <rpc/rpc.h>\n");
+ tell = ftell (fout);
+ while ((def = get_definition ()) != NULL)
+ {
+ has_program += write_sample_clnt (def);
+ }
+
+ if (has_program)
+ write_sample_clnt_main ();
+
+ if (extend && tell == ftell (fout))
+ {
+ unlink (outfilename);
+ }
+ close_input ();
+ close_output (outfilename);
+}
+
+static const char space[] = " ";
+
+static char *
+file_name (const char *file, const char *ext)
+{
+ char *temp;
+ temp = extendfile (file, ext);
+
+ if (access (temp, F_OK) != -1)
+ return (temp);
+
+ free (temp);
+ return (char *) space;
+}
+
+static void
+mkfile_output (struct commandline *cmd)
+{
+ char *mkfilename;
+ char *clientname, *clntname, *xdrname, *hdrname;
+ char *servername, *svcname, *servprogname, *clntprogname;
+
+ svcname = file_name (cmd->infile, "_svc.c");
+ clntname = file_name (cmd->infile, "_clnt.c");
+ xdrname = file_name (cmd->infile, "_xdr.c");
+ hdrname = file_name (cmd->infile, ".h");
+
+ if (allfiles)
+ {
+ servername = extendfile (cmd->infile, "_server.c");
+ clientname = extendfile (cmd->infile, "_client.c");
+ }
+ else
+ {
+ servername = (char *) space;
+ clientname = (char *) space;
+ }
+ servprogname = extendfile (cmd->infile, "_server");
+ clntprogname = extendfile (cmd->infile, "_client");
+
+ if (allfiles)
+ {
+ char *cp, *temp;
+
+ mkfilename = alloc (strlen ("Makefile.") + strlen (cmd->infile) + 1);
+ if (mkfilename == NULL)
+ abort ();
+ temp = rindex (cmd->infile, '.');
+ cp = stpcpy (mkfilename, "Makefile.");
+ if (temp != NULL)
+ *((char *) stpncpy (cp, cmd->infile, temp - cmd->infile)) = '\0';
+ else
+ stpcpy (cp, cmd->infile);
+
+ }
+ else
+ mkfilename = (char *) cmd->outfile;
+
+ checkfiles (NULL, mkfilename);
+ open_output (NULL, mkfilename);
+
+ fprintf (fout, "\n# This is a template Makefile generated by rpcgen\n");
+
+ f_print (fout, "\n# Parameters\n\n");
+
+ f_print (fout, "CLIENT = %s\nSERVER = %s\n\n", clntprogname, servprogname);
+ f_print (fout, "SOURCES_CLNT.c = \nSOURCES_CLNT.h = \n");
+ f_print (fout, "SOURCES_SVC.c = \nSOURCES_SVC.h = \n");
+ f_print (fout, "SOURCES.x = %s\n\n", cmd->infile);
+ f_print (fout, "TARGETS_SVC.c = %s %s %s \n",
+ svcname, servername, xdrname);
+ f_print (fout, "TARGETS_CLNT.c = %s %s %s \n",
+ clntname, clientname, xdrname);
+ f_print (fout, "TARGETS = %s %s %s %s %s %s\n\n",
+ hdrname, xdrname, clntname,
+ svcname, clientname, servername);
+
+ f_print (fout, "OBJECTS_CLNT = $(SOURCES_CLNT.c:%%.c=%%.o) \
+$(TARGETS_CLNT.c:%%.c=%%.o)");
+
+ f_print (fout, "\nOBJECTS_SVC = $(SOURCES_SVC.c:%%.c=%%.o) \
+$(TARGETS_SVC.c:%%.c=%%.o)");
+
+ f_print (fout, "\n# Compiler flags \n");
+ if (mtflag)
+ fprintf (fout, "\nCPPFLAGS += -D_REENTRANT\nCFLAGS += -g \nLDLIBS \
++= -lnsl -lpthread \n ");
+ else
+ f_print (fout, "\nCFLAGS += -g \nLDLIBS += -lnsl\n");
+ f_print (fout, "RPCGENFLAGS = \n");
+
+ f_print (fout, "\n# Targets \n\n");
+
+ f_print (fout, "all : $(CLIENT) $(SERVER)\n\n");
+ f_print (fout, "$(TARGETS) : $(SOURCES.x) \n");
+ f_print (fout, "\trpcgen $(RPCGENFLAGS) $(SOURCES.x)\n\n");
+ f_print (fout, "$(OBJECTS_CLNT) : $(SOURCES_CLNT.c) $(SOURCES_CLNT.h) \
+$(TARGETS_CLNT.c) \n\n");
+
+ f_print (fout, "$(OBJECTS_SVC) : $(SOURCES_SVC.c) $(SOURCES_SVC.h) \
+$(TARGETS_SVC.c) \n\n");
+ f_print (fout, "$(CLIENT) : $(OBJECTS_CLNT) \n");
+ f_print (fout, "\t$(LINK.c) -o $(CLIENT) $(OBJECTS_CLNT) \
+$(LDLIBS) \n\n");
+ f_print (fout, "$(SERVER) : $(OBJECTS_SVC) \n");
+ f_print (fout, "\t$(LINK.c) -o $(SERVER) $(OBJECTS_SVC) $(LDLIBS)\n\n ");
+ f_print (fout, "clean:\n\t $(RM) core $(TARGETS) $(OBJECTS_CLNT) \
+$(OBJECTS_SVC) $(CLIENT) $(SERVER)\n\n");
+ close_output (mkfilename);
+
+ free (clntprogname);
+ free (servprogname);
+ if (servername != space)
+ free (servername);
+ if (clientname != space)
+ free (clientname);
+ if (mkfilename != (char *) cmd->outfile)
+ free (mkfilename);
+ if (svcname != space)
+ free (svcname);
+ if (clntname != space)
+ free (clntname);
+ if (xdrname != space)
+ free (xdrname);
+ if (hdrname != space)
+ free (hdrname);
+}
+
+/*
+ * Perform registrations for service output
+ * Return 0 if failed; 1 otherwise.
+ */
+static int
+do_registers (int argc, const char *argv[])
+{
+ int i;
+
+ if (inetdflag || !tirpcflag)
+ {
+ for (i = 1; i < argc; i++)
+ {
+ if (streq (argv[i], "-s"))
+ {
+ if (!check_nettype (argv[i + 1], valid_i_nettypes))
+ return 0;
+ write_inetd_register (argv[i + 1]);
+ i++;
+ }
+ }
+ }
+ else
+ {
+ for (i = 1; i < argc; i++)
+ if (streq (argv[i], "-s"))
+ {
+ if (!check_nettype (argv[i + 1], valid_ti_nettypes))
+ return 0;
+ write_nettype_register (argv[i + 1]);
+ i++;
+ }
+ else if (streq (argv[i], "-n"))
+ {
+ write_netid_register (argv[i + 1]);
+ i++;
+ }
+ }
+ return 1;
+}
+
+/*
+ * Add another argument to the arg list
+ */
+static void
+addarg (const char *cp)
+{
+ if (argcount >= ARGLISTLEN)
+ {
+ fprintf (stderr, _("rpcgen: too many defines\n"));
+ crash ();
+ /*NOTREACHED */
+ }
+ arglist[argcount++] = cp;
+}
+
+static void
+putarg (int whereto, const char *cp)
+{
+ if (whereto >= ARGLISTLEN)
+ {
+ fprintf (stderr, _("rpcgen: arglist coding error\n"));
+ crash ();
+ /*NOTREACHED */
+ }
+ arglist[whereto] = cp;
+}
+
+/*
+ * if input file is stdin and an output file is specified then complain
+ * if the file already exists. Otherwise the file may get overwritten
+ * If input file does not exist, exit with an error
+ */
+
+static void
+checkfiles (const char *infile, const char *outfile)
+{
+ struct stat64 buf;
+
+ if (infile) /* infile ! = NULL */
+ if (stat64 (infile, &buf) < 0)
+ {
+ perror (infile);
+ crash ();
+ }
+ if (outfile)
+ {
+ if (stat64 (outfile, &buf) < 0)
+ return; /* file does not exist */
+ else
+ {
+ fprintf (stderr,
+ /* TRANS: the file will not be removed; this is an
+ TRANS: informative message. */
+ _("file `%s' already exists and may be overwritten\n"),
+ outfile);
+ crash ();
+ }
+ }
+}
+
+/*
+ * Parse command line arguments
+ */
+static int
+parseargs (int argc, const char *argv[], struct commandline *cmd)
+{
+ int i;
+ int j;
+ int c;
+ char flag[(1 << 8 * sizeof (char))];
+ int nflags;
+
+ cmdname = argv[0];
+ cmd->infile = cmd->outfile = NULL;
+ if (argc < 2)
+ {
+ return (0);
+ }
+ allfiles = 0;
+ flag['c'] = 0;
+ flag['h'] = 0;
+ flag['l'] = 0;
+ flag['m'] = 0;
+ flag['o'] = 0;
+ flag['s'] = 0;
+ flag['n'] = 0;
+ flag['t'] = 0;
+ flag['S'] = 0;
+ flag['C'] = 0;
+ flag['M'] = 0;
+
+ for (i = 1; i < argc; i++)
+ {
+ if (argv[i][0] != '-')
+ {
+ if (cmd->infile)
+ {
+ fprintf (stderr,
+ _("Cannot specify more than one input file!\n"));
+ return 0;
+ }
+ cmd->infile = argv[i];
+ }
+ else if (strcmp (argv[i], "--help") == 0)
+ usage (stdout, 0);
+ else if (strcmp (argv[i], "--version") == 0)
+ print_version ();
+ else
+ {
+ for (j = 1; argv[i][j] != 0; j++)
+ {
+ c = argv[i][j];
+ switch (c)
+ {
+ case 'a':
+ allfiles = 1;
+ break;
+ case 'c':
+ case 'h':
+ case 'l':
+ case 'm':
+ case 't':
+ if (flag[c])
+ return 0;
+ flag[c] = 1;
+ break;
+ case 'S':
+ /* sample flag: Ss or Sc.
+ Ss means set flag['S'];
+ Sc means set flag['C'];
+ Sm means set flag['M']; */
+ c = argv[i][++j]; /* get next char */
+ if (c == 's')
+ c = 'S';
+ else if (c == 'c')
+ c = 'C';
+ else if (c == 'm')
+ c = 'M';
+ else
+ return 0;
+
+ if (flag[c])
+ return 0;
+ flag[c] = 1;
+ break;
+ case 'C': /* ANSI C syntax */
+ Cflag = 1;
+ break;
+
+ case 'k': /* K&R C syntax */
+ Cflag = 0;
+ break;
+
+ case 'b': /* turn TIRPC flag off for
+ generating backward compatible
+ */
+ tirpcflag = 0;
+ break;
+
+ case '5': /* turn TIRPC flag on for
+ generating SysVr4 compatible
+ */
+ tirpcflag = 1;
+ break;
+ case 'I':
+ inetdflag = 1;
+ break;
+ case 'N':
+ newstyle = 1;
+ break;
+ case 'L':
+ logflag = 1;
+ break;
+ case 'K':
+ if (++i == argc)
+ {
+ return (0);
+ }
+ svcclosetime = argv[i];
+ goto nextarg;
+ case 'T':
+ tblflag = 1;
+ break;
+ case 'M':
+ mtflag = 1;
+ break;
+ case 'i':
+ if (++i == argc)
+ {
+ return (0);
+ }
+ inlineflag = atoi (argv[i]);
+ goto nextarg;
+ case 'n':
+ case 'o':
+ case 's':
+ if (argv[i][j - 1] != '-' ||
+ argv[i][j + 1] != 0)
+ {
+ return (0);
+ }
+ flag[c] = 1;
+ if (++i == argc)
+ {
+ return (0);
+ }
+ if (c == 's')
+ {
+ if (!streq (argv[i], "udp") &&
+ !streq (argv[i], "tcp"))
+ return 0;
+ }
+ else if (c == 'o')
+ {
+ if (cmd->outfile)
+ return 0;
+ cmd->outfile = argv[i];
+ }
+ goto nextarg;
+ case 'D':
+ if (argv[i][j - 1] != '-')
+ return 0;
+ addarg (argv[i]);
+ goto nextarg;
+ case 'Y':
+ if (++i == argc)
+ return 0;
+ {
+ size_t len = strlen (argv[i]);
+ pathbuf = malloc (len + 5);
+ if (pathbuf == NULL)
+ {
+ perror (cmdname);
+ crash ();
+ }
+ stpcpy (stpcpy (pathbuf,
+ argv[i]),
+ "/cpp");
+ CPP = pathbuf;
+ cppDefined = 1;
+ goto nextarg;
+ }
+
+ default:
+ return 0;
+ }
+ }
+ nextarg:
+ ;
+ }
+ }
+
+ cmd->cflag = flag['c'];
+ cmd->hflag = flag['h'];
+ cmd->lflag = flag['l'];
+ cmd->mflag = flag['m'];
+ cmd->nflag = flag['n'];
+ cmd->sflag = flag['s'];
+ cmd->tflag = flag['t'];
+ cmd->Ssflag = flag['S'];
+ cmd->Scflag = flag['C'];
+ cmd->makefileflag = flag['M'];
+
+#ifndef _RPC_THREAD_SAFE_
+ if (mtflag || newstyle)
+ {
+ /* glibc doesn't support these flags. */
+ f_print (stderr,
+ _("This implementation doesn't support newstyle or MT-safe code!\n"));
+ return (0);
+ }
+#endif
+ if (tirpcflag)
+ {
+ pmflag = inetdflag ? 0 : 1; /* pmflag or inetdflag is always TRUE */
+ if ((inetdflag && cmd->nflag))
+ { /* netid not allowed with inetdflag */
+ fprintf (stderr, _("Cannot use netid flag with inetd flag!\n"));
+ return 0;
+ }
+ }
+ else
+ { /* 4.1 mode */
+ pmflag = 0; /* set pmflag only in tirpcmode */
+ if (cmd->nflag)
+ { /* netid needs TIRPC */
+ f_print (stderr, _("Cannot use netid flag without TIRPC!\n"));
+ return (0);
+ }
+ }
+
+ if (newstyle && (tblflag || cmd->tflag))
+ {
+ f_print (stderr, _("Cannot use table flags with newstyle!\n"));
+ return (0);
+ }
+
+ /* check no conflicts with file generation flags */
+ nflags = cmd->cflag + cmd->hflag + cmd->lflag + cmd->mflag +
+ cmd->sflag + cmd->nflag + cmd->tflag + cmd->Ssflag + cmd->Scflag;
+
+ if (nflags == 0)
+ {
+ if (cmd->outfile != NULL || cmd->infile == NULL)
+ {
+ return (0);
+ }
+ }
+ else if (cmd->infile == NULL &&
+ (cmd->Ssflag || cmd->Scflag || cmd->makefileflag))
+ {
+ fprintf (stderr,
+ _("\"infile\" is required for template generation flags.\n"));
+ return 0;
+ }
+ if (nflags > 1)
+ {
+ fprintf (stderr, _("Cannot have more than one file generation flag!\n"));
+ return 0;
+ }
+ return 1;
+}
+
+static void
+usage (FILE *stream, int status)
+{
+ fprintf (stream, _("usage: %s infile\n"), cmdname);
+ fprintf (stream, _("\t%s [-abkCLNTM][-Dname[=value]] [-i size] \
+[-I [-K seconds]] [-Y path] infile\n"), cmdname);
+ fprintf (stream, _("\t%s [-c | -h | -l | -m | -t | -Sc | -Ss | -Sm] \
+[-o outfile] [infile]\n"), cmdname);
+ fprintf (stream, _("\t%s [-s nettype]* [-o outfile] [infile]\n"), cmdname);
+ fprintf (stream, _("\t%s [-n netid]* [-o outfile] [infile]\n"), cmdname);
+ options_usage (stream, status);
+ exit (status);
+}
+
+static void
+options_usage (FILE *stream, int status)
+{
+ f_print (stream, _("options:\n"));
+ f_print (stream, _("-a\t\tgenerate all files, including samples\n"));
+ f_print (stream, _("-b\t\tbackward compatibility mode (generates code for SunOS 4.1)\n"));
+ f_print (stream, _("-c\t\tgenerate XDR routines\n"));
+ f_print (stream, _("-C\t\tANSI C mode\n"));
+ f_print (stream, _("-Dname[=value]\tdefine a symbol (same as #define)\n"));
+ f_print (stream, _("-h\t\tgenerate header file\n"));
+ f_print (stream, _("-i size\t\tsize at which to start generating inline code\n"));
+ f_print (stream, _("-I\t\tgenerate code for inetd support in server (for SunOS 4.1)\n"));
+ f_print (stream, _("-K seconds\tserver exits after K seconds of inactivity\n"));
+ f_print (stream, _("-l\t\tgenerate client side stubs\n"));
+ f_print (stream, _("-L\t\tserver errors will be printed to syslog\n"));
+ f_print (stream, _("-m\t\tgenerate server side stubs\n"));
+ f_print (stream, _("-M\t\tgenerate MT-safe code\n"));
+ f_print (stream, _("-n netid\tgenerate server code that supports named netid\n"));
+ f_print (stream, _("-N\t\tsupports multiple arguments and call-by-value\n"));
+ f_print (stream, _("-o outfile\tname of the output file\n"));
+ f_print (stream, _("-s nettype\tgenerate server code that supports named nettype\n"));
+ f_print (stream, _("-Sc\t\tgenerate sample client code that uses remote procedures\n"));
+ f_print (stream, _("-Ss\t\tgenerate sample server code that defines remote procedures\n"));
+ f_print (stream, _("-Sm \t\tgenerate makefile template \n"));
+ f_print (stream, _("-t\t\tgenerate RPC dispatch table\n"));
+ f_print (stream, _("-T\t\tgenerate code to support RPC dispatch tables\n"));
+ f_print (stream, _("-Y path\t\tdirectory name to find C preprocessor (cpp)\n"));
+ f_print (stream, _("-5\t\tSysVr4 compatibility mode\n"));
+ f_print (stream, _("--help\t\tgive this help list\n"));
+ f_print (stream, _("--version\tprint program version\n"));
+
+ f_print (stream, _("\n\
+For bug reporting instructions, please see:\n\
+%s.\n"), REPORT_BUGS_TO);
+ exit (status);
+}
+
+static void
+print_version (void)
+{
+ printf ("rpcgen %s%s\n", PKGVERSION, VERSION);
+ exit (0);
+}
diff --git a/sunrpc/rpc_parse.c b/sunrpc/rpc_parse.c
new file mode 100644
index 0000000..1a1df6d
--- /dev/null
+++ b/sunrpc/rpc_parse.c
@@ -0,0 +1,687 @@
+/*
+ * From: @(#)rpc_parse.c 1.8 89/02/22
+ *
+ * Copyright (c) 2010, Oracle America, Inc.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * rpc_parse.c, Parser for the RPC protocol compiler
+ * Copyright (C) 1987 Sun Microsystems, Inc.
+ */
+#include <stdio.h>
+#include <string.h>
+#include "rpc/types.h"
+#include "rpc_scan.h"
+#include "rpc_parse.h"
+#include "rpc_util.h"
+#include "proto.h"
+
+#define ARGNAME "arg"
+
+static void isdefined (definition * defp);
+static void def_struct (definition * defp);
+static void def_program (definition * defp);
+static void def_enum (definition * defp);
+static void def_const (definition * defp);
+static void def_union (definition * defp);
+static void check_type_name (const char *name, int new_type);
+static void def_typedef (definition * defp);
+static void get_declaration (declaration * dec, defkind dkind);
+static void get_prog_declaration (declaration * dec, defkind dkind, int num);
+static void get_type (const char **prefixp, const char **typep, defkind dkind);
+static void unsigned_dec (const char **typep);
+
+/*
+ * return the next definition you see
+ */
+definition *
+get_definition (void)
+{
+ definition *defp;
+ token tok;
+
+ defp = ALLOC (definition);
+ get_token (&tok);
+ switch (tok.kind)
+ {
+ case TOK_STRUCT:
+ def_struct (defp);
+ break;
+ case TOK_UNION:
+ def_union (defp);
+ break;
+ case TOK_TYPEDEF:
+ def_typedef (defp);
+ break;
+ case TOK_ENUM:
+ def_enum (defp);
+ break;
+ case TOK_PROGRAM:
+ def_program (defp);
+ break;
+ case TOK_CONST:
+ def_const (defp);
+ break;
+ case TOK_EOF:
+ free (defp);
+ return (NULL);
+ default:
+ error ("definition keyword expected");
+ }
+ scan (TOK_SEMICOLON, &tok);
+ isdefined (defp);
+ return (defp);
+}
+
+static void
+isdefined (definition * defp)
+{
+ STOREVAL (&defined, defp);
+}
+
+static void
+def_struct (definition * defp)
+{
+ token tok;
+ declaration dec;
+ decl_list *decls;
+ decl_list **tailp;
+
+ defp->def_kind = DEF_STRUCT;
+
+ scan (TOK_IDENT, &tok);
+ defp->def_name = tok.str;
+ scan (TOK_LBRACE, &tok);
+ tailp = &defp->def.st.decls;
+ do
+ {
+ get_declaration (&dec, DEF_STRUCT);
+ decls = ALLOC (decl_list);
+ decls->decl = dec;
+ *tailp = decls;
+ tailp = &decls->next;
+ scan (TOK_SEMICOLON, &tok);
+ peek (&tok);
+ }
+ while (tok.kind != TOK_RBRACE);
+ get_token (&tok);
+ *tailp = NULL;
+}
+
+static void
+def_program (definition * defp)
+{
+ token tok;
+ declaration dec;
+ decl_list *decls;
+ decl_list **tailp;
+ version_list *vlist;
+ version_list **vtailp;
+ proc_list *plist;
+ proc_list **ptailp;
+ int num_args;
+ bool_t isvoid = FALSE; /* whether first argument is void */
+ defp->def_kind = DEF_PROGRAM;
+ scan (TOK_IDENT, &tok);
+ defp->def_name = tok.str;
+ scan (TOK_LBRACE, &tok);
+ vtailp = &defp->def.pr.versions;
+ tailp = &defp->def.st.decls;
+ scan (TOK_VERSION, &tok);
+ do
+ {
+ scan (TOK_IDENT, &tok);
+ vlist = ALLOC (version_list);
+ vlist->vers_name = tok.str;
+ scan (TOK_LBRACE, &tok);
+ ptailp = &vlist->procs;
+ do
+ {
+ /* get result type */
+ plist = ALLOC (proc_list);
+ get_type (&plist->res_prefix, &plist->res_type,
+ DEF_PROGRAM);
+ if (streq (plist->res_type, "opaque"))
+ {
+ error ("illegal result type");
+ }
+ scan (TOK_IDENT, &tok);
+ plist->proc_name = tok.str;
+ scan (TOK_LPAREN, &tok);
+ /* get args - first one */
+ num_args = 1;
+ isvoid = FALSE;
+ /* type of DEF_PROGRAM in the first
+ * get_prog_declaration and DEF_STURCT in the next
+ * allows void as argument if it is the only argument
+ */
+ get_prog_declaration (&dec, DEF_PROGRAM, num_args);
+ if (streq (dec.type, "void"))
+ isvoid = TRUE;
+ decls = ALLOC (decl_list);
+ plist->args.decls = decls;
+ decls->decl = dec;
+ tailp = &decls->next;
+ /* get args */
+ while (peekscan (TOK_COMMA, &tok))
+ {
+ num_args++;
+ get_prog_declaration (&dec, DEF_STRUCT,
+ num_args);
+ decls = ALLOC (decl_list);
+ decls->decl = dec;
+ *tailp = decls;
+ if (streq (dec.type, "void"))
+ isvoid = TRUE;
+ tailp = &decls->next;
+ }
+ /* multiple arguments are only allowed in newstyle */
+ if (!newstyle && num_args > 1)
+ {
+ error ("only one argument is allowed");
+ }
+ if (isvoid && num_args > 1)
+ {
+ error ("illegal use of void in program definition");
+ }
+ *tailp = NULL;
+ scan (TOK_RPAREN, &tok);
+ scan (TOK_EQUAL, &tok);
+ scan_num (&tok);
+ scan (TOK_SEMICOLON, &tok);
+ plist->proc_num = tok.str;
+ plist->arg_num = num_args;
+ *ptailp = plist;
+ ptailp = &plist->next;
+ peek (&tok);
+ }
+ while (tok.kind != TOK_RBRACE);
+ *ptailp = NULL;
+ *vtailp = vlist;
+ vtailp = &vlist->next;
+ scan (TOK_RBRACE, &tok);
+ scan (TOK_EQUAL, &tok);
+ scan_num (&tok);
+ vlist->vers_num = tok.str;
+ /* make the argument structure name for each arg */
+ for (plist = vlist->procs; plist != NULL;
+ plist = plist->next)
+ {
+ plist->args.argname = make_argname (plist->proc_name,
+ vlist->vers_num);
+ /* free the memory ?? */
+ }
+ scan (TOK_SEMICOLON, &tok);
+ scan2 (TOK_VERSION, TOK_RBRACE, &tok);
+ }
+ while (tok.kind == TOK_VERSION);
+ scan (TOK_EQUAL, &tok);
+ scan_num (&tok);
+ defp->def.pr.prog_num = tok.str;
+ *vtailp = NULL;
+}
+
+
+static void
+def_enum (definition * defp)
+{
+ token tok;
+ enumval_list *elist;
+ enumval_list **tailp;
+
+ defp->def_kind = DEF_ENUM;
+ scan (TOK_IDENT, &tok);
+ defp->def_name = tok.str;
+ scan (TOK_LBRACE, &tok);
+ tailp = &defp->def.en.vals;
+ do
+ {
+ scan (TOK_IDENT, &tok);
+ elist = ALLOC (enumval_list);
+ elist->name = tok.str;
+ elist->assignment = NULL;
+ scan3 (TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok);
+ if (tok.kind == TOK_EQUAL)
+ {
+ scan_num (&tok);
+ elist->assignment = tok.str;
+ scan2 (TOK_COMMA, TOK_RBRACE, &tok);
+ }
+ *tailp = elist;
+ tailp = &elist->next;
+ }
+ while (tok.kind != TOK_RBRACE);
+ *tailp = NULL;
+}
+
+static void
+def_const (definition * defp)
+{
+ token tok;
+
+ defp->def_kind = DEF_CONST;
+ scan (TOK_IDENT, &tok);
+ defp->def_name = tok.str;
+ scan (TOK_EQUAL, &tok);
+ scan2 (TOK_IDENT, TOK_STRCONST, &tok);
+ defp->def.co = tok.str;
+}
+
+static void
+def_union (definition *defp)
+{
+ token tok;
+ declaration dec;
+ case_list *cases;
+/* case_list *tcase; */
+ case_list **tailp;
+#if 0
+ int flag;
+#endif
+
+ defp->def_kind = DEF_UNION;
+ scan (TOK_IDENT, &tok);
+ defp->def_name = tok.str;
+ scan (TOK_SWITCH, &tok);
+ scan (TOK_LPAREN, &tok);
+ get_declaration (&dec, DEF_UNION);
+ defp->def.un.enum_decl = dec;
+ tailp = &defp->def.un.cases;
+ scan (TOK_RPAREN, &tok);
+ scan (TOK_LBRACE, &tok);
+ scan (TOK_CASE, &tok);
+ while (tok.kind == TOK_CASE)
+ {
+ scan2 (TOK_IDENT, TOK_CHARCONST, &tok);
+ cases = ALLOC (case_list);
+ cases->case_name = tok.str;
+ scan (TOK_COLON, &tok);
+ /* now peek at next token */
+#if 0
+ flag = 0;
+#endif
+ if (peekscan (TOK_CASE, &tok))
+ {
+
+ do
+ {
+ scan2 (TOK_IDENT, TOK_CHARCONST, &tok);
+ cases->contflag = 1; /* continued case statement */
+ *tailp = cases;
+ tailp = &cases->next;
+ cases = ALLOC (case_list);
+ cases->case_name = tok.str;
+ scan (TOK_COLON, &tok);
+
+ }
+ while (peekscan (TOK_CASE, &tok));
+ }
+#if 0
+ else if (flag)
+ {
+
+ *tailp = cases;
+ tailp = &cases->next;
+ cases = ALLOC (case_list);
+ };
+#endif
+
+ get_declaration (&dec, DEF_UNION);
+ cases->case_decl = dec;
+ cases->contflag = 0; /* no continued case statement */
+ *tailp = cases;
+ tailp = &cases->next;
+ scan (TOK_SEMICOLON, &tok);
+
+ scan3 (TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok);
+ }
+ *tailp = NULL;
+ if (tok.kind == TOK_DEFAULT)
+ {
+ scan (TOK_COLON, &tok);
+ get_declaration (&dec, DEF_UNION);
+ defp->def.un.default_decl = ALLOC (declaration);
+ *defp->def.un.default_decl = dec;
+ scan (TOK_SEMICOLON, &tok);
+ scan (TOK_RBRACE, &tok);
+ }
+ else
+ {
+ defp->def.un.default_decl = NULL;
+ }
+}
+
+static const char *reserved_words[] =
+{
+ "array",
+ "bytes",
+ "destroy",
+ "free",
+ "getpos",
+ "inline",
+ "pointer",
+ "reference",
+ "setpos",
+ "sizeof",
+ "union",
+ "vector",
+ NULL
+};
+
+static const char *reserved_types[] =
+{
+ "opaque",
+ "string",
+ NULL
+};
+
+/*
+ * check that the given name is not one that would eventually result in
+ * xdr routines that would conflict with internal XDR routines.
+ */
+static void
+check_type_name (const char *name, int new_type)
+{
+ int i;
+ char tmp[100];
+
+ for (i = 0; reserved_words[i] != NULL; i++)
+ {
+ if (strcmp (name, reserved_words[i]) == 0)
+ {
+ sprintf (tmp,
+ "illegal (reserved) name :\'%s\' in type definition", name);
+ error (tmp);
+ }
+ }
+ if (new_type)
+ {
+ for (i = 0; reserved_types[i] != NULL; i++)
+ {
+ if (strcmp (name, reserved_types[i]) == 0)
+ {
+ sprintf (tmp,
+ "illegal (reserved) name :\'%s\' in type definition", name);
+ error (tmp);
+ }
+ }
+ }
+}
+
+
+
+static void
+def_typedef (definition * defp)
+{
+ declaration dec;
+
+ defp->def_kind = DEF_TYPEDEF;
+ get_declaration (&dec, DEF_TYPEDEF);
+ defp->def_name = dec.name;
+ check_type_name (dec.name, 1);
+ defp->def.ty.old_prefix = dec.prefix;
+ defp->def.ty.old_type = dec.type;
+ defp->def.ty.rel = dec.rel;
+ defp->def.ty.array_max = dec.array_max;
+}
+
+static void
+get_declaration (declaration * dec, defkind dkind)
+{
+ token tok;
+
+ get_type (&dec->prefix, &dec->type, dkind);
+ dec->rel = REL_ALIAS;
+ if (streq (dec->type, "void"))
+ {
+ return;
+ }
+
+ check_type_name (dec->type, 0);
+
+ scan2 (TOK_STAR, TOK_IDENT, &tok);
+ if (tok.kind == TOK_STAR)
+ {
+ dec->rel = REL_POINTER;
+ scan (TOK_IDENT, &tok);
+ }
+ dec->name = tok.str;
+ if (peekscan (TOK_LBRACKET, &tok))
+ {
+ if (dec->rel == REL_POINTER)
+ {
+ error ("no array-of-pointer declarations -- use typedef");
+ }
+ dec->rel = REL_VECTOR;
+ scan_num (&tok);
+ dec->array_max = tok.str;
+ scan (TOK_RBRACKET, &tok);
+ }
+ else if (peekscan (TOK_LANGLE, &tok))
+ {
+ if (dec->rel == REL_POINTER)
+ {
+ error ("no array-of-pointer declarations -- use typedef");
+ }
+ dec->rel = REL_ARRAY;
+ if (peekscan (TOK_RANGLE, &tok))
+ {
+ dec->array_max = "~0"; /* unspecified size, use max */
+ }
+ else
+ {
+ scan_num (&tok);
+ dec->array_max = tok.str;
+ scan (TOK_RANGLE, &tok);
+ }
+ }
+ if (streq (dec->type, "opaque"))
+ {
+ if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR)
+ {
+ error ("array declaration expected");
+ }
+ }
+ else if (streq (dec->type, "string"))
+ {
+ if (dec->rel != REL_ARRAY)
+ {
+ error ("variable-length array declaration expected");
+ }
+ }
+}
+
+static void
+get_prog_declaration (declaration * dec, defkind dkind, int num /* arg number */ )
+{
+ token tok;
+ char name[10]; /* argument name */
+
+ if (dkind == DEF_PROGRAM)
+ {
+ peek (&tok);
+ if (tok.kind == TOK_RPAREN)
+ { /* no arguments */
+ dec->rel = REL_ALIAS;
+ dec->type = "void";
+ dec->prefix = NULL;
+ dec->name = NULL;
+ return;
+ }
+ }
+ get_type (&dec->prefix, &dec->type, dkind);
+ dec->rel = REL_ALIAS;
+ if (peekscan (TOK_IDENT, &tok)) /* optional name of argument */
+ strcpy (name, tok.str);
+ else
+ sprintf (name, "%s%d", ARGNAME, num); /* default name of argument */
+
+ dec->name = (char *) strdup (name);
+
+ if (streq (dec->type, "void"))
+ {
+ return;
+ }
+
+ if (streq (dec->type, "opaque"))
+ {
+ error ("opaque -- illegal argument type");
+ }
+ if (peekscan (TOK_STAR, &tok))
+ {
+ if (streq (dec->type, "string"))
+ {
+ error ("pointer to string not allowed in program arguments\n");
+ }
+ dec->rel = REL_POINTER;
+ if (peekscan (TOK_IDENT, &tok)) /* optional name of argument */
+ dec->name = strdup (tok.str);
+ }
+ if (peekscan (TOK_LANGLE, &tok))
+ {
+ if (!streq (dec->type, "string"))
+ {
+ error ("arrays cannot be declared as arguments to procedures -- use typedef");
+ }
+ dec->rel = REL_ARRAY;
+ if (peekscan (TOK_RANGLE, &tok))
+ {
+ dec->array_max = "~0"; /* unspecified size, use max */
+ }
+ else
+ {
+ scan_num (&tok);
+ dec->array_max = tok.str;
+ scan (TOK_RANGLE, &tok);
+ }
+ }
+ if (streq (dec->type, "string"))
+ {
+ if (dec->rel != REL_ARRAY)
+ { /* .x specifies just string as
+ * type of argument
+ * - make it string<>
+ */
+ dec->rel = REL_ARRAY;
+ dec->array_max = "~0"; /* unspecified size, use max */
+ }
+ }
+}
+
+static void
+get_type (const char **prefixp, const char **typep, defkind dkind)
+{
+ token tok;
+
+ *prefixp = NULL;
+ get_token (&tok);
+ switch (tok.kind)
+ {
+ case TOK_IDENT:
+ *typep = tok.str;
+ break;
+ case TOK_STRUCT:
+ case TOK_ENUM:
+ case TOK_UNION:
+ *prefixp = tok.str;
+ scan (TOK_IDENT, &tok);
+ *typep = tok.str;
+ break;
+ case TOK_UNSIGNED:
+ unsigned_dec (typep);
+ break;
+ case TOK_SHORT:
+ *typep = "short";
+ (void) peekscan (TOK_INT, &tok);
+ break;
+ case TOK_LONG:
+ *typep = "long";
+ (void) peekscan (TOK_INT, &tok);
+ break;
+ case TOK_HYPER:
+ *typep = "quad_t";
+ (void) peekscan(TOK_INT, &tok);
+ break;
+ case TOK_VOID:
+ if (dkind != DEF_UNION && dkind != DEF_PROGRAM)
+ {
+ error ("voids allowed only inside union and program definitions with one argument");
+ }
+ *typep = tok.str;
+ break;
+ case TOK_STRING:
+ case TOK_OPAQUE:
+ case TOK_CHAR:
+ case TOK_INT:
+ case TOK_FLOAT:
+ case TOK_DOUBLE:
+ case TOK_BOOL:
+ *typep = tok.str;
+ break;
+ default:
+ error ("expected type specifier");
+ }
+}
+
+static void
+unsigned_dec (const char **typep)
+{
+ token tok;
+
+ peek (&tok);
+ switch (tok.kind)
+ {
+ case TOK_CHAR:
+ get_token (&tok);
+ *typep = "u_char";
+ break;
+ case TOK_SHORT:
+ get_token (&tok);
+ *typep = "u_short";
+ (void) peekscan (TOK_INT, &tok);
+ break;
+ case TOK_LONG:
+ get_token (&tok);
+ *typep = "u_long";
+ (void) peekscan (TOK_INT, &tok);
+ break;
+ case TOK_HYPER:
+ get_token (&tok);
+ *typep = "u_quad_t";
+ (void) peekscan(TOK_INT, &tok);
+ break;
+ case TOK_INT:
+ get_token (&tok);
+ *typep = "u_int";
+ break;
+ default:
+ *typep = "u_int";
+ break;
+ }
+}
diff --git a/sunrpc/rpc_parse.h b/sunrpc/rpc_parse.h
new file mode 100644
index 0000000..e2e2f1e
--- /dev/null
+++ b/sunrpc/rpc_parse.h
@@ -0,0 +1,165 @@
+/* @(#)rpc_parse.h 1.3 90/08/29
+ *
+ * Copyright (c) 2010, Oracle America, Inc.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * rpc_parse.h, Definitions for the RPCL parser
+ */
+
+enum defkind {
+ DEF_CONST,
+ DEF_STRUCT,
+ DEF_UNION,
+ DEF_ENUM,
+ DEF_TYPEDEF,
+ DEF_PROGRAM
+};
+typedef enum defkind defkind;
+
+typedef const char *const_def;
+
+enum relation {
+ REL_VECTOR, /* fixed length array */
+ REL_ARRAY, /* variable length array */
+ REL_POINTER, /* pointer */
+ REL_ALIAS /* simple */
+};
+typedef enum relation relation;
+
+struct typedef_def {
+ const char *old_prefix;
+ const char *old_type;
+ relation rel;
+ const char *array_max;
+};
+typedef struct typedef_def typedef_def;
+
+struct enumval_list {
+ const char *name;
+ const char *assignment;
+ struct enumval_list *next;
+};
+typedef struct enumval_list enumval_list;
+
+struct enum_def {
+ enumval_list *vals;
+};
+typedef struct enum_def enum_def;
+
+struct declaration {
+ const char *prefix;
+ const char *type;
+ const char *name;
+ relation rel;
+ const char *array_max;
+};
+typedef struct declaration declaration;
+
+struct decl_list {
+ declaration decl;
+ struct decl_list *next;
+};
+typedef struct decl_list decl_list;
+
+struct struct_def {
+ decl_list *decls;
+};
+typedef struct struct_def struct_def;
+
+struct case_list {
+ const char *case_name;
+ int contflag;
+ declaration case_decl;
+ struct case_list *next;
+};
+typedef struct case_list case_list;
+
+struct union_def {
+ declaration enum_decl;
+ case_list *cases;
+ declaration *default_decl;
+};
+typedef struct union_def union_def;
+
+struct arg_list {
+ const char *argname; /* name of struct for arg*/
+ decl_list *decls;
+};
+
+typedef struct arg_list arg_list;
+
+struct proc_list {
+ const char *proc_name;
+ const char *proc_num;
+ arg_list args;
+ int arg_num;
+ const char *res_type;
+ const char *res_prefix;
+ struct proc_list *next;
+};
+typedef struct proc_list proc_list;
+
+struct version_list {
+ const char *vers_name;
+ const char *vers_num;
+ proc_list *procs;
+ struct version_list *next;
+};
+typedef struct version_list version_list;
+
+struct program_def {
+ const char *prog_num;
+ version_list *versions;
+};
+typedef struct program_def program_def;
+
+struct definition {
+ const char *def_name;
+ defkind def_kind;
+ union {
+ const_def co;
+ struct_def st;
+ union_def un;
+ enum_def en;
+ typedef_def ty;
+ program_def pr;
+ } def;
+};
+typedef struct definition definition;
+
+definition *get_definition(void);
+
+
+struct bas_type
+{
+ const char *name;
+ int length;
+ struct bas_type *next;
+};
+
+typedef struct bas_type bas_type;
diff --git a/sunrpc/rpc_prot.c b/sunrpc/rpc_prot.c
new file mode 100644
index 0000000..e086746
--- /dev/null
+++ b/sunrpc/rpc_prot.c
@@ -0,0 +1,276 @@
+/*
+ * rpc_prot.c
+ *
+ * Copyright (c) 2010, Oracle America, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.
+ */
+
+#include <sys/param.h>
+
+#include <rpc/rpc.h>
+
+/* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */
+
+/*
+ * XDR an opaque authentication struct
+ * (see auth.h)
+ */
+bool_t
+xdr_opaque_auth (XDR *xdrs, struct opaque_auth *ap)
+{
+
+ if (xdr_enum (xdrs, &(ap->oa_flavor)))
+ return xdr_bytes (xdrs, &ap->oa_base,
+ &ap->oa_length, MAX_AUTH_BYTES);
+ return FALSE;
+}
+libc_hidden_nolink_sunrpc (xdr_opaque_auth, GLIBC_2_0)
+
+/*
+ * XDR a DES block
+ */
+bool_t
+xdr_des_block (XDR *xdrs, des_block *blkp)
+{
+ return xdr_opaque (xdrs, (caddr_t) blkp, sizeof (des_block));
+}
+libc_hidden_nolink_sunrpc (xdr_des_block, GLIBC_2_0)
+
+/* * * * * * * * * * * * * * 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 *) & (ar->ar_stat)))
+ return FALSE;
+ switch (ar->ar_stat)
+ {
+ case SUCCESS:
+ return ((*(ar->ar_results.proc)) (xdrs, ar->ar_results.where, 0));
+ case PROG_MISMATCH:
+ if (!xdr_u_long (xdrs, &(ar->ar_vers.low)))
+ return FALSE;
+ return (xdr_u_long (xdrs, &(ar->ar_vers.high)));
+ default:
+ return TRUE;
+ }
+ return TRUE; /* TRUE => open ended set of problems */
+}
+libc_hidden_nolink_sunrpc (xdr_accepted_reply, GLIBC_2_0)
+
+/*
+ * 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 *) & (rr->rj_stat)))
+ return FALSE;
+ switch (rr->rj_stat)
+ {
+ case RPC_MISMATCH:
+ if (!xdr_u_long (xdrs, &(rr->rj_vers.low)))
+ return FALSE;
+ return xdr_u_long (xdrs, &(rr->rj_vers.high));
+
+ case AUTH_ERROR:
+ return xdr_enum (xdrs, (enum_t *) & (rr->rj_why));
+ }
+ return FALSE;
+}
+libc_hidden_nolink_sunrpc (xdr_rejected_reply, GLIBC_2_0)
+
+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_long (xdrs, &(rmsg->rm_xid)) &&
+ xdr_enum (xdrs, (enum_t *) & (rmsg->rm_direction)) &&
+ (rmsg->rm_direction == REPLY))
+ return xdr_union (xdrs, (enum_t *) & (rmsg->rm_reply.rp_stat),
+ (caddr_t) & (rmsg->rm_reply.ru), reply_dscrm,
+ NULL_xdrproc_t);
+ return FALSE;
+}
+libc_hidden_nolink_sunrpc (xdr_replymsg, GLIBC_2_0)
+
+
+/*
+ * 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_long (xdrs, &(cmsg->rm_xid)) &&
+ xdr_enum (xdrs, (enum_t *) & (cmsg->rm_direction)) &&
+ xdr_u_long (xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
+ xdr_u_long (xdrs, &(cmsg->rm_call.cb_prog)))
+ return xdr_u_long (xdrs, &(cmsg->rm_call.cb_vers));
+ return FALSE;
+}
+libc_hidden_nolink_sunrpc (xdr_callhdr, GLIBC_2_0)
+
+/* ************************** Client utility routine ************* */
+
+static void
+accepted (enum accept_stat acpt_stat,
+ struct rpc_err *error)
+{
+ 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 = (long) MSG_ACCEPTED;
+ error->re_lb.s2 = (long) acpt_stat;
+}
+
+static void
+rejected (enum reject_stat rjct_stat,
+ struct rpc_err *error)
+{
+ switch (rjct_stat)
+ {
+ case RPC_MISMATCH:
+ error->re_status = RPC_VERSMISMATCH;
+ return;
+ case AUTH_ERROR:
+ error->re_status = RPC_AUTHERROR;
+ return;
+ default:
+ /* something's wrong, but we don't know what ... */
+ error->re_status = RPC_FAILED;
+ error->re_lb.s1 = (long) MSG_DENIED;
+ error->re_lb.s2 = (long) rjct_stat;
+ return;
+ }
+}
+
+/*
+ * given a reply message, fills in the error
+ */
+void
+_seterr_reply (struct rpc_msg *msg,
+ struct rpc_err *error)
+{
+ /* 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 = (long) (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;
+ default:
+ break;
+ }
+}
+libc_hidden_nolink_sunrpc (_seterr_reply, GLIBC_2_0)
diff --git a/sunrpc/rpc_sample.c b/sunrpc/rpc_sample.c
new file mode 100644
index 0000000..e90b58c
--- /dev/null
+++ b/sunrpc/rpc_sample.c
@@ -0,0 +1,336 @@
+/*
+ * From: @(#)rpc_sample.c 1.1 90/08/30
+ *
+ * Copyright (c) 2010, Oracle America, Inc.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * rpc_sample.c, Sample client-server code outputter for the RPC protocol compiler
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "rpc_parse.h"
+#include "rpc_util.h"
+#include "proto.h"
+
+
+static const char RQSTP[] = "rqstp";
+
+static void write_sample_client (const char *program_name, version_list * vp);
+static void write_sample_server (definition * def);
+static void return_type (proc_list * plist);
+
+
+void
+write_sample_svc (definition * def)
+{
+
+ if (def->def_kind != DEF_PROGRAM)
+ return;
+ write_sample_server (def);
+}
+
+
+int
+write_sample_clnt (definition * def)
+{
+ version_list *vp;
+ int count = 0;
+
+ if (def->def_kind != DEF_PROGRAM)
+ return 0;
+ /* generate sample code for each version */
+ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next)
+ {
+ write_sample_client (def->def_name, vp);
+ ++count;
+ }
+ return count;
+}
+
+
+static void
+write_sample_client (const char *program_name, version_list * vp)
+{
+ proc_list *proc;
+ int i;
+ decl_list *l;
+
+ f_print (fout, "\n\nvoid\n");
+ pvname (program_name, vp->vers_num);
+ if (Cflag)
+ f_print (fout, "(char *host)\n{\n");
+ else
+ f_print (fout, "(host)\nchar *host;\n{\n");
+ f_print (fout, "\tCLIENT *clnt;\n");
+
+ i = 0;
+ for (proc = vp->procs; proc != NULL; proc = proc->next)
+ {
+ f_print (fout, "\t");
+ ++i;
+ if (mtflag)
+ {
+ f_print (fout, "enum clnt_stat retval_%d;\n\t", i);
+ ptype (proc->res_prefix, proc->res_type, 1);
+ if (!streq (proc->res_type, "void"))
+ f_print (fout, "result_%d;\n", i);
+ else
+ fprintf (fout, "*result_%d;\n", i);
+ }
+ else
+ {
+ ptype (proc->res_prefix, proc->res_type, 1);
+ f_print (fout, " *result_%d;\n", i);
+ }
+ /* print out declarations for arguments */
+ if (proc->arg_num < 2 && !newstyle)
+ {
+ f_print (fout, "\t");
+ if (!streq (proc->args.decls->decl.type, "void"))
+ {
+ ptype (proc->args.decls->decl.prefix,
+ proc->args.decls->decl.type, 1);
+ f_print (fout, " ");
+ }
+ else
+ f_print (fout, "char *"); /* cannot have "void" type */
+ pvname (proc->proc_name, vp->vers_num);
+ f_print (fout, "_arg;\n");
+ }
+ else if (!streq (proc->args.decls->decl.type, "void"))
+ {
+ for (l = proc->args.decls; l != NULL; l = l->next)
+ {
+ f_print (fout, "\t");
+ ptype (l->decl.prefix, l->decl.type, 1);
+ if (strcmp (l->decl.type, "string") == 1)
+ f_print (fout, " ");
+ pvname (proc->proc_name, vp->vers_num);
+ f_print (fout, "_%s;\n", l->decl.name);
+ }
+ }
+ }
+
+ /* generate creation of client handle */
+ f_print(fout, "\n#ifndef\tDEBUG\n");
+ f_print (fout, "\tclnt = clnt_create (host, %s, %s, \"%s\");\n",
+ program_name, vp->vers_name, tirpcflag ? "netpath" : "udp");
+ f_print (fout, "\tif (clnt == NULL) {\n");
+ f_print (fout, "\t\tclnt_pcreateerror (host);\n");
+ f_print (fout, "\t\texit (1);\n\t}\n");
+ f_print(fout, "#endif\t/* DEBUG */\n\n");
+
+ /* generate calls to procedures */
+ i = 0;
+ for (proc = vp->procs; proc != NULL; proc = proc->next)
+ {
+ if (mtflag)
+ f_print(fout, "\tretval_%d = ",++i);
+ else
+ f_print (fout, "\tresult_%d = ", ++i);
+ pvname (proc->proc_name, vp->vers_num);
+ if (proc->arg_num < 2 && !newstyle)
+ {
+ f_print (fout, "(");
+ if (streq (proc->args.decls->decl.type, "void"))/* cast to void* */
+ f_print (fout, "(void*)");
+ f_print (fout, "&");
+ pvname (proc->proc_name, vp->vers_num);
+ if (mtflag)
+ f_print(fout, "_arg, &result_%d, clnt);\n", i);
+ else
+ f_print (fout, "_arg, clnt);\n");
+ }
+ else if (streq (proc->args.decls->decl.type, "void"))
+ {
+ if (mtflag)
+ f_print (fout, "(&result_%d, clnt);\n", i);
+ else
+ f_print (fout, "(clnt);\n");
+ }
+ else
+ {
+ f_print (fout, "(");
+ for (l = proc->args.decls; l != NULL; l = l->next)
+ {
+ pvname (proc->proc_name, vp->vers_num);
+ f_print (fout, "_%s, ", l->decl.name);
+ }
+ if (mtflag)
+ f_print(fout, "&result_%d, ", i);
+ f_print (fout, "clnt);\n");
+ }
+ if (mtflag)
+ {
+ f_print(fout, "\tif (retval_%d != RPC_SUCCESS) {\n", i);
+ }
+ else
+ {
+ f_print(fout, "\tif (result_%d == (", i);
+ ptype(proc->res_prefix, proc->res_type, 1);
+ f_print(fout, "*) NULL) {\n");
+ }
+ f_print(fout, "\t\tclnt_perror (clnt, \"call failed\");\n");
+ f_print(fout, "\t}\n");
+ }
+
+ f_print (fout, "#ifndef\tDEBUG\n");
+ f_print (fout, "\tclnt_destroy (clnt);\n");
+ f_print (fout, "#endif\t /* DEBUG */\n");
+ f_print (fout, "}\n");
+}
+
+static void
+write_sample_server (definition * def)
+{
+ version_list *vp;
+ proc_list *proc;
+
+ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next)
+ {
+ for (proc = vp->procs; proc != NULL; proc = proc->next)
+ {
+ f_print (fout, "\n");
+ if (!mtflag)
+ {
+ return_type (proc);
+ f_print (fout, "*\n");
+ }
+ else
+ f_print (fout, "bool_t\n");
+ if (Cflag || mtflag)
+ pvname_svc (proc->proc_name, vp->vers_num);
+ else
+ pvname(proc->proc_name, vp->vers_num);
+ printarglist(proc, "result", RQSTP, "struct svc_req *");
+ f_print(fout, "{\n");
+ if (!mtflag)
+ {
+ f_print(fout, "\tstatic ");
+ if(!streq(proc->res_type, "void"))
+ return_type(proc);
+ else
+ f_print(fout, "char *");
+ /* cannot have void type */
+ /* f_print(fout, " result;\n", proc->res_type); */
+ f_print(fout, " result;\n");
+ }
+ else
+ f_print(fout, "\tbool_t retval;\n");
+ fprintf (fout, "\n\t/*\n\t * insert server code here\n\t */\n\n");
+
+ if (!mtflag)
+ {
+ if (!streq(proc->res_type, "void"))
+ f_print(fout, "\treturn &result;\n}\n");
+ else /* cast back to void * */
+ f_print(fout, "\treturn (void *) &result;\n}\n");
+ }
+ else
+ f_print(fout, "\treturn retval;\n}\n");
+ }
+
+ /* put in sample freeing routine */
+ if (mtflag)
+ {
+ f_print(fout, "\nint\n");
+ pvname(def->def_name, vp->vers_num);
+ if (Cflag)
+ f_print(fout,"_freeresult (SVCXPRT *transp, xdrproc_t xdr_result, caddr_t result)\n");
+ else
+ {
+ f_print(fout,"_freeresult (transp, xdr_result, result)\n");
+ f_print(fout,"\tSVCXPRT *transp;\n");
+ f_print(fout,"\txdrproc_t xdr_result;\n");
+ f_print(fout,"\tcaddr_t result;\n");
+ }
+ f_print(fout, "{\n");
+ f_print(fout, "\txdr_free (xdr_result, result);\n");
+ f_print(fout,
+ "\n\t/*\n\t * Insert additional freeing code here, if needed\n\t */\n");
+ f_print(fout, "\n\treturn 1;\n}\n");
+ }
+ }
+}
+
+
+
+static void
+return_type (proc_list * plist)
+{
+ ptype (plist->res_prefix, plist->res_type, 1);
+}
+
+void
+add_sample_msg (void)
+{
+ f_print (fout, "/*\n");
+ f_print (fout, " * This is sample code generated by rpcgen.\n");
+ f_print (fout, " * These are only templates and you can use them\n");
+ f_print (fout, " * as a guideline for developing your own functions.\n");
+ f_print (fout, " */\n\n");
+}
+
+void
+write_sample_clnt_main (void)
+{
+ list *l;
+ definition *def;
+ version_list *vp;
+
+ f_print (fout, "\n\n");
+ if (Cflag)
+ f_print (fout, "int\nmain (int argc, char *argv[])\n{\n");
+ else
+ f_print (fout, "int\nmain (argc, argv)\nint argc;\nchar *argv[];\n{\n");
+
+ f_print (fout, "\tchar *host;");
+ f_print (fout, "\n\n\tif (argc < 2) {");
+ f_print (fout, "\n\t\tprintf (\"usage: %%s server_host\\n\", argv[0]);\n");
+ f_print (fout, "\t\texit (1);\n\t}");
+ f_print (fout, "\n\thost = argv[1];\n");
+
+ for (l = defined; l != NULL; l = l->next)
+ {
+ def = l->val;
+ if (def->def_kind != DEF_PROGRAM)
+ {
+ continue;
+ }
+ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next)
+ {
+ f_print (fout, "\t");
+ pvname (def->def_name, vp->vers_num);
+ f_print (fout, " (host);\n");
+ }
+ }
+ f_print (fout, "exit (0);\n}\n");
+}
diff --git a/sunrpc/rpc_scan.c b/sunrpc/rpc_scan.c
new file mode 100644
index 0000000..7b1e769
--- /dev/null
+++ b/sunrpc/rpc_scan.c
@@ -0,0 +1,548 @@
+/*
+ * From: @(#)rpc_scan.c 1.11 89/02/22
+ *
+ * Copyright (c) 2010, Oracle America, Inc.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * rpc_scan.c, Scanner for the RPC protocol compiler
+ * Copyright (C) 1987, Sun Microsystems, Inc.
+ */
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#ifndef SYLIXOS
+#include <libintl.h>
+#else
+#include <rpc/types.h>
+#endif
+#include "rpc_scan.h"
+#include "rpc_parse.h"
+#include "rpc_util.h"
+#include "proto.h"
+
+#define startcomment(where) (where[0] == '/' && where[1] == '*')
+#define endcomment(where) (where[-1] == '*' && where[0] == '/')
+
+static int pushed = 0; /* is a token pushed */
+static token lasttok; /* last token, if pushed */
+
+static void unget_token (token * tokp);
+static void findstrconst (const char **str, const char **val);
+static void findchrconst (const char **str, const char **val);
+static void findconst (const char **str, const char **val);
+static void findkind (const char **mark, token * tokp);
+static int cppline (const char *line);
+static int directive (const char *line);
+static void printdirective (const char *line);
+static void docppline (const char *line, int *lineno, const char **fname);
+
+/*
+ * scan expecting 1 given token
+ */
+void
+scan (tok_kind expect, token * tokp)
+{
+ get_token (tokp);
+ if (tokp->kind != expect)
+ expected1 (expect);
+}
+
+/*
+ * scan expecting any of the 2 given tokens
+ */
+void
+scan2 (tok_kind expect1, tok_kind expect2, token * tokp)
+{
+ get_token (tokp);
+ if (tokp->kind != expect1 && tokp->kind != expect2)
+ {
+ expected2 (expect1, expect2);
+ }
+}
+
+/*
+ * scan expecting any of the 3 given token
+ */
+void
+scan3 (tok_kind expect1, tok_kind expect2, tok_kind expect3, token * tokp)
+{
+ get_token (tokp);
+ if (tokp->kind != expect1 && tokp->kind != expect2
+ && tokp->kind != expect3)
+ {
+ expected3 (expect1, expect2, expect3);
+ }
+}
+
+/*
+ * scan expecting a constant, possibly symbolic
+ */
+void
+scan_num (token *tokp)
+{
+ get_token (tokp);
+ switch (tokp->kind)
+ {
+ case TOK_IDENT:
+ break;
+ default:
+ error (_("constant or identifier expected"));
+ }
+}
+
+/*
+ * Peek at the next token
+ */
+void
+peek (token *tokp)
+{
+ get_token (tokp);
+ unget_token (tokp);
+}
+
+/*
+ * Peek at the next token and scan it if it matches what you expect
+ */
+int
+peekscan (tok_kind expect, token *tokp)
+{
+ peek (tokp);
+ if (tokp->kind == expect)
+ {
+ get_token (tokp);
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Get the next token, printing out any directive that are encountered.
+ */
+void
+get_token (token *tokp)
+{
+ int commenting;
+
+ if (pushed)
+ {
+ pushed = 0;
+ *tokp = lasttok;
+ return;
+ }
+ commenting = 0;
+ for (;;)
+ {
+ if (*where == 0)
+ {
+ for (;;)
+ {
+ if (!fgets (curline, MAXLINESIZE, fin))
+ {
+ tokp->kind = TOK_EOF;
+ *curline = 0;
+ where = curline;
+ return;
+ }
+ linenum++;
+ if (commenting)
+ {
+ break;
+ }
+ else if (cppline (curline))
+ {
+ docppline (curline, &linenum,
+ &infilename);
+ }
+ else if (directive (curline))
+ {
+ printdirective (curline);
+ }
+ else
+ {
+ break;
+ }
+ }
+ where = curline;
+ }
+ else if (isspace (*where))
+ {
+ while (isspace (*where))
+ {
+ where++; /* eat */
+ }
+ }
+ else if (commenting)
+ {
+ for (where++; *where; where++)
+ {
+ if (endcomment (where))
+ {
+ where++;
+ commenting--;
+ break;
+ }
+ }
+ }
+ else if (startcomment (where))
+ {
+ where += 2;
+ commenting++;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ /*
+ * 'where' is not whitespace, comment or directive Must be a token!
+ */
+ switch (*where)
+ {
+ case ':':
+ tokp->kind = TOK_COLON;
+ where++;
+ break;
+ case ';':
+ tokp->kind = TOK_SEMICOLON;
+ where++;
+ break;
+ case ',':
+ tokp->kind = TOK_COMMA;
+ where++;
+ break;
+ case '=':
+ tokp->kind = TOK_EQUAL;
+ where++;
+ break;
+ case '*':
+ tokp->kind = TOK_STAR;
+ where++;
+ break;
+ case '[':
+ tokp->kind = TOK_LBRACKET;
+ where++;
+ break;
+ case ']':
+ tokp->kind = TOK_RBRACKET;
+ where++;
+ break;
+ case '{':
+ tokp->kind = TOK_LBRACE;
+ where++;
+ break;
+ case '}':
+ tokp->kind = TOK_RBRACE;
+ where++;
+ break;
+ case '(':
+ tokp->kind = TOK_LPAREN;
+ where++;
+ break;
+ case ')':
+ tokp->kind = TOK_RPAREN;
+ where++;
+ break;
+ case '<':
+ tokp->kind = TOK_LANGLE;
+ where++;
+ break;
+ case '>':
+ tokp->kind = TOK_RANGLE;
+ where++;
+ break;
+
+ case '"':
+ tokp->kind = TOK_STRCONST;
+ findstrconst (&where, &tokp->str);
+ break;
+ case '\'':
+ tokp->kind = TOK_CHARCONST;
+ findchrconst (&where, &tokp->str);
+ break;
+
+ case '-':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ tokp->kind = TOK_IDENT;
+ findconst (&where, &tokp->str);
+ break;
+
+ default:
+ if (!(isalpha (*where) || *where == '_'))
+ {
+ char buf[100];
+ char *p;
+
+ s_print (buf, _("illegal character in file: "));
+ p = buf + strlen (buf);
+ if (isprint (*where))
+ {
+ s_print (p, "%c", *where);
+ }
+ else
+ {
+ s_print (p, "%d", *where);
+ }
+ error (buf);
+ }
+ findkind (&where, tokp);
+ break;
+ }
+}
+
+static void
+unget_token (token * tokp)
+{
+ lasttok = *tokp;
+ pushed = 1;
+}
+
+static void
+findstrconst (const char **str, const char **val)
+{
+ const char *p;
+ char *tmp;
+ int size;
+
+ p = *str;
+ do
+ {
+ p++;
+ }
+ while (*p && *p != '"');
+ if (*p == 0)
+ {
+ error (_("unterminated string constant"));
+ }
+ p++;
+ size = p - *str;
+ tmp = alloc (size + 1);
+ strncpy (tmp, *str, size);
+ tmp[size] = 0;
+ *val = tmp;
+ *str = p;
+}
+
+static void
+findchrconst (const char **str, const char **val)
+{
+ const char *p;
+ char *tmp;
+ int size;
+
+ p = *str;
+ do
+ {
+ p++;
+ }
+ while (*p && *p != '\'');
+ if (*p == 0)
+ {
+ error (_("unterminated string constant"));
+ }
+ p++;
+ size = p - *str;
+ if (size != 3)
+ {
+ error (_("empty char string"));
+ }
+ tmp = alloc (size + 1);
+ strncpy (tmp, *str, size);
+ tmp[size] = 0;
+ *val = tmp;
+ *str = p;
+}
+
+static void
+findconst (const char **str, const char **val)
+{
+ const char *p;
+ char *tmp;
+ int size;
+
+ p = *str;
+ if (*p == '0' && *(p + 1) == 'x')
+ {
+ p++;
+ do
+ {
+ p++;
+ }
+ while (isxdigit (*p));
+ }
+ else
+ {
+ do
+ {
+ p++;
+ }
+ while (isdigit (*p));
+ }
+ size = p - *str;
+ tmp = alloc (size + 1);
+ strncpy (tmp, *str, size);
+ tmp[size] = 0;
+ *val = tmp;
+ *str = p;
+}
+
+static const token symbols[] =
+{
+ {TOK_CONST, "const"},
+ {TOK_UNION, "union"},
+ {TOK_SWITCH, "switch"},
+ {TOK_CASE, "case"},
+ {TOK_DEFAULT, "default"},
+ {TOK_STRUCT, "struct"},
+ {TOK_TYPEDEF, "typedef"},
+ {TOK_ENUM, "enum"},
+ {TOK_OPAQUE, "opaque"},
+ {TOK_BOOL, "bool"},
+ {TOK_VOID, "void"},
+ {TOK_CHAR, "char"},
+ {TOK_INT, "int"},
+ {TOK_UNSIGNED, "unsigned"},
+ {TOK_SHORT, "short"},
+ {TOK_LONG, "long"},
+ {TOK_HYPER, "hyper"},
+ {TOK_FLOAT, "float"},
+ {TOK_DOUBLE, "double"},
+ {TOK_STRING, "string"},
+ {TOK_PROGRAM, "program"},
+ {TOK_VERSION, "version"},
+ {TOK_EOF, "??????"},
+};
+
+static void
+findkind (const char **mark, token *tokp)
+{
+ int len;
+ const token *s;
+ const char *str;
+ char *tmp;
+
+ str = *mark;
+ for (s = symbols; s->kind != TOK_EOF; s++)
+ {
+ len = strlen (s->str);
+ if (strncmp (str, s->str, len) == 0)
+ {
+ if (!isalnum (str[len]) && str[len] != '_')
+ {
+ tokp->kind = s->kind;
+ tokp->str = s->str;
+ *mark = str + len;
+ return;
+ }
+ }
+ }
+ tokp->kind = TOK_IDENT;
+ for (len = 0; isalnum (str[len]) || str[len] == '_'; len++);
+ tmp = alloc (len + 1);
+ strncpy (tmp, str, len);
+ tmp[len] = 0;
+ tokp->str = tmp;
+ *mark = str + len;
+}
+
+static int
+cppline (const char *line)
+{
+ return line == curline && *line == '#';
+}
+
+static int
+directive (const char *line)
+{
+ return line == curline && *line == '%';
+}
+
+static void
+printdirective (const char *line)
+{
+ f_print (fout, "%s", line + 1);
+}
+
+static void
+docppline (const char *line, int *lineno, const char **fname)
+{
+ char *file;
+ int num;
+ char *p;
+
+ line++;
+ while (isspace (*line))
+ {
+ line++;
+ }
+ num = atoi (line);
+ while (isdigit (*line))
+ {
+ line++;
+ }
+ while (isspace (*line))
+ {
+ line++;
+ }
+ if (*line != '"')
+ {
+ error (_("preprocessor error"));
+ }
+ line++;
+ p = file = alloc (strlen (line) + 1);
+ while (*line && *line != '"')
+ {
+ *p++ = *line++;
+ }
+ if (*line == 0)
+ {
+ error (_("preprocessor error"));
+ }
+ *p = 0;
+ if (*file == 0)
+ {
+ free (file);
+ *fname = NULL;
+ }
+ else
+ {
+ *fname = file;
+ }
+ *lineno = num - 1;
+}
diff --git a/sunrpc/rpc_scan.h b/sunrpc/rpc_scan.h
new file mode 100644
index 0000000..9786a51
--- /dev/null
+++ b/sunrpc/rpc_scan.h
@@ -0,0 +1,104 @@
+/* @(#)rpc_scan.h 1.3 90/08/29 */
+
+/*
+ * Copyright (c) 2010, Oracle America, Inc.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * rpc_scan.h, Definitions for the RPCL scanner
+ */
+
+/*
+ * kinds of tokens
+ */
+enum tok_kind {
+ TOK_IDENT,
+ TOK_CHARCONST,
+ TOK_STRCONST,
+ TOK_LPAREN,
+ TOK_RPAREN,
+ TOK_LBRACE,
+ TOK_RBRACE,
+ TOK_LBRACKET,
+ TOK_RBRACKET,
+ TOK_LANGLE,
+ TOK_RANGLE,
+ TOK_STAR,
+ TOK_COMMA,
+ TOK_EQUAL,
+ TOK_COLON,
+ TOK_SEMICOLON,
+ TOK_CONST,
+ TOK_STRUCT,
+ TOK_UNION,
+ TOK_SWITCH,
+ TOK_CASE,
+ TOK_DEFAULT,
+ TOK_ENUM,
+ TOK_TYPEDEF,
+ TOK_INT,
+ TOK_SHORT,
+ TOK_LONG,
+ TOK_HYPER,
+ TOK_UNSIGNED,
+ TOK_FLOAT,
+ TOK_DOUBLE,
+ TOK_OPAQUE,
+ TOK_CHAR,
+ TOK_STRING,
+ TOK_BOOL,
+ TOK_VOID,
+ TOK_PROGRAM,
+ TOK_VERSION,
+ TOK_EOF
+};
+typedef enum tok_kind tok_kind;
+
+/*
+ * a token
+ */
+struct token {
+ tok_kind kind;
+ const char *str;
+};
+typedef struct token token;
+
+
+/*
+ * routine interface
+ */
+void scan(tok_kind expect, token *tokp);
+void scan2(tok_kind expect1, tok_kind expect2, token *tokp);
+void scan3(tok_kind expect1, tok_kind expect2, tok_kind expect3, token *tokp);
+void scan_num(token *tokp);
+void peek(token *tokp);
+int peekscan(tok_kind expect, token *tokp);
+void get_token(token *tokp);
+void expected1(tok_kind exp1) __attribute__ ((noreturn));
+void expected2(tok_kind exp1, tok_kind exp2) __attribute__ ((noreturn));
+void expected3(tok_kind exp1, tok_kind exp2, tok_kind exp3)
+ __attribute__ ((noreturn));
diff --git a/sunrpc/rpc_svcout.c b/sunrpc/rpc_svcout.c
new file mode 100644
index 0000000..4f12a81
--- /dev/null
+++ b/sunrpc/rpc_svcout.c
@@ -0,0 +1,1093 @@
+/*
+ * From: @(#)rpc_svcout.c 1.29 89/03/30
+ *
+ * Copyright (c) 2010, Oracle America, Inc.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ * * Neither the name of the "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * rpc_svcout.c, Server-skeleton outputter for the RPC protocol compiler
+ */
+#include <stdio.h>
+#include <string.h>
+#include "rpc_parse.h"
+#include "rpc_util.h"
+#include "proto.h"
+
+static const char RQSTP[] = "rqstp";
+static const char TRANSP[] = "transp";
+static const char ARG[] = "argument";
+static const char RESULT[] = "result";
+static const char ROUTINE[] = "local";
+static char RETVAL[] = "retval";
+
+char _errbuf[256]; /* For all messages */
+
+static void internal_proctype (const proc_list * plist);
+static void p_xdrfunc (const char *rname, const char *typename);
+static void write_real_program (const definition * def);
+static void write_program (const definition * def, const char *storage);
+static void printerr (const char *err, const char *transp);
+static void printif (const char *proc, const char *transp, const char *arg);
+static void write_inetmost (const char *infile);
+static void print_return (const char *space);
+static void print_pmapunset (const char *space);
+static void print_err_message (const char *space);
+static void write_timeout_func (void);
+static void write_pm_most (const char *infile, int netflag);
+static void write_rpc_svc_fg (const char *infile, const char *sp);
+static void open_log_file (const char *infile, const char *sp);
+
+static void
+p_xdrfunc (const char *rname, const char *typename)
+{
+ if (Cflag)
+ f_print (fout, "\t\t_xdr_%s = (xdrproc_t) xdr_%s;\n", rname,
+ stringfix (typename));
+ else
+ f_print (fout, "\t\t_xdr_%s = xdr_%s;\n", rname, stringfix (typename));
+}
+
+void
+internal_proctype (const proc_list * plist)
+{
+ f_print (fout, "static ");
+ ptype (plist->res_prefix, plist->res_type, 1);
+ f_print (fout, "*");
+}
+
+
+/*
+ * write most of the service, that is, everything but the registrations.
+ */
+void
+write_most (const char *infile /* our name */ , int netflag, int nomain)
+{
+ if (inetdflag || pmflag)
+ {
+ const char *var_type;
+ /* WHY? */
+ var_type = (nomain ? "extern" : "");
+ f_print (fout, "%s int _rpcpmstart;", var_type);
+ f_print (fout, "\t\t/* Started by a port monitor ? */\n");
+ if (!tirpcflag)
+ {
+ f_print (fout, "%s int _rpcfdtype;", var_type);
+ f_print (fout, "\t\t/* Whether Stream or Datagram ? */\n");
+ }
+ if (timerflag)
+ {
+#if 0
+ f_print (fout, "%s int _rpcsvcdirty;", var_type);
+ f_print (fout, "\t/* Still serving ? */\n");
+#else
+ f_print(fout, " /* States a server can be in wrt request */\n\n");
+ f_print(fout, "#define\t_IDLE 0\n");
+ f_print(fout, "#define\t_SERVED 1\n");
+ f_print(fout, "#define\t_SERVING 2\n\n");
+ f_print(fout, "static int _rpcsvcstate = _IDLE;");
+ f_print(fout, "\t /* Set when a request is serviced */\n");
+
+ if (mtflag)
+ {
+ f_print (fout, "mutex_t _svcstate_lock;");
+ f_print (fout,
+ "\t\t\t/* Mutex lock for variable_rpcsvcstate */\n");
+ }
+#endif
+ }
+ write_svc_aux (nomain);
+ }
+ /* write out dispatcher and stubs */
+ write_programs (nomain ? NULL : "static");
+
+ if (nomain)
+ return;
+
+ if (Cflag)
+ f_print (fout, "\nint\nmain (int argc, char **argv)\n");
+ else
+ {
+ f_print (fout, "\nint\nmain (argc, argv)\n");
+ f_print (fout, "\tint argc;\n");
+ f_print (fout, "\tchar **argv;\n");
+ }
+ f_print (fout, "{\n");
+ if (inetdflag)
+ {
+ write_inetmost (infile); /* Includes call to write_rpc_svc_fg() */
+ }
+ else
+ {
+ if (tirpcflag)
+ {
+ if (netflag)
+ {
+ f_print (fout, "\tregister SVCXPRT *%s;\n", TRANSP);
+ f_print (fout, "\tstruct netconfig *nconf = NULL;\n");
+ }
+ f_print (fout, "\tpid_t pid;\n");
+ f_print (fout, "\tint i;\n");
+ f_print (fout, "\tchar mname[FMNAMESZ + 1];\n\n");
+
+ if (mtflag & timerflag)
+ f_print (fout,
+ "\tmutex_init (&_svcstate_lock, USYNC_THREAD, NULL);\n");
+
+ write_pm_most (infile, netflag);
+ f_print (fout, "\telse {\n");
+ write_rpc_svc_fg (infile, "\t\t");
+ f_print (fout, "\t}\n");
+ }
+ else
+ {
+ f_print (fout, "\tregister SVCXPRT *%s;\n", TRANSP);
+ f_print (fout, "\n");
+ print_pmapunset ("\t");
+ }
+ }
+
+ if (logflag && !inetdflag)
+ {
+ open_log_file (infile, "\t");
+ }
+}
+
+/*
+ * write a registration for the given transport
+ */
+void
+write_netid_register (const char *transp)
+{
+ list *l;
+ definition *def;
+ version_list *vp;
+ const char *sp;
+ char tmpbuf[32];
+
+ sp = "";
+ f_print (fout, "\n");
+ f_print (fout, "%s\tnconf = getnetconfigent (\"%s\");\n", sp, transp);
+ f_print (fout, "%s\tif (nconf == NULL) {\n", sp);
+ (void) sprintf (_errbuf, "cannot find %s netid.", transp);
+ sprintf (tmpbuf, "%s\t\t", sp);
+ print_err_message (tmpbuf);
+ f_print (fout, "%s\t\texit (1);\n", sp);
+ f_print (fout, "%s\t}\n", sp);
+ f_print (fout, "%s\t%s = svc_tli_create (RPC_ANYFD, nconf, 0, 0, 0);\n",
+ sp, TRANSP /*, transp *//* ?!?... */ );
+ f_print (fout, "%s\tif (%s == NULL) {\n", sp, TRANSP);
+ sprintf (_errbuf, "cannot create %s service.", transp);
+ print_err_message (tmpbuf);
+ f_print (fout, "%s\t\texit (1);\n", sp);
+ f_print (fout, "%s\t}\n", sp);
+
+ for (l = defined; l != NULL; l = l->next)
+ {
+ def = (definition *) l->val;
+ if (def->def_kind != DEF_PROGRAM)
+ {
+ continue;
+ }
+ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next)
+ {
+ f_print (fout, "%s\t(void) rpcb_unset (%s, %s, nconf);\n",
+ sp, def->def_name, vp->vers_name);
+ f_print (fout, "%s\tif (!svc_reg (%s, %s, %s, ",
+ sp, TRANSP, def->def_name, vp->vers_name);
+ pvname (def->def_name, vp->vers_num);
+ f_print (fout, ", nconf)) {\n");
+ (void) sprintf (_errbuf, "unable to register (%s, %s, %s).",
+ def->def_name, vp->vers_name, transp);
+ print_err_message (tmpbuf);
+ f_print (fout, "%s\t\texit (1);\n", sp);
+ f_print (fout, "%s\t}\n", sp);
+ }
+ }
+ f_print (fout, "%s\tfreenetconfigent (nconf);\n", sp);
+}
+
+/*
+ * write a registration for the given transport for TLI
+ */
+void
+write_nettype_register (const char *transp)
+{
+ list *l;
+ definition *def;
+ version_list *vp;
+
+ for (l = defined; l != NULL; l = l->next)
+ {
+ def = (definition *) l->val;
+ if (def->def_kind != DEF_PROGRAM)
+ {
+ continue;
+ }
+ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next)
+ {
+ f_print (fout, "\tif (!svc_create (");
+ pvname (def->def_name, vp->vers_num);
+ f_print (fout, ", %s, %s, \"%s\")) {\n ",
+ def->def_name, vp->vers_name, transp);
+ (void) sprintf (_errbuf,
+ "unable to create (%s, %s) for %s.",
+ def->def_name, vp->vers_name, transp);
+ print_err_message ("\t\t");
+ f_print (fout, "\t\texit (1);\n");
+ f_print (fout, "\t}\n");
+ }
+ }
+}
+
+/*
+ * write the rest of the service
+ */
+void
+write_rest (void)
+{
+ f_print (fout, "\n");
+ if (inetdflag)
+ {
+ f_print (fout, "\tif (%s == (SVCXPRT *)NULL) {\n", TRANSP);
+ (void) sprintf (_errbuf, "could not create a handle");
+ print_err_message ("\t\t");
+ f_print (fout, "\t\texit (1);\n");
+ f_print (fout, "\t}\n");
+ if (timerflag)
+ {
+ f_print (fout, "\tif (_rpcpmstart) {\n");
+ f_print (fout,
+ "\t\t(void) signal (SIGALRM, %s closedown);\n",
+ Cflag ? "(SIG_PF)" : "(void(*)())");
+ f_print (fout, "\t\t(void) alarm (_RPCSVC_CLOSEDOWN);\n");
+ f_print (fout, "\t}\n");
+ }
+ }
+ f_print (fout, "\tsvc_run ();\n");
+ (void) sprintf (_errbuf, "svc_run returned");
+ print_err_message ("\t");
+ f_print (fout, "\texit (1);\n");
+ f_print (fout, "\t/* NOTREACHED */\n");
+ f_print (fout, "}\n");
+}
+
+void
+write_programs (const char *storage)
+{
+ list *l;
+ definition *def;
+
+ /* write out stubs for procedure definitions */
+ for (l = defined; l != NULL; l = l->next)
+ {
+ def = (definition *) l->val;
+ if (def->def_kind == DEF_PROGRAM)
+ {
+ write_real_program (def);
+ }
+ }
+
+ /* write out dispatcher for each program */
+ for (l = defined; l != NULL; l = l->next)
+ {
+ def = (definition *) l->val;
+ if (def->def_kind == DEF_PROGRAM)
+ {
+ write_program (def, storage);
+ }
+ }
+}
+
+/* write out definition of internal function (e.g. _printmsg_1(...))
+ which calls server's defintion of actual function (e.g. printmsg_1(...)).
+ Unpacks single user argument of printmsg_1 to call-by-value format
+ expected by printmsg_1. */
+static void
+write_real_program (const definition * def)
+{
+ version_list *vp;
+ proc_list *proc;
+ decl_list *l;
+
+ if (!newstyle)
+ return; /* not needed for old style */
+ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next)
+ {
+ for (proc = vp->procs; proc != NULL; proc = proc->next)
+ {
+ fprintf (fout, "\n");
+ if (!mtflag)
+ internal_proctype (proc);
+ else
+ f_print (fout, "int");
+ f_print (fout, "\n_");
+ pvname (proc->proc_name, vp->vers_num);
+ if (Cflag)
+ {
+ f_print (fout, " (");
+ /* arg name */
+ if (proc->arg_num > 1)
+ f_print (fout, "%s", proc->args.argname);
+ else
+ ptype (proc->args.decls->decl.prefix,
+ proc->args.decls->decl.type, 0);
+ if (mtflag)
+ {
+ f_print(fout, " *argp, void *%s, struct svc_req *%s)\n",
+ RESULT, RQSTP);
+ }
+ else
+ f_print (fout, " *argp, struct svc_req *%s)\n",
+ RQSTP);
+ }
+ else
+ {
+ if (mtflag)
+ f_print(fout, " (argp, %s, %s)\n", RESULT, RQSTP);
+ else
+ f_print (fout, " (argp, %s)\n", RQSTP);
+ /* arg name */
+ if (proc->arg_num > 1)
+ f_print (fout, "\t%s *argp;\n", proc->args.argname);
+ else
+ {
+ f_print (fout, "\t");
+ ptype (proc->args.decls->decl.prefix,
+ proc->args.decls->decl.type, 0);
+ f_print (fout, " *argp;\n");
+ }
+ f_print (fout, " struct svc_req *%s;\n", RQSTP);
+ }
+
+ f_print (fout, "{\n");
+ f_print (fout, "\treturn (");
+ if (Cflag || mtflag)
+ pvname_svc (proc->proc_name, vp->vers_num);
+ else
+ pvname (proc->proc_name, vp->vers_num);
+ f_print (fout, "(");
+ if (proc->arg_num < 2)
+ { /* single argument */
+ if (!streq (proc->args.decls->decl.type, "void"))
+ f_print (fout, "*argp, "); /* non-void */
+ }
+ else
+ {
+ for (l = proc->args.decls; l != NULL; l = l->next)
+ f_print (fout, "argp->%s, ", l->decl.name);
+ }
+ if (mtflag)
+ f_print (fout, "%s, ", RESULT);
+ f_print (fout, "%s));\n}\n", RQSTP);
+ }
+ }
+}
+
+static void
+write_program (const definition * def, const char *storage)
+{
+ version_list *vp;
+ proc_list *proc;
+ int filled;
+
+ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next)
+ {
+ f_print (fout, "\n");
+ if (storage != NULL)
+ {
+ f_print (fout, "%s ", storage);
+ }
+ f_print (fout, "void\n");
+ pvname (def->def_name, vp->vers_num);
+
+ if (Cflag)
+ {
+ f_print (fout, "(struct svc_req *%s, ", RQSTP);
+ f_print (fout, "register SVCXPRT *%s)\n", TRANSP);
+ }
+ else
+ {
+ f_print (fout, "(%s, %s)\n", RQSTP, TRANSP);
+ f_print (fout, " struct svc_req *%s;\n", RQSTP);
+ f_print (fout, " register SVCXPRT *%s;\n", TRANSP);
+ }
+
+ f_print (fout, "{\n");
+
+ filled = 0;
+ f_print (fout, "\tunion {\n");
+ for (proc = vp->procs; proc != NULL; proc = proc->next)
+ {
+ if (proc->arg_num < 2)
+ { /* single argument */
+ if (streq (proc->args.decls->decl.type,
+ "void"))
+ {
+ continue;
+ }
+ filled = 1;
+ f_print (fout, "\t\t");
+ ptype (proc->args.decls->decl.prefix,
+ proc->args.decls->decl.type, 0);
+ pvname (proc->proc_name, vp->vers_num);
+ f_print (fout, "_arg;\n");
+
+ }
+ else
+ {
+ filled = 1;
+ f_print (fout, "\t\t%s", proc->args.argname);
+ f_print (fout, " ");
+ pvname (proc->proc_name, vp->vers_num);
+ f_print (fout, "_arg;\n");
+ }
+ }
+ if (!filled)
+ {
+ f_print (fout, "\t\tint fill;\n");
+ }
+ f_print (fout, "\t} %s;\n", ARG);
+ if (mtflag)
+ {
+ f_print(fout, "\tunion {\n");
+ for (proc = vp->procs; proc != NULL; proc = proc->next)
+ if (!streq (proc->res_type, "void"))
+ {
+ f_print(fout, "\t\t");
+ ptype(proc->res_prefix, proc->res_type, 0);
+ pvname(proc->proc_name, vp->vers_num);
+ f_print(fout, "_res;\n");
+ }
+ f_print(fout, "\t} %s;\n", RESULT);
+ f_print(fout, "\tbool_t %s;\n", RETVAL);
+
+ } else
+ f_print (fout, "\tchar *%s;\n", RESULT);
+
+ if (Cflag)
+ {
+ f_print (fout, "\txdrproc_t _xdr_%s, _xdr_%s;\n", ARG, RESULT);
+ if (mtflag)
+ f_print(fout,
+ "\tbool_t (*%s)(char *, void *, struct svc_req *);\n",
+ ROUTINE);
+ else
+ f_print (fout, "\tchar *(*%s)(char *, struct svc_req *);\n",
+ ROUTINE);
+ }
+ else
+ {
+ f_print (fout, "\tbool_t (*_xdr_%s)(), (*_xdr_%s)();\n", ARG, RESULT);
+ if (mtflag)
+ f_print(fout, "\tbool_t (*%s)();\n", ROUTINE);
+ else
+ f_print (fout, "\tchar *(*%s)();\n", ROUTINE);
+ }
+ f_print (fout, "\n");
+
+ if (timerflag)
+#if 0
+ f_print (fout, "\t_rpcsvcdirty = 1;\n");
+#else
+ {
+ if (mtflag)
+ f_print(fout, "\tmutex_lock(&_svcstate_lock);\n");
+ f_print(fout, "\t_rpcsvcstate = _SERVING;\n");
+ if (mtflag)
+ f_print(fout, "\tmutex_unlock(&_svcstate_lock);\n");
+ }
+#endif
+
+ f_print (fout, "\tswitch (%s->rq_proc) {\n", RQSTP);
+ if (!nullproc (vp->procs))
+ {
+ f_print (fout, "\tcase NULLPROC:\n");
+ f_print (fout,
+ "\t\t(void) svc_sendreply (%s, (xdrproc_t) xdr_void, (char *)NULL);\n",
+ TRANSP);
+ print_return ("\t\t");
+ f_print (fout, "\n");
+ }
+ for (proc = vp->procs; proc != NULL; proc = proc->next)
+ {
+ f_print (fout, "\tcase %s:\n", proc->proc_name);
+ if (proc->arg_num < 2)
+ { /* single argument */
+ p_xdrfunc (ARG, proc->args.decls->decl.type);
+ }
+ else
+ {
+ p_xdrfunc (ARG, proc->args.argname);
+ }
+ p_xdrfunc (RESULT, proc->res_type);
+ if (Cflag)
+ {
+ if (mtflag)
+ f_print(fout,
+ "\t\t%s = (bool_t (*) (char *, void *, struct svc_req *))",
+ ROUTINE);
+ else
+ f_print (fout,
+ "\t\t%s = (char *(*)(char *, struct svc_req *)) ",
+ ROUTINE);
+ }
+ else
+ if (mtflag)
+ f_print(fout, "\t\t%s = (bool_t (*)()) ", ROUTINE);
+ else
+ f_print (fout, "\t\t%s = (char *(*)()) ", ROUTINE);
+
+ if (newstyle)
+ { /* new style: calls internal routine */
+ f_print (fout, "_");
+ }
+ if ((Cflag || mtflag) && !newstyle)
+ pvname_svc (proc->proc_name, vp->vers_num);
+ else
+ pvname (proc->proc_name, vp->vers_num);
+ f_print (fout, ";\n");
+ f_print (fout, "\t\tbreak;\n\n");
+ }
+ f_print (fout, "\tdefault:\n");
+ printerr ("noproc", TRANSP);
+ print_return ("\t\t");
+ f_print (fout, "\t}\n");
+
+ f_print (fout, "\tmemset ((char *)&%s, 0, sizeof (%s));\n", ARG, ARG);
+ printif ("getargs", TRANSP, ARG);
+ printerr ("decode", TRANSP);
+ print_return ("\t\t");
+ f_print (fout, "\t}\n");
+
+ if (!mtflag)
+ {
+ if (Cflag)
+ f_print (fout, "\t%s = (*%s)((char *)&%s, %s);\n",
+ RESULT, ROUTINE, ARG, RQSTP);
+ else
+ f_print (fout, "\t%s = (*%s)(&%s, %s);\n",
+ RESULT, ROUTINE, ARG, RQSTP);
+ }
+ else
+ if (Cflag)
+ f_print(fout, "\t%s = (bool_t) (*%s)((char *)&%s, (void *)&%s, %s);\n",
+ RETVAL, ROUTINE, ARG, RESULT, RQSTP);
+ else
+ f_print(fout, "\t%s = (bool_t) (*%s)(&%s, &%s, %s);\n",
+ RETVAL, ROUTINE, ARG, RESULT, RQSTP);
+ if (mtflag)
+ f_print(fout,
+ "\tif (%s > 0 && !svc_sendreply(%s, (xdrproc_t) _xdr_%s, (char *)&%s)) {\n",
+ RETVAL, TRANSP, RESULT, RESULT);
+ else
+ f_print(fout,
+ "\tif (%s != NULL && !svc_sendreply(%s, (xdrproc_t) _xdr_%s, %s)) {\n",
+ RESULT, TRANSP, RESULT, RESULT);
+
+ printerr ("systemerr", TRANSP);
+ f_print (fout, "\t}\n");
+
+ printif ("freeargs", TRANSP, ARG);
+
+ sprintf (_errbuf, "unable to free arguments");
+ print_err_message ("\t\t");
+ f_print (fout, "\t\texit (1);\n");
+ f_print (fout, "\t}\n");
+ /* print out free routine */
+ if (mtflag)
+ {
+ f_print(fout,"\tif (!");
+ pvname(def->def_name, vp->vers_num);
+ f_print(fout,"_freeresult (%s, _xdr_%s, (caddr_t) &%s))\n",
+ TRANSP, RESULT, RESULT);
+ (void) sprintf(_errbuf, "unable to free results");
+ print_err_message("\t\t");
+ f_print(fout, "\n");
+ }
+ print_return ("\t");
+ f_print (fout, "}\n");
+ }
+}
+
+static void
+printerr (const char *err, const char *transp)
+{
+ f_print (fout, "\t\tsvcerr_%s (%s);\n", err, transp);
+}
+
+static void
+printif (const char *proc, const char *transp, const char *arg)
+{
+ f_print (fout, "\tif (!svc_%s (%s, (xdrproc_t) _xdr_%s, (caddr_t) &%s)) {\n",
+ proc, transp, arg, arg);
+}
+
+int
+nullproc (const proc_list * proc)
+{
+ for (; proc != NULL; proc = proc->next)
+ {
+ if (streq (proc->proc_num, "0"))
+ {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static void
+write_inetmost (const char *infile)
+{
+ f_print (fout, "\tregister SVCXPRT *%s;\n", TRANSP);
+ f_print (fout, "\tint sock;\n");
+ f_print (fout, "\tint proto;\n");
+ f_print (fout, "\tstruct sockaddr_in sad