summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/Makefile.am21
-rw-r--r--tools/Makefile.in718
-rw-r--r--tools/locktest/Makefile.am9
-rw-r--r--tools/locktest/Makefile.in706
-rw-r--r--tools/locktest/testlk.c107
-rw-r--r--tools/mountstats/Makefile.am13
-rw-r--r--tools/mountstats/Makefile.in621
-rw-r--r--tools/mountstats/mountstats.man151
-rwxr-xr-xtools/mountstats/mountstats.py1145
-rw-r--r--tools/nfs-iostat/Makefile.am13
-rw-r--r--tools/nfs-iostat/Makefile.in621
-rwxr-xr-xtools/nfs-iostat/nfs-iostat.py678
-rw-r--r--tools/nfs-iostat/nfsiostat.man141
-rw-r--r--tools/nfsconf/Makefile.am11
-rw-r--r--tools/nfsconf/Makefile.in807
-rw-r--r--tools/nfsconf/nfsconf.man120
-rw-r--r--tools/nfsconf/nfsconfcli.c253
-rw-r--r--tools/nfsdclddb/Makefile.am13
-rw-r--r--tools/nfsdclddb/Makefile.in621
-rw-r--r--tools/nfsdclddb/nfsdclddb.man83
-rw-r--r--tools/nfsdclddb/nfsdclddb.py266
-rw-r--r--tools/nfsdclnts/Makefile.am13
-rw-r--r--tools/nfsdclnts/Makefile.in621
-rw-r--r--tools/nfsdclnts/nfsdclnts.man180
-rwxr-xr-xtools/nfsdclnts/nfsdclnts.py255
-rw-r--r--tools/nfsrahead/99-nfs.rules1
-rw-r--r--tools/nfsrahead/99-nfs.rules.in1
-rw-r--r--tools/nfsrahead/Makefile.am16
-rw-r--r--tools/nfsrahead/Makefile.in843
-rw-r--r--tools/nfsrahead/main.c192
-rw-r--r--tools/nfsrahead/nfsrahead.man72
-rw-r--r--tools/nlmtest/Makefile.am7
-rw-r--r--tools/nlmtest/Makefile.in538
-rw-r--r--tools/nlmtest/README5
-rw-r--r--tools/nlmtest/host.h28
-rw-r--r--tools/nlmtest/nlm_prot.x183
-rw-r--r--tools/nlmtest/nlmtest.c264
-rw-r--r--tools/rpcctl/Makefile.am13
-rw-r--r--tools/rpcctl/Makefile.in621
-rw-r--r--tools/rpcctl/rpcctl.man67
-rwxr-xr-xtools/rpcctl/rpcctl.py262
-rw-r--r--tools/rpcdebug/Makefile.am9
-rw-r--r--tools/rpcdebug/Makefile.in806
-rw-r--r--tools/rpcdebug/rpcdebug.c364
-rw-r--r--tools/rpcdebug/rpcdebug.man88
-rw-r--r--tools/rpcgen/Makefile.am13
-rw-r--r--tools/rpcgen/Makefile.in850
-rw-r--r--tools/rpcgen/README8
-rw-r--r--tools/rpcgen/proto.h65
-rw-r--r--tools/rpcgen/rpc_clntout.c333
-rw-r--r--tools/rpcgen/rpc_cout.c813
-rw-r--r--tools/rpcgen/rpc_hout.c607
-rw-r--r--tools/rpcgen/rpc_main.c1459
-rw-r--r--tools/rpcgen/rpc_output.h16
-rw-r--r--tools/rpcgen/rpc_parse.c686
-rw-r--r--tools/rpcgen/rpc_parse.h165
-rw-r--r--tools/rpcgen/rpc_sample.c336
-rw-r--r--tools/rpcgen/rpc_scan.c548
-rw-r--r--tools/rpcgen/rpc_scan.h104
-rw-r--r--tools/rpcgen/rpc_svcout.c1093
-rw-r--r--tools/rpcgen/rpc_tblout.c178
-rw-r--r--tools/rpcgen/rpc_util.c525
-rw-r--r--tools/rpcgen/rpc_util.h154
-rw-r--r--tools/rpcgen/rpcgen.1442
64 files changed, 20962 insertions, 0 deletions
diff --git a/tools/Makefile.am b/tools/Makefile.am
new file mode 100644
index 0000000..48fd0cd
--- /dev/null
+++ b/tools/Makefile.am
@@ -0,0 +1,21 @@
+## Process this file with automake to produce Makefile.in
+
+OPTDIRS =
+
+if CONFIG_RPCGEN
+OPTDIRS += rpcgen
+endif
+
+OPTDIRS += nfsconf
+
+if CONFIG_NFSDCLD
+OPTDIRS += nfsdclddb
+endif
+
+if CONFIG_NFSRAHEAD
+OPTDIRS += nfsrahead
+endif
+
+SUBDIRS = locktest rpcdebug nlmtest mountstats nfs-iostat rpcctl nfsdclnts $(OPTDIRS)
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/tools/Makefile.in b/tools/Makefile.in
new file mode 100644
index 0000000..bd9f73c
--- /dev/null
+++ b/tools/Makefile.in
@@ -0,0 +1,718 @@
+# Makefile.in generated by automake 1.16.5 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@CONFIG_RPCGEN_TRUE@am__append_1 = rpcgen
+@CONFIG_NFSDCLD_TRUE@am__append_2 = nfsdclddb
+@CONFIG_NFSRAHEAD_TRUE@am__append_3 = nfsrahead
+subdir = tools
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/aclocal/ax_gcc_func_attribute.m4 \
+ $(top_srcdir)/aclocal/bsdsignals.m4 \
+ $(top_srcdir)/aclocal/getrandom.m4 \
+ $(top_srcdir)/aclocal/ipv6.m4 \
+ $(top_srcdir)/aclocal/kerberos5.m4 \
+ $(top_srcdir)/aclocal/keyutils.m4 \
+ $(top_srcdir)/aclocal/libblkid.m4 \
+ $(top_srcdir)/aclocal/libcap.m4 \
+ $(top_srcdir)/aclocal/libevent.m4 \
+ $(top_srcdir)/aclocal/libpthread.m4 \
+ $(top_srcdir)/aclocal/libsqlite3.m4 \
+ $(top_srcdir)/aclocal/libtirpc.m4 \
+ $(top_srcdir)/aclocal/libxml2.m4 \
+ $(top_srcdir)/aclocal/nfs-utils.m4 \
+ $(top_srcdir)/aclocal/rpcsec_vers.m4 \
+ $(top_srcdir)/aclocal/tcp-wrappers.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/support/include/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+ ctags-recursive dvi-recursive html-recursive info-recursive \
+ install-data-recursive install-dvi-recursive \
+ install-exec-recursive install-html-recursive \
+ install-info-recursive install-pdf-recursive \
+ install-ps-recursive install-recursive installcheck-recursive \
+ installdirs-recursive pdf-recursive ps-recursive \
+ tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+ $(RECURSIVE_TARGETS) \
+ $(RECURSIVE_CLEAN_TARGETS) \
+ $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+ distdir distdir-am
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+DIST_SUBDIRS = locktest rpcdebug nlmtest mountstats nfs-iostat rpcctl \
+ nfsdclnts rpcgen nfsconf nfsdclddb nfsrahead
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
+AM_CPPFLAGS = @AM_CPPFLAGS@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CXXFLAGS_FOR_BUILD = @CXXFLAGS_FOR_BUILD@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ETAGS = @ETAGS@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FILECMD = @FILECMD@
+GREP = @GREP@
+GSSAPI_CFLAGS = @GSSAPI_CFLAGS@
+GSSAPI_LIBS = @GSSAPI_LIBS@
+GSSD = @GSSD@
+GSSGLUE_CFLAGS = @GSSGLUE_CFLAGS@
+GSSGLUE_LIBS = @GSSGLUE_LIBS@
+GSSKRB_CFLAGS = @GSSKRB_CFLAGS@
+GSSKRB_LIBS = @GSSKRB_LIBS@
+HAVE_GETRANDOM = @HAVE_GETRANDOM@
+HAVE_LIBWRAP = @HAVE_LIBWRAP@
+HAVE_TCP_WRAPPER = @HAVE_TCP_WRAPPER@
+IDMAPD = @IDMAPD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+K5VERS = @K5VERS@
+KRBCFLAGS = @KRBCFLAGS@
+KRBDIR = @KRBDIR@
+KRBLDFLAGS = @KRBLDFLAGS@
+KRBLIBS = @KRBLIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@
+LIBBLKID = @LIBBLKID@
+LIBBSD = @LIBBSD@
+LIBCAP = @LIBCAP@
+LIBCRYPT = @LIBCRYPT@
+LIBEVENT = @LIBEVENT@
+LIBKEYUTILS = @LIBKEYUTILS@
+LIBMOUNT = @LIBMOUNT@
+LIBMOUNT_CFLAGS = @LIBMOUNT_CFLAGS@
+LIBMOUNT_LIBS = @LIBMOUNT_LIBS@
+LIBNSL = @LIBNSL@
+LIBOBJS = @LIBOBJS@
+LIBPTHREAD = @LIBPTHREAD@
+LIBS = @LIBS@
+LIBSOCKET = @LIBSOCKET@
+LIBSQLITE = @LIBSQLITE@
+LIBTIRPC = @LIBTIRPC@
+LIBTOOL = @LIBTOOL@
+LIBWRAP = @LIBWRAP@
+LIBXML2 = @LIBXML2@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_PLUGINS = @PATH_PLUGINS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
+RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
+RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SVCGSSD = @SVCGSSD@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+VERSION = @VERSION@
+XML2_CFLAGS = @XML2_CFLAGS@
+XML2_LIBS = @XML2_LIBS@
+_rpc_pipefsmount = @_rpc_pipefsmount@
+_statedir = @_statedir@
+_sysconfdir = @_sysconfdir@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
+enable_mountconfig = @enable_mountconfig@
+enable_nfsv4 = @enable_nfsv4@
+enable_nfsv41 = @enable_nfsv41@
+enable_svcgss = @enable_svcgss@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+kprefix = @kprefix@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+mountfile = @mountfile@
+nfsconfig = @nfsconfig@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+rpc_pipefsmount = @rpc_pipefsmount@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+startstatd = @startstatd@
+statdpath = @statdpath@
+statduser = @statduser@
+statedir = @statedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+unitdir = @unitdir@
+OPTDIRS = $(am__append_1) nfsconf $(am__append_2) $(am__append_3)
+SUBDIRS = locktest rpcdebug nlmtest mountstats nfs-iostat rpcctl nfsdclnts $(OPTDIRS)
+MAINTAINERCLEANFILES = Makefile.in
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tools/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu tools/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+# (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+ @fail=; \
+ if $(am__make_keepgoing); then \
+ failcom='fail=yes'; \
+ else \
+ failcom='exit 1'; \
+ fi; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(am__recursive_targets) install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+ check-am clean clean-generic clean-libtool cscopelist-am ctags \
+ ctags-am distclean distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ installdirs-am maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+ ps ps-am tags tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tools/locktest/Makefile.am b/tools/locktest/Makefile.am
new file mode 100644
index 0000000..e891465
--- /dev/null
+++ b/tools/locktest/Makefile.am
@@ -0,0 +1,9 @@
+## Process this file with automake to produce Makefile.in
+
+noinst_PROGRAMS = testlk
+testlk_SOURCES = testlk.c
+testlk_CFLAGS=$(CFLAGS_FOR_BUILD)
+testlk_CPPFLAGS=$(CPPFLAGS_FOR_BUILD)
+testlk_LDFLAGS=$(LDFLAGS_FOR_BUILD)
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/tools/locktest/Makefile.in b/tools/locktest/Makefile.in
new file mode 100644
index 0000000..7bc60ce
--- /dev/null
+++ b/tools/locktest/Makefile.in
@@ -0,0 +1,706 @@
+# Makefile.in generated by automake 1.16.5 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+noinst_PROGRAMS = testlk$(EXEEXT)
+subdir = tools/locktest
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/aclocal/ax_gcc_func_attribute.m4 \
+ $(top_srcdir)/aclocal/bsdsignals.m4 \
+ $(top_srcdir)/aclocal/getrandom.m4 \
+ $(top_srcdir)/aclocal/ipv6.m4 \
+ $(top_srcdir)/aclocal/kerberos5.m4 \
+ $(top_srcdir)/aclocal/keyutils.m4 \
+ $(top_srcdir)/aclocal/libblkid.m4 \
+ $(top_srcdir)/aclocal/libcap.m4 \
+ $(top_srcdir)/aclocal/libevent.m4 \
+ $(top_srcdir)/aclocal/libpthread.m4 \
+ $(top_srcdir)/aclocal/libsqlite3.m4 \
+ $(top_srcdir)/aclocal/libtirpc.m4 \
+ $(top_srcdir)/aclocal/libxml2.m4 \
+ $(top_srcdir)/aclocal/nfs-utils.m4 \
+ $(top_srcdir)/aclocal/rpcsec_vers.m4 \
+ $(top_srcdir)/aclocal/tcp-wrappers.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/support/include/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+PROGRAMS = $(noinst_PROGRAMS)
+am_testlk_OBJECTS = testlk-testlk.$(OBJEXT)
+testlk_OBJECTS = $(am_testlk_OBJECTS)
+testlk_LDADD = $(LDADD)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+testlk_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(testlk_CFLAGS) $(CFLAGS) \
+ $(testlk_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/testlk-testlk.Po
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(testlk_SOURCES)
+DIST_SOURCES = $(testlk_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
+AM_CPPFLAGS = @AM_CPPFLAGS@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CXXFLAGS_FOR_BUILD = @CXXFLAGS_FOR_BUILD@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ETAGS = @ETAGS@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FILECMD = @FILECMD@
+GREP = @GREP@
+GSSAPI_CFLAGS = @GSSAPI_CFLAGS@
+GSSAPI_LIBS = @GSSAPI_LIBS@
+GSSD = @GSSD@
+GSSGLUE_CFLAGS = @GSSGLUE_CFLAGS@
+GSSGLUE_LIBS = @GSSGLUE_LIBS@
+GSSKRB_CFLAGS = @GSSKRB_CFLAGS@
+GSSKRB_LIBS = @GSSKRB_LIBS@
+HAVE_GETRANDOM = @HAVE_GETRANDOM@
+HAVE_LIBWRAP = @HAVE_LIBWRAP@
+HAVE_TCP_WRAPPER = @HAVE_TCP_WRAPPER@
+IDMAPD = @IDMAPD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+K5VERS = @K5VERS@
+KRBCFLAGS = @KRBCFLAGS@
+KRBDIR = @KRBDIR@
+KRBLDFLAGS = @KRBLDFLAGS@
+KRBLIBS = @KRBLIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@
+LIBBLKID = @LIBBLKID@
+LIBBSD = @LIBBSD@
+LIBCAP = @LIBCAP@
+LIBCRYPT = @LIBCRYPT@
+LIBEVENT = @LIBEVENT@
+LIBKEYUTILS = @LIBKEYUTILS@
+LIBMOUNT = @LIBMOUNT@
+LIBMOUNT_CFLAGS = @LIBMOUNT_CFLAGS@
+LIBMOUNT_LIBS = @LIBMOUNT_LIBS@
+LIBNSL = @LIBNSL@
+LIBOBJS = @LIBOBJS@
+LIBPTHREAD = @LIBPTHREAD@
+LIBS = @LIBS@
+LIBSOCKET = @LIBSOCKET@
+LIBSQLITE = @LIBSQLITE@
+LIBTIRPC = @LIBTIRPC@
+LIBTOOL = @LIBTOOL@
+LIBWRAP = @LIBWRAP@
+LIBXML2 = @LIBXML2@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_PLUGINS = @PATH_PLUGINS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
+RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
+RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SVCGSSD = @SVCGSSD@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+VERSION = @VERSION@
+XML2_CFLAGS = @XML2_CFLAGS@
+XML2_LIBS = @XML2_LIBS@
+_rpc_pipefsmount = @_rpc_pipefsmount@
+_statedir = @_statedir@
+_sysconfdir = @_sysconfdir@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
+enable_mountconfig = @enable_mountconfig@
+enable_nfsv4 = @enable_nfsv4@
+enable_nfsv41 = @enable_nfsv41@
+enable_svcgss = @enable_svcgss@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+kprefix = @kprefix@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+mountfile = @mountfile@
+nfsconfig = @nfsconfig@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+rpc_pipefsmount = @rpc_pipefsmount@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+startstatd = @startstatd@
+statdpath = @statdpath@
+statduser = @statduser@
+statedir = @statedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+unitdir = @unitdir@
+testlk_SOURCES = testlk.c
+testlk_CFLAGS = $(CFLAGS_FOR_BUILD)
+testlk_CPPFLAGS = $(CPPFLAGS_FOR_BUILD)
+testlk_LDFLAGS = $(LDFLAGS_FOR_BUILD)
+MAINTAINERCLEANFILES = Makefile.in
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tools/locktest/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu tools/locktest/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+testlk$(EXEEXT): $(testlk_OBJECTS) $(testlk_DEPENDENCIES) $(EXTRA_testlk_DEPENDENCIES)
+ @rm -f testlk$(EXEEXT)
+ $(AM_V_CCLD)$(testlk_LINK) $(testlk_OBJECTS) $(testlk_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testlk-testlk.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+testlk-testlk.o: testlk.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(testlk_CPPFLAGS) $(CPPFLAGS) $(testlk_CFLAGS) $(CFLAGS) -MT testlk-testlk.o -MD -MP -MF $(DEPDIR)/testlk-testlk.Tpo -c -o testlk-testlk.o `test -f 'testlk.c' || echo '$(srcdir)/'`testlk.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/testlk-testlk.Tpo $(DEPDIR)/testlk-testlk.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='testlk.c' object='testlk-testlk.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(testlk_CPPFLAGS) $(CPPFLAGS) $(testlk_CFLAGS) $(CFLAGS) -c -o testlk-testlk.o `test -f 'testlk.c' || echo '$(srcdir)/'`testlk.c
+
+testlk-testlk.obj: testlk.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(testlk_CPPFLAGS) $(CPPFLAGS) $(testlk_CFLAGS) $(CFLAGS) -MT testlk-testlk.obj -MD -MP -MF $(DEPDIR)/testlk-testlk.Tpo -c -o testlk-testlk.obj `if test -f 'testlk.c'; then $(CYGPATH_W) 'testlk.c'; else $(CYGPATH_W) '$(srcdir)/testlk.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/testlk-testlk.Tpo $(DEPDIR)/testlk-testlk.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='testlk.c' object='testlk-testlk.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(testlk_CPPFLAGS) $(CPPFLAGS) $(testlk_CFLAGS) $(CFLAGS) -c -o testlk-testlk.obj `if test -f 'testlk.c'; then $(CYGPATH_W) 'testlk.c'; else $(CYGPATH_W) '$(srcdir)/testlk.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/testlk-testlk.Po
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/testlk-testlk.Po
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
+ clean-generic clean-libtool clean-noinstPROGRAMS cscopelist-am \
+ ctags ctags-am distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tools/locktest/testlk.c b/tools/locktest/testlk.c
new file mode 100644
index 0000000..ea51f78
--- /dev/null
+++ b/tools/locktest/testlk.c
@@ -0,0 +1,107 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#ifdef linux
+#include <getopt.h>
+#endif
+#include <fcntl.h>
+
+static void usage(int exval);
+static void fatal(char *);
+
+int
+main(int argc, char **argv)
+{
+ unsigned long start = 0, len = 0;
+ struct flock fl;
+ int c, fd, cmd, typ;
+ char *fname;
+
+ typ = F_RDLCK;
+ cmd = F_SETLK;
+
+ while ((c = getopt(argc, argv, "bhrtw")) != EOF) {
+ switch (c) {
+ case 'h':
+ usage(0);
+ case 'r':
+ cmd = F_SETLK;
+ typ = F_RDLCK;
+ break;
+ case 'w':
+ cmd = F_SETLK;
+ typ = F_WRLCK;
+ break;
+ case 'b':
+ cmd = F_SETLKW;
+ typ = F_WRLCK;
+ break;
+ case 't':
+ cmd = F_GETLK;
+ break;
+ case '?':
+ usage(1);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc <= 0 || argc > 3)
+ usage(1);
+
+ fname = argv[0];
+ /* printf("TP\n"); */
+ if (argc > 1)
+ start = atoi(argv[1]);
+ /* printf("TP\n"); */
+ if (argc > 2)
+ len = atoi(argv[2]);
+ /* printf("TP\n"); */
+
+ if ((fd = open(fname, O_RDWR, 0644)) < 0)
+ fatal(fname);
+
+ /* printf("TP1\n"); */
+ fl.l_type = typ;
+ fl.l_whence = 0;
+ fl.l_start = start;
+ fl.l_len = len;
+
+ if (fcntl(fd, cmd, &fl) < 0)
+ fatal("fcntl");
+ printf("fcntl: ok\n");
+
+ /* printf("TP2\n"); */
+ if (cmd == F_GETLK) {
+ if (fl.l_type == F_UNLCK) {
+ printf("%s: no conflicting lock\n", fname);
+ } else {
+ printf("%s: conflicting lock by %d on (%zd;%zd)\n",
+ fname, fl.l_pid, fl.l_start, fl.l_len);
+ }
+ return 0;
+ }
+
+ /* printf("TP3\n"); */
+ pause();
+ return 0;
+}
+
+static void
+usage(int exval)
+{
+ fprintf(stderr, "usage: testlk filename [start [len]]\n");
+ exit(exval);
+}
+
+static void
+fatal(char *msg)
+{
+ perror(msg);
+ exit(2);
+}
diff --git a/tools/mountstats/Makefile.am b/tools/mountstats/Makefile.am
new file mode 100644
index 0000000..c2e9f99
--- /dev/null
+++ b/tools/mountstats/Makefile.am
@@ -0,0 +1,13 @@
+## Process this file with automake to produce Makefile.in
+PYTHON_FILES = mountstats.py
+
+man8_MANS = mountstats.man
+
+EXTRA_DIST = $(man8_MANS) $(PYTHON_FILES)
+
+all-local: $(PYTHON_FILES)
+
+install-data-hook:
+ $(INSTALL) -m 755 mountstats.py $(DESTDIR)$(sbindir)/mountstats
+
+MAINTAINERCLEANFILES=Makefile.in
diff --git a/tools/mountstats/Makefile.in b/tools/mountstats/Makefile.in
new file mode 100644
index 0000000..79294bc
--- /dev/null
+++ b/tools/mountstats/Makefile.in
@@ -0,0 +1,621 @@
+# Makefile.in generated by automake 1.16.5 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = tools/mountstats
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/aclocal/ax_gcc_func_attribute.m4 \
+ $(top_srcdir)/aclocal/bsdsignals.m4 \
+ $(top_srcdir)/aclocal/getrandom.m4 \
+ $(top_srcdir)/aclocal/ipv6.m4 \
+ $(top_srcdir)/aclocal/kerberos5.m4 \
+ $(top_srcdir)/aclocal/keyutils.m4 \
+ $(top_srcdir)/aclocal/libblkid.m4 \
+ $(top_srcdir)/aclocal/libcap.m4 \
+ $(top_srcdir)/aclocal/libevent.m4 \
+ $(top_srcdir)/aclocal/libpthread.m4 \
+ $(top_srcdir)/aclocal/libsqlite3.m4 \
+ $(top_srcdir)/aclocal/libtirpc.m4 \
+ $(top_srcdir)/aclocal/libxml2.m4 \
+ $(top_srcdir)/aclocal/nfs-utils.m4 \
+ $(top_srcdir)/aclocal/rpcsec_vers.m4 \
+ $(top_srcdir)/aclocal/tcp-wrappers.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/support/include/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+man8dir = $(mandir)/man8
+am__installdirs = "$(DESTDIR)$(man8dir)"
+NROFF = nroff
+MANS = $(man8_MANS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
+AM_CPPFLAGS = @AM_CPPFLAGS@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CXXFLAGS_FOR_BUILD = @CXXFLAGS_FOR_BUILD@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ETAGS = @ETAGS@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FILECMD = @FILECMD@
+GREP = @GREP@
+GSSAPI_CFLAGS = @GSSAPI_CFLAGS@
+GSSAPI_LIBS = @GSSAPI_LIBS@
+GSSD = @GSSD@
+GSSGLUE_CFLAGS = @GSSGLUE_CFLAGS@
+GSSGLUE_LIBS = @GSSGLUE_LIBS@
+GSSKRB_CFLAGS = @GSSKRB_CFLAGS@
+GSSKRB_LIBS = @GSSKRB_LIBS@
+HAVE_GETRANDOM = @HAVE_GETRANDOM@
+HAVE_LIBWRAP = @HAVE_LIBWRAP@
+HAVE_TCP_WRAPPER = @HAVE_TCP_WRAPPER@
+IDMAPD = @IDMAPD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+K5VERS = @K5VERS@
+KRBCFLAGS = @KRBCFLAGS@
+KRBDIR = @KRBDIR@
+KRBLDFLAGS = @KRBLDFLAGS@
+KRBLIBS = @KRBLIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@
+LIBBLKID = @LIBBLKID@
+LIBBSD = @LIBBSD@
+LIBCAP = @LIBCAP@
+LIBCRYPT = @LIBCRYPT@
+LIBEVENT = @LIBEVENT@
+LIBKEYUTILS = @LIBKEYUTILS@
+LIBMOUNT = @LIBMOUNT@
+LIBMOUNT_CFLAGS = @LIBMOUNT_CFLAGS@
+LIBMOUNT_LIBS = @LIBMOUNT_LIBS@
+LIBNSL = @LIBNSL@
+LIBOBJS = @LIBOBJS@
+LIBPTHREAD = @LIBPTHREAD@
+LIBS = @LIBS@
+LIBSOCKET = @LIBSOCKET@
+LIBSQLITE = @LIBSQLITE@
+LIBTIRPC = @LIBTIRPC@
+LIBTOOL = @LIBTOOL@
+LIBWRAP = @LIBWRAP@
+LIBXML2 = @LIBXML2@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_PLUGINS = @PATH_PLUGINS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
+RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
+RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SVCGSSD = @SVCGSSD@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+VERSION = @VERSION@
+XML2_CFLAGS = @XML2_CFLAGS@
+XML2_LIBS = @XML2_LIBS@
+_rpc_pipefsmount = @_rpc_pipefsmount@
+_statedir = @_statedir@
+_sysconfdir = @_sysconfdir@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
+enable_mountconfig = @enable_mountconfig@
+enable_nfsv4 = @enable_nfsv4@
+enable_nfsv41 = @enable_nfsv41@
+enable_svcgss = @enable_svcgss@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+kprefix = @kprefix@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+mountfile = @mountfile@
+nfsconfig = @nfsconfig@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+rpc_pipefsmount = @rpc_pipefsmount@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+startstatd = @startstatd@
+statdpath = @statdpath@
+statduser = @statduser@
+statedir = @statedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+unitdir = @unitdir@
+PYTHON_FILES = mountstats.py
+man8_MANS = mountstats.man
+EXTRA_DIST = $(man8_MANS) $(PYTHON_FILES)
+MAINTAINERCLEANFILES = Makefile.in
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tools/mountstats/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu tools/mountstats/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(man8_MANS)
+ @$(NORMAL_INSTALL)
+ @list1='$(man8_MANS)'; \
+ list2=''; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list='$(man8_MANS)'; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(MANS) all-local
+installdirs:
+ for dir in "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-data-hook
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man
+
+uninstall-man: uninstall-man8
+
+.MAKE: install-am install-data-am install-strip
+
+.PHONY: all all-am all-local check check-am clean clean-generic \
+ clean-libtool cscopelist-am ctags-am distclean \
+ distclean-generic distclean-libtool distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-data-hook install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-man8 \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags-am uninstall uninstall-am uninstall-man uninstall-man8
+
+.PRECIOUS: Makefile
+
+
+all-local: $(PYTHON_FILES)
+
+install-data-hook:
+ $(INSTALL) -m 755 mountstats.py $(DESTDIR)$(sbindir)/mountstats
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tools/mountstats/mountstats.man b/tools/mountstats/mountstats.man
new file mode 100644
index 0000000..d5595fc
--- /dev/null
+++ b/tools/mountstats/mountstats.man
@@ -0,0 +1,151 @@
+.\"
+.\" mountstats(8)
+.\"
+.TH mountstats 8 "12 Dec 2014"
+.SH NAME
+mountstats \- Displays various NFS client per-mount statistics
+.SH SYNOPSIS
+.B mountstats
+.RB [ \-h | \-\-help ]
+.RB [ \-v | \-\-version ]
+.RB [ \-f | \-\-file
+.IR infile ]
+.RB [ \-S | \-\-since
+.IR sincefile ]
+.\" .RB [ \-n | \-\-nfs | \-r | \-\-rpc | \-R | \-\-raw ]
+[
+.RB [ \-n | \-\-nfs ]
+|
+.RB [ \-r | \-\-rpc ]
+|
+.RB [ \-R | \-\-raw ]
+|
+.RB [ \-x | \-\-xprt ]
+]
+.RI [ mountpoint ] ...
+.P
+.B mountstats iostat
+.RB [ \-h | \-\-help ]
+.RB [ \-v | \-\-version ]
+.RB [ \-f | \-\-file
+.IR infile ]
+.RB [ \-S | \-\-since
+.IR sincefile ]
+.RI [ interval ]
+.RI [ count ]
+.RI [ mountpoint ] ...
+.P
+.B mountstats nfsstat
+.RB [ \-h | \-\-help ]
+.RB [ \-v | \-\-version ]
+.RB [ \-f | \-\-file
+.IR infile ]
+.RB [ \-S | \-\-since
+.IR sincefile ]
+.RB [ \-3 ]
+.RB [ \-4 ]
+.RI [ mountpoint ] ...
+.P
+.SH DESCRIPTION
+.RB "The " mountstats " command displays various NFS client statisitics for each given"
+.IR mountpoint .
+.P
+.RI "If no " mountpoint " is given, statistics will be displayed for all NFS mountpoints on the client."
+.SS Sub-commands
+Valid
+.BR mountstats (8)
+subcommands are:
+.IP "\fBmountstats\fP"
+Display a combination of per-op RPC statistics, NFS event counts, and NFS byte counts. This is the default sub-command that will be executed if no sub-command is given.
+.IP "\fBiostat\fP"
+Display iostat-like statistics.
+.IP "\fBnfsstat\fP"
+Display nfsstat-like statistics.
+.SH OPTIONS
+.SS Options valid for all sub-commands
+.TP
+.B \-h, \-\-help
+show the help message and exit
+.TP
+.B \-v, \-\-version
+show program's version number and exit
+.TP
+\fB\-f \fIinfile\fR, \fB\-\-file \fIinfile
+Read stats from
+.I infile
+instead of
+.IR /proc/self/mountstats ". " infile
+must be in the same format as
+.IR /proc/self/mountstats .
+This may be used with the
+.BR \-S | \-\-since
+options to display the delta between two different points in time.
+This may not be used with the
+.IR interval " or " count
+options of the
+.B iostat
+sub-command.
+.TP
+\fB\-S \fIsincefile\fR, \fB\-\-since \fIsincefile
+Show difference between current stats and those in
+.IR sincefile ". " sincefile
+must be in the same format as
+.IR /proc/self/mountstats .
+This may be used with the
+.BR \-f | \-\-file
+options to display the delta between two different points in time.
+This may not be used with the
+.IR interval " or " count
+options of the
+.B iostat
+sub-command.
+.SS Options specific to the mountstats sub-command
+.B \-n, \-\-nfs
+Display only the NFS statistics
+.TP
+.B \-r, \-\-rpc
+Display only the RPC statistics
+.TP
+.B \-R, \-\-raw
+Display only the raw statistics. This is intended for use with the
+.BR \-f | \-\-file
+and
+.BR \-S | \-\-since
+options.
+.TP
+.B \-x, \-\-xprt
+Display only the transport statistics
+.SS Options specific to the iostat sub-command
+.IP "\fIinterval\fP"
+Specifies the amount of time in seconds between each report. The first report contains statistics for the time since each file system was mounted. Each subsequent report contains statistics collected during the interval since the previous report. This may not be used with the
+.BR \-f | \-\-file
+or
+.BR \-S | \-\-since
+options.
+.P
+.IP "\fIcount\fP"
+Determines the number of reports generated at
+.I interval
+seconds apart. If the
+.I interval
+parameter is specified without the
+.I count
+parameter, the command generates reports continuously. This may not be used with the
+.BR \-f | \-\-file
+or
+.BR \-S | \-\-since
+options.
+.SS Options specific to the nfsstat sub-command
+.IP "\fB\-3\fP"
+Show only NFS version 3 statistics. The default is to show both version 3 and version 4 statistics.
+.IP "\fB\-4\fP"
+Show only NFS version 4 statistics. The default is to show both version 3 and version 4 statistics.
+.SH FILES
+.TP
+.B /proc/self/mountstats
+.SH SEE ALSO
+.BR iostat (8),
+.BR nfsiostat (8),
+.BR nfsstat (8)
+.SH AUTHOR
+Chuck Lever <chuck.lever@oracle.com>
diff --git a/tools/mountstats/mountstats.py b/tools/mountstats/mountstats.py
new file mode 100755
index 0000000..8e129c8
--- /dev/null
+++ b/tools/mountstats/mountstats.py
@@ -0,0 +1,1145 @@
+#!/usr/bin/python3
+# -*- python-mode -*-
+"""Parse /proc/self/mountstats and display it in human readable form
+"""
+
+from __future__ import print_function
+import datetime as datetime
+
+__copyright__ = """
+Copyright (C) 2005, Chuck Lever <cel@netapp.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 2 as
+published by the Free Software Foundation.
+
+This program 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+MA 02110-1301 USA
+"""
+
+import sys, os, time
+from operator import itemgetter, add
+try:
+ import argparse
+except ImportError:
+ print('%s: Failed to import argparse - make sure argparse is installed!'
+ % sys.argv[0])
+ sys.exit(1)
+
+Mountstats_version = '0.3'
+
+def difference(x, y):
+ """Used for a map() function
+ """
+ return x - y
+
+NfsEventCounters = [
+ 'inoderevalidates',
+ 'dentryrevalidates',
+ 'datainvalidates',
+ 'attrinvalidates',
+ 'vfsopen',
+ 'vfslookup',
+ 'vfspermission',
+ 'vfsupdatepage',
+ 'vfsreadpage',
+ 'vfsreadpages',
+ 'vfswritepage',
+ 'vfswritepages',
+ 'vfsreaddir',
+ 'vfssetattr',
+ 'vfsflush',
+ 'vfsfsync',
+ 'vfslock',
+ 'vfsrelease',
+ 'congestionwait',
+ 'setattrtrunc',
+ 'extendwrite',
+ 'sillyrenames',
+ 'shortreads',
+ 'shortwrites',
+ 'delay',
+ 'pnfsreads',
+ 'pnfswrites'
+]
+
+NfsByteCounters = [
+ 'normalreadbytes',
+ 'normalwritebytes',
+ 'directreadbytes',
+ 'directwritebytes',
+ 'serverreadbytes',
+ 'serverwritebytes',
+ 'readpages',
+ 'writepages'
+]
+
+XprtUdpCounters = [
+ 'port',
+ 'bind_count',
+ 'rpcsends',
+ 'rpcreceives',
+ 'badxids',
+ 'inflightsends',
+ 'backlogutil',
+ 'maxslots',
+ 'sendutil',
+ 'pendutil'
+]
+
+XprtTcpCounters = [
+ 'port',
+ 'bind_count',
+ 'connect_count',
+ 'connect_time',
+ 'idle_time',
+ 'rpcsends',
+ 'rpcreceives',
+ 'badxids',
+ 'inflightsends',
+ 'backlogutil',
+ 'maxslots',
+ 'sendutil',
+ 'pendutil'
+]
+
+XprtRdmaCounters = [
+ 'port',
+ 'bind_count',
+ 'connect_count',
+ 'connect_time',
+ 'idle_time',
+ 'rpcsends',
+ 'rpcreceives',
+ 'badxids',
+ 'inflightsends',
+ 'backlogutil',
+ 'read_segments',
+ 'write_segments',
+ 'reply_segments',
+ 'total_rdma_req',
+ 'total_rdma_rep',
+ 'pullup',
+ 'fixup',
+ 'hardway',
+ 'failed_marshal',
+ 'bad_reply',
+ 'nomsg_calls',
+ 'recovered_mrs',
+ 'orphaned_mrs',
+ 'allocated_mrs',
+ 'local_invalidates',
+ 'empty_sendctx_q',
+ 'reply_waits_for_send',
+]
+
+Nfsv3ops = [
+ 'NULL',
+ 'GETATTR',
+ 'SETATTR',
+ 'LOOKUP',
+ 'ACCESS',
+ 'READLINK',
+ 'READ',
+ 'WRITE',
+ 'CREATE',
+ 'MKDIR',
+ 'SYMLINK',
+ 'MKNOD',
+ 'REMOVE',
+ 'RMDIR',
+ 'RENAME',
+ 'LINK',
+ 'READDIR',
+ 'READDIRPLUS',
+ 'FSSTAT',
+ 'FSINFO',
+ 'PATHCONF',
+ 'COMMIT'
+]
+
+# This list should be kept in-sync with the NFSPROC4_CLNT_* enum in
+# include/linux/nfs4.h in the kernel.
+Nfsv4ops = [
+ 'NULL',
+ 'READ',
+ 'WRITE',
+ 'COMMIT',
+ 'OPEN',
+ 'OPEN_CONFIRM',
+ 'OPEN_NOATTR',
+ 'OPEN_DOWNGRADE',
+ 'CLOSE',
+ 'SETATTR',
+ 'FSINFO',
+ 'RENEW',
+ 'SETCLIENTID',
+ 'SETCLIENTID_CONFIRM',
+ 'LOCK',
+ 'LOCKT',
+ 'LOCKU',
+ 'ACCESS',
+ 'GETATTR',
+ 'LOOKUP',
+ 'LOOKUP_ROOT',
+ 'REMOVE',
+ 'RENAME',
+ 'LINK',
+ 'SYMLINK',
+ 'CREATE',
+ 'PATHCONF',
+ 'STATFS',
+ 'READLINK',
+ 'READDIR',
+ 'SERVER_CAPS',
+ 'DELEGRETURN',
+ 'GETACL',
+ 'SETACL',
+ 'FS_LOCATIONS',
+ 'RELEASE_LOCKOWNER',
+ 'SECINFO',
+ 'FSID_PRESENT',
+ 'EXCHANGE_ID',
+ 'CREATE_SESSION',
+ 'DESTROY_SESSION',
+ 'SEQUENCE',
+ 'GET_LEASE_TIME',
+ 'RECLAIM_COMPLETE',
+ 'LAYOUTGET',
+ 'GETDEVICEINFO',
+ 'LAYOUTCOMMIT',
+ 'LAYOUTRETURN',
+ 'SECINFO_NO_NAME',
+ 'TEST_STATEID',
+ 'FREE_STATEID',
+ 'GETDEVICELIST',
+ 'BIND_CONN_TO_SESSION',
+ 'DESTROY_CLIENTID',
+ 'SEEK',
+ 'ALLOCATE',
+ 'DEALLOCATE',
+ 'LAYOUTSTATS',
+ 'CLONE',
+ 'COPY',
+ 'OFFLOAD_CANCEL',
+ 'LOOKUPP',
+ 'LAYOUTERROR',
+ 'COPY_NOTIFY'
+]
+
+class DeviceData:
+ """DeviceData objects provide methods for parsing and displaying
+ data for a single mount grabbed from /proc/self/mountstats
+ """
+ def __init__(self):
+ self.__nfs_data = dict()
+ self.__rpc_data = dict()
+ self.__rpc_data['ops'] = []
+
+ def __parse_nfs_line(self, words):
+ if words[0] == 'device':
+ self.__nfs_data['export'] = words[1]
+ self.__nfs_data['mountpoint'] = words[4]
+ self.__nfs_data['fstype'] = words[7]
+ if words[7].find('nfs') != -1 and words[7] != 'nfsd':
+ self.__nfs_data['statvers'] = words[8]
+ elif 'nfs' in words or 'nfs4' in words:
+ self.__nfs_data['export'] = words[0]
+ self.__nfs_data['mountpoint'] = words[3]
+ self.__nfs_data['fstype'] = words[6]
+ if words[6].find('nfs') != -1 and words[6] != 'nfsd':
+ self.__nfs_data['statvers'] = words[7]
+ elif words[0] == 'age:':
+ self.__nfs_data['age'] = int(words[1])
+ elif words[0] == 'opts:':
+ self.__nfs_data['mountoptions'] = ''.join(words[1:]).split(',')
+ elif words[0] == 'caps:':
+ self.__nfs_data['servercapabilities'] = ''.join(words[1:]).split(',')
+ elif words[0] == 'nfsv4:':
+ self.__nfs_data['nfsv4flags'] = ''.join(words[1:]).split(',')
+ elif words[0] == 'sec:':
+ keys = ''.join(words[1:]).split(',')
+ self.__nfs_data['flavor'] = int(keys[0].split('=')[1])
+ self.__nfs_data['pseudoflavor'] = 0
+ if self.__nfs_data['flavor'] == 6:
+ self.__nfs_data['pseudoflavor'] = int(keys[1].split('=')[1])
+ elif words[0] == 'events:':
+ i = 1
+ for key in NfsEventCounters:
+ try:
+ self.__nfs_data[key] = int(words[i])
+ except IndexError as err:
+ self.__nfs_data[key] = 0
+ i += 1
+ elif words[0] == 'bytes:':
+ i = 1
+ for key in NfsByteCounters:
+ self.__nfs_data[key] = int(words[i])
+ i += 1
+
+ def __parse_rpc_line(self, words):
+ if words[0] == 'RPC':
+ self.__rpc_data['statsvers'] = float(words[3])
+ self.__rpc_data['programversion'] = words[5]
+ elif words[0] == 'xprt:':
+ self.__rpc_data['protocol'] = words[1]
+ if words[1] == 'udp':
+ i = 2
+ for key in XprtUdpCounters:
+ if i < len(words):
+ self.__rpc_data[key] = int(words[i])
+ i += 1
+ elif words[1] == 'tcp':
+ i = 2
+ for key in XprtTcpCounters:
+ if i < len(words):
+ self.__rpc_data[key] = int(words[i])
+ i += 1
+ elif words[1] == 'rdma':
+ i = 2
+ for key in XprtRdmaCounters:
+ if i < len(words):
+ self.__rpc_data[key] = int(words[i])
+ i += 1
+ elif words[0] == 'per-op':
+ self.__rpc_data['per-op'] = words
+ else:
+ op = words[0][:-1]
+ self.__rpc_data['ops'] += [op]
+ self.__rpc_data[op] = [int(word) for word in words[1:]]
+ if len(self.__rpc_data[op]) < 9:
+ self.__rpc_data[op] += [0]
+
+ def parse_stats(self, lines):
+ """Turn a list of lines from a mount stat file into a
+ dictionary full of stats, keyed by name
+ """
+ found = False
+ for line in lines:
+ words = line.split()
+ if len(words) == 0:
+ continue
+ if (not found and words[0] != 'RPC'):
+ self.__parse_nfs_line(words)
+ continue
+
+ found = True
+ self.__parse_rpc_line(words)
+
+ def is_nfs_mountpoint(self):
+ """Return True if this is an NFS or NFSv4 mountpoint,
+ otherwise return False
+ """
+ if self.__nfs_data['fstype'] == 'nfs':
+ return True
+ elif self.__nfs_data['fstype'] == 'nfs4':
+ return True
+ return False
+
+ def nfs_version(self):
+ if self.is_nfs_mountpoint():
+ prog, vers = self.__rpc_data['programversion'].split('/')
+ return int(vers)
+
+ def display_raw_stats(self):
+ """Prints out stats in the same format as /proc/self/mountstats
+ """
+ print('device %s mounted on %s with fstype %s %s' % \
+ (self.__nfs_data['export'], self.__nfs_data['mountpoint'], \
+ self.__nfs_data['fstype'], self.__nfs_data['statvers']))
+ print('\topts:\t%s' % ','.join(self.__nfs_data['mountoptions']))
+ print('\tage:\t%d' % self.__nfs_data['age'])
+ print('\tcaps:\t%s' % ','.join(self.__nfs_data['servercapabilities']))
+ print('\tsec:\tflavor=%d,pseudoflavor=%d' % (self.__nfs_data['flavor'], \
+ self.__nfs_data['pseudoflavor']))
+ print('\tevents:\t%s' % " ".join([str(self.__nfs_data[key]) for key in NfsEventCounters]))
+ print('\tbytes:\t%s' % " ".join([str(self.__nfs_data[key]) for key in NfsByteCounters]))
+ print('\tRPC iostats version: %1.1f p/v: %s (nfs)' % (self.__rpc_data['statsvers'], \
+ self.__rpc_data['programversion']))
+ if self.__rpc_data['protocol'] == 'udp':
+ print('\txprt:\tudp %s' % " ".join([str(self.__rpc_data[key]) for key in XprtUdpCounters]))
+ elif self.__rpc_data['protocol'] == 'tcp':
+ print('\txprt:\ttcp %s' % " ".join([str(self.__rpc_data[key]) for key in XprtTcpCounters]))
+ elif self.__rpc_data['protocol'] == 'rdma':
+ print('\txprt:\trdma %s' % " ".join([str(self.__rpc_data[key]) for key in XprtRdmaCounters]))
+ else:
+ raise Exception('Unknown RPC transport protocol %s' % self.__rpc_data['protocol'])
+ print('\tper-op statistics')
+ prog, vers = self.__rpc_data['programversion'].split('/')
+ if vers == '3':
+ for op in Nfsv3ops:
+ print('\t%12s: %s' % (op, " ".join(str(x) for x in self.__rpc_data[op])))
+ elif vers == '4':
+ for op in Nfsv4ops:
+ try:
+ print('\t%12s: %s' % (op, " ".join(str(x) for x in self.__rpc_data[op])))
+ except KeyError:
+ continue
+ else:
+ print('\tnot implemented for version %d' % vers)
+ print()
+
+ def display_stats_header(self):
+ print('Stats for %s mounted on %s:' % \
+ (self.__nfs_data['export'], self.__nfs_data['mountpoint']))
+ print()
+
+ def display_nfs_options(self):
+ """Pretty-print the NFS options
+ """
+ print(' NFS mount options: %s' % ','.join(self.__nfs_data['mountoptions']))
+ print(' NFS mount age: %s' % datetime.timedelta(seconds = self.__nfs_data['age']))
+ print(' NFS server capabilities: %s' % ','.join(self.__nfs_data['servercapabilities']))
+ if 'nfsv4flags' in self.__nfs_data:
+ print(' NFSv4 capability flags: %s' % ','.join(self.__nfs_data['nfsv4flags']))
+ if 'pseudoflavor' in self.__nfs_data:
+ print(' NFS security flavor: %d pseudoflavor: %d' % \
+ (self.__nfs_data['flavor'], self.__nfs_data['pseudoflavor']))
+ else:
+ print(' NFS security flavor: %d' % self.__nfs_data['flavor'])
+
+ def display_nfs_events(self):
+ """Pretty-print the NFS event counters
+ """
+ print()
+ print('Cache events:')
+ print(' data cache invalidated %d times' % self.__nfs_data['datainvalidates'])
+ print(' attribute cache invalidated %d times' % self.__nfs_data['attrinvalidates'])
+ print()
+ print('VFS calls:')
+ print(' VFS requested %d inode revalidations' % self.__nfs_data['inoderevalidates'])
+ print(' VFS requested %d dentry revalidations' % self.__nfs_data['dentryrevalidates'])
+ print()
+ print(' VFS called nfs_readdir() %d times' % self.__nfs_data['vfsreaddir'])
+ print(' VFS called nfs_lookup() %d times' % self.__nfs_data['vfslookup'])
+ print(' VFS called nfs_permission() %d times' % self.__nfs_data['vfspermission'])
+ print(' VFS called nfs_file_open() %d times' % self.__nfs_data['vfsopen'])
+ print(' VFS called nfs_file_flush() %d times' % self.__nfs_data['vfsflush'])
+ print(' VFS called nfs_lock() %d times' % self.__nfs_data['vfslock'])
+ print(' VFS called nfs_fsync() %d times' % self.__nfs_data['vfsfsync'])
+ print(' VFS called nfs_file_release() %d times' % self.__nfs_data['vfsrelease'])
+ print()
+ print('VM calls:')
+ print(' VFS called nfs_readpage() %d times' % self.__nfs_data['vfsreadpage'])
+ print(' VFS called nfs_readpages() %d times' % self.__nfs_data['vfsreadpages'])
+ print(' VFS called nfs_writepage() %d times' % self.__nfs_data['vfswritepage'])
+ print(' VFS called nfs_writepages() %d times' % self.__nfs_data['vfswritepages'])
+ print()
+ print('Generic NFS counters:')
+ print(' File size changing operations:')
+ print(' truncating SETATTRs: %d extending WRITEs: %d' % \
+ (self.__nfs_data['setattrtrunc'], self.__nfs_data['extendwrite']))
+ print(' %d silly renames' % self.__nfs_data['sillyrenames'])
+ print(' short reads: %d short writes: %d' % \
+ (self.__nfs_data['shortreads'], self.__nfs_data['shortwrites']))
+ print(' NFSERR_DELAYs from server: %d' % self.__nfs_data['delay'])
+ print(' pNFS READs: %d' % self.__nfs_data['pnfsreads'])
+ print(' pNFS WRITEs: %d' % self.__nfs_data['pnfswrites'])
+
+ def display_nfs_bytes(self):
+ """Pretty-print the NFS event counters
+ """
+ print()
+ print('NFS byte counts:')
+ print(' applications read %d bytes via read(2)' % self.__nfs_data['normalreadbytes'])
+ print(' applications wrote %d bytes via write(2)' % self.__nfs_data['normalwritebytes'])
+ print(' applications read %d bytes via O_DIRECT read(2)' % self.__nfs_data['directreadbytes'])
+ print(' applications wrote %d bytes via O_DIRECT write(2)' % self.__nfs_data['directwritebytes'])
+ print(' client read %d bytes via NFS READ' % self.__nfs_data['serverreadbytes'])
+ print(' client wrote %d bytes via NFS WRITE' % self.__nfs_data['serverwritebytes'])
+
+ def display_rpc_generic_stats(self):
+ """Pretty-print the generic RPC stats
+ """
+ sends = self.__rpc_data['rpcsends']
+
+ print('RPC statistics:')
+
+ print(' %d RPC requests sent, %d RPC replies received (%d XIDs not found)' % \
+ (sends, self.__rpc_data['rpcreceives'], self.__rpc_data['badxids']))
+ if sends != 0:
+ print(' average backlog queue length: %d' % \
+ (float(self.__rpc_data['backlogutil']) / sends))
+
+ def display_rpc_op_stats(self):
+ """Pretty-print the per-op stats
+ """
+ sends = self.__rpc_data['rpcsends']
+
+ allstats = []
+ for op in self.__rpc_data['ops']:
+ allstats.append([op] + self.__rpc_data[op])
+
+ print()
+ for stats in sorted(allstats, key=itemgetter(1), reverse=True):
+ count = stats[1]
+ if count != 0:
+ print('%s:' % stats[0])
+ ops_pcnt = 0
+ if sends != 0:
+ ops_pcnt = (count * 100) / sends
+ print('\t%d ops (%d%%)' % \
+ (count, ops_pcnt), end=' ')
+ retrans = stats[2] - count
+ if retrans != 0:
+ print('\t%d retrans (%d%%)' % (retrans, ((retrans * 100) / count)), end=' ')
+ print('\t%d major timeouts' % stats[3], end='')
+ if len(stats) >= 10 and stats[9] != 0:
+ print('\t%d errors (%d%%)' % (stats[9], ((stats[9] * 100) / count)))
+ else:
+ print('')
+ print('\tavg bytes sent per op: %d\tavg bytes received per op: %d' % \
+ (stats[4] / count, stats[5] / count))
+ print('\tbacklog wait: %f' % (float(stats[6]) / count), end=' ')
+ print('\tRTT: %f' % (float(stats[7]) / count), end=' ')
+ print('\ttotal execute time: %f (milliseconds)' % \
+ (float(stats[8]) / count))
+
+ def client_rpc_stats(self):
+ """Tally high-level rpc stats for the nfsstat command
+ """
+ sends = 0
+ trans = 0
+ authrefrsh = 0
+ for op in self.__rpc_data['ops']:
+ sends += self.__rpc_data[op][0]
+ trans += self.__rpc_data[op][1]
+ retrans = trans - sends
+ # authrefresh stats don't actually get captured in
+ # /proc/self/mountstats, so we fudge it here
+ authrefrsh = sends
+ return (sends, retrans, authrefrsh)
+
+ def display_nfsstat_stats(self):
+ """Pretty-print nfsstat-style stats
+ """
+ sends = 0
+ for op in self.__rpc_data['ops']:
+ sends += self.__rpc_data[op][0]
+ if sends == 0:
+ return
+ print()
+ vers = self.nfs_version()
+ print('Client nfs v%d' % vers)
+ info = []
+ for op in self.__rpc_data['ops']:
+ print('%-13s' % str.lower(op)[:12], end='')
+ count = self.__rpc_data[op][0]
+ pct = (count * 100) / sends
+ info.append((count, pct))
+ if (self.__rpc_data['ops'].index(op) + 1) % 6 == 0:
+ print()
+ for (count, pct) in info:
+ print('%-8u%3u%% ' % (count, pct), end='')
+ print()
+ info = []
+ print()
+ if len(info) > 0:
+ for (count, pct) in info:
+ print('%-8u%3u%% ' % (count, pct), end='')
+ print()
+
+ def compare_iostats(self, old_stats):
+ """Return the difference between two sets of stats
+ """
+ if old_stats.__nfs_data['age'] > self.__nfs_data['age']:
+ return self
+
+ result = DeviceData()
+ protocol = self.__rpc_data['protocol']
+
+ # copy self into result
+ for key, value in self.__nfs_data.items():
+ result.__nfs_data[key] = value
+ for key, value in self.__rpc_data.items():
+ result.__rpc_data[key] = value
+
+ # compute the difference of each item in the list
+ # note the copy loop above does not copy the lists, just
+ # the reference to them. so we build new lists here
+ # for the result object.
+ for op in result.__rpc_data['ops']:
+ try:
+ result.__rpc_data[op] = list(map(difference, self.__rpc_data[op], old_stats.__rpc_data[op]))
+ except KeyError:
+ continue
+
+ # update the remaining keys
+ if protocol == 'udp':
+ for key in XprtUdpCounters:
+ result.__rpc_data[key] -= old_stats.__rpc_data[key]
+ elif protocol == 'tcp':
+ for key in XprtTcpCounters:
+ result.__rpc_data[key] -= old_stats.__rpc_data[key]
+ elif protocol == 'rdma':
+ for key in XprtRdmaCounters:
+ result.__rpc_data[key] -= old_stats.__rpc_data[key]
+ result.__nfs_data['age'] -= old_stats.__nfs_data['age']
+ for key in NfsEventCounters:
+ result.__nfs_data[key] -= old_stats.__nfs_data[key]
+ for key in NfsByteCounters:
+ result.__nfs_data[key] -= old_stats.__nfs_data[key]
+ return result
+
+ def setup_accumulator(self, ops):
+ """Initialize a DeviceData instance to tally stats for all mountpoints
+ with the same major version. This is for the nfsstat command.
+ """
+ if ops == Nfsv3ops:
+ self.__rpc_data['programversion'] = '100003/3'
+ self.__nfs_data['fstype'] = 'nfs'
+ elif ops == Nfsv4ops:
+ self.__rpc_data['programversion'] = '100003/4'
+ self.__nfs_data['fstype'] = 'nfs4'
+ self.__rpc_data['ops'] = ops
+ for op in ops:
+ self.__rpc_data[op] = [0 for i in range(9)]
+
+ def accumulate_iostats(self, new_stats):
+ """Accumulate counters from all RPC op buckets in new_stats. This is
+ for the nfsstat command.
+ """
+ for op in new_stats.__rpc_data['ops']:
+ try:
+ self.__rpc_data[op] = list(map(add, self.__rpc_data[op], new_stats.__rpc_data[op]))
+ except KeyError:
+ continue
+
+ def __print_rpc_op_stats(self, op, sample_time):
+ """Print generic stats for one RPC op
+ """
+ if op not in self.__rpc_data:
+ return
+
+ rpc_stats = self.__rpc_data[op]
+ ops = float(rpc_stats[0])
+ retrans = float(rpc_stats[1] - rpc_stats[0])
+ kilobytes = float(rpc_stats[3] + rpc_stats[4]) / 1024
+ queued_for = float(rpc_stats[5])
+ rtt = float(rpc_stats[6])
+ exe = float(rpc_stats[7])
+ if len(rpc_stats) >= 9:
+ errs = int(rpc_stats[8])
+
+ # prevent floating point exceptions
+ if ops != 0:
+ kb_per_op = kilobytes / ops
+ retrans_percent = (retrans * 100) / ops
+ rtt_per_op = rtt / ops
+ exe_per_op = exe / ops
+ queued_for_per_op = queued_for / ops
+ if len(rpc_stats) >= 9:
+ errs_percent = (errs * 100) / ops
+ else:
+ kb_per_op = 0.0
+ retrans_percent = 0.0
+ rtt_per_op = 0.0
+ exe_per_op = 0.0
+ queued_for_per_op = 0.0
+ errs_percent = 0.0
+
+ op += ':'
+ print(format(op.lower(), '<16s'), end='')
+ print(format('ops/s', '>8s'), end='')
+ print(format('kB/s', '>16s'), end='')
+ print(format('kB/op', '>16s'), end='')
+ print(format('retrans', '>16s'), end='')
+ print(format('avg RTT (ms)', '>16s'), end='')
+ print(format('avg exe (ms)', '>16s'), end='')
+ print(format('avg queue (ms)', '>16s'), end='')
+ if len(rpc_stats) >= 9:
+ print(format('errors', '>16s'), end='')
+ print()
+
+ print(format((ops / sample_time), '>24.3f'), end='')
+ print(format((kilobytes / sample_time), '>16.3f'), end='')
+ print(format(kb_per_op, '>16.3f'), end='')
+ retransmits = '{0:>10.0f} ({1:>3.1f}%)'.format(retrans, retrans_percent).strip()
+ print(format(retransmits, '>16'), end='')
+ print(format(rtt_per_op, '>16.3f'), end='')
+ print(format(exe_per_op, '>16.3f'), end='')
+ print(format(queued_for_per_op, '>16.3f'), end='')
+ if len(rpc_stats) >= 9:
+ errors = '{0:>10.0f} ({1:>3.1f}%)'.format(errs, errs_percent).strip()
+ print(format(errors, '>16'), end='')
+ print()
+
+ def display_iostats(self, sample_time):
+ """Display NFS and RPC stats in an iostat-like way
+ """
+ sends = float(self.__rpc_data['rpcsends'])
+ if sample_time == 0:
+ sample_time = float(self.__nfs_data['age'])
+ # sample_time could still be zero if the export was just mounted.
+ # Set it to 1 to avoid divide by zero errors in this case since we'll
+ # likely still have relevant mount statistics to show.
+ #
+ if sample_time == 0:
+ sample_time = 1;
+ if sends != 0:
+ backlog = (float(self.__rpc_data['backlogutil']) / sends) / sample_time
+ else:
+ backlog = 0.0
+
+ print()
+ print('%s mounted on %s:' % \
+ (self.__nfs_data['export'], self.__nfs_data['mountpoint']))
+ print()
+
+ print(format('ops/s', '>16') + format('rpc bklog', '>16'))
+ print(format((sends / sample_time), '>16.3f'), end='')
+ print(format(backlog, '>16.3f'))
+ print()
+
+ self.__print_rpc_op_stats('READ', sample_time)
+ self.__print_rpc_op_stats('WRITE', sample_time)
+ sys.stdout.flush()
+
+ def display_xprt_stats(self):
+ """Pretty-print the xprt statistics
+ """
+ if self.__rpc_data['protocol'] == 'udp':
+ print('\tTransport protocol: udp')
+ print('\tSource port: %d' % self.__rpc_data['port'])
+ print('\tBind count: %d' % self.__rpc_data['bind_count'])
+ print('\tRPC requests: %d' % self.__rpc_data['rpcsends'])
+ print('\tRPC replies: %d' % self.__rpc_data['rpcreceives'])
+ print('\tXIDs not found: %d' % self.__rpc_data['badxids'])
+ print('\tMax slots: %d' % self.__rpc_data['maxslots'])
+ if self.__rpc_data['rpcsends'] != 0:
+ print('\tAvg backlog length: %d' % \
+ (float(self.__rpc_data['backlogutil']) / self.__rpc_data['rpcsends']))
+ print('\tAvg send queue length: %d' % \
+ (float(self.__rpc_data['sendutil']) / self.__rpc_data['rpcsends']))
+ print('\tAvg pending queue length: %d' % \
+ (float(self.__rpc_data['pendutil']) / self.__rpc_data['rpcsends']))
+ elif self.__rpc_data['protocol'] == 'tcp':
+ print('\tTransport protocol: tcp')
+ print('\tSource port: %d' % self.__rpc_data['port'])
+ print('\tBind count: %d' % self.__rpc_data['bind_count'])
+ print('\tConnect count: %d' % self.__rpc_data['connect_count'])
+ print('\tConnect time: %d seconds' % self.__rpc_data['connect_time'])
+ print('\tIdle time: %d seconds' % self.__rpc_data['idle_time'])
+ print('\tRPC requests: %d' % self.__rpc_data['rpcsends'])
+ print('\tRPC replies: %d' % self.__rpc_data['rpcreceives'])
+ print('\tXIDs not found: %d' % self.__rpc_data['badxids'])
+ print('\tMax slots: %d' % self.__rpc_data['maxslots'])
+ if self.__rpc_data['rpcsends'] != 0:
+ print('\tAvg backlog length: %d' % \
+ (float(self.__rpc_data['backlogutil']) / self.__rpc_data['rpcsends']))
+ print('\tAvg send queue length: %d' % \
+ (float(self.__rpc_data['sendutil']) / self.__rpc_data['rpcsends']))
+ print('\tAvg pending queue length: %d' % \
+ (float(self.__rpc_data['pendutil']) / self.__rpc_data['rpcsends']))
+ elif self.__rpc_data['protocol'] == 'rdma':
+ print('\tTransport protocol: rdma')
+ print('\tConnect count: %d' % self.__rpc_data['connect_count'])
+ print('\tConnect time: %d seconds' % self.__rpc_data['connect_time'])
+ print('\tIdle time: %d seconds' % self.__rpc_data['idle_time'])
+ sends = self.__rpc_data['rpcsends']
+ print('\tRPC requests: %d' % self.__rpc_data['rpcsends'])
+ print('\tRPC replies: %d' % self.__rpc_data['rpcreceives'])
+ print('\tXIDs not found: %d' % self.__rpc_data['badxids'])
+ if self.__rpc_data['rpcsends'] != 0:
+ print('\tAvg backlog length: %d' % \
+ (float(self.__rpc_data['backlogutil']) / self.__rpc_data['rpcsends']))
+ print('\tRead segments: %d' % self.__rpc_data['read_segments'])
+ print('\tWrite segments: %d' % self.__rpc_data['write_segments'])
+ print('\tReply segments: %d' % self.__rpc_data['reply_segments'])
+ print('\tRegistered: %d bytes' % self.__rpc_data['total_rdma_req'])
+ print('\tRDMA received: %d bytes' % self.__rpc_data['total_rdma_rep'])
+ print('\tTotal pull-up: %d bytes' % self.__rpc_data['pullup'])
+ print('\tTotal fix-up: %d bytes' % self.__rpc_data['fixup'])
+ print('\tHardway allocations: %d bytes' % self.__rpc_data['hardway'])
+ print('\tFailed marshals: %d' % self.__rpc_data['failed_marshal'])
+ print('\tBad replies: %d' % self.__rpc_data['bad_reply'])
+
+ """ Counters not present in all kernels """
+ if 'nomsg_calls' in self.__rpc_data:
+ print('\tRDMA_NOMSG calls: %d' % self.__rpc_data['nomsg_calls'])
+ if 'allocated_mrs' in self.__rpc_data:
+ print('\tAllocated MRs: %d' % self.__rpc_data['allocated_mrs'])
+ if 'recovered_mrs' in self.__rpc_data:
+ print('\tRecovered MRs: %d' % self.__rpc_data['recovered_mrs'])
+ if 'orphaned_mrs' in self.__rpc_data:
+ print('\tOrphaned MRs: %d' % self.__rpc_data['orphaned_mrs'])
+ if 'local_invalidates' in self.__rpc_data:
+ print('\tLocal Invalidates needed: %d' % self.__rpc_data['local_invalidates'])
+ if 'empty_sendctx_q' in self.__rpc_data:
+ print('\tEmpty sendctx queue count: %d' % self.__rpc_data['empty_sendctx_q'])
+ if 'reply_waits_for_send' in self.__rpc_data:
+ print('\tReplies that waited for Send completion: %d' % self.__rpc_data['reply_waits_for_send'])
+ else:
+ raise Exception('Unknown RPC transport protocol %s' % self.__rpc_data['protocol'])
+
+def parse_stats_file(f):
+ """pop the contents of a mountstats file into a dictionary,
+ keyed by mount point. each value object is a list of the
+ lines in the mountstats file corresponding to the mount
+ point named in the key.
+ """
+ ms_dict = dict()
+ key = ''
+
+ f.seek(0)
+ for line in f.readlines():
+ words = line.split()
+ if len(words) == 0:
+ continue
+ if words[0] == 'device':
+ key = words[4]
+ new = [ line.strip() ]
+ elif 'nfs' in words or 'nfs4' in words:
+ key = words[3]
+ new = [ line.strip() ]
+ else:
+ new += [ line.strip() ]
+ ms_dict[key] = new
+
+ return ms_dict
+
+def print_mountstats(stats, nfs_only, rpc_only, raw, xprt_only):
+ if nfs_only:
+ stats.display_stats_header()
+ stats.display_nfs_options()
+ stats.display_nfs_events()
+ stats.display_nfs_bytes()
+ elif rpc_only:
+ stats.display_stats_header()
+ stats.display_rpc_generic_stats()
+ stats.display_rpc_op_stats()
+ elif raw:
+ stats.display_raw_stats()
+ elif xprt_only:
+ stats.display_stats_header()
+ stats.display_xprt_stats()
+ else:
+ stats.display_stats_header()
+ stats.display_nfs_options()
+ stats.display_nfs_bytes()
+ stats.display_rpc_generic_stats()
+ stats.display_rpc_op_stats()
+ print()
+
+def mountstats_command(args):
+ """Mountstats command
+ """
+ mountstats = parse_stats_file(args.infile)
+ mountpoints = [os.path.normpath(mp) for mp in args.mountpoints]
+
+ # make certain devices contains only NFS mount points
+ if len(mountpoints) > 0:
+ check = []
+ for device in mountpoints:
+ stats = DeviceData()
+ try:
+ stats.parse_stats(mountstats[device])
+ if stats.is_nfs_mountpoint():
+ check += [device]
+ except KeyError:
+ continue
+ mountpoints = check
+ else:
+ for device, descr in mountstats.items():
+ stats = DeviceData()
+ stats.parse_stats(descr)
+ if stats.is_nfs_mountpoint():
+ mountpoints += [device]
+ if len(mountpoints) == 0:
+ print('No NFS mount points were found')
+ return 1
+
+ if args.since:
+ old_mountstats = parse_stats_file(args.since)
+
+ for mp in mountpoints:
+ stats = DeviceData()
+ stats.parse_stats(mountstats[mp])
+ if not args.since:
+ print_mountstats(stats, args.nfs_only, args.rpc_only, args.raw, args.xprt_only)
+ elif args.since and mp not in old_mountstats:
+ print_mountstats(stats, args.nfs_only, args.rpc_only, args.raw, args.xprt_only)
+ else:
+ old_stats = DeviceData()
+ old_stats.parse_stats(old_mountstats[mp])
+ diff_stats = stats.compare_iostats(old_stats)
+ print_mountstats(diff_stats, args.nfs_only, args.rpc_only, args.raw, args.xprt_only)
+
+ args.infile.close()
+ if args.since:
+ args.since.close()
+ return 0
+
+def nfsstat_command(args):
+ """nfsstat-like command for NFS mount points
+ """
+ mountstats = parse_stats_file(args.infile)
+ mountpoints = [os.path.normpath(mp) for mp in args.mountpoints]
+ v3stats = DeviceData()
+ v3stats.setup_accumulator(Nfsv3ops)
+ v4stats = DeviceData()
+ v4stats.setup_accumulator(Nfsv4ops)
+
+ # ensure stats get printed if neither v3 nor v4 was specified
+ if args.show_v3 or args.show_v4:
+ show_both = False
+ else:
+ show_both = True
+
+ # make certain devices contains only NFS mount points
+ if len(mountpoints) > 0:
+ check = []
+ for device in mountpoints:
+ stats = DeviceData()
+ try:
+ stats.parse_stats(mountstats[device])
+ if stats.is_nfs_mountpoint():
+ check += [device]
+ except KeyError:
+ continue
+ mountpoints = check
+ else:
+ for device, descr in mountstats.items():
+ stats = DeviceData()
+ stats.parse_stats(descr)
+ if stats.is_nfs_mountpoint():
+ mountpoints += [device]
+ if len(mountpoints) == 0:
+ print('No NFS mount points were found')
+ return 1
+
+ if args.since:
+ old_mountstats = parse_stats_file(args.since)
+
+ for mp in mountpoints:
+ stats = DeviceData()
+ stats.parse_stats(mountstats[mp])
+ vers = stats.nfs_version()
+
+ if not args.since:
+ acc_stats = stats
+ elif args.since and mp not in old_mountstats:
+ acc_stats = stats
+ else:
+ old_stats = DeviceData()
+ old_stats.parse_stats(old_mountstats[mp])
+ acc_stats = stats.compare_iostats(old_stats)
+
+ if vers == 3 and (show_both or args.show_v3):
+ v3stats.accumulate_iostats(acc_stats)
+ elif vers == 4 and (show_both or args.show_v4):
+ v4stats.accumulate_iostats(acc_stats)
+
+ sends, retrans, authrefrsh = map(add, v3stats.client_rpc_stats(), v4stats.client_rpc_stats())
+ print('Client rpc stats:')
+ print('calls retrans authrefrsh')
+ print('%-11u%-11u%-11u' % (sends, retrans, authrefrsh))
+
+ if show_both or args.show_v3:
+ v3stats.display_nfsstat_stats()
+ if show_both or args.show_v4:
+ v4stats.display_nfsstat_stats()
+
+ args.infile.close()
+ if args.since:
+ args.since.close()
+ return 0
+
+def print_iostat_summary(old, new, devices, time):
+ for device in devices:
+ stats = DeviceData()
+ stats.parse_stats(new[device])
+ if not old or device not in old:
+ stats.display_iostats(time)
+ else:
+ if ("fstype autofs" not in str(old[device])) and ("fstype autofs" not in str(new[device])):
+ old_stats = DeviceData()
+ old_stats.parse_stats(old[device])
+ diff_stats = stats.compare_iostats(old_stats)
+ diff_stats.display_iostats(time)
+
+def iostat_command(args):
+ """iostat-like command for NFS mount points
+ """
+ mountstats = parse_stats_file(args.infile)
+ devices = [os.path.normpath(mp) for mp in args.mountpoints]
+
+ if args.since:
+ old_mountstats = parse_stats_file(args.since)
+ else:
+ old_mountstats = None
+
+ # make certain devices contains only NFS mount points
+ if len(devices) > 0:
+ check = []
+ for device in devices:
+ stats = DeviceData()
+ try:
+ stats.parse_stats(mountstats[device])
+ if stats.is_nfs_mountpoint():
+ check += [device]
+ except KeyError:
+ continue
+ devices = check
+ else:
+ for device, descr in mountstats.items():
+ stats = DeviceData()
+ stats.parse_stats(descr)
+ if stats.is_nfs_mountpoint():
+ devices += [device]
+ if len(devices) == 0:
+ print('No NFS mount points were found')
+ return 1
+
+ sample_time = 0
+
+ if args.interval is None:
+ print_iostat_summary(old_mountstats, mountstats, devices, sample_time)
+ return
+
+ if args.count is not None:
+ count = args.count
+ while count != 0:
+ print_iostat_summary(old_mountstats, mountstats, devices, sample_time)
+ old_mountstats = mountstats
+ time.sleep(args.interval)
+ sample_time = args.interval
+ mountstats = parse_stats_file(args.infile)
+ count -= 1
+ else:
+ while True:
+ print_iostat_summary(old_mountstats, mountstats, devices, sample_time)
+ old_mountstats = mountstats
+ time.sleep(args.interval)
+ sample_time = args.interval
+ mountstats = parse_stats_file(args.infile)
+
+ args.infile.close()
+ if args.since:
+ args.since.close()
+ return 0
+
+class ICMAction(argparse.Action):
+ """Custom action to deal with interval, count, and mountpoints.
+ """
+ def __call__(self, parser, namespace, values, option_string=None):
+ if namespace.mountpoints is None:
+ namespace.mountpoints = []
+ if values is None:
+ return
+ elif (type(values) == type([])):
+ for value in values:
+ self._handle_one(namespace, value)
+ else:
+ self._handle_one(namespace, values)
+
+ def _handle_one(self, namespace, value):
+ try:
+ intval = int(value)
+ if namespace.infile.name != '/proc/self/mountstats':
+ raise argparse.ArgumentError(self, "not allowed with argument -f/--file or -S/--since")
+ self._handle_int(namespace, intval)
+ except ValueError:
+ namespace.mountpoints.append(value)
+
+ def _handle_int(self, namespace, value):
+ if namespace.interval is None:
+ namespace.interval = value
+ elif namespace.count is None:
+ namespace.count = value
+ else:
+ raise argparse.ArgumentError(self, "too many integer arguments")
+
+def main():
+ parser = argparse.ArgumentParser(epilog='For specific sub-command help, '
+ 'run \'mountstats SUB-COMMAND -h|--help\'')
+ subparsers = parser.add_subparsers(help='sub-command help')
+
+ common_parser = argparse.ArgumentParser(add_help=False)
+ common_parser.add_argument('-v', '--version', action='version',
+ version='mountstats ' + Mountstats_version)
+ common_parser.add_argument('-f', '--file', default=open('/proc/self/mountstats', 'r'),
+ type=argparse.FileType('r'), dest='infile',
+ help='Read stats from %(dest)s instead of /proc/self/mountstats')
+ common_parser.add_argument('-S', '--since', type=argparse.FileType('r'),
+ metavar='SINCEFILE',
+ help='Show difference between current stats and those in SINCEFILE')
+
+ mountstats_parser = subparsers.add_parser('mountstats',
+ parents=[common_parser],
+ help='Display a combination of per-op RPC statistics, NFS event counts, and NFS byte counts. '
+ 'This is the default sub-command if no sub-command is given.')
+ group = mountstats_parser.add_mutually_exclusive_group()
+ group.add_argument('-n', '--nfs', action='store_true', dest='nfs_only',
+ help='Display only the NFS statistics')
+ group.add_argument('-r', '--rpc', action='store_true', dest='rpc_only',
+ help='Display only the RPC statistics')
+ group.add_argument('-R', '--raw', action='store_true',
+ help='Display only the raw statistics')
+ group.add_argument('-x', '--xprt', action='store_true', dest='xprt_only',
+ help='Display only the xprt statistics')
+ # The mountpoints argument cannot be moved into the common_parser because
+ # it will screw up the parsing of the iostat arguments (interval and count)
+ mountstats_parser.add_argument('mountpoints', nargs='*', metavar='mountpoint',
+ help='Display statistics for this mountpoint. More than one may be specified. '
+ 'If absent, statistics for all NFS mountpoints will be generated.')
+ mountstats_parser.set_defaults(func=mountstats_command)
+
+ nfsstat_parser = subparsers.add_parser('nfsstat',
+ parents=[common_parser],
+ help='Display nfsstat-like statistics.')
+ nfsstat_parser.add_argument('-3', action='store_true', dest='show_v3',
+ help='Show NFS version 3 statistics')
+ nfsstat_parser.add_argument('-4', action='store_true', dest='show_v4',
+ help='Show NFS version 4 statistics')
+ # The mountpoints argument cannot be moved into the common_parser because
+ # it will screw up the parsing of the iostat arguments (interval and count)
+ nfsstat_parser.add_argument('mountpoints', nargs='*', metavar='mountpoint',
+ help='Display statistics for this mountpoint. More than one may be specified. '
+ 'If absent, statistics for all NFS mountpoints will be generated.')
+ nfsstat_parser.set_defaults(func=nfsstat_command)
+
+ iostat_parser = subparsers.add_parser('iostat',
+ parents=[common_parser],
+ help='Display iostat-like statistics.')
+ iostat_parser.add_argument('interval', nargs='?', action=ICMAction,
+ help='Number of seconds between reports. If absent, only one report will '
+ 'be generated.')
+ iostat_parser.add_argument('count', nargs='?', action=ICMAction,
+ help='Number of reports generated at <interval> seconds apart. If absent, '
+ 'reports will be generated continuously.')
+ # The mountpoints argument cannot be moved into the common_parser because
+ # it will screw up the parsing of the iostat arguments (interval and count)
+ iostat_parser.add_argument('mountpoints', nargs='*', action=ICMAction, metavar='mountpoint',
+ help='Display statsistics for this mountpoint. More than one may be specified. '
+ 'If absent, statistics for all NFS mountpoints will be generated.')
+ iostat_parser.set_defaults(func=iostat_command)
+
+ args = parser.parse_args()
+ return args.func(args)
+
+try:
+ if __name__ == '__main__':
+ # Run the mounstats sub-command if no sub-command (or the help flag)
+ # is given. If the argparse module ever gets support for optional
+ # (default) sub-commands, then this can be changed.
+ if len(sys.argv) == 1:
+ sys.argv.insert(1, 'mountstats')
+ elif sys.argv[1] not in ['-h', '--help', 'mountstats', 'iostat', 'nfsstat']:
+ sys.argv.insert(1, 'mountstats')
+ res = main()
+ sys.stdout.close()
+ sys.stderr.close()
+ sys.exit(res)
+except (KeyboardInterrupt, RuntimeError):
+ sys.exit(1)
+except IOError:
+ pass
+
diff --git a/tools/nfs-iostat/Makefile.am b/tools/nfs-iostat/Makefile.am
new file mode 100644
index 0000000..3ae0f29
--- /dev/null
+++ b/tools/nfs-iostat/Makefile.am
@@ -0,0 +1,13 @@
+## Process this file with automake to produce Makefile.in
+PYTHON_FILES = nfs-iostat.py
+
+man8_MANS = nfsiostat.man
+
+EXTRA_DIST = $(man8_MANS) $(PYTHON_FILES)
+
+all-local: $(PYTHON_FILES)
+
+install-data-hook:
+ $(INSTALL) -m 755 nfs-iostat.py $(DESTDIR)$(sbindir)/nfsiostat
+
+MAINTAINERCLEANFILES=Makefile.in
diff --git a/tools/nfs-iostat/Makefile.in b/tools/nfs-iostat/Makefile.in
new file mode 100644
index 0000000..fc02eb6
--- /dev/null
+++ b/tools/nfs-iostat/Makefile.in
@@ -0,0 +1,621 @@
+# Makefile.in generated by automake 1.16.5 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = tools/nfs-iostat
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/aclocal/ax_gcc_func_attribute.m4 \
+ $(top_srcdir)/aclocal/bsdsignals.m4 \
+ $(top_srcdir)/aclocal/getrandom.m4 \
+ $(top_srcdir)/aclocal/ipv6.m4 \
+ $(top_srcdir)/aclocal/kerberos5.m4 \
+ $(top_srcdir)/aclocal/keyutils.m4 \
+ $(top_srcdir)/aclocal/libblkid.m4 \
+ $(top_srcdir)/aclocal/libcap.m4 \
+ $(top_srcdir)/aclocal/libevent.m4 \
+ $(top_srcdir)/aclocal/libpthread.m4 \
+ $(top_srcdir)/aclocal/libsqlite3.m4 \
+ $(top_srcdir)/aclocal/libtirpc.m4 \
+ $(top_srcdir)/aclocal/libxml2.m4 \
+ $(top_srcdir)/aclocal/nfs-utils.m4 \
+ $(top_srcdir)/aclocal/rpcsec_vers.m4 \
+ $(top_srcdir)/aclocal/tcp-wrappers.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/support/include/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+man8dir = $(mandir)/man8
+am__installdirs = "$(DESTDIR)$(man8dir)"
+NROFF = nroff
+MANS = $(man8_MANS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
+AM_CPPFLAGS = @AM_CPPFLAGS@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CXXFLAGS_FOR_BUILD = @CXXFLAGS_FOR_BUILD@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ETAGS = @ETAGS@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FILECMD = @FILECMD@
+GREP = @GREP@
+GSSAPI_CFLAGS = @GSSAPI_CFLAGS@
+GSSAPI_LIBS = @GSSAPI_LIBS@
+GSSD = @GSSD@
+GSSGLUE_CFLAGS = @GSSGLUE_CFLAGS@
+GSSGLUE_LIBS = @GSSGLUE_LIBS@
+GSSKRB_CFLAGS = @GSSKRB_CFLAGS@
+GSSKRB_LIBS = @GSSKRB_LIBS@
+HAVE_GETRANDOM = @HAVE_GETRANDOM@
+HAVE_LIBWRAP = @HAVE_LIBWRAP@
+HAVE_TCP_WRAPPER = @HAVE_TCP_WRAPPER@
+IDMAPD = @IDMAPD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+K5VERS = @K5VERS@
+KRBCFLAGS = @KRBCFLAGS@
+KRBDIR = @KRBDIR@
+KRBLDFLAGS = @KRBLDFLAGS@
+KRBLIBS = @KRBLIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@
+LIBBLKID = @LIBBLKID@
+LIBBSD = @LIBBSD@
+LIBCAP = @LIBCAP@
+LIBCRYPT = @LIBCRYPT@
+LIBEVENT = @LIBEVENT@
+LIBKEYUTILS = @LIBKEYUTILS@
+LIBMOUNT = @LIBMOUNT@
+LIBMOUNT_CFLAGS = @LIBMOUNT_CFLAGS@
+LIBMOUNT_LIBS = @LIBMOUNT_LIBS@
+LIBNSL = @LIBNSL@
+LIBOBJS = @LIBOBJS@
+LIBPTHREAD = @LIBPTHREAD@
+LIBS = @LIBS@
+LIBSOCKET = @LIBSOCKET@
+LIBSQLITE = @LIBSQLITE@
+LIBTIRPC = @LIBTIRPC@
+LIBTOOL = @LIBTOOL@
+LIBWRAP = @LIBWRAP@
+LIBXML2 = @LIBXML2@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_PLUGINS = @PATH_PLUGINS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
+RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
+RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SVCGSSD = @SVCGSSD@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+VERSION = @VERSION@
+XML2_CFLAGS = @XML2_CFLAGS@
+XML2_LIBS = @XML2_LIBS@
+_rpc_pipefsmount = @_rpc_pipefsmount@
+_statedir = @_statedir@
+_sysconfdir = @_sysconfdir@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
+enable_mountconfig = @enable_mountconfig@
+enable_nfsv4 = @enable_nfsv4@
+enable_nfsv41 = @enable_nfsv41@
+enable_svcgss = @enable_svcgss@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+kprefix = @kprefix@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+mountfile = @mountfile@
+nfsconfig = @nfsconfig@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+rpc_pipefsmount = @rpc_pipefsmount@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+startstatd = @startstatd@
+statdpath = @statdpath@
+statduser = @statduser@
+statedir = @statedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+unitdir = @unitdir@
+PYTHON_FILES = nfs-iostat.py
+man8_MANS = nfsiostat.man
+EXTRA_DIST = $(man8_MANS) $(PYTHON_FILES)
+MAINTAINERCLEANFILES = Makefile.in
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tools/nfs-iostat/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu tools/nfs-iostat/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(man8_MANS)
+ @$(NORMAL_INSTALL)
+ @list1='$(man8_MANS)'; \
+ list2=''; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list='$(man8_MANS)'; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(MANS) all-local
+installdirs:
+ for dir in "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-data-hook
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man
+
+uninstall-man: uninstall-man8
+
+.MAKE: install-am install-data-am install-strip
+
+.PHONY: all all-am all-local check check-am clean clean-generic \
+ clean-libtool cscopelist-am ctags-am distclean \
+ distclean-generic distclean-libtool distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-data-hook install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-man8 \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags-am uninstall uninstall-am uninstall-man uninstall-man8
+
+.PRECIOUS: Makefile
+
+
+all-local: $(PYTHON_FILES)
+
+install-data-hook:
+ $(INSTALL) -m 755 nfs-iostat.py $(DESTDIR)$(sbindir)/nfsiostat
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tools/nfs-iostat/nfs-iostat.py b/tools/nfs-iostat/nfs-iostat.py
new file mode 100755
index 0000000..85294fb
--- /dev/null
+++ b/tools/nfs-iostat/nfs-iostat.py
@@ -0,0 +1,678 @@
+#!/usr/bin/python3
+# -*- python-mode -*-
+"""Emulate iostat for NFS mount points using /proc/self/mountstats
+"""
+
+from __future__ import print_function
+
+__copyright__ = """
+Copyright (C) 2005, Chuck Lever <cel@netapp.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 2 as
+published by the Free Software Foundation.
+
+This program 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+MA 02110-1301 USA
+"""
+
+import sys, os, time
+from optparse import OptionParser, OptionGroup
+
+Iostats_version = '0.2'
+
+def difference(x, y):
+ """Used for a map() function
+ """
+ return x - y
+
+NfsEventCounters = [
+ 'inoderevalidates',
+ 'dentryrevalidates',
+ 'datainvalidates',
+ 'attrinvalidates',
+ 'vfsopen',
+ 'vfslookup',
+ 'vfspermission',
+ 'vfsupdatepage',
+ 'vfsreadpage',
+ 'vfsreadpages', # or vfsreadahead in statvers=1.2 or above
+ 'vfswritepage',
+ 'vfswritepages',
+ 'vfsreaddir',
+ 'vfssetattr',
+ 'vfsflush',
+ 'vfsfsync',
+ 'vfslock',
+ 'vfsrelease',
+ 'congestionwait',
+ 'setattrtrunc',
+ 'extendwrite',
+ 'sillyrenames',
+ 'shortreads',
+ 'shortwrites',
+ 'delay'
+]
+
+NfsByteCounters = [
+ 'normalreadbytes',
+ 'normalwritebytes',
+ 'directreadbytes',
+ 'directwritebytes',
+ 'serverreadbytes',
+ 'serverwritebytes',
+ 'readpages',
+ 'writepages'
+]
+
+class DeviceData:
+ """DeviceData objects provide methods for parsing and displaying
+ data for a single mount grabbed from /proc/self/mountstats
+ """
+ def __init__(self):
+ self.__nfs_data = dict()
+ self.__rpc_data = dict()
+ self.__rpc_data['ops'] = []
+
+ def __parse_nfs_line(self, words):
+ if words[0] == 'device':
+ self.__nfs_data['export'] = words[1]
+ self.__nfs_data['mountpoint'] = words[4]
+ self.__nfs_data['fstype'] = words[7]
+ if words[7] == 'nfs' or words[7] == 'nfs4':
+ self.__nfs_data['statvers'] = float(words[8].split('=',1)[1])
+ elif 'nfs' in words or 'nfs4' in words:
+ self.__nfs_data['export'] = words[0]
+ self.__nfs_data['mountpoint'] = words[3]
+ self.__nfs_data['fstype'] = words[6]
+ if words[6] == 'nfs':
+ self.__nfs_data['statvers'] = float(words[7].split('=',1)[1])
+ elif words[0] == 'age:':
+ self.__nfs_data['age'] = int(words[1])
+ elif words[0] == 'opts:':
+ self.__nfs_data['mountoptions'] = ''.join(words[1:]).split(',')
+ elif words[0] == 'caps:':
+ self.__nfs_data['servercapabilities'] = ''.join(words[1:]).split(',')
+ elif words[0] == 'nfsv4:':
+ self.__nfs_data['nfsv4flags'] = ''.join(words[1:]).split(',')
+ elif words[0] == 'sec:':
+ keys = ''.join(words[1:]).split(',')
+ self.__nfs_data['flavor'] = int(keys[0].split('=')[1])
+ self.__nfs_data['pseudoflavor'] = 0
+ if self.__nfs_data['flavor'] == 6:
+ self.__nfs_data['pseudoflavor'] = int(keys[1].split('=')[1])
+ elif words[0] == 'events:':
+ i = 1
+ for key in NfsEventCounters:
+ self.__nfs_data[key] = int(words[i])
+ i += 1
+ elif words[0] == 'bytes:':
+ i = 1
+ for key in NfsByteCounters:
+ self.__nfs_data[key] = int(words[i])
+ i += 1
+
+ def __parse_rpc_line(self, words):
+ if words[0] == 'RPC':
+ self.__rpc_data['statsvers'] = float(words[3])
+ self.__rpc_data['programversion'] = words[5]
+ elif words[0] == 'xprt:':
+ self.__rpc_data['protocol'] = words[1]
+ if words[1] == 'udp':
+ self.__rpc_data['port'] = int(words[2])
+ self.__rpc_data['bind_count'] = int(words[3])
+ self.__rpc_data['rpcsends'] = int(words[4])
+ self.__rpc_data['rpcreceives'] = int(words[5])
+ self.__rpc_data['badxids'] = int(words[6])
+ self.__rpc_data['inflightsends'] = int(words[7])
+ self.__rpc_data['backlogutil'] = int(words[8])
+ elif words[1] == 'tcp':
+ self.__rpc_data['port'] = words[2]
+ self.__rpc_data['bind_count'] = int(words[3])
+ self.__rpc_data['connect_count'] = int(words[4])
+ self.__rpc_data['connect_time'] = int(words[5])
+ self.__rpc_data['idle_time'] = int(words[6])
+ self.__rpc_data['rpcsends'] = int(words[7])
+ self.__rpc_data['rpcreceives'] = int(words[8])
+ self.__rpc_data['badxids'] = int(words[9])
+ self.__rpc_data['inflightsends'] = int(words[10])
+ self.__rpc_data['backlogutil'] = int(words[11])
+ elif words[1] == 'rdma':
+ self.__rpc_data['port'] = words[2]
+ self.__rpc_data['bind_count'] = int(words[3])
+ self.__rpc_data['connect_count'] = int(words[4])
+ self.__rpc_data['connect_time'] = int(words[5])
+ self.__rpc_data['idle_time'] = int(words[6])
+ self.__rpc_data['rpcsends'] = int(words[7])
+ self.__rpc_data['rpcreceives'] = int(words[8])
+ self.__rpc_data['badxids'] = int(words[9])
+ self.__rpc_data['backlogutil'] = int(words[10])
+ self.__rpc_data['read_chunks'] = int(words[11])
+ self.__rpc_data['write_chunks'] = int(words[12])
+ self.__rpc_data['reply_chunks'] = int(words[13])
+ self.__rpc_data['total_rdma_req'] = int(words[14])
+ self.__rpc_data['total_rdma_rep'] = int(words[15])
+ self.__rpc_data['pullup'] = int(words[16])
+ self.__rpc_data['fixup'] = int(words[17])
+ self.__rpc_data['hardway'] = int(words[18])
+ self.__rpc_data['failed_marshal'] = int(words[19])
+ self.__rpc_data['bad_reply'] = int(words[20])
+ elif words[0] == 'per-op':
+ self.__rpc_data['per-op'] = words
+ else:
+ op = words[0][:-1]
+ self.__rpc_data['ops'] += [op]
+ self.__rpc_data[op] = [int(word) for word in words[1:]]
+
+ def parse_stats(self, lines):
+ """Turn a list of lines from a mount stat file into a
+ dictionary full of stats, keyed by name
+ """
+ found = False
+ for line in lines:
+ words = line.split()
+ if len(words) == 0:
+ continue
+ if (not found and words[0] != 'RPC'):
+ self.__parse_nfs_line(words)
+ continue
+
+ found = True
+ self.__parse_rpc_line(words)
+
+ def is_nfs_mountpoint(self):
+ """Return True if this is an NFS or NFSv4 mountpoint,
+ otherwise return False
+ """
+ if self.__nfs_data['fstype'] == 'nfs':
+ return True
+ elif self.__nfs_data['fstype'] == 'nfs4':
+ return True
+ return False
+
+ def compare_iostats(self, old_stats):
+ """Return the difference between two sets of stats
+ """
+ result = DeviceData()
+
+ # copy self into result
+ for key, value in self.__nfs_data.items():
+ result.__nfs_data[key] = value
+ for key, value in self.__rpc_data.items():
+ result.__rpc_data[key] = value
+
+ # compute the difference of each item in the list
+ # note the copy loop above does not copy the lists, just
+ # the reference to them. so we build new lists here
+ # for the result object.
+ for op in result.__rpc_data['ops']:
+ try:
+ result.__rpc_data[op] = list(map(
+ difference, self.__rpc_data[op], old_stats.__rpc_data[op]))
+ except KeyError:
+ continue
+
+ # update the remaining keys we care about
+ result.__rpc_data['rpcsends'] -= old_stats.__rpc_data['rpcsends']
+ result.__rpc_data['backlogutil'] -= old_stats.__rpc_data['backlogutil']
+
+ for key in NfsEventCounters:
+ result.__nfs_data[key] -= old_stats.__nfs_data[key]
+ for key in NfsByteCounters:
+ result.__nfs_data[key] -= old_stats.__nfs_data[key]
+
+ return result
+
+ def __print_data_cache_stats(self):
+ """Print the data cache hit rate
+ """
+ nfs_stats = self.__nfs_data
+ app_bytes_read = float(nfs_stats['normalreadbytes'])
+ if app_bytes_read != 0:
+ client_bytes_read = float(nfs_stats['serverreadbytes'] - nfs_stats['directreadbytes'])
+ ratio = ((app_bytes_read - client_bytes_read) * 100) / app_bytes_read
+
+ print()
+ print('app bytes: %f client bytes %f' % (app_bytes_read, client_bytes_read))
+ print('Data cache hit ratio: %4.2f%%' % ratio)
+
+ def __print_attr_cache_stats(self, sample_time):
+ """Print attribute cache efficiency stats
+ """
+ nfs_stats = self.__nfs_data
+
+ print()
+ print('%d VFS opens' % (nfs_stats['vfsopen']))
+ print('%d inoderevalidates (forced GETATTRs)' % \
+ (nfs_stats['inoderevalidates']))
+ print('%d page cache invalidations' % \
+ (nfs_stats['datainvalidates']))
+ print('%d attribute cache invalidations' % \
+ (nfs_stats['attrinvalidates']))
+
+ def __print_dir_cache_stats(self, sample_time):
+ """Print directory stats
+ """
+ nfs_stats = self.__nfs_data
+ lookup_ops = self.__rpc_data['LOOKUP'][0]
+ readdir_ops = self.__rpc_data['READDIR'][0]
+ if 'READDIRPLUS' in self.__rpc_data:
+ readdir_ops += self.__rpc_data['READDIRPLUS'][0]
+
+ dentry_revals = nfs_stats['dentryrevalidates']
+ opens = nfs_stats['vfsopen']
+ lookups = nfs_stats['vfslookup']
+ getdents = nfs_stats['vfsreaddir']
+
+ print()
+ print('%d open operations (pathname lookups)' % opens)
+ print('%d dentry revalidates and %d vfs lookup requests' % \
+ (dentry_revals, lookups))
+ print('resulted in %d LOOKUPs on the wire' % lookup_ops)
+ print('%d vfs getdents calls resulted in %d READDIRs on the wire' % \
+ (getdents, readdir_ops))
+
+ def __print_page_stats(self, sample_time):
+ """Print page cache stats
+ """
+ nfs_stats = self.__nfs_data
+
+ vfsreadpage = nfs_stats['vfsreadpage']
+ vfsreadpages = nfs_stats['vfsreadpages']
+ pages_read = nfs_stats['readpages']
+ vfswritepage = nfs_stats['vfswritepage']
+ vfswritepages = nfs_stats['vfswritepages']
+ pages_written = nfs_stats['writepages']
+
+ print()
+ print('%d nfs_readpage() calls read %d pages' % \
+ (vfsreadpage, vfsreadpage))
+ multipageread = "readpages"
+ if self.__nfs_data['statvers'] >= 1.2:
+ multipageread = "readahead"
+ print('%d nfs_%s() calls read %d pages' % \
+ (vfsreadpages, multipageread, pages_read - vfsreadpage))
+ if vfsreadpages != 0:
+ print('(%.1f pages per call)' % \
+ (float(pages_read - vfsreadpage) / vfsreadpages))
+ else:
+ print()
+
+ print()
+ print('%d nfs_updatepage() calls' % nfs_stats['vfsupdatepage'])
+ print('%d nfs_writepage() calls wrote %d pages' % \
+ (vfswritepage, vfswritepage))
+ print('%d nfs_writepages() calls wrote %d pages' % \
+ (vfswritepages, pages_written - vfswritepage))
+ if (vfswritepages) != 0:
+ print('(%.1f pages per call)' % \
+ (float(pages_written - vfswritepage) / vfswritepages))
+ else:
+ print()
+
+ congestionwaits = nfs_stats['congestionwait']
+ if congestionwaits != 0:
+ print()
+ print('%d congestion waits' % congestionwaits)
+
+ def __print_rpc_op_stats(self, op, sample_time):
+ """Print generic stats for one RPC op
+ """
+ if op not in self.__rpc_data:
+ return
+
+ rpc_stats = self.__rpc_data[op]
+ ops = float(rpc_stats[0])
+ retrans = float(rpc_stats[1] - rpc_stats[0])
+ kilobytes = float(rpc_stats[3] + rpc_stats[4]) / 1024
+ queued_for = float(rpc_stats[5])
+ rtt = float(rpc_stats[6])
+ exe = float(rpc_stats[7])
+ if len(rpc_stats) >= 9:
+ errs = float(rpc_stats[8])
+
+ # prevent floating point exceptions
+ if ops != 0:
+ kb_per_op = kilobytes / ops
+ retrans_percent = (retrans * 100) / ops
+ rtt_per_op = rtt / ops
+ exe_per_op = exe / ops
+ queued_for_per_op = queued_for / ops
+ if len(rpc_stats) >= 9:
+ errs_percent = (errs * 100) / ops
+ else:
+ kb_per_op = 0.0
+ retrans_percent = 0.0
+ rtt_per_op = 0.0
+ exe_per_op = 0.0
+ queued_for_per_op = 0.0
+ if len(rpc_stats) >= 9:
+ errs_percent = 0.0
+
+ op += ':'
+ print(format(op.lower(), '<16s'), end='')
+ print(format('ops/s', '>8s'), end='')
+ print(format('kB/s', '>16s'), end='')
+ print(format('kB/op', '>16s'), end='')
+ print(format('retrans', '>16s'), end='')
+ print(format('avg RTT (ms)', '>16s'), end='')
+ print(format('avg exe (ms)', '>16s'), end='')
+ print(format('avg queue (ms)', '>16s'), end='')
+ if len(rpc_stats) >= 9:
+ print(format('errors', '>16s'), end='')
+ print()
+
+ print(format((ops / sample_time), '>24.3f'), end='')
+ print(format((kilobytes / sample_time), '>16.3f'), end='')
+ print(format(kb_per_op, '>16.3f'), end='')
+ retransmits = '{0:>10.0f} ({1:>3.1f}%)'.format(retrans, retrans_percent).strip()
+ print(format(retransmits, '>16'), end='')
+ print(format(rtt_per_op, '>16.3f'), end='')
+ print(format(exe_per_op, '>16.3f'), end='')
+ print(format(queued_for_per_op, '>16.3f'), end='')
+ if len(rpc_stats) >= 9:
+ errors = '{0:>10.0f} ({1:>3.1f}%)'.format(errs, errs_percent).strip()
+ print(format(errors, '>16'), end='')
+ print()
+
+ def ops(self, sample_time):
+ sends = float(self.__rpc_data['rpcsends'])
+ if sample_time == 0:
+ sample_time = float(self.__nfs_data['age'])
+ if sample_time == 0:
+ sample_time = 1;
+ return (sends / sample_time)
+
+ def display_iostats(self, sample_time, which):
+ """Display NFS and RPC stats in an iostat-like way
+ """
+ sends = float(self.__rpc_data['rpcsends'])
+ if sample_time == 0:
+ sample_time = float(self.__nfs_data['age'])
+ # sample_time could still be zero if the export was just mounted.
+ # Set it to 1 to avoid divide by zero errors in this case since we'll
+ # likely still have relevant mount statistics to show.
+ #
+ if sample_time == 0:
+ sample_time = 1;
+ if sends != 0:
+ backlog = (float(self.__rpc_data['backlogutil']) / sends) / sample_time
+ else:
+ backlog = 0.0
+
+ print()
+ print('%s mounted on %s:' % \
+ (self.__nfs_data['export'], self.__nfs_data['mountpoint']))
+ print()
+
+ print(format('ops/s', '>16') + format('rpc bklog', '>16'))
+ print(format((sends / sample_time), '>16.3f'), end='')
+ print(format(backlog, '>16.3f'))
+ print()
+
+ if which == 0:
+ self.__print_rpc_op_stats('READ', sample_time)
+ self.__print_rpc_op_stats('WRITE', sample_time)
+ elif which == 1:
+ self.__print_rpc_op_stats('GETATTR', sample_time)
+ self.__print_rpc_op_stats('ACCESS', sample_time)
+ self.__print_attr_cache_stats(sample_time)
+ elif which == 2:
+ self.__print_rpc_op_stats('LOOKUP', sample_time)
+ self.__print_rpc_op_stats('READDIR', sample_time)
+ if 'READDIRPLUS' in self.__rpc_data:
+ self.__print_rpc_op_stats('READDIRPLUS', sample_time)
+ self.__print_dir_cache_stats(sample_time)
+ elif which == 3:
+ self.__print_rpc_op_stats('READ', sample_time)
+ self.__print_rpc_op_stats('WRITE', sample_time)
+ self.__print_page_stats(sample_time)
+
+ sys.stdout.flush()
+
+#
+# Functions
+#
+
+def parse_stats_file(filename):
+ """pop the contents of a mountstats file into a dictionary,
+ keyed by mount point. each value object is a list of the
+ lines in the mountstats file corresponding to the mount
+ point named in the key.
+ """
+ ms_dict = dict()
+ key = ''
+
+ f = open(filename)
+ for line in f.readlines():
+ words = line.split()
+ if len(words) == 0:
+ continue
+ if line.startswith("no device mounted"):
+ continue
+ if words[0] == 'device':
+ key = words[4]
+ new = [ line.strip() ]
+ elif 'nfs' in words or 'nfs4' in words:
+ key = words[3]
+ new = [ line.strip() ]
+ else:
+ new += [ line.strip() ]
+ ms_dict[key] = new
+ f.close
+
+ return ms_dict
+
+def print_iostat_summary(old, new, devices, time, options):
+ stats = {}
+ diff_stats = {}
+ devicelist = []
+ if old:
+ # Trim device list to only include intersection of old and new data,
+ # this addresses umounts due to autofs mountpoints
+ for device in devices:
+ if "fstype autofs" not in str(old[device]):
+ devicelist.append(device)
+ else:
+ devicelist = devices
+
+ for device in devicelist:
+ stats[device] = DeviceData()
+ stats[device].parse_stats(new[device])
+ if old:
+ old_stats = DeviceData()
+ old_stats.parse_stats(old[device])
+ diff_stats[device] = stats[device].compare_iostats(old_stats)
+
+ if options.sort:
+ if old:
+ # We now have compared data and can print a comparison
+ # ordered by mountpoint ops per second
+ devicelist.sort(key=lambda x: diff_stats[x].ops(time), reverse=True)
+ else:
+ # First iteration, just sort by newly parsed ops/s
+ devicelist.sort(key=lambda x: stats[x].ops(time), reverse=True)
+
+ count = 1
+ for device in devicelist:
+ if old:
+ diff_stats[device].display_iostats(time, options.which)
+ else:
+ stats[device].display_iostats(time, options.which)
+
+ count += 1
+ if (count > options.list):
+ return
+
+
+def list_nfs_mounts(givenlist, mountstats):
+ """return a list of NFS mounts given a list to validate or
+ return a full list if the given list is empty -
+ may return an empty list if none found
+ """
+ devicelist = []
+ if len(givenlist) > 0:
+ for device in givenlist:
+ stats = DeviceData()
+ stats.parse_stats(mountstats[device])
+ if stats.is_nfs_mountpoint():
+ devicelist += [device]
+ else:
+ for device, descr in mountstats.items():
+ stats = DeviceData()
+ stats.parse_stats(descr)
+ if stats.is_nfs_mountpoint():
+ devicelist += [device]
+ return devicelist
+
+def iostat_command(name):
+ """iostat-like command for NFS mount points
+ """
+ mountstats = parse_stats_file('/proc/self/mountstats')
+ devices = []
+ origdevices = []
+ interval_seen = False
+ count_seen = False
+
+ mydescription= """
+Sample iostat-like program to display NFS client per-mount'
+statistics. The <interval> parameter specifies the amount of time in seconds
+between each report. The first report contains statistics for the time since
+each file system was mounted. Each subsequent report contains statistics
+collected during the interval since the previous report. If the <count>
+parameter is specified, the value of <count> determines the number of reports
+generated at <interval> seconds apart. If the interval parameter is specified
+without the <count> parameter, the command generates reports continuously.
+If one or more <mount point> names are specified, statistics for only these
+mount points will be displayed. Otherwise, all NFS mount points on the
+client are listed.
+"""
+ parser = OptionParser(
+ usage="usage: %prog [ <interval> [ <count> ] ] [ <options> ] [ <mount point> ]",
+ description=mydescription,
+ version='version %s' % Iostats_version)
+ parser.set_defaults(which=0, sort=False, list=sys.maxsize)
+
+ statgroup = OptionGroup(parser, "Statistics Options",
+ 'File I/O is displayed unless one of the following is specified:')
+ statgroup.add_option('-a', '--attr',
+ action="store_const",
+ dest="which",
+ const=1,
+ help='displays statistics related to the attribute cache')
+ statgroup.add_option('-d', '--dir',
+ action="store_const",
+ dest="which",
+ const=2,
+ help='displays statistics related to directory operations')
+ statgroup.add_option('-p', '--page',
+ action="store_const",
+ dest="which",
+ const=3,
+ help='displays statistics related to the page cache')
+ parser.add_option_group(statgroup)
+ displaygroup = OptionGroup(parser, "Display Options",
+ 'Options affecting display format:')
+ displaygroup.add_option('-s', '--sort',
+ action="store_true",
+ dest="sort",
+ help="Sort NFS mount points by ops/second")
+ displaygroup.add_option('-l','--list',
+ action="store",
+ type="int",
+ dest="list",
+ help="only print stats for first LIST mount points")
+ parser.add_option_group(displaygroup)
+
+ (options, args) = parser.parse_args(sys.argv)
+ for arg in args:
+
+ if arg == sys.argv[0]:
+ continue
+
+ if arg in mountstats:
+ origdevices += [arg]
+ elif not interval_seen:
+ try:
+ interval = int(arg)
+ except:
+ print('Illegal <interval> value %s' % arg)
+ return
+ if interval > 0:
+ interval_seen = True
+ else:
+ print('Illegal <interval> value %s' % arg)
+ return
+ elif not count_seen:
+ try:
+ count = int(arg)
+ except:
+ print('Ilegal <count> value %s' % arg)
+ return
+ if count > 0:
+ count_seen = True
+ else:
+ print('Illegal <count> value %s' % arg)
+ return
+
+ # make certain devices contains only NFS mount points
+ devices = list_nfs_mounts(origdevices, mountstats)
+ if len(devices) == 0:
+ print('No NFS mount points were found')
+ return
+
+
+ old_mountstats = None
+ sample_time = 0.0
+
+ if not interval_seen:
+ print_iostat_summary(old_mountstats, mountstats, devices, sample_time, options)
+ return
+
+ if count_seen:
+ while count != 0:
+ print_iostat_summary(old_mountstats, mountstats, devices, sample_time, options)
+ old_mountstats = mountstats
+ time.sleep(interval)
+ sample_time = interval
+ mountstats = parse_stats_file('/proc/self/mountstats')
+ # automount mountpoints add and drop, if automount is involved
+ # we need to recheck the devices list when reparsing
+ devices = list_nfs_mounts(origdevices,mountstats)
+ if len(devices) == 0:
+ print('No NFS mount points were found')
+ return
+ count -= 1
+ else:
+ while True:
+ print_iostat_summary(old_mountstats, mountstats, devices, sample_time, options)
+ old_mountstats = mountstats
+ time.sleep(interval)
+ sample_time = interval
+ mountstats = parse_stats_file('/proc/self/mountstats')
+ # automount mountpoints add and drop, if automount is involved
+ # we need to recheck the devices list when reparsing
+ devices = list_nfs_mounts(origdevices,mountstats)
+ if len(devices) == 0:
+ print('No NFS mount points were found')
+ return
+
+#
+# Main
+#
+prog = os.path.basename(sys.argv[0])
+
+try:
+ iostat_command(prog)
+except KeyboardInterrupt:
+ print('Caught ^C... exiting')
+ sys.exit(1)
+
+sys.exit(0)
diff --git a/tools/nfs-iostat/nfsiostat.man b/tools/nfs-iostat/nfsiostat.man
new file mode 100644
index 0000000..940c043
--- /dev/null
+++ b/tools/nfs-iostat/nfsiostat.man
@@ -0,0 +1,141 @@
+.\"
+.\" nfsiostat(8)
+.\"
+.TH nfsiostat 8 "15 Apr 2010"
+.SH NAME
+nfsiostat \- Emulate iostat for NFS mount points using /proc/self/mountstats
+.SH SYNOPSIS
+.BI "nfsiostat [[" <interval> "] [" <count> "]] [" <options> "]["<mount_point> "]
+.SH DESCRIPTION
+The
+.B nfsiostat
+command displays NFS client per-mount statisitics.
+.TP
+<interval>
+specifies the amount of time in seconds between each report.
+The first report contains statistics for the time since each file
+system was mounted. Each subsequent report contains statistics collected
+during the interval since the previous report.
+.TP
+<count>
+If the
+.I <count>
+parameter is
+specified, the value of
+.I <count>
+determines the number of reports generated at
+.I <interval>
+seconds apart. if the interval parameter is
+specified without the
+.I <count>
+parameter, the command generates reports continuously.
+.TP
+<options>
+Define below
+.TP
+<mount_point>
+If one or more
+.I <mount point>
+names are specified, statistics for only these mount points will
+be displayed. Otherwise, all NFS mount points on the client are listed.
+.TP
+The meaning of each column of \fBnfsiostat\fR's output is the following:
+.RS 8
+- \fBop/s\fR
+.RS
+This is the number of operations per second.
+.RS
+.RE
+.RE
+.RE
+.RS 8
+- \fBrpc bklog\fR
+.RS
+This is the length of the backlog queue.
+.RE
+.RE
+.RE
+.RS 8
+- \fBkB/s\fR
+.RS
+This is the number of kB written/read per second.
+.RE
+.RE
+.RE
+.RS 8
+- \fBkB/op\fR
+.RS
+This is the number of kB written/read per each operation.
+.RE
+.RE
+.RE
+.RS 8
+- \fBretrans\fR
+.RS
+This is the number of retransmissions.
+.RE
+.RE
+.RE
+.RS 8
+- \fBavg RTT (ms)\fR
+.RS
+This is the duration from the time that client's kernel sends the RPC request until the time it receives the reply.
+.RE
+.RE
+.RE
+.RS 8
+- \fBavg exe (ms)\fR
+.RS
+This is the duration from the time that NFS client does the RPC request to its kernel until the RPC request is completed, this includes the RTT time above.
+.RE
+.RE
+.RE
+.RS 8
+- \fBavg queue (ms)\fR
+.RS
+This is the duration from the time the NFS client created the RPC request task to the time the request is transmitted.
+.RE
+.RE
+.RE
+.RS 8
+- \fBerrors\fR
+.RS
+This is the number of operations that completed with an error status (status < 0). This count is only available on kernels with RPC iostats version 1.1 or above.
+.RS
+.RE
+.RE
+.RE
+.TP
+Note that if an interval is used as argument to \fBnfsiostat\fR, then the diffrence from previous interval will be displayed, otherwise the results will be from the time that the share was mounted.
+
+.SH OPTIONS
+.TP
+.B \-a " or " \-\-attr
+displays statistics related to the attribute cache
+.TP
+.B \-d " or " \-\-dir
+displays statistics related to directory operations
+.TP
+.B \-h " or " \-\-help
+shows help message and exit
+.TP
+.B \-l LIST or " \-\-list=LIST
+only print stats for first LIST mount points
+.TP
+.B \-p " or " \-\-page
+displays statistics related to the page cache
+.TP
+.B \-s " or " \-\-sort
+Sort NFS mount points by ops/second
+.TP
+.B \-\-version
+show program's version number and exit
+.SH FILES
+.TP
+.B /proc/self/mountstats
+.SH SEE ALSO
+.BR iostat (8),
+.BR mountstats (8),
+.BR nfsstat(8)
+.SH AUTHOR
+Chuck Lever <chuck.lever@oracle.com>
diff --git a/tools/nfsconf/Makefile.am b/tools/nfsconf/Makefile.am
new file mode 100644
index 0000000..b3c1495
--- /dev/null
+++ b/tools/nfsconf/Makefile.am
@@ -0,0 +1,11 @@
+## Process this file with automake to produce Makefile.in
+
+man8_MANS = nfsconf.man
+EXTRA_DIST = $(man8_MANS)
+
+sbin_PROGRAMS = nfsconf
+
+nfsconf_SOURCES = nfsconfcli.c
+nfsconf_LDADD = ../../support/nfs/libnfsconf.la
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/tools/nfsconf/Makefile.in b/tools/nfsconf/Makefile.in
new file mode 100644
index 0000000..aee89ea
--- /dev/null
+++ b/tools/nfsconf/Makefile.in
@@ -0,0 +1,807 @@
+# Makefile.in generated by automake 1.16.5 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+sbin_PROGRAMS = nfsconf$(EXEEXT)
+subdir = tools/nfsconf
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/aclocal/ax_gcc_func_attribute.m4 \
+ $(top_srcdir)/aclocal/bsdsignals.m4 \
+ $(top_srcdir)/aclocal/getrandom.m4 \
+ $(top_srcdir)/aclocal/ipv6.m4 \
+ $(top_srcdir)/aclocal/kerberos5.m4 \
+ $(top_srcdir)/aclocal/keyutils.m4 \
+ $(top_srcdir)/aclocal/libblkid.m4 \
+ $(top_srcdir)/aclocal/libcap.m4 \
+ $(top_srcdir)/aclocal/libevent.m4 \
+ $(top_srcdir)/aclocal/libpthread.m4 \
+ $(top_srcdir)/aclocal/libsqlite3.m4 \
+ $(top_srcdir)/aclocal/libtirpc.m4 \
+ $(top_srcdir)/aclocal/libxml2.m4 \
+ $(top_srcdir)/aclocal/nfs-utils.m4 \
+ $(top_srcdir)/aclocal/rpcsec_vers.m4 \
+ $(top_srcdir)/aclocal/tcp-wrappers.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/support/include/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"
+PROGRAMS = $(sbin_PROGRAMS)
+am_nfsconf_OBJECTS = nfsconfcli.$(OBJEXT)
+nfsconf_OBJECTS = $(am_nfsconf_OBJECTS)
+nfsconf_DEPENDENCIES = ../../support/nfs/libnfsconf.la
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/nfsconfcli.Po
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(nfsconf_SOURCES)
+DIST_SOURCES = $(nfsconf_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(man8_MANS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
+AM_CPPFLAGS = @AM_CPPFLAGS@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CXXFLAGS_FOR_BUILD = @CXXFLAGS_FOR_BUILD@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ETAGS = @ETAGS@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FILECMD = @FILECMD@
+GREP = @GREP@
+GSSAPI_CFLAGS = @GSSAPI_CFLAGS@
+GSSAPI_LIBS = @GSSAPI_LIBS@
+GSSD = @GSSD@
+GSSGLUE_CFLAGS = @GSSGLUE_CFLAGS@
+GSSGLUE_LIBS = @GSSGLUE_LIBS@
+GSSKRB_CFLAGS = @GSSKRB_CFLAGS@
+GSSKRB_LIBS = @GSSKRB_LIBS@
+HAVE_GETRANDOM = @HAVE_GETRANDOM@
+HAVE_LIBWRAP = @HAVE_LIBWRAP@
+HAVE_TCP_WRAPPER = @HAVE_TCP_WRAPPER@
+IDMAPD = @IDMAPD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+K5VERS = @K5VERS@
+KRBCFLAGS = @KRBCFLAGS@
+KRBDIR = @KRBDIR@
+KRBLDFLAGS = @KRBLDFLAGS@
+KRBLIBS = @KRBLIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@
+LIBBLKID = @LIBBLKID@
+LIBBSD = @LIBBSD@
+LIBCAP = @LIBCAP@
+LIBCRYPT = @LIBCRYPT@
+LIBEVENT = @LIBEVENT@
+LIBKEYUTILS = @LIBKEYUTILS@
+LIBMOUNT = @LIBMOUNT@
+LIBMOUNT_CFLAGS = @LIBMOUNT_CFLAGS@
+LIBMOUNT_LIBS = @LIBMOUNT_LIBS@
+LIBNSL = @LIBNSL@
+LIBOBJS = @LIBOBJS@
+LIBPTHREAD = @LIBPTHREAD@
+LIBS = @LIBS@
+LIBSOCKET = @LIBSOCKET@
+LIBSQLITE = @LIBSQLITE@
+LIBTIRPC = @LIBTIRPC@
+LIBTOOL = @LIBTOOL@
+LIBWRAP = @LIBWRAP@
+LIBXML2 = @LIBXML2@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_PLUGINS = @PATH_PLUGINS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
+RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
+RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SVCGSSD = @SVCGSSD@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+VERSION = @VERSION@
+XML2_CFLAGS = @XML2_CFLAGS@
+XML2_LIBS = @XML2_LIBS@
+_rpc_pipefsmount = @_rpc_pipefsmount@
+_statedir = @_statedir@
+_sysconfdir = @_sysconfdir@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
+enable_mountconfig = @enable_mountconfig@
+enable_nfsv4 = @enable_nfsv4@
+enable_nfsv41 = @enable_nfsv41@
+enable_svcgss = @enable_svcgss@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+kprefix = @kprefix@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+mountfile = @mountfile@
+nfsconfig = @nfsconfig@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+rpc_pipefsmount = @rpc_pipefsmount@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+startstatd = @startstatd@
+statdpath = @statdpath@
+statduser = @statduser@
+statedir = @statedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+unitdir = @unitdir@
+man8_MANS = nfsconf.man
+EXTRA_DIST = $(man8_MANS)
+nfsconf_SOURCES = nfsconfcli.c
+nfsconf_LDADD = ../../support/nfs/libnfsconf.la
+MAINTAINERCLEANFILES = Makefile.in
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tools/nfsconf/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu tools/nfsconf/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-sbinPROGRAMS: $(sbin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \
+ fi; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p \
+ || test -f $$p1 \
+ ; then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' \
+ -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-sbinPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' \
+ `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(sbindir)" && rm -f $$files
+
+clean-sbinPROGRAMS:
+ @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+nfsconf$(EXEEXT): $(nfsconf_OBJECTS) $(nfsconf_DEPENDENCIES) $(EXTRA_nfsconf_DEPENDENCIES)
+ @rm -f nfsconf$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(nfsconf_OBJECTS) $(nfsconf_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nfsconfcli.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(man8_MANS)
+ @$(NORMAL_INSTALL)
+ @list1='$(man8_MANS)'; \
+ list2=''; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list='$(man8_MANS)'; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(MANS)
+installdirs:
+ for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/nfsconfcli.Po
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-sbinPROGRAMS
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/nfsconfcli.Po
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-sbinPROGRAMS
+
+uninstall-man: uninstall-man8
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
+ clean-generic clean-libtool clean-sbinPROGRAMS cscopelist-am \
+ ctags ctags-am distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am install-sbinPROGRAMS \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \
+ uninstall-man uninstall-man8 uninstall-sbinPROGRAMS
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tools/nfsconf/nfsconf.man b/tools/nfsconf/nfsconf.man
new file mode 100644
index 0000000..d44e86f
--- /dev/null
+++ b/tools/nfsconf/nfsconf.man
@@ -0,0 +1,120 @@
+.\"
+.\" nfsconf(8)
+.\"
+.TH nfsconf 8 "2 May 2018"
+.SH NAME
+nfsconf \- Query various NFS configuration settings
+.SH SYNOPSIS
+.B nfsconf \-\-dump
+.RB [ \-v | \-\-verbose ]
+.RB [ \-f | \-\-file
+.IR infile.conf ]
+.RI [ outfile ]
+.P
+.B nfsconf \-\-entry
+.RB [ \-\-arg
+.IR subsection]
+.IR section
+.IR tag
+.P
+.B nfsconf \-\-get
+.RB [ \-v | \-\-verbose ]
+.RB [ \-f | \-\-file
+.IR infile.conf ]
+.RB [ \-a | \-\-arg
+.IR subsection ]
+.IR section
+.IR tag
+.P
+.B nfsconf \-\-isset
+.RB [ \-v | \-\-verbose ]
+.RB [ \-f | \-\-file
+.IR infile.conf ]
+.RB [ \-a | \-\-arg
+.IR subsection ]
+.IR section
+.IR tag
+.P
+.B nfsconf \-\-set
+.RB [ \-v | \-\-verbose ]
+.RB [ \-m | \-\-modified
+.IR "Modified by text" ]
+.RB [ \-f | \-\-file
+.IR infile.conf ]
+.RB [ \-a | \-\-arg
+.IR subsection ]
+.IR section
+.IR tag
+.IR value
+.P
+.B nfsconf \-\-unset
+.RB [ \-v | \-\-verbose ]
+.RB [ \-f | \-\-file
+.IR infile.conf ]
+.RB [ \-a | \-\-arg
+.IR subsection ]
+.IR section
+.IR tag
+.SH DESCRIPTION
+The
+.B nfsconf
+command can be used to test for and retrieve configuration settings
+from a range of nfs-utils configuration files.
+.SS Modes
+The following modes are available:
+.IP "\fB\-d, \-\-dump\fP"
+Output an alphabetically sorted dump of the current configuration in conf file format. Accepts an optional filename in which to write the output.
+.IP "\fB\-e, \-\-entry\fP"
+retrieve the config entry rather than its current expanded value
+.IP "\fB\-i, \-\-isset\fP"
+Test if a specific tag has a value set.
+.IP "\fB\-g, \-\-get\fP"
+Output the current value of the specified tag.
+.IP "\fB\-s, \-\-set\fP"
+Update or Add a tag and value to the config file in a specified section, creating the tag, section, and file if necessary. If the section is defined as '#' then a comment is appended to the file. If a comment is set with a tag name then any exiting tagged comment with a matching name is replaced.
+.IP "\fB\-u, \-\-unset\fP"
+Remove the specified tag and its value from the config file.
+.SH OPTIONS
+.SS Options valid in all modes
+.TP
+.B \-v, \-\-verbose
+Increase verbosity and print debugging information.
+.TP
+.B \-f, \-\-file \fIinfile\fR
+Select a different config file to operate upon, default is
+.I /etc/nfs.conf
+.SS Options only valid in \fB\-\-entry\fR and \fB\-\-get\fR and \fB\-\-isset\fR modes.
+.TP
+.B \-a, \-\-arg \fIsubsection\fR
+Select a specific sub-section
+.SS Options only valid in \fB\-\-set\fR mode.
+.B \-m, \-\-modified \fI"Modified by nfsconf"\fR
+Set the text on the Modified date comment in the file. Set to empty to remove.
+.SH EXIT STATUS
+.SS \fB\-\-isset\fR mode
+In this mode the command will return success (0) if the selected tag has a value, any other exit code indicates the value is not set, or some other error has occurred.
+.SS all other modes
+Success is indicated by an exit status of zero, any other status indicates an error. Error messages are output on stderr, and increasing verbosity will give more detailed explanations if any are available.
+.SH EXAMPLES
+.TP
+.B nfsconf -v --dump --file /tmp/testconf.conf sorted.conf
+Check a new config file for syntax errors and output a sorted version for ease of comparison with existing settings.
+.TP
+.B if ! nfsconf --isset gssd preferred-realm ; then echo 'No preferred realm configured for gss'; fi
+The tool allows for easy testing of configuration values from shell scripts, here we test if a specific value has been set.
+.TP
+.B nfsconf --file /etc/nfsmount.conf --get --arg /home MountPoint background
+Show default value for \fIbackground\fR option for NFS mounts of the \fI/home\fR path.
+.TP
+.B nfsconf --file /etc/nfs.conf --set nfsd debug 1
+Enable debugging in nfsd
+.SH FILES
+.TP
+.B /etc/nfs.conf
+.SH SEE ALSO
+.BR nfsd (8),
+.BR exportfs (8),
+.BR idmapd (8),
+.BR statd (8)
+.SH AUTHOR
+Justin Mitchell <jumitche@redhat.com>
diff --git a/tools/nfsconf/nfsconfcli.c b/tools/nfsconf/nfsconfcli.c
new file mode 100644
index 0000000..b2ef96d
--- /dev/null
+++ b/tools/nfsconf/nfsconfcli.c
@@ -0,0 +1,253 @@
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <getopt.h>
+#include <string.h>
+#include <errno.h>
+#include "config.h"
+#include "conffile.h"
+#include "xlog.h"
+
+typedef enum {
+ MODE_NONE,
+ MODE_GET,
+ MODE_ENTRY,
+ MODE_ISSET,
+ MODE_DUMP,
+ MODE_SET,
+ MODE_UNSET
+} confmode_t;
+
+static void usage(const char *name)
+{
+ fprintf(stderr, "Usage: %s [-v] [--file filename.conf] ...\n", name);
+ fprintf(stderr, "Options:\n");
+ fprintf(stderr, " -v Increase Verbosity\n");
+ fprintf(stderr, " --file filename.conf Load this config file\n");
+ fprintf(stderr, " (Default config file: " NFS_CONFFILE "\n");
+ fprintf(stderr, " --modified \"info\" Use \"info\" in file modified header\n");
+ fprintf(stderr, "Modes:\n");
+ fprintf(stderr, " --dump [outputfile]\n");
+ fprintf(stderr, " Outputs the configuration to the named file\n");
+ fprintf(stderr, " --get [--arg subsection] {section} {tag}\n");
+ fprintf(stderr, " Output one specific config value\n");
+ fprintf(stderr, " --entry [--arg subsection] {section} {tag}\n");
+ fprintf(stderr, " Output the uninterpreted config entry\n");
+ fprintf(stderr, " --isset [--arg subsection] {section} {tag}\n");
+ fprintf(stderr, " Return code indicates if config value is present\n");
+ fprintf(stderr, " --set [--arg subsection] {section} {tag} {value}\n");
+ fprintf(stderr, " Set and Write a config value\n");
+ fprintf(stderr, " --unset [--arg subsection] {section} {tag}\n");
+ fprintf(stderr, " Remove an existing config value\n");
+}
+
+int main(int argc, char **argv)
+{
+ char * confpath = NFS_CONFFILE;
+ char * arg = NULL;
+ int verbose=0;
+ int ret = 0;
+ char * dumpfile = NULL;
+
+ confmode_t mode = MODE_NONE;
+
+ modified_by = "Modified by nfsconf";
+
+ while (1) {
+ int c;
+ int index = 0;
+ struct option long_options[] = {
+ {"get", no_argument, 0, 'g' },
+ {"entry", no_argument, 0, 'e' },
+ {"set", no_argument, 0, 's' },
+ {"unset", no_argument, 0, 'u' },
+ {"arg", required_argument, 0, 'a' },
+ {"isset", no_argument, 0, 'i' },
+ {"dump", optional_argument, 0, 'd' },
+ {"file", required_argument, 0, 'f' },
+ {"verbose", no_argument, 0, 'v' },
+ {"modified", required_argument, 0, 'm' },
+ {NULL, 0, 0, 0 }
+ };
+
+ c = getopt_long(argc, argv, "gesua:id::f:vm:", long_options, &index);
+ if (c == -1) break;
+
+ switch (c) {
+ case 0:
+ break;
+ case 'f':
+ /* user specified source path for config */
+ confpath = optarg;
+ break;
+ case 'a':
+ /* user supplied a sub-section name */
+ arg = optarg;
+ break;
+ case 'v':
+ verbose++;
+ break;
+ case 'g':
+ mode = MODE_GET;
+ break;
+ case 'e':
+ mode = MODE_ENTRY;
+ break;
+ case 's':
+ mode = MODE_SET;
+ break;
+ case 'u':
+ mode = MODE_UNSET;
+ break;
+ case 'i':
+ mode = MODE_ISSET;
+ break;
+ case 'd':
+ /* check if user supplied a filename for dump */
+ if (optarg == NULL && argv[optind] != NULL
+ && argv[optind][0] != '-')
+ optarg = argv[optind++];
+ mode = MODE_DUMP;
+ dumpfile = optarg;
+ break;
+ case 'm':
+ if (optarg == NULL || *optarg == 0)
+ modified_by = NULL;
+ else
+ modified_by = optarg;
+ break;
+ default:
+ usage(argv[0]);
+ return 1;
+ }
+ }
+
+ /* configure the logging that conffile.c uses */
+ if (verbose)
+ xlog_config(D_ALL, 1);
+ xlog_stderr(1);
+ xlog_syslog(0);
+ xlog_open("nfsconf");
+
+ if (mode == MODE_NONE) {
+ fprintf(stderr, "Error: No MODE selected.\n");
+ usage(argv[0]);
+ return 1;
+ }
+
+ if (mode != MODE_SET && mode != MODE_UNSET) {
+ if (conf_init_file(confpath)) {
+ /* config file was missing or had an error, warn about it */
+ if (verbose || mode != MODE_ISSET) {
+ fprintf(stderr, "Error loading config file %s\n",
+ confpath);
+ }
+
+ /* this isnt fatal for --isset */
+ if (mode != MODE_ISSET)
+ return 1;
+ }
+ }
+
+ /* --dump mode, output the current configuration */
+ if (mode == MODE_DUMP) {
+ /* default to writing it to stdout */
+ FILE *out = stdout;
+
+ /* user specified a file to write to instead */
+ if (dumpfile) {
+ out = fopen(dumpfile, "w");
+ if (out == NULL) {
+ fprintf(stderr, "Error opening dumpfile %s: %s\n",
+ dumpfile, strerror(errno));
+ ret = 2;
+ goto cleanup;
+ }
+ if (verbose)
+ printf("Dumping config to %s\n", dumpfile);
+ }
+
+ /* output the configuration */
+ conf_report(out);
+
+ /* close that user specified file */
+ if (dumpfile)
+ fclose(out);
+ } else
+ /* --isset and --get share a lot of code */
+ if (mode == MODE_GET || mode == MODE_ISSET || mode == MODE_ENTRY) {
+ char * section = NULL;
+ char * tag = NULL;
+ const char * val;
+
+ /* test they supplied section and tag names */
+ if (optind+1 >= argc) {
+ fprintf(stderr, "Error: insufficient arguments for mode\n");
+ usage(argv[0]);
+ ret = 2;
+ goto cleanup;
+ }
+
+ /* now we have a section and tag name */
+ section = argv[optind++];
+ tag = argv[optind++];
+
+ /* retrieve the specified tags value */
+ if (mode == MODE_ENTRY)
+ val = conf_get_entry(section, arg, tag);
+ else
+ val = conf_get_section(section, arg, tag);
+ if (val != NULL) {
+ /* ret=0, success, mode --get wants to output the value as well */
+ if (mode != MODE_ISSET)
+ printf("%s\n", val);
+ } else {
+ /* ret=1, no value found, tell the user if they asked */
+ if (mode != MODE_ISSET && verbose)
+ fprintf(stderr, "Tag '%s' not found\n", tag);
+ ret = 1;
+ }
+ } else
+ if (mode == MODE_SET || mode == MODE_UNSET) {
+ char * section = NULL;
+ char * tag = NULL;
+ char * val = NULL;
+ int need = 2;
+
+ if (mode == MODE_UNSET)
+ need = 1;
+
+ /* test they supplied section and tag names */
+ if (optind+need >= argc) {
+ fprintf(stderr, "Error: insufficient arguments for mode\n");
+ usage(argv[0]);
+ ret = 2;
+ goto cleanup;
+ }
+
+ /* now we have a section and tag name */
+ section = argv[optind++];
+ tag = argv[optind++];
+ if (mode == MODE_SET)
+ val = argv[optind++];
+
+ /* setting an empty string is same as unsetting */
+ if (val!=NULL && *val == '\0') {
+ mode = MODE_UNSET;
+ val = NULL;
+ }
+
+ if (conf_write(confpath, section, arg, tag, val)) {
+ if (verbose)
+ fprintf(stderr, "Error writing config\n");
+ ret = 1;
+ }
+ } else {
+ fprintf(stderr, "Mode not yet implemented.\n");
+ ret = 2;
+ }
+
+cleanup:
+ conf_cleanup();
+ return ret;
+}
diff --git a/tools/nfsdclddb/Makefile.am b/tools/nfsdclddb/Makefile.am
new file mode 100644
index 0000000..18263fb
--- /dev/null
+++ b/tools/nfsdclddb/Makefile.am
@@ -0,0 +1,13 @@
+## Process this file with automake to produce Makefile.in
+PYTHON_FILES = nfsdclddb.py
+
+man8_MANS = nfsdclddb.man
+
+EXTRA_DIST = $(man8_MANS) $(PYTHON_FILES)
+
+all-local: $(PYTHON_FILES)
+
+install-data-hook:
+ $(INSTALL) -m 755 nfsdclddb.py $(DESTDIR)$(sbindir)/nfsdclddb
+
+MAINTAINERCLEANFILES=Makefile.in
diff --git a/tools/nfsdclddb/Makefile.in b/tools/nfsdclddb/Makefile.in
new file mode 100644
index 0000000..308178b
--- /dev/null
+++ b/tools/nfsdclddb/Makefile.in
@@ -0,0 +1,621 @@
+# Makefile.in generated by automake 1.16.5 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = tools/nfsdclddb
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/aclocal/ax_gcc_func_attribute.m4 \
+ $(top_srcdir)/aclocal/bsdsignals.m4 \
+ $(top_srcdir)/aclocal/getrandom.m4 \
+ $(top_srcdir)/aclocal/ipv6.m4 \
+ $(top_srcdir)/aclocal/kerberos5.m4 \
+ $(top_srcdir)/aclocal/keyutils.m4 \
+ $(top_srcdir)/aclocal/libblkid.m4 \
+ $(top_srcdir)/aclocal/libcap.m4 \
+ $(top_srcdir)/aclocal/libevent.m4 \
+ $(top_srcdir)/aclocal/libpthread.m4 \
+ $(top_srcdir)/aclocal/libsqlite3.m4 \
+ $(top_srcdir)/aclocal/libtirpc.m4 \
+ $(top_srcdir)/aclocal/libxml2.m4 \
+ $(top_srcdir)/aclocal/nfs-utils.m4 \
+ $(top_srcdir)/aclocal/rpcsec_vers.m4 \
+ $(top_srcdir)/aclocal/tcp-wrappers.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/support/include/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+man8dir = $(mandir)/man8
+am__installdirs = "$(DESTDIR)$(man8dir)"
+NROFF = nroff
+MANS = $(man8_MANS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
+AM_CPPFLAGS = @AM_CPPFLAGS@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CXXFLAGS_FOR_BUILD = @CXXFLAGS_FOR_BUILD@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ETAGS = @ETAGS@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FILECMD = @FILECMD@
+GREP = @GREP@
+GSSAPI_CFLAGS = @GSSAPI_CFLAGS@
+GSSAPI_LIBS = @GSSAPI_LIBS@
+GSSD = @GSSD@
+GSSGLUE_CFLAGS = @GSSGLUE_CFLAGS@
+GSSGLUE_LIBS = @GSSGLUE_LIBS@
+GSSKRB_CFLAGS = @GSSKRB_CFLAGS@
+GSSKRB_LIBS = @GSSKRB_LIBS@
+HAVE_GETRANDOM = @HAVE_GETRANDOM@
+HAVE_LIBWRAP = @HAVE_LIBWRAP@
+HAVE_TCP_WRAPPER = @HAVE_TCP_WRAPPER@
+IDMAPD = @IDMAPD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+K5VERS = @K5VERS@
+KRBCFLAGS = @KRBCFLAGS@
+KRBDIR = @KRBDIR@
+KRBLDFLAGS = @KRBLDFLAGS@
+KRBLIBS = @KRBLIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@
+LIBBLKID = @LIBBLKID@
+LIBBSD = @LIBBSD@
+LIBCAP = @LIBCAP@
+LIBCRYPT = @LIBCRYPT@
+LIBEVENT = @LIBEVENT@
+LIBKEYUTILS = @LIBKEYUTILS@
+LIBMOUNT = @LIBMOUNT@
+LIBMOUNT_CFLAGS = @LIBMOUNT_CFLAGS@
+LIBMOUNT_LIBS = @LIBMOUNT_LIBS@
+LIBNSL = @LIBNSL@
+LIBOBJS = @LIBOBJS@
+LIBPTHREAD = @LIBPTHREAD@
+LIBS = @LIBS@
+LIBSOCKET = @LIBSOCKET@
+LIBSQLITE = @LIBSQLITE@
+LIBTIRPC = @LIBTIRPC@
+LIBTOOL = @LIBTOOL@
+LIBWRAP = @LIBWRAP@
+LIBXML2 = @LIBXML2@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_PLUGINS = @PATH_PLUGINS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
+RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
+RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SVCGSSD = @SVCGSSD@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+VERSION = @VERSION@
+XML2_CFLAGS = @XML2_CFLAGS@
+XML2_LIBS = @XML2_LIBS@
+_rpc_pipefsmount = @_rpc_pipefsmount@
+_statedir = @_statedir@
+_sysconfdir = @_sysconfdir@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
+enable_mountconfig = @enable_mountconfig@
+enable_nfsv4 = @enable_nfsv4@
+enable_nfsv41 = @enable_nfsv41@
+enable_svcgss = @enable_svcgss@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+kprefix = @kprefix@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+mountfile = @mountfile@
+nfsconfig = @nfsconfig@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+rpc_pipefsmount = @rpc_pipefsmount@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+startstatd = @startstatd@
+statdpath = @statdpath@
+statduser = @statduser@
+statedir = @statedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+unitdir = @unitdir@
+PYTHON_FILES = nfsdclddb.py
+man8_MANS = nfsdclddb.man
+EXTRA_DIST = $(man8_MANS) $(PYTHON_FILES)
+MAINTAINERCLEANFILES = Makefile.in
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tools/nfsdclddb/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu tools/nfsdclddb/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(man8_MANS)
+ @$(NORMAL_INSTALL)
+ @list1='$(man8_MANS)'; \
+ list2=''; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list='$(man8_MANS)'; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(MANS) all-local
+installdirs:
+ for dir in "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-data-hook
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man
+
+uninstall-man: uninstall-man8
+
+.MAKE: install-am install-data-am install-strip
+
+.PHONY: all all-am all-local check check-am clean clean-generic \
+ clean-libtool cscopelist-am ctags-am distclean \
+ distclean-generic distclean-libtool distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-data-hook install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-man8 \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags-am uninstall uninstall-am uninstall-man uninstall-man8
+
+.PRECIOUS: Makefile
+
+
+all-local: $(PYTHON_FILES)
+
+install-data-hook:
+ $(INSTALL) -m 755 nfsdclddb.py $(DESTDIR)$(sbindir)/nfsdclddb
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tools/nfsdclddb/nfsdclddb.man b/tools/nfsdclddb/nfsdclddb.man
new file mode 100644
index 0000000..8ec7b18
--- /dev/null
+++ b/tools/nfsdclddb/nfsdclddb.man
@@ -0,0 +1,83 @@
+.\"
+.\" nfsdclddb(8)
+.\"
+.TH nfsdclddb 8 "07 Aug 2019"
+.SH NAME
+nfsdclddb \- Tool for manipulating the nfsdcld sqlite database
+.SH SYNOPSIS
+.B nfsdclddb
+.RB [ \-h | \-\-help ]
+.P
+.B nfsdclddb
+.RB [ \-p | \-\-path
+.IR dbpath ]
+.B fix-table-names
+.RB [ \-h | \-\-help ]
+.P
+.B nfsdclddb
+.RB [ \-p | \-\-path
+.IR dbpath ]
+.B downgrade-schema
+.RB [ \-h | \-\-help ]
+.RB [ \-v | \-\-version
+.IR to-version ]
+.P
+.B nfsdclddb
+.RB [ \-p | \-\-path
+.IR dbpath ]
+.B print
+.RB [ \-h | \-\-help ]
+.RB [ \-s | \-\-summary ]
+.P
+
+.SH DESCRIPTION
+.RB "The " nfsdclddb " command is provided to perform some manipulation of the nfsdcld sqlite database schema and to print the contents of the database."
+.SS Sub-commands
+Valid
+.B nfsdclddb
+subcommands are:
+.IP "\fBfix-table-names\fP"
+.RB "A previous version of " nfsdcld "(8) contained a bug that corrupted the reboot epoch table names. This sub-command will fix those table names."
+.IP "\fBdowngrade-schema\fP"
+Downgrade the database schema. Currently the schema can only to downgraded from version 4 to version 3.
+.IP "\fBprint\fP"
+Display the contents of the database. Prints the schema version and the values of the current and recovery epochs. If the
+.BR \-s | \-\-summary
+option is not given, also prints the clients in the reboot epoch tables.
+.SH OPTIONS
+.SS Options valid for all sub-commands
+.TP
+.B \-h, \-\-help
+Show the help message and exit
+.TP
+\fB\-p \fIdbpath\fR, \fB\-\-path \fIdbpath\fR
+Open the sqlite database located at
+.I dbpath
+instead of
+.IR /var/lib/nfs/nfsdcld/main.sqlite ". "
+This is mainly for testing purposes.
+.SS Options specific to the downgrade-schema sub-command
+.TP
+\fB\-v \fIto-version\fR, \fB\-\-version \fIto-version\fR
+The schema version to downgrade to. Currently the schema can only be downgraded to version 3.
+.SS Options specific to the print sub-command
+.TP
+.B \-s, \-\-summary
+Do not list the clients in the reboot epoch tables in the output.
+.SH NOTES
+The
+.B nfsdclddb
+command will not allow the
+.B fix-table-names
+or
+.B downgrade-schema
+subcommands to be used if
+.BR nfsdcld (8)
+is running.
+.SH FILES
+.TP
+.B /var/lib/nfs/nfsdcld/main.sqlite
+.SH SEE ALSO
+.BR nfsdcld (8)
+.SH AUTHOR
+Scott Mayhew <smayhew@redhat.com>
diff --git a/tools/nfsdclddb/nfsdclddb.py b/tools/nfsdclddb/nfsdclddb.py
new file mode 100644
index 0000000..8a66131
--- /dev/null
+++ b/tools/nfsdclddb/nfsdclddb.py
@@ -0,0 +1,266 @@
+#!/usr/bin/python3
+"""Tool for manipulating the nfsdcld sqlite database
+"""
+
+__copyright__ = """
+Copyright (C) 2019 Scott Mayhew <smayhew@redhat.com>
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+MA 02110-1301, USA.
+"""
+
+import argparse
+import os
+import sqlite3
+import sys
+
+
+class CldDb():
+ def __init__(self, path):
+ self.con = sqlite3.connect(path)
+ self.con.row_factory = sqlite3.Row
+ for row in self.con.execute('select value from parameters '
+ 'where key = "version"'):
+ self.version = int(row['value'])
+ for row in self.con.execute('select * from grace'):
+ self.current = int(row['current'])
+ self.recovery = int(row['recovery'])
+
+ def __del__(self):
+ self.con.close()
+
+ def __str__(self):
+ return ('Schema version: {self.version} '
+ 'current epoch: {self.current} '
+ 'recovery epoch: {self.recovery}'.format(self=self))
+
+ def _print_clients(self, epoch):
+ if epoch:
+ for row in self.con.execute('select * from "rec-{:016x}"'
+ .format(epoch)):
+ if self.version >= 4:
+ if row['princhash'] is not None:
+ princhash = row['princhash'].hex()
+ else:
+ princhash = "(null)"
+ print('id = {}, princhash = {}'
+ .format(row['id'].decode(), princhash))
+ else:
+ print('id = {}'.format(row['id'].decode()))
+
+ def print_current_clients(self):
+ print('Clients in current epoch:')
+ self._print_clients(self.current)
+
+ def print_recovery_clients(self):
+ if self.recovery:
+ print('Clients in recovery epoch:')
+ self._print_clients(self.recovery)
+
+ def check_bad_table_names(self):
+ bad_names = []
+ for row in self.con.execute('select name from sqlite_master '
+ 'where type = "table" '
+ 'and name like "%rec-%" '
+ 'and length(name) < 20'):
+ bad_names.append(row['name'])
+ return bad_names
+
+ def fix_bad_table_names(self):
+ try:
+ self.con.execute('begin exclusive transaction')
+ bad_names = self.check_bad_table_names()
+ for bad_name in bad_names:
+ epoch = int(bad_name.split('-')[1], base=16)
+ if epoch == self.current or epoch == self.recovery:
+ if epoch == self.current:
+ which = 'current'
+ else:
+ which = 'recovery'
+ print('found invalid table name {} for {} epoch'
+ .format(bad_name, which))
+ self.con.execute('alter table "{}" '
+ 'rename to "rec-{:016x}"'
+ .format(bad_name, epoch))
+ print('renamed to rec-{:016x}'.format(epoch))
+ else:
+ print('found invalid table name {} for unknown epoch {}'
+ .format(bad_name, epoch))
+ self.con.execute('drop table "{}"'.format(bad_name))
+ print('dropped table {}'.format(bad_name))
+ except sqlite3.Error:
+ self.con.rollback()
+ else:
+ self.con.commit()
+
+ def has_princ_data(self):
+ if self.version < 4:
+ return False
+ for row in self.con.execute('select count(*) '
+ 'from "rec-{:016x}" '
+ 'where princhash not null'
+ .format(self.current)):
+ count = row[0]
+ if self.recovery:
+ for row in self.con.execute('select count(*) '
+ 'from "rec-{:016x}" '
+ 'where princhash not null'
+ .format(self.current)):
+ count = count + row[0]
+ if count:
+ return True
+ return False
+
+ def _downgrade_table_v4_to_v3(self, epoch):
+ if not self.con.in_transaction:
+ raise sqlite3.Error
+ try:
+ self.con.execute('create table "new_rec-{:016x}" '
+ '(id blob primary key)'.format(epoch))
+ self.con.execute('insert into "new_rec-{:016x}" '
+ 'select id from "rec-{:016x}"'
+ .format(epoch, epoch))
+ self.con.execute('drop table "rec-{:016x}"'.format(epoch))
+ self.con.execute('alter table "new_rec-{:016x}" '
+ 'rename to "rec-{:016x}"'
+ .format(epoch, epoch))
+ except sqlite3.Error:
+ raise
+
+ def downgrade_schema_v4_to_v3(self):
+ try:
+ self.con.execute('begin exclusive transaction')
+ for row in self.con.execute('select value from parameters '
+ 'where key = "version"'):
+ version = int(row['value'])
+ if version != self.version:
+ raise sqlite3.Error
+ for row in self.con.execute('select * from grace'):
+ current = int(row['current'])
+ recovery = int(row['recovery'])
+ if current != self.current:
+ raise sqlite3.Error
+ if recovery != self.recovery:
+ raise sqlite3.Error
+ self._downgrade_table_v4_to_v3(current)
+ if recovery:
+ self._downgrade_table_v4_to_v3(recovery)
+ self.con.execute('update parameters '
+ 'set value = "3" '
+ 'where key = "version"')
+ self.version = 3
+ except sqlite3.Error:
+ self.con.rollback()
+ print('Downgrade failed')
+ else:
+ self.con.commit()
+ print('Downgrade successful')
+
+
+def nfsdcld_active():
+ rc = os.system('ps -C nfsdcld >/dev/null 2>/dev/null')
+ if rc == 0:
+ return True
+ return False
+
+
+def fix_table_names_command(db, args):
+ if nfsdcld_active():
+ print('Warning: nfsdcld is running!')
+ ans = input('Continue? ')
+ if ans.lower() not in ['y', 'yes']:
+ print('Operation canceled.')
+ return
+ bad_names = db.check_bad_table_names()
+ if not bad_names:
+ print('No invalid table names found.')
+ return
+ db.fix_bad_table_names()
+
+
+def downgrade_schema_command(db, args):
+ if nfsdcld_active():
+ print('Warning: nfsdcld is running!')
+ ans = input('Continue? ')
+ if ans.lower() not in ['y', 'yes']:
+ print('Operation canceled')
+ return
+ if db.version != 4:
+ print('Cannot downgrade database from schema version {}.'
+ .format(db.version))
+ return
+ if args.version != 3:
+ print('Cannot downgrade to version {}.'.format(args.version))
+ return
+ bad_names = db.check_bad_table_names()
+ if bad_names:
+ print('Invalid table names detected.')
+ print('Please run "{} fix-table-names" before downgrading the schema.'
+ .format(sys.argv[0]))
+ return
+ if db.has_princ_data():
+ print('Warning: database has principal data, which will be erased.')
+ ans = input('Continue? ')
+ if ans.lower() not in ['y', 'yes']:
+ print('Operation canceled')
+ return
+ db.downgrade_schema_v4_to_v3()
+
+
+def print_command(db, args):
+ print(str(db))
+ if not args.summary:
+ bad_names = db.check_bad_table_names()
+ if bad_names:
+ print('Invalid table names detected.')
+ print('Please run "{} fix-table-names".'.format(sys.argv[0]))
+ return
+ db.print_current_clients()
+ db.print_recovery_clients()
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('-p', '--path',
+ default='/var/lib/nfs/nfsdcld/main.sqlite',
+ help='path to the database '
+ '(default: /var/lib/nfs/nfsdcld/main.sqlite)')
+ subparsers = parser.add_subparsers(help='sub-command help')
+ fix_parser = subparsers.add_parser('fix-table-names',
+ help='fix invalid table names')
+ fix_parser.set_defaults(func=fix_table_names_command)
+ downgrade_parser = subparsers.add_parser('downgrade-schema',
+ help='downgrade database schema')
+ downgrade_parser.add_argument('-v', '--version', type=int, choices=[3],
+ default=3,
+ help='version to downgrade to')
+ downgrade_parser.set_defaults(func=downgrade_schema_command)
+ print_parser = subparsers.add_parser('print',
+ help='print database info')
+ print_parser.add_argument('-s', '--summary', default=False,
+ action='store_true',
+ help='print summary only')
+ print_parser.set_defaults(func=print_command)
+ args = parser.parse_args()
+ if not os.path.exists(args.path):
+ return parser.print_usage()
+ clddb = CldDb(args.path)
+ return args.func(clddb, args)
+
+
+if __name__ == '__main__':
+ if len(sys.argv) == 1:
+ sys.argv.extend(['print', '--summary'])
+ main()
diff --git a/tools/nfsdclnts/Makefile.am b/tools/nfsdclnts/Makefile.am
new file mode 100644
index 0000000..d513edb
--- /dev/null
+++ b/tools/nfsdclnts/Makefile.am
@@ -0,0 +1,13 @@
+## Process this file with automake to produce Makefile.in
+PYTHON_FILES = nfsdclnts.py
+
+man8_MANS = nfsdclnts.man
+
+EXTRA_DIST = $(man8_MANS) $(PYTHON_FILES)
+
+all-local: $(PYTHON_FILES)
+
+install-data-hook:
+ $(INSTALL) -m 755 nfsdclnts.py $(DESTDIR)$(sbindir)/nfsdclnts
+
+MAINTAINERCLEANFILES=Makefile.in
diff --git a/tools/nfsdclnts/Makefile.in b/tools/nfsdclnts/Makefile.in
new file mode 100644
index 0000000..f0b3463
--- /dev/null
+++ b/tools/nfsdclnts/Makefile.in
@@ -0,0 +1,621 @@
+# Makefile.in generated by automake 1.16.5 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = tools/nfsdclnts
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/aclocal/ax_gcc_func_attribute.m4 \
+ $(top_srcdir)/aclocal/bsdsignals.m4 \
+ $(top_srcdir)/aclocal/getrandom.m4 \
+ $(top_srcdir)/aclocal/ipv6.m4 \
+ $(top_srcdir)/aclocal/kerberos5.m4 \
+ $(top_srcdir)/aclocal/keyutils.m4 \
+ $(top_srcdir)/aclocal/libblkid.m4 \
+ $(top_srcdir)/aclocal/libcap.m4 \
+ $(top_srcdir)/aclocal/libevent.m4 \
+ $(top_srcdir)/aclocal/libpthread.m4 \
+ $(top_srcdir)/aclocal/libsqlite3.m4 \
+ $(top_srcdir)/aclocal/libtirpc.m4 \
+ $(top_srcdir)/aclocal/libxml2.m4 \
+ $(top_srcdir)/aclocal/nfs-utils.m4 \
+ $(top_srcdir)/aclocal/rpcsec_vers.m4 \
+ $(top_srcdir)/aclocal/tcp-wrappers.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/support/include/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+man8dir = $(mandir)/man8
+am__installdirs = "$(DESTDIR)$(man8dir)"
+NROFF = nroff
+MANS = $(man8_MANS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
+AM_CPPFLAGS = @AM_CPPFLAGS@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CXXFLAGS_FOR_BUILD = @CXXFLAGS_FOR_BUILD@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ETAGS = @ETAGS@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FILECMD = @FILECMD@
+GREP = @GREP@
+GSSAPI_CFLAGS = @GSSAPI_CFLAGS@
+GSSAPI_LIBS = @GSSAPI_LIBS@
+GSSD = @GSSD@
+GSSGLUE_CFLAGS = @GSSGLUE_CFLAGS@
+GSSGLUE_LIBS = @GSSGLUE_LIBS@
+GSSKRB_CFLAGS = @GSSKRB_CFLAGS@
+GSSKRB_LIBS = @GSSKRB_LIBS@
+HAVE_GETRANDOM = @HAVE_GETRANDOM@
+HAVE_LIBWRAP = @HAVE_LIBWRAP@
+HAVE_TCP_WRAPPER = @HAVE_TCP_WRAPPER@
+IDMAPD = @IDMAPD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+K5VERS = @K5VERS@
+KRBCFLAGS = @KRBCFLAGS@
+KRBDIR = @KRBDIR@
+KRBLDFLAGS = @KRBLDFLAGS@
+KRBLIBS = @KRBLIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@
+LIBBLKID = @LIBBLKID@
+LIBBSD = @LIBBSD@
+LIBCAP = @LIBCAP@
+LIBCRYPT = @LIBCRYPT@
+LIBEVENT = @LIBEVENT@
+LIBKEYUTILS = @LIBKEYUTILS@
+LIBMOUNT = @LIBMOUNT@
+LIBMOUNT_CFLAGS = @LIBMOUNT_CFLAGS@
+LIBMOUNT_LIBS = @LIBMOUNT_LIBS@
+LIBNSL = @LIBNSL@
+LIBOBJS = @LIBOBJS@
+LIBPTHREAD = @LIBPTHREAD@
+LIBS = @LIBS@
+LIBSOCKET = @LIBSOCKET@
+LIBSQLITE = @LIBSQLITE@
+LIBTIRPC = @LIBTIRPC@
+LIBTOOL = @LIBTOOL@
+LIBWRAP = @LIBWRAP@
+LIBXML2 = @LIBXML2@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_PLUGINS = @PATH_PLUGINS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
+RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
+RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SVCGSSD = @SVCGSSD@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+VERSION = @VERSION@
+XML2_CFLAGS = @XML2_CFLAGS@
+XML2_LIBS = @XML2_LIBS@
+_rpc_pipefsmount = @_rpc_pipefsmount@
+_statedir = @_statedir@
+_sysconfdir = @_sysconfdir@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
+enable_mountconfig = @enable_mountconfig@
+enable_nfsv4 = @enable_nfsv4@
+enable_nfsv41 = @enable_nfsv41@
+enable_svcgss = @enable_svcgss@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+kprefix = @kprefix@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+mountfile = @mountfile@
+nfsconfig = @nfsconfig@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+rpc_pipefsmount = @rpc_pipefsmount@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+startstatd = @startstatd@
+statdpath = @statdpath@
+statduser = @statduser@
+statedir = @statedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+unitdir = @unitdir@
+PYTHON_FILES = nfsdclnts.py
+man8_MANS = nfsdclnts.man
+EXTRA_DIST = $(man8_MANS) $(PYTHON_FILES)
+MAINTAINERCLEANFILES = Makefile.in
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tools/nfsdclnts/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu tools/nfsdclnts/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(man8_MANS)
+ @$(NORMAL_INSTALL)
+ @list1='$(man8_MANS)'; \
+ list2=''; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list='$(man8_MANS)'; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(MANS) all-local
+installdirs:
+ for dir in "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-data-hook
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man
+
+uninstall-man: uninstall-man8
+
+.MAKE: install-am install-data-am install-strip
+
+.PHONY: all all-am all-local check check-am clean clean-generic \
+ clean-libtool cscopelist-am ctags-am distclean \
+ distclean-generic distclean-libtool distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-data-hook install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-man8 \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags-am uninstall uninstall-am uninstall-man uninstall-man8
+
+.PRECIOUS: Makefile
+
+
+all-local: $(PYTHON_FILES)
+
+install-data-hook:
+ $(INSTALL) -m 755 nfsdclnts.py $(DESTDIR)$(sbindir)/nfsdclnts
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tools/nfsdclnts/nfsdclnts.man b/tools/nfsdclnts/nfsdclnts.man
new file mode 100644
index 0000000..c7efbd7
--- /dev/null
+++ b/tools/nfsdclnts/nfsdclnts.man
@@ -0,0 +1,180 @@
+.\"
+.\" nfsdclnts(8)
+.\"
+.TH "NFSDCLTS" "8" "2020-05-09" "nfsdclnts" "nfsdclnts"
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.ss \n[.ss] 0
+.nh
+.ad l
+.de URL
+\fI\\$2\fP <\\$1>\\$3
+..
+.als MTO URL
+.if \n[.g] \{\
+. mso www.tmac
+. am URL
+. ad l
+. .
+. am MTO
+. ad l
+. .
+. LINKSTYLE blue R < >
+.\}
+.SH "NAME"
+nfsdclnts \- print various nfs client information for knfsd server.
+.SH "SYNOPSIS"
+.sp
+\fBnfsdclnts\fP [\fI\-h\fP] [\fI\-t type\fP] [\fI\-\-clientinfo\fP] [\fI\-\-hostname\fP] [\fI\-q\fP]
+.SH "DESCRIPTION"
+.sp
+The nfsdclnts(8) command parses the content present in /proc/fs/nfsd/clients/ directories. nfsdclnts(8) displays files which are open, locked, delegated by the nfs\-client. It also prints useful client information such as hostname, clientID, NFS version mounted by the nfs\-client.
+.SH "OPTIONS"
+.sp
+\fB\-t, \-\-type\fP=TYPE
+.RS 4
+Specify the type of file to be displayed. Takes only one TYPE at a time.
+.sp
+\fIopen\fP, \fIlock\fP, \fIdeleg\fP, \fIlayout\fP, or \fIall\fP
+.sp
+open: displays the open files by nfs\-client(s).
+.sp
+lock: displays the files locked by nfs\-client(s).
+.sp
+layout: displays the files for which layout is given.
+.sp
+deleg: displays delegated files information and delegation type.
+.sp
+all: prints all the above type.
+.RE
+.sp
+\fB\-\-clientinfo\fP
+.RS 4
+displays various nfs\-client info fields such as version of nfs mounted at nfs\-client and clientID.
+.RE
+.sp
+\fB\-\-hostname\fP
+.RS 4
+Print hostname of nfs\-client instead of ip-address.
+.RE
+.sp
+\fB\-q, \-\-quiet\fP
+.RS 4
+Hide the header information.
+.RE
+.sp
+\fB\-v, \-\-verbose\fP
+.RS 4
+Verbose operation, show debug messages.
+.RE
+.sp
+\fB\-f, \-\-file\fP
+.RS 4
+Instead of processing all client directories under /proc/fs/nfsd/clients, one can provide a specific
+states file to process. One should make sure that info file resides in the same directory as states file.
+If the info file is not valid or present the fields would be marked as "N/A".
+.RE
+.sp
+\fB\-h, \-\-help\fP
+.RS 4
+Print help explaining the command line options.
+.SH "EXAMPLES"
+.sp
+\fBnfsdclnts \-\-type open\fP
+.RS 4
+List all files with open type only.
+.RE
+.sp
+.if n .RS 4
+.nf
+Inode number | Type | Access | Deny | ip address | Filename
+33823232 | open | r\- | \-\- | [::1]:757 | testfile
+.fi
+.if n .RE
+.sp
+\fBnfsdclnts \-\-type deleg\fP
+.RS 4
+List all files with deleg type only.
+.RE
+.sp
+.if n .RS 4
+.nf
+Inode number | Type | Access | ip address | Filename
+33823232 | deleg | r | [::1]:757 | testfile
+.fi
+.if n .RE
+.sp
+\fBnfsdclnts \-\-hostname\fP
+.RS 4
+Print hostname instead of ip\-address.
+.RE
+.sp
+.if n .RS 4
+.nf
+Inode number | Type | Access | Deny | Hostname | Filename
+33823232 | open | r\- | \-\- | nfs\-server | testfile
+33823232 | deleg | r | | nfs\-server | testfile
+.fi
+.if n .RE
+.sp
+\fBnfsdclnts \-\-clientinfo\fP
+.RS 4
+Print client information.
+.RE
+.sp
+.if n .RS 4
+.nf
+Inode number | Type | Access | Deny | ip address | Client ID | vers | Filename
+33823232 | open | r\- | \-\- | [::1]:757 | 0xc79a009f5eb65e84 | 4.2 | testfile
+33823232 | deleg | r | | [::1]:757 | 0xc79a009f5eb65e84 | 4.2 | testfile
+.fi
+.if n .RE
+.sp
+\fBnfsdclnts \-\-file /proc/fs/nfsd/clients/3/states -t open\fP
+.RS 4
+Process specific states file.
+.RE
+.sp
+.if n .RS 4
+.nf
+Inode number | Type | Access | Deny | ip address | Client ID | vers | Filename
+33823232 | open | r\- | \-\- | [::1]:757 | 0xc79a009f5eb65e84 | 4.2 | testfile
+.fi
+.if n .RE
+.sp
+\fBnfsdclnts \-\-quiet \-\-hostname\fP
+.RS 4
+Hide the header information.
+.RE
+.sp
+.if n .RS 4
+.nf
+33823232 | open | r\- | \-\- | nfs\-server | testfile
+33823232 | deleg | r | | nfs\-server | testfile
+.fi
+.if n .RE
+.SH "FILES"
+.sp
+\fB/proc/fs/nfsd/clients/\fP
+.sp
+Displays basic information about each NFSv4 client.
+.sp
+\fB/proc/fs/nfsd/clients/#/info\fP
+.sp
+Displays information about all the opens held by the given client, including open modes, device numbers, inode numbers, and open owners.
+.sp
+\fB/proc/fs/nfsd/clients/#/states\fP
+.SH "NOTES"
+.sp
+/proc/fs/nfsd/clients/ support was initially introduced in 5.3 kernel and is only implemented for mount points using NFSv4.
+.SH "BUGS"
+Please report any BUGs to \c
+.MTO "linux\-nfs\(atvger.kernel.org" "" ""
+.SH SEE ALSO
+.BR nfsd (8),
+.BR exportfs (8),
+.BR idmapd (8),
+.BR statd (8)
+.SH "AUTHORS"
+Achilles Gaikwad <agaikwad@redhat.com> and
+Kenneth D'souza <kdsouza@redhat.com>
diff --git a/tools/nfsdclnts/nfsdclnts.py b/tools/nfsdclnts/nfsdclnts.py
new file mode 100755
index 0000000..b7280f2
--- /dev/null
+++ b/tools/nfsdclnts/nfsdclnts.py
@@ -0,0 +1,255 @@
+#!/usr/bin/python3
+# -*- python-mode -*-
+'''
+ Copyright (C) 2020
+ Authors: Achilles Gaikwad <agaikwad@redhat.com>
+ Kenneth D'souza <kdsouza@redhat.com>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+'''
+
+import multiprocessing as mp
+import os
+import signal
+import sys
+
+try:
+ import argparse
+except ImportError:
+ print('%s: Failed to import argparse - make sure argparse is installed!'
+ % sys.argv[0])
+ sys.exit(1)
+try:
+ import yaml
+except ImportError:
+ print('%s: Failed to import yaml - make sure python3-pyyaml is installed!'
+ % sys.argv[0])
+ sys.exit(1)
+
+BBOLD = '\033[1;30;47m' #Bold black text with white background.
+ENDC = '\033[m' #Rest to defaults
+
+def init_worker():
+ signal.signal(signal.SIGINT, signal.SIG_IGN)
+
+# this function converts the info file to a dictionary format, sorta.
+def file_to_dict(path):
+ client_info = {}
+ try:
+ with open(path) as f:
+ for line in f:
+ try:
+ (key, val) = line.split(':', 1)
+ client_info[key] = val.strip()
+ # FIXME: There has to be a better way of converting the info file to a dictionary.
+ except ValueError as reason:
+ if verbose:
+ print('Exception occured, %s' % reason)
+
+ if len(client_info) == 0 and verbose:
+ print("Provided %s file is not valid" %path)
+ return client_info
+
+ except OSError as reason:
+ if verbose:
+ print('%s' % reason)
+
+# this function gets the paths from /proc/fs/nfsd/clients/
+# returns a list of paths for each client which has nfs-share mounted.
+def getpaths():
+ path = []
+ try:
+ dirs = os.listdir('/proc/fs/nfsd/clients/')
+ except OSError as reason:
+ exit('%s' % reason)
+ if len(dirs) !=0:
+ for i in dirs:
+ path.append('/proc/fs/nfsd/clients/' + i + '/states')
+ return (path)
+ else:
+ exit('Nothing to process')
+
+# A single function to rule them all, in this function we gather all the data
+# from already populated data_list and client_info.
+def printer(data_list, argument):
+ client_info_path = data_list.pop()
+ client_info = file_to_dict(client_info_path)
+ for i in data_list:
+ for key in i:
+ inode = i[key]['superblock'].split(':')[-1]
+ # The ip address is quoted, so we dequote it.
+ try:
+ client_ip = client_info['address'][1:-1]
+ except:
+ client_ip = "N/A"
+ try:
+ # if the nfs-server reboots while the nfs-client holds the files open,
+ # the nfs-server would print the filename as '/'. For such instaces we
+ # print the output as disconnected dentry instead of '/'.
+ if(i[key]['filename']=='/'):
+ fname = 'disconnected dentry'
+ else:
+ fname = i[key]['filename'].split('/')[-1]
+ except KeyError:
+ # for older kernels which do not have the fname patch in kernel, they
+ # won't be able to see the fname field. Therefore post it as N/A.
+ fname = "N/A"
+ otype = i[key]['type']
+ try:
+ access = i[key]['access']
+ except:
+ access = ''
+ try:
+ deny = i[key]['deny']
+ except:
+ deny = ''
+ try:
+ hostname = client_info['name'].split()[-1].split('"')[0]
+ hostname = hostname.split('.')[0]
+ # if the hostname is too long, it messes up with the output being in columns,
+ # therefore we truncate the hostname followed by two '..' as suffix.
+ if len(hostname) > 20:
+ hostname = hostname[0:20] + '..'
+ except:
+ hostname = "N/A"
+ try:
+ clientid = client_info['clientid']
+ except:
+ clientid = "N/A"
+ try:
+ minorversion = "4." + client_info['minor version']
+ except:
+ minorversion = "N/A"
+
+ otype = i[key]['type']
+ # since some fields do not have deny column, we drop those if -t is either
+ # layout or lock.
+ drop = ['layout', 'lock']
+
+ # Printing the output this way instead of a single string which is concatenated
+ # this makes it better to quickly add more columns in future.
+ if(otype == argument.type or argument.type == 'all'):
+ print('%-13s' %inode, end='| ')
+ print('%-7s' %otype, end='| ')
+ if (argument.type not in drop):
+ print('%-7s' %access, end='| ')
+ if (argument.type not in drop and argument.type !='deleg'):
+ print('%-5s' %deny, end='| ')
+ if (argument.hostname == True):
+ print('%-22s' %hostname, end='| ')
+ else:
+ print('%-22s' %client_ip, end='| ')
+ if (argument.clientinfo == True) :
+ print('%-20s' %clientid, end='| ')
+ print('%-5s' %minorversion, end='| ')
+ print(fname)
+
+def opener(path):
+ try:
+ with open(path, 'r') as nfsdata:
+ try:
+ data = yaml.load(nfsdata, Loader = yaml.BaseLoader)
+ if data is not None:
+ clientinfo = path.rsplit('/', 1)[0] + '/info'
+ data.append(clientinfo)
+ return data
+ except:
+ if verbose:
+ print("Exception occurred, Please make sure %s is a YAML file" %path)
+
+ except OSError as reason:
+ if verbose:
+ print('%s' % reason)
+
+def print_cols(argument):
+ title_inode = 'Inode number'
+ title_otype = 'Type'
+ title_access = 'Access'
+ title_deny = 'Deny'
+ title_fname = 'Filename'
+ title_clientID = 'Client ID'
+ title_hostname = 'Hostname'
+ title_ip = 'ip address'
+ title_nfsvers = 'vers'
+
+ drop = ['lock', 'layout']
+ print(BBOLD, end='')
+ print('%-13s' %title_inode, end='| ')
+ print('%-7s' %title_otype, end='| ')
+ if (argument.type not in drop):
+ print('%-7s' %title_access, end='| ')
+ if (argument.type not in drop and argument.type !='deleg'):
+ print('%-5s' %title_deny, end='| ')
+ if (argument.hostname == True):
+ print('%-22s' %title_hostname, end='| ')
+ else:
+ print('%-22s' %title_ip, end='| ')
+ if (argument.clientinfo == True):
+ print('%-20s' %title_clientID, end='| ')
+ print('%-5s' %title_nfsvers, end='| ')
+ print(title_fname, end='')
+ print(ENDC)
+
+def nfsd4_show():
+
+ parser = argparse.ArgumentParser(description = 'Parse the nfsd states and clientinfo files.')
+ parser.add_argument('-t', '--type', metavar = 'type', type = str, choices = ['open',
+ 'deleg', 'lock', 'layout', 'all'],
+ default = 'all',
+ help = 'Input the type that you want to be printed: open, lock, deleg, layout, all')
+ parser.add_argument('--clientinfo', action = 'store_true',
+ help = 'output clients information, --hostname is implied.')
+ parser.add_argument('--hostname', action = 'store_true',
+ help = 'print hostname of client instead of its ip address. Longer hostnames are truncated.')
+ parser.add_argument('-v', '--verbose', action = 'store_true',
+ help = 'Verbose operation, show debug messages.')
+ parser.add_argument('-f', '--file', nargs='+', type = str, metavar='',
+ help = 'pass client states file, provided that info file resides in the same directory.')
+ parser.add_argument('-q', '--quiet', action = 'store_true',
+ help = 'don\'t print the header information')
+
+ args = parser.parse_args()
+
+ global verbose
+ verbose = False
+ signal.signal(signal.SIGPIPE, signal.SIG_DFL)
+ if args.verbose:
+ verbose = True
+
+ if args.file:
+ paths = args.file
+ else:
+ paths = getpaths()
+
+ p = mp.Pool(mp.cpu_count(), init_worker)
+ try:
+ result = p.map(opener, paths)
+ ### Drop None entries from list
+ final_result = list(filter(None, result))
+ p.close()
+ p.join()
+
+ if len(final_result) !=0 and not args.quiet:
+ print_cols(args)
+
+ for item in final_result:
+ printer(item, args)
+
+ except KeyboardInterrupt:
+ print('Caught KeyboardInterrupt, terminating workers')
+ p.terminate()
+ p.join()
+
+if __name__ == "__main__":
+ nfsd4_show()
diff --git a/tools/nfsrahead/99-nfs.rules b/tools/nfsrahead/99-nfs.rules
new file mode 100644
index 0000000..c74914b
--- /dev/null
+++ b/tools/nfsrahead/99-nfs.rules
@@ -0,0 +1 @@
+SUBSYSTEM=="bdi", ACTION=="add", PROGRAM="/usr/libexec/nfsrahead %k", ATTR{read_ahead_kb}="%c"
diff --git a/tools/nfsrahead/99-nfs.rules.in b/tools/nfsrahead/99-nfs.rules.in
new file mode 100644
index 0000000..648813c
--- /dev/null
+++ b/tools/nfsrahead/99-nfs.rules.in
@@ -0,0 +1 @@
+SUBSYSTEM=="bdi", ACTION=="add", PROGRAM="_libexecdir_/nfsrahead %k", ATTR{read_ahead_kb}="%c"
diff --git a/tools/nfsrahead/Makefile.am b/tools/nfsrahead/Makefile.am
new file mode 100644
index 0000000..7e08233
--- /dev/null
+++ b/tools/nfsrahead/Makefile.am
@@ -0,0 +1,16 @@
+libexec_PROGRAMS = nfsrahead
+nfsrahead_SOURCES = main.c
+nfsrahead_LDFLAGS= $(LIBMOUNT_LIBS)
+nfsrahead_LDADD = ../../support/nfs/libnfsconf.la
+
+man5_MANS = nfsrahead.man
+EXTRA_DIST = $(man5_MANS)
+
+udev_rulesdir = /usr/lib/udev/rules.d/
+udev_rules_DATA = 99-nfs.rules
+
+99-nfs.rules: 99-nfs.rules.in $(builddefs)
+ $(SED) "s|_libexecdir_|@libexecdir@|g" 99-nfs.rules.in > $@
+
+clean-local:
+ $(RM) 99-nfs.rules
diff --git a/tools/nfsrahead/Makefile.in b/tools/nfsrahead/Makefile.in
new file mode 100644
index 0000000..41d8159
--- /dev/null
+++ b/tools/nfsrahead/Makefile.in
@@ -0,0 +1,843 @@
+# Makefile.in generated by automake 1.16.5 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+libexec_PROGRAMS = nfsrahead$(EXEEXT)
+subdir = tools/nfsrahead
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/aclocal/ax_gcc_func_attribute.m4 \
+ $(top_srcdir)/aclocal/bsdsignals.m4 \
+ $(top_srcdir)/aclocal/getrandom.m4 \
+ $(top_srcdir)/aclocal/ipv6.m4 \
+ $(top_srcdir)/aclocal/kerberos5.m4 \
+ $(top_srcdir)/aclocal/keyutils.m4 \
+ $(top_srcdir)/aclocal/libblkid.m4 \
+ $(top_srcdir)/aclocal/libcap.m4 \
+ $(top_srcdir)/aclocal/libevent.m4 \
+ $(top_srcdir)/aclocal/libpthread.m4 \
+ $(top_srcdir)/aclocal/libsqlite3.m4 \
+ $(top_srcdir)/aclocal/libtirpc.m4 \
+ $(top_srcdir)/aclocal/libxml2.m4 \
+ $(top_srcdir)/aclocal/nfs-utils.m4 \
+ $(top_srcdir)/aclocal/rpcsec_vers.m4 \
+ $(top_srcdir)/aclocal/tcp-wrappers.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/support/include/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(man5dir)" \
+ "$(DESTDIR)$(udev_rulesdir)"
+PROGRAMS = $(libexec_PROGRAMS)
+am_nfsrahead_OBJECTS = main.$(OBJEXT)
+nfsrahead_OBJECTS = $(am_nfsrahead_OBJECTS)
+nfsrahead_DEPENDENCIES = ../../support/nfs/libnfsconf.la
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+nfsrahead_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(nfsrahead_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/main.Po
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(nfsrahead_SOURCES)
+DIST_SOURCES = $(nfsrahead_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+man5dir = $(mandir)/man5
+NROFF = nroff
+MANS = $(man5_MANS)
+DATA = $(udev_rules_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
+AM_CPPFLAGS = @AM_CPPFLAGS@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CXXFLAGS_FOR_BUILD = @CXXFLAGS_FOR_BUILD@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ETAGS = @ETAGS@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FILECMD = @FILECMD@
+GREP = @GREP@
+GSSAPI_CFLAGS = @GSSAPI_CFLAGS@
+GSSAPI_LIBS = @GSSAPI_LIBS@
+GSSD = @GSSD@
+GSSGLUE_CFLAGS = @GSSGLUE_CFLAGS@
+GSSGLUE_LIBS = @GSSGLUE_LIBS@
+GSSKRB_CFLAGS = @GSSKRB_CFLAGS@
+GSSKRB_LIBS = @GSSKRB_LIBS@
+HAVE_GETRANDOM = @HAVE_GETRANDOM@
+HAVE_LIBWRAP = @HAVE_LIBWRAP@
+HAVE_TCP_WRAPPER = @HAVE_TCP_WRAPPER@
+IDMAPD = @IDMAPD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+K5VERS = @K5VERS@
+KRBCFLAGS = @KRBCFLAGS@
+KRBDIR = @KRBDIR@
+KRBLDFLAGS = @KRBLDFLAGS@
+KRBLIBS = @KRBLIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@
+LIBBLKID = @LIBBLKID@
+LIBBSD = @LIBBSD@
+LIBCAP = @LIBCAP@
+LIBCRYPT = @LIBCRYPT@
+LIBEVENT = @LIBEVENT@
+LIBKEYUTILS = @LIBKEYUTILS@
+LIBMOUNT = @LIBMOUNT@
+LIBMOUNT_CFLAGS = @LIBMOUNT_CFLAGS@
+LIBMOUNT_LIBS = @LIBMOUNT_LIBS@
+LIBNSL = @LIBNSL@
+LIBOBJS = @LIBOBJS@
+LIBPTHREAD = @LIBPTHREAD@
+LIBS = @LIBS@
+LIBSOCKET = @LIBSOCKET@
+LIBSQLITE = @LIBSQLITE@
+LIBTIRPC = @LIBTIRPC@
+LIBTOOL = @LIBTOOL@
+LIBWRAP = @LIBWRAP@
+LIBXML2 = @LIBXML2@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_PLUGINS = @PATH_PLUGINS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
+RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
+RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SVCGSSD = @SVCGSSD@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+VERSION = @VERSION@
+XML2_CFLAGS = @XML2_CFLAGS@
+XML2_LIBS = @XML2_LIBS@
+_rpc_pipefsmount = @_rpc_pipefsmount@
+_statedir = @_statedir@
+_sysconfdir = @_sysconfdir@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
+enable_mountconfig = @enable_mountconfig@
+enable_nfsv4 = @enable_nfsv4@
+enable_nfsv41 = @enable_nfsv41@
+enable_svcgss = @enable_svcgss@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+kprefix = @kprefix@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+mountfile = @mountfile@
+nfsconfig = @nfsconfig@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+rpc_pipefsmount = @rpc_pipefsmount@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+startstatd = @startstatd@
+statdpath = @statdpath@
+statduser = @statduser@
+statedir = @statedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+unitdir = @unitdir@
+nfsrahead_SOURCES = main.c
+nfsrahead_LDFLAGS = $(LIBMOUNT_LIBS)
+nfsrahead_LDADD = ../../support/nfs/libnfsconf.la
+man5_MANS = nfsrahead.man
+EXTRA_DIST = $(man5_MANS)
+udev_rulesdir = /usr/lib/udev/rules.d/
+udev_rules_DATA = 99-nfs.rules
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tools/nfsrahead/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu tools/nfsrahead/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-libexecPROGRAMS: $(libexec_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(libexecdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(libexecdir)" || exit 1; \
+ fi; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p \
+ || test -f $$p1 \
+ ; then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' \
+ -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(libexecdir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(libexecdir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-libexecPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' \
+ `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(libexecdir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(libexecdir)" && rm -f $$files
+
+clean-libexecPROGRAMS:
+ @list='$(libexec_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+nfsrahead$(EXEEXT): $(nfsrahead_OBJECTS) $(nfsrahead_DEPENDENCIES) $(EXTRA_nfsrahead_DEPENDENCIES)
+ @rm -f nfsrahead$(EXEEXT)
+ $(AM_V_CCLD)$(nfsrahead_LINK) $(nfsrahead_OBJECTS) $(nfsrahead_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man5: $(man5_MANS)
+ @$(NORMAL_INSTALL)
+ @list1='$(man5_MANS)'; \
+ list2=''; \
+ test -n "$(man5dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man5dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man5dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.5[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man5:
+ @$(NORMAL_UNINSTALL)
+ @list='$(man5_MANS)'; test -n "$(man5dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir)
+install-udev_rulesDATA: $(udev_rules_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(udev_rules_DATA)'; test -n "$(udev_rulesdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(udev_rulesdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(udev_rulesdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(udev_rulesdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(udev_rulesdir)" || exit $$?; \
+ done
+
+uninstall-udev_rulesDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(udev_rules_DATA)'; test -n "$(udev_rulesdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(udev_rulesdir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(udev_rulesdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libexecPROGRAMS clean-libtool \
+ clean-local mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/main.Po
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-udev_rulesDATA
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-libexecPROGRAMS
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man5
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/main.Po
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-libexecPROGRAMS uninstall-man \
+ uninstall-udev_rulesDATA
+
+uninstall-man: uninstall-man5
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
+ clean-generic clean-libexecPROGRAMS clean-libtool clean-local \
+ cscopelist-am ctags ctags-am distclean distclean-compile \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-libexecPROGRAMS \
+ install-man install-man5 install-pdf install-pdf-am install-ps \
+ install-ps-am install-strip install-udev_rulesDATA \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am uninstall-libexecPROGRAMS \
+ uninstall-man uninstall-man5 uninstall-udev_rulesDATA
+
+.PRECIOUS: Makefile
+
+
+99-nfs.rules: 99-nfs.rules.in $(builddefs)
+ $(SED) "s|_libexecdir_|@libexecdir@|g" 99-nfs.rules.in > $@
+
+clean-local:
+ $(RM) 99-nfs.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tools/nfsrahead/main.c b/tools/nfsrahead/main.c
new file mode 100644
index 0000000..8a11cf1
--- /dev/null
+++ b/tools/nfsrahead/main.c
@@ -0,0 +1,192 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <libmount/libmount.h>
+#include <sys/sysmacros.h>
+
+#include "xlog.h"
+#include "conffile.h"
+
+#ifndef MOUNTINFO_PATH
+#define MOUNTINFO_PATH "/proc/self/mountinfo"
+#endif
+
+#define CONF_NAME "nfsrahead"
+#define NFS_DEFAULT_READAHEAD 128
+
+/* Device information from the system */
+struct device_info {
+ char *device_number;
+ dev_t dev;
+ char *mountpoint;
+ char *fstype;
+};
+
+/* Convert a string in the format n:m to a device number */
+static int fill_device_number(struct device_info *info)
+{
+ char *s = strdup(info->device_number), *p;
+ char *maj_s, *min_s;
+ unsigned int maj, min;
+ int err = -EINVAL;
+
+ maj_s = p = s;
+ for ( ; *p != ':' && *p != '\0'; p++)
+ ;
+
+ if (*p == '\0')
+ goto out_free;
+
+ err = 0;
+ *p = '\0';
+ min_s = p + 1;
+
+ maj = strtol(maj_s, NULL, 10);
+ min = strtol(min_s, NULL, 10);
+
+ info->dev = makedev(maj, min);
+out_free:
+ free(s);
+ return err;
+}
+
+#define sfree(ptr) if (ptr) free(ptr)
+
+/* device_info maintenance */
+static void init_device_info(struct device_info *di, const char *device_number)
+{
+ di->device_number = strdup(device_number);
+ di->dev = 0;
+ di->mountpoint = NULL;
+ di->fstype = NULL;
+}
+
+
+static void free_device_info(struct device_info *di)
+{
+ sfree(di->mountpoint);
+ sfree(di->fstype);
+ sfree(di->device_number);
+}
+
+static int get_mountinfo(const char *device_number, struct device_info *device_info, const char *mountinfo_path)
+{
+ int ret = 0;
+ struct libmnt_table *mnttbl;
+ struct libmnt_fs *fs;
+ char *target;
+
+ init_device_info(device_info, device_number);
+ if ((ret = fill_device_number(device_info)) < 0)
+ goto out_free_device_info;
+
+ mnttbl = mnt_new_table();
+
+ if ((ret = mnt_table_parse_file(mnttbl, mountinfo_path)) < 0) {
+ xlog(D_GENERAL, "Failed to parse %s\n", mountinfo_path);
+ goto out_free_tbl;
+ }
+
+ if ((fs = mnt_table_find_devno(mnttbl, device_info->dev, MNT_ITER_FORWARD)) == NULL) {
+ ret = ENOENT;
+ goto out_free_tbl;
+ }
+
+ if ((target = (char *)mnt_fs_get_target(fs)) == NULL) {
+ ret = ENOENT;
+ goto out_free_fs;
+ }
+
+ device_info->mountpoint = strdup(target);
+ target = (char *)mnt_fs_get_fstype(fs);
+ if (target)
+ device_info->fstype = strdup(target);
+
+out_free_fs:
+ mnt_free_fs(fs);
+out_free_tbl:
+ mnt_free_table(mnttbl);
+out_free_device_info:
+ free(device_info->device_number);
+ device_info->device_number = NULL;
+ return ret;
+}
+
+static int get_device_info(const char *device_number, struct device_info *device_info)
+{
+ int ret = ENOENT;
+ for (int retry_count = 0; retry_count < 10 && ret != 0; retry_count++)
+ ret = get_mountinfo(device_number, device_info, MOUNTINFO_PATH);
+
+ return ret;
+}
+
+static int conf_get_readahead(const char *kind) {
+ int readahead = 0;
+
+ if((readahead = conf_get_num(CONF_NAME, kind, -1)) == -1)
+ readahead = conf_get_num(CONF_NAME, "default", NFS_DEFAULT_READAHEAD);
+
+ return readahead;
+}
+
+int main(int argc, char **argv)
+{
+ int ret = 0, retry, opt;
+ struct device_info device;
+ unsigned int readahead = 128, log_level, log_stderr = 0;
+
+
+ log_level = D_ALL & ~D_GENERAL;
+ while((opt = getopt(argc, argv, "dF")) != -1) {
+ switch (opt) {
+ case 'd':
+ log_level = D_ALL;
+ break;
+ case 'F':
+ log_stderr = 1;
+ break;
+ }
+ }
+
+ conf_init_file(NFS_CONFFILE);
+
+ xlog_stderr(log_stderr);
+ xlog_syslog(~log_stderr);
+ xlog_config(log_level, 1);
+ xlog_open(CONF_NAME);
+
+ // xlog_err causes the system to exit
+ if ((argc - optind) != 1)
+ xlog_err("expected the device number of a BDI; is udev ok?");
+
+ for (retry = 0; retry <= 10; retry++ )
+ if ((ret = get_device_info(argv[optind], &device)) == 0)
+ break;
+
+ if (ret != 0 || device.fstype == NULL) {
+ xlog(D_GENERAL, "unable to find device %s\n", argv[optind]);
+ goto out;
+ }
+
+ if (strncmp("nfs", device.fstype, 3) != 0) {
+ xlog(D_GENERAL,
+ "not setting readahead for non supported fstype %s on device %s\n",
+ device.fstype, argv[optind]);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ readahead = conf_get_readahead(device.fstype);
+
+ xlog(D_FAC7, "setting %s readahead to %d\n", device.mountpoint, readahead);
+
+ printf("%d\n", readahead);
+
+out:
+ free_device_info(&device);
+ return ret;
+}
diff --git a/tools/nfsrahead/nfsrahead.man b/tools/nfsrahead/nfsrahead.man
new file mode 100644
index 0000000..5488f63
--- /dev/null
+++ b/tools/nfsrahead/nfsrahead.man
@@ -0,0 +1,72 @@
+.\" Manpage for nfsrahead.
+.nh
+.ad l
+.TH man 5 "08 Mar 2022" "1.0" "nfsrahead man page"
+.SH NAME
+
+nfsrahead \- Configure the readahead for NFS mounts
+
+.SH SYNOPSIS
+
+nfsrahead [-F] [-d] <device>
+
+.SH DESCRIPTION
+
+\fInfsrahead\fR is a tool intended to be used with udev to set the \fIread_ahead_kb\fR parameter of NFS mounts, according to the configuration file (see \fICONFIGURATION\fR). \fIdevice\fR is the device number for the NFS backing device as provided by the kernel.
+
+.SH OPTIONS
+.TP
+.B -F
+Send messages to
+.I stderr
+instead of
+.I syslog
+
+.TP
+.B -d
+Increase the debugging level.
+
+.SH CONFIGURATION
+.I nfsrahead
+is configured in
+.IR /etc/nfs.conf ,
+in the section titled
+.IR nfsrahead .
+It accepts the following configurations.
+
+.TP
+.B nfs=<value>
+The readahead value applied to NFSv3 mounts.
+
+.TP
+.B nfs4=<value>
+The readahead value applied to NFSv4 mounts.
+
+.TP
+.B default=<value>
+The default configuration when none of the configurations above is set.
+
+.SH EXAMPLE CONFIGURATION
+[nfsrahead]
+.br
+nfs=15000 # readahead of 15000 for NFSv3 mounts
+.br
+nfs4=16000 # readahead of 16000 for NFSv4 mounts
+.br
+default=128 # default is 128
+
+.SH SEE ALSO
+
+.BR mount.nfs (8),
+.BR nfs (5),
+.BR nfs.conf (5),
+.BR udev (7),
+.BR bcc-readahead (8)
+
+.SH BUGS
+
+No known bugs.
+
+.SH AUTHOR
+
+Thiago Rafael Becker <trbecker@gmail.com>
diff --git a/tools/nlmtest/Makefile.am b/tools/nlmtest/Makefile.am
new file mode 100644
index 0000000..fbf9fb3
--- /dev/null
+++ b/tools/nlmtest/Makefile.am
@@ -0,0 +1,7 @@
+## Process this file with automake to produce Makefile.in
+
+EXTRA_DIST = \
+ README \
+ host.h \
+ nlm_prot.x \
+ nlmtest.c
diff --git a/tools/nlmtest/Makefile.in b/tools/nlmtest/Makefile.in
new file mode 100644
index 0000000..efd6207
--- /dev/null
+++ b/tools/nlmtest/Makefile.in
@@ -0,0 +1,538 @@
+# Makefile.in generated by automake 1.16.5 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = tools/nlmtest
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/aclocal/ax_gcc_func_attribute.m4 \
+ $(top_srcdir)/aclocal/bsdsignals.m4 \
+ $(top_srcdir)/aclocal/getrandom.m4 \
+ $(top_srcdir)/aclocal/ipv6.m4 \
+ $(top_srcdir)/aclocal/kerberos5.m4 \
+ $(top_srcdir)/aclocal/keyutils.m4 \
+ $(top_srcdir)/aclocal/libblkid.m4 \
+ $(top_srcdir)/aclocal/libcap.m4 \
+ $(top_srcdir)/aclocal/libevent.m4 \
+ $(top_srcdir)/aclocal/libpthread.m4 \
+ $(top_srcdir)/aclocal/libsqlite3.m4 \
+ $(top_srcdir)/aclocal/libtirpc.m4 \
+ $(top_srcdir)/aclocal/libxml2.m4 \
+ $(top_srcdir)/aclocal/nfs-utils.m4 \
+ $(top_srcdir)/aclocal/rpcsec_vers.m4 \
+ $(top_srcdir)/aclocal/tcp-wrappers.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/support/include/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(srcdir)/Makefile.in README
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
+AM_CPPFLAGS = @AM_CPPFLAGS@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CXXFLAGS_FOR_BUILD = @CXXFLAGS_FOR_BUILD@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ETAGS = @ETAGS@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FILECMD = @FILECMD@
+GREP = @GREP@
+GSSAPI_CFLAGS = @GSSAPI_CFLAGS@
+GSSAPI_LIBS = @GSSAPI_LIBS@
+GSSD = @GSSD@
+GSSGLUE_CFLAGS = @GSSGLUE_CFLAGS@
+GSSGLUE_LIBS = @GSSGLUE_LIBS@
+GSSKRB_CFLAGS = @GSSKRB_CFLAGS@
+GSSKRB_LIBS = @GSSKRB_LIBS@
+HAVE_GETRANDOM = @HAVE_GETRANDOM@
+HAVE_LIBWRAP = @HAVE_LIBWRAP@
+HAVE_TCP_WRAPPER = @HAVE_TCP_WRAPPER@
+IDMAPD = @IDMAPD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+K5VERS = @K5VERS@
+KRBCFLAGS = @KRBCFLAGS@
+KRBDIR = @KRBDIR@
+KRBLDFLAGS = @KRBLDFLAGS@
+KRBLIBS = @KRBLIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@
+LIBBLKID = @LIBBLKID@
+LIBBSD = @LIBBSD@
+LIBCAP = @LIBCAP@
+LIBCRYPT = @LIBCRYPT@
+LIBEVENT = @LIBEVENT@
+LIBKEYUTILS = @LIBKEYUTILS@
+LIBMOUNT = @LIBMOUNT@
+LIBMOUNT_CFLAGS = @LIBMOUNT_CFLAGS@
+LIBMOUNT_LIBS = @LIBMOUNT_LIBS@
+LIBNSL = @LIBNSL@
+LIBOBJS = @LIBOBJS@
+LIBPTHREAD = @LIBPTHREAD@
+LIBS = @LIBS@
+LIBSOCKET = @LIBSOCKET@
+LIBSQLITE = @LIBSQLITE@
+LIBTIRPC = @LIBTIRPC@
+LIBTOOL = @LIBTOOL@
+LIBWRAP = @LIBWRAP@
+LIBXML2 = @LIBXML2@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_PLUGINS = @PATH_PLUGINS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
+RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
+RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SVCGSSD = @SVCGSSD@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+VERSION = @VERSION@
+XML2_CFLAGS = @XML2_CFLAGS@
+XML2_LIBS = @XML2_LIBS@
+_rpc_pipefsmount = @_rpc_pipefsmount@
+_statedir = @_statedir@
+_sysconfdir = @_sysconfdir@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
+enable_mountconfig = @enable_mountconfig@
+enable_nfsv4 = @enable_nfsv4@
+enable_nfsv41 = @enable_nfsv41@
+enable_svcgss = @enable_svcgss@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+kprefix = @kprefix@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+mountfile = @mountfile@
+nfsconfig = @nfsconfig@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+rpc_pipefsmount = @rpc_pipefsmount@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+startstatd = @startstatd@
+statdpath = @statdpath@
+statduser = @statduser@
+statedir = @statedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+unitdir = @unitdir@
+EXTRA_DIST = \
+ README \
+ host.h \
+ nlm_prot.x \
+ nlmtest.c
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tools/nlmtest/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu tools/nlmtest/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+ cscopelist-am ctags-am distclean distclean-generic \
+ distclean-libtool distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tools/nlmtest/README b/tools/nlmtest/README
new file mode 100644
index 0000000..b54cb43
--- /dev/null
+++ b/tools/nlmtest/README
@@ -0,0 +1,5 @@
+
+This is a simple tool to test your lockd server. This is a very
+primitive program. To use it on your system, you have to edit
+host.h and adjust the inode and device numbers in nltest.c to
+suit your nfs server.
diff --git a/tools/nlmtest/host.h b/tools/nlmtest/host.h
new file mode 100644
index 0000000..b4f30df
--- /dev/null
+++ b/tools/nlmtest/host.h
@@ -0,0 +1,28 @@
+/*
+ * host.h
+ *
+ * Defaults for nlmtest
+ */
+
+#ifndef NLMTEST_HOST_H
+#define NLMTEST_HOST_H
+
+/*
+ * The host on which lockd runs
+ */
+#define NLMTEST_HOST "crutch"
+
+/*
+ * NFS mount point
+ */
+#define NLMTEST_DIR "../../mount/"
+
+/*
+ * The default file name and its inode version number.
+ * There's no way the test program can find out the version number,
+ * so you have to add it here.
+ */
+#define NLMTEST_FILE NLMTEST_DIR "COPYING"
+#define NLMTEST_VERSION 1
+
+#endif /* NLMTEST_HOST_H */
diff --git a/tools/nlmtest/nlm_prot.x b/tools/nlmtest/nlm_prot.x
new file mode 100644
index 0000000..a425912
--- /dev/null
+++ b/tools/nlmtest/nlm_prot.x
@@ -0,0 +1,183 @@
+/* @(#)nlm_prot.x 2.1 88/08/01 4.0 RPCSRC */
+/* @(#)nlm_prot.x 1.8 87/09/21 Copyr 1987 Sun Micro */
+
+/*
+ * Network lock manager protocol definition
+ * Copyright (C) 1986 Sun Microsystems, Inc.
+ *
+ * protocol used between local lock manager and remote lock manager
+ */
+
+#ifdef RPC_CLNT
+%#include <string.h>
+#endif
+
+#ifdef RPC_HDR
+%#define LM_MAXSTRLEN 1024
+%#define MAXNAMELEN LM_MAXSTRLEN+1
+#endif
+
+/*
+ * status of a call to the lock manager
+ */
+enum nlm_stats {
+ nlm_granted = 0,
+ nlm_denied = 1,
+ nlm_denied_nolocks = 2,
+ nlm_blocked = 3,
+ nlm_denied_grace_period = 4
+};
+
+struct nlm_holder {
+ bool exclusive;
+ int svid;
+ netobj oh;
+ unsigned l_offset;
+ unsigned l_len;
+};
+
+union nlm_testrply switch (nlm_stats stat) {
+ case nlm_denied:
+ struct nlm_holder holder;
+ default:
+ void;
+};
+
+struct nlm_stat {
+ nlm_stats stat;
+};
+
+struct nlm_res {
+ netobj cookie;
+ nlm_stat stat;
+};
+
+struct nlm_testres {
+ netobj cookie;
+ nlm_testrply stat;
+};
+
+struct nlm_lock {
+ string caller_name<LM_MAXSTRLEN>;
+ netobj fh; /* identify a file */
+ netobj oh; /* identify owner of a lock */
+ int svid; /* generated from pid for svid */
+ unsigned l_offset;
+ unsigned l_len;
+};
+
+struct nlm_lockargs {
+ netobj cookie;
+ bool block;
+ bool exclusive;
+ struct nlm_lock alock;
+ bool reclaim; /* used for recovering locks */
+ int state; /* specify local status monitor state */
+};
+
+struct nlm_cancargs {
+ netobj cookie;
+ bool block;
+ bool exclusive;
+ struct nlm_lock alock;
+};
+
+struct nlm_testargs {
+ netobj cookie;
+ bool exclusive;
+ struct nlm_lock alock;
+};
+
+struct nlm_unlockargs {
+ netobj cookie;
+ struct nlm_lock alock;
+};
+
+
+#ifdef RPC_HDR
+%/*
+% * The following enums are actually bit encoded for efficient
+% * boolean algebra.... DON'T change them.....
+% */
+#endif
+enum fsh_mode {
+ fsm_DN = 0, /* deny none */
+ fsm_DR = 1, /* deny read */
+ fsm_DW = 2, /* deny write */
+ fsm_DRW = 3 /* deny read/write */
+};
+
+enum fsh_access {
+ fsa_NONE = 0, /* for completeness */
+ fsa_R = 1, /* read only */
+ fsa_W = 2, /* write only */
+ fsa_RW = 3 /* read/write */
+};
+
+struct nlm_share {
+ string caller_name<LM_MAXSTRLEN>;
+ netobj fh;
+ netobj oh;
+ fsh_mode mode;
+ fsh_access access;
+};
+
+struct nlm_shareargs {
+ netobj cookie;
+ nlm_share share;
+ bool reclaim;
+};
+
+struct nlm_shareres {
+ netobj cookie;
+ nlm_stats stat;
+ int sequence;
+};
+
+struct nlm_notify {
+ string name<MAXNAMELEN>;
+ long state;
+};
+
+/*
+ * Over-the-wire protocol used between the network lock managers
+ */
+
+program NLM_PROG {
+ version NLM_VERS {
+
+ nlm_testres NLM_TEST(struct nlm_testargs) = 1;
+
+ nlm_res NLM_LOCK(struct nlm_lockargs) = 2;
+
+ nlm_res NLM_CANCEL(struct nlm_cancargs) = 3;
+ nlm_res NLM_UNLOCK(struct nlm_unlockargs) = 4;
+
+ /*
+ * remote lock manager call-back to grant lock
+ */
+ nlm_res NLM_GRANTED(struct nlm_testargs)= 5;
+ /*
+ * message passing style of requesting lock
+ */
+ void NLM_TEST_MSG(struct nlm_testargs) = 6;
+ void NLM_LOCK_MSG(struct nlm_lockargs) = 7;
+ void NLM_CANCEL_MSG(struct nlm_cancargs) =8;
+ void NLM_UNLOCK_MSG(struct nlm_unlockargs) = 9;
+ void NLM_GRANTED_MSG(struct nlm_testargs) = 10;
+ void NLM_TEST_RES(nlm_testres) = 11;
+ void NLM_LOCK_RES(nlm_res) = 12;
+ void NLM_CANCEL_RES(nlm_res) = 13;
+ void NLM_UNLOCK_RES(nlm_res) = 14;
+ void NLM_GRANTED_RES(nlm_res) = 15;
+ } = 1;
+
+ version NLM_VERSX {
+ nlm_shareres NLM_SHARE(nlm_shareargs) = 20;
+ nlm_shareres NLM_UNSHARE(nlm_shareargs) = 21;
+ nlm_res NLM_NM_LOCK(nlm_lockargs) = 22;
+ void NLM_FREE_ALL(nlm_notify) = 23;
+ } = 3;
+
+} = 100021;
+
diff --git a/tools/nlmtest/nlmtest.c b/tools/nlmtest/nlmtest.c
new file mode 100644
index 0000000..d0acc47
--- /dev/null
+++ b/tools/nlmtest/nlmtest.c
@@ -0,0 +1,264 @@
+/*
+ * nlmtest
+ *
+ * Simple tool for NLM testing. You will have to adjust the values in
+ * host.h to your test system.
+ *
+ * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
+ */
+
+#include "config.h"
+
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <nfs/nfs.h>
+#include <getopt.h>
+#include "nlm_prot.h"
+#include "host.h"
+
+static char myhostname[256];
+static int hostnamelen;
+
+static void makelock(struct nlm_lock *, u_int32_t, off_t, off_t);
+static void makeowner(struct netobj *, u_int32_t);
+static void makefileh(struct netobj *);
+static char * nlm_stat_name(int status);
+static char * holderstr(struct netobj *oh);
+
+int
+main(int argc, char **argv)
+{
+ CLIENT *client;
+ nlm_testargs testargs;
+ nlm_lockargs lockargs;
+ nlm_unlockargs unlockargs;
+ nlm_lock alock;
+ nlm_testres *testres;
+ nlm_res *lockres;
+ char *filename = NLMTEST_FILE;
+ char *svchost = NLMTEST_HOST;
+ unsigned long offset = 0, length = 0;
+ int exclusive = 0;
+ int blocking = 0;
+ int unlock = 0;
+ u_int32_t cookie = 4321;
+ u_int32_t mypid = 1234;
+ int c;
+
+ while ((c = getopt(argc, argv, "bf:h:l:o:p:ux")) != EOF) {
+ switch(c) {
+ case 'b':
+ blocking = 1;
+ break;
+ case 'f':
+ filename = optarg;
+ break;
+ case 'h':
+ svchost = optarg;
+ break;
+ case 'l':
+ length = atoi(optarg);
+ break;
+ case 'o':
+ offset = atoi(optarg);
+ break;
+ case 'p':
+ mypid = atoi(optarg);
+ break;
+ case 'u':
+ unlock = 1;
+ break;
+ case 'x':
+ exclusive = 1;
+ break;
+ default:
+ fprintf(stderr, "nlmtest: bad option %c\n", c);
+ exit (2);
+ }
+ }
+
+ client = clnt_create(svchost, NLM_PROG, NLM_VERS, "udp");
+ if (client == NULL) {
+ clnt_pcreateerror("localhost");
+ exit(1);
+ }
+
+ /* Get local host name */
+ if (gethostname(myhostname, sizeof(myhostname)) < 0)
+ strcpy(myhostname, "unknown");
+ hostnamelen = strlen(myhostname);
+
+ makelock(&alock, mypid, offset, length);
+
+ testargs.cookie.n_bytes = (void*)&cookie;
+ testargs.cookie.n_len = 4;
+ testargs.exclusive = exclusive;
+ testargs.alock = alock;
+
+ if ((testres = nlm_test_1(&testargs, client)) == NULL) {
+ clnt_perror(client, "nlm_test call failed:");
+ exit (1);
+ }
+ printf ("nlm_test reply:\n"
+ "\tcookie: %d\n"
+ "\tstatus: %s\n",
+ *(int*)(testres->cookie.n_bytes),
+ nlm_stat_name(testres->stat.stat)
+ );
+
+ if (testres->stat.stat == nlm_denied) {
+ nlm_holder *holder = &(testres->stat.nlm_testrply_u.holder);
+ printf ("\tconflicting lock:\n"
+ "\t oh: %s\n"
+ "\t pid: %d\n"
+ "\t offset: %d\n"
+ "\t length: %d\n"
+ "\t exclusive: %d\n",
+ holderstr(&holder->oh),
+ holder->svid,
+ holder->l_offset,
+ holder->l_len,
+ holder->exclusive);
+ }
+
+ if (testres->stat.stat != nlm_granted && !unlock && !blocking)
+ return 1;
+
+ if (unlock) {
+ unlockargs.cookie.n_bytes = (void*)&cookie;
+ unlockargs.cookie.n_len = sizeof(cookie);
+ unlockargs.alock = alock;
+
+ if ((lockres = nlm_unlock_1(&unlockargs, client)) == NULL) {
+ clnt_perror(client, "nlm_unlock call failed:");
+ exit (1);
+ }
+ printf ("nlm_unlock reply:\n"
+ "\tcookie: %d\n"
+ "\tstatus: %s\n",
+ *(int*)(lockres->cookie.n_bytes),
+ nlm_stat_name(lockres->stat.stat)
+ );
+ } else {
+ lockargs.cookie.n_bytes = (void*)&cookie;
+ lockargs.cookie.n_len = sizeof(cookie);
+ lockargs.exclusive = exclusive;
+ lockargs.alock = alock;
+ lockargs.reclaim = 0;
+ lockargs.state = 0;
+
+ if ((lockres = nlm_lock_1(&lockargs, client)) == NULL) {
+ clnt_perror(client, "nlm_lock call failed:");
+ exit (1);
+ }
+ printf ("nlm_lock reply:\n"
+ "\tcookie: %d\n"
+ "\tstatus: %s\n",
+ *(int*)(lockres->cookie.n_bytes),
+ nlm_stat_name(lockres->stat.stat)
+ );
+ }
+
+ return 0;
+}
+
+static char *
+nlm_stat_name(int status)
+{
+ static char buf[12];
+
+ switch (status) {
+ case nlm_granted:
+ return "nlm_granted";
+ case nlm_denied:
+ return "nlm_denied";
+ case nlm_denied_nolocks:
+ return "nlm_denied_nolocks";
+ case nlm_blocked:
+ return "nlm_blocked";
+ case nlm_denied_grace_period:
+ return "nlm_denied_grace_period";
+ }
+ sprintf(buf, "%d", status);
+ return buf;
+}
+
+static char *
+holderstr(struct netobj *oh)
+{
+ static char buffer[4096];
+ unsigned char c, *sp;
+ int i;
+
+ for (i = 0, sp = buffer; i < oh->n_len; i++) {
+ c = (unsigned char) oh->n_bytes[i];
+ if (c < 0x20 || c > 0x7f)
+ sp += sprintf(sp, "\\%03o", c);
+ else
+ *sp++ = c;
+ }
+ *sp++ = '\0';
+
+ return buffer;
+}
+
+static void
+makelock(struct nlm_lock *alock, u_int32_t mypid, off_t offset, off_t length)
+{
+ makeowner(&alock->oh, mypid); /* Create owner handle */
+ makefileh(&alock->fh); /* Create file handle */
+
+ alock->caller_name = myhostname;
+ alock->svid = mypid;
+ alock->l_offset = offset;
+ alock->l_len = length;
+}
+
+static void
+makeowner(struct netobj *oh, u_int32_t mypid)
+{
+ static char ohdata[1024];
+
+ oh->n_bytes = ohdata;
+ oh->n_len = hostnamelen + 1 + 4;
+
+ strcpy(ohdata, myhostname);
+ memcpy(ohdata + hostnamelen + 1, &mypid, 4);
+}
+
+static void
+makefileh(struct netobj *fh)
+{
+ static struct knfs_fh f;
+ struct stat stb;
+#error this needs updating if it is still wanted
+ memset(&f, 0, sizeof(f));
+#if 0
+ if (stat(NLMTEST_DIR, &stb) < 0) {
+ perror("couldn't stat mount point " NLMTEST_DIR);
+ exit(1);
+ }
+ f.fh_xdev = stb.st_dev;
+ f.fh_xino = stb.st_ino;
+
+ if (stat(NLMTEST_DIR, &stb) < 0) {
+ perror("couldn't stat mount point " NLMTEST_DIR);
+ exit(1);
+ }
+ f.fh_dev = stb.st_dev;
+ f.fh_ino = stb.st_ino;
+
+ f.fh_version = NLMTEST_VERSION;
+#else
+ f.fh_xdev = 0x801;
+ f.fh_xino = 37596;
+ f.fh_dev = 0x801;
+ f.fh_ino = 37732;
+#endif
+
+ fh->n_len = 32;
+ fh->n_bytes = (void *) &f;
+}
diff --git a/tools/rpcctl/Makefile.am b/tools/rpcctl/Makefile.am
new file mode 100644
index 0000000..33fb431
--- /dev/null
+++ b/tools/rpcctl/Makefile.am
@@ -0,0 +1,13 @@
+## Process this file with automake to produce Makefile.in
+PYTHON_FILES = rpcctl.py
+
+man8_MANS = rpcctl.man
+
+EXTRA_DIST = $(man8_MANS) $(PYTHON_FILES)
+
+all-local: $(PYTHON_FILES)
+
+install-data-hook:
+ $(INSTALL) -m 755 rpcctl.py $(DESTDIR)$(sbindir)/rpcctl
+
+MAINTAINERCLEANFILES=Makefile.in
diff --git a/tools/rpcctl/Makefile.in b/tools/rpcctl/Makefile.in
new file mode 100644
index 0000000..f678865
--- /dev/null
+++ b/tools/rpcctl/Makefile.in
@@ -0,0 +1,621 @@
+# Makefile.in generated by automake 1.16.5 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = tools/rpcctl
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/aclocal/ax_gcc_func_attribute.m4 \
+ $(top_srcdir)/aclocal/bsdsignals.m4 \
+ $(top_srcdir)/aclocal/getrandom.m4 \
+ $(top_srcdir)/aclocal/ipv6.m4 \
+ $(top_srcdir)/aclocal/kerberos5.m4 \
+ $(top_srcdir)/aclocal/keyutils.m4 \
+ $(top_srcdir)/aclocal/libblkid.m4 \
+ $(top_srcdir)/aclocal/libcap.m4 \
+ $(top_srcdir)/aclocal/libevent.m4 \
+ $(top_srcdir)/aclocal/libpthread.m4 \
+ $(top_srcdir)/aclocal/libsqlite3.m4 \
+ $(top_srcdir)/aclocal/libtirpc.m4 \
+ $(top_srcdir)/aclocal/libxml2.m4 \
+ $(top_srcdir)/aclocal/nfs-utils.m4 \
+ $(top_srcdir)/aclocal/rpcsec_vers.m4 \
+ $(top_srcdir)/aclocal/tcp-wrappers.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/support/include/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+man8dir = $(mandir)/man8
+am__installdirs = "$(DESTDIR)$(man8dir)"
+NROFF = nroff
+MANS = $(man8_MANS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
+AM_CPPFLAGS = @AM_CPPFLAGS@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CXXFLAGS_FOR_BUILD = @CXXFLAGS_FOR_BUILD@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ETAGS = @ETAGS@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FILECMD = @FILECMD@
+GREP = @GREP@
+GSSAPI_CFLAGS = @GSSAPI_CFLAGS@
+GSSAPI_LIBS = @GSSAPI_LIBS@
+GSSD = @GSSD@
+GSSGLUE_CFLAGS = @GSSGLUE_CFLAGS@
+GSSGLUE_LIBS = @GSSGLUE_LIBS@
+GSSKRB_CFLAGS = @GSSKRB_CFLAGS@
+GSSKRB_LIBS = @GSSKRB_LIBS@
+HAVE_GETRANDOM = @HAVE_GETRANDOM@
+HAVE_LIBWRAP = @HAVE_LIBWRAP@
+HAVE_TCP_WRAPPER = @HAVE_TCP_WRAPPER@
+IDMAPD = @IDMAPD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+K5VERS = @K5VERS@
+KRBCFLAGS = @KRBCFLAGS@
+KRBDIR = @KRBDIR@
+KRBLDFLAGS = @KRBLDFLAGS@
+KRBLIBS = @KRBLIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@
+LIBBLKID = @LIBBLKID@
+LIBBSD = @LIBBSD@
+LIBCAP = @LIBCAP@
+LIBCRYPT = @LIBCRYPT@
+LIBEVENT = @LIBEVENT@
+LIBKEYUTILS = @LIBKEYUTILS@
+LIBMOUNT = @LIBMOUNT@
+LIBMOUNT_CFLAGS = @LIBMOUNT_CFLAGS@
+LIBMOUNT_LIBS = @LIBMOUNT_LIBS@
+LIBNSL = @LIBNSL@
+LIBOBJS = @LIBOBJS@
+LIBPTHREAD = @LIBPTHREAD@
+LIBS = @LIBS@
+LIBSOCKET = @LIBSOCKET@
+LIBSQLITE = @LIBSQLITE@
+LIBTIRPC = @LIBTIRPC@
+LIBTOOL = @LIBTOOL@
+LIBWRAP = @LIBWRAP@
+LIBXML2 = @LIBXML2@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_PLUGINS = @PATH_PLUGINS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
+RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
+RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SVCGSSD = @SVCGSSD@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+VERSION = @VERSION@
+XML2_CFLAGS = @XML2_CFLAGS@
+XML2_LIBS = @XML2_LIBS@
+_rpc_pipefsmount = @_rpc_pipefsmount@
+_statedir = @_statedir@
+_sysconfdir = @_sysconfdir@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
+enable_mountconfig = @enable_mountconfig@
+enable_nfsv4 = @enable_nfsv4@
+enable_nfsv41 = @enable_nfsv41@
+enable_svcgss = @enable_svcgss@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+kprefix = @kprefix@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+mountfile = @mountfile@
+nfsconfig = @nfsconfig@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+rpc_pipefsmount = @rpc_pipefsmount@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+startstatd = @startstatd@
+statdpath = @statdpath@
+statduser = @statduser@
+statedir = @statedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+unitdir = @unitdir@
+PYTHON_FILES = rpcctl.py
+man8_MANS = rpcctl.man
+EXTRA_DIST = $(man8_MANS) $(PYTHON_FILES)
+MAINTAINERCLEANFILES = Makefile.in
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tools/rpcctl/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu tools/rpcctl/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(man8_MANS)
+ @$(NORMAL_INSTALL)
+ @list1='$(man8_MANS)'; \
+ list2=''; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list='$(man8_MANS)'; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(MANS) all-local
+installdirs:
+ for dir in "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-data-hook
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man
+
+uninstall-man: uninstall-man8
+
+.MAKE: install-am install-data-am install-strip
+
+.PHONY: all all-am all-local check check-am clean clean-generic \
+ clean-libtool cscopelist-am ctags-am distclean \
+ distclean-generic distclean-libtool distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-data-hook install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-man8 \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags-am uninstall uninstall-am uninstall-man uninstall-man8
+
+.PRECIOUS: Makefile
+
+
+all-local: $(PYTHON_FILES)
+
+install-data-hook:
+ $(INSTALL) -m 755 rpcctl.py $(DESTDIR)$(sbindir)/rpcctl
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tools/rpcctl/rpcctl.man b/tools/rpcctl/rpcctl.man
new file mode 100644
index 0000000..b87ba0d
--- /dev/null
+++ b/tools/rpcctl/rpcctl.man
@@ -0,0 +1,67 @@
+.\"
+.\" rpcctl(8)
+.\"
+.TH rpcctl 8 "15 Feb 2022"
+.SH NAME
+rpcctl \- Displays SunRPC connection information
+.SH SYNOPSIS
+.nf
+.BR rpcctl " [ \fB\-h \fR| \fB\-\-help \fR] { \fBclient \fR| \fBswitch \fR| \fBxprt \fR}"
+.P
+.BR "rpcctl client" " \fR[ \fB\-h \fR| \fB\-\-help \fR] { \fBshow \fR}"
+.BR "rpcctl client show " "\fR[ \fB\-h \f| \fB\-\-help \fR] [ \fIXPRT \fR]"
+.P
+.BR "rpcctl switch" " \fR[ \fB\-h \fR| \fB\-\-help \fR] { \fBset \fR| \fBshow \fR}"
+.BR "rpcctl switch set" " \fR[ \fB\-h \fR| \fB\-\-help \fR] \fISWITCH \fBdstaddr \fINEWADDR"
+.BR "rpcctl switch show" " \fR[ \fB\-h \fR| \fB\-\-help \fR] [ \fISWITCH \fR]"
+.P
+.BR "rpcctl xprt" " \fR[ \fB\-h \fR| \fB\-\-help \fR] { \fBremove \fR| \fBset \fR| \fBshow \fR}"
+.BR "rpcctl xprt remove" " \fR[ \fB\-h \fR| \fB\-\-help \fR] \fIXPRT"
+.BR "rpcctl xprt set" " \fR[ \fB\-h \fR| \fB\-\-help \fR] \fIXPRT \fR{ \fBdstaddr \fINEWADDR \fR| \fBoffline \fR| \fBonline \fR}"
+.BR "rpcctl xprt show" " \fR[ \fB\-h \fR| \fB\-\-help \fR] [ \fIXPRT \fR]"
+.fi
+.SH DESCRIPTION
+.RB "The " rpcctl " command displays information collected in the SunRPC sysfs files about the system's SunRPC objects.
+.P
+.SS rpcctl client \fR- \fBCommands operating on RPC clients
+.IP "\fBshow \fR[ \fICLIENT \fR] \fB(default)"
+Show detailed information about the RPC clients on this system.
+If \fICLIENT \fRwas provided, then only show information about a single RPC client.
+.P
+.SS rpcctl switch \fR- \fBCommands operating on groups of transports
+.IP "\fBset \fISWITCH \fBdstaddr \fINEWADDR"
+Change the destination address of all transports in the \fISWITCH \fRto \fINEWADDR\fR.
+\fINEWADDR \fRcan be an IP address, DNS name, or anything else resolvable by \fBgethostbyname\fR(3).
+.IP "\fBshow \fR[ \fISWITCH \fR] \fB(default)"
+Show detailed information about groups of transports on this system.
+If \fISWITCH \fRwas provided, then only show information about a single transport group.
+.P
+.SS rpcctl xprt \fR- \fBCommands operating on individual transports
+.IP "\fBremove \fIXPRT"
+Removes the specified \fIXPRT \fRfrom the system.
+Note that "main" transports cannot be removed.
+.P
+.IP "\fBset \fIXPRT \fBdstaddr \fINEWADDR"
+Change the destination address of the specified \fIXPRT \fR to \fINEWADDR\fR.
+\fINEWADDR \fRcan be an IP address, DNS name, or anything else resolvable by \fBgethostbyname\fR(3).
+.P
+.IP "\fBset \fIXPRT \fBoffline"
+Sets the specified \fIXPRT\fR's state to offline.
+.P
+.IP "\fBset \fIXPRT \fBonline"
+Sets the specified \fIXPRT\fR's state to online.
+.IP "\fBshow \fR[ \fIXPRT \fR] \fB(default)"
+Show detailed information about this system's transports.
+If \fIXPRT \fRwas provided, then only show information about a single transport.
+.SH EXAMPLES
+.IP "\fBrpcctl switch show switch-2"
+Show details about the RPC switch named "switch-2".
+.IP "\fBrpcctl xprt remove xprt-4"
+Remove the xprt named "xprt-4" from the system.
+.IP "\fBrpcctl xprt set xprt-3 dstaddr https://linux-nfs.org
+Change the dstaddr of the xprt named "xprt-3" to point to linux-nfs.org
+.SH DIRECTORY
+.TP
+.B /sys/kernel/sunrpc/
+.SH AUTHOR
+Anna Schumaker <Anna.Schumaker@Netapp.com>
diff --git a/tools/rpcctl/rpcctl.py b/tools/rpcctl/rpcctl.py
new file mode 100755
index 0000000..d2110ad
--- /dev/null
+++ b/tools/rpcctl/rpcctl.py
@@ -0,0 +1,262 @@
+#!/usr/bin/python3
+import argparse
+import collections
+import errno
+import os
+import pathlib
+import socket
+import sys
+
+with open("/proc/mounts", 'r') as f:
+ mount = [ line.split()[1] for line in f if "sysfs" in line ]
+ if len(mount) == 0:
+ print("ERROR: sysfs is not mounted")
+ sys.exit(1)
+
+sunrpc = pathlib.Path(mount[0]) / "kernel" / "sunrpc"
+if not sunrpc.is_dir():
+ print("ERROR: sysfs does not have sunrpc directory")
+ sys.exit(1)
+
+def read_addr_file(path):
+ try:
+ with open(path, 'r') as f:
+ return f.readline().strip()
+ except:
+ return "(enoent)"
+
+def write_addr_file(path, newaddr):
+ with open(path, 'w') as f:
+ f.write(newaddr)
+ return read_addr_file(path)
+
+def read_info_file(path):
+ res = collections.defaultdict(int)
+ try:
+ with open(path) as info:
+ lines = [ l.split("=", 1) for l in info if "=" in l ]
+ res.update({ key:int(val.strip()) for (key, val) in lines })
+ finally:
+ return res
+
+
+class Xprt:
+ def __init__(self, path):
+ self.path = path
+ self.name = path.stem.rsplit("-", 1)[0]
+ self.type = path.stem.split("-")[2]
+ self.info = read_info_file(path / "xprt_info")
+ self.dstaddr = read_addr_file(path / "dstaddr")
+ self.srcaddr = read_addr_file(path / "srcaddr")
+ self.read_state()
+
+ def __lt__(self, rhs):
+ return self.name < rhs.name
+
+ def _xprt(self):
+ main = ", main" if self.info.get("main_xprt") else ""
+ return f"{self.name}: {self.type}, {self.dstaddr}, " \
+ f"port {self.info['dst_port']}, state <{self.state}>{main}"
+
+ def _src_reqs(self):
+ return f" Source: {self.srcaddr}, port {self.info['src_port']}, " \
+ f"Requests: {self.info['num_reqs']}"
+
+ def _cong_slots(self):
+ return f" Congestion: cur {self.info['cur_cong']}, win {self.info['cong_win']}, " \
+ f"Slots: min {self.info['min_num_slots']}, max {self.info['max_num_slots']}"
+
+ def _queues(self):
+ return f" Queues: binding {self.info['binding_q_len']}, " \
+ f"sending {self.info['sending_q_len']}, pending {self.info['pending_q_len']}, " \
+ f"backlog {self.info['backlog_q_len']}, tasks {self.info['tasks_queuelen']}"
+
+ def __str__(self):
+ if not self.path.exists():
+ return f"{self.name}: has been removed"
+ return "\n".join([self._xprt(), self._src_reqs(),
+ self._cong_slots(), self._queues() ])
+
+ def read_state(self):
+ if self.path.exists():
+ with open(self.path / "xprt_state") as f:
+ self.state = ','.join(f.readline().split()[1:])
+
+ def small_str(self):
+ main = " [main]" if self.info.get("main_xprt") else ""
+ return f"{self.name}: {self.type}, {self.dstaddr}{main}"
+
+ def set_dstaddr(self, newaddr):
+ self.dstaddr = write_addr_file(self.path / "dstaddr", newaddr)
+
+ def set_state(self, state):
+ if self.info.get("main_xprt"):
+ raise Exception(f"Main xprts cannot be set {state}")
+ with open(self.path / "xprt_state", 'w') as f:
+ f.write(state)
+ self.read_state()
+
+ def remove(self):
+ if self.info.get("main_xprt"):
+ raise Exception("Main xprts cannot be removed")
+ self.set_state("offline")
+ self.set_state("remove")
+
+ def add_command(subparser):
+ parser = subparser.add_parser("xprt", help="Commands for individual xprts")
+ parser.set_defaults(func=Xprt.show, xprt=None)
+ subparser = parser.add_subparsers()
+
+ remove = subparser.add_parser("remove", help="Remove an xprt")
+ remove.add_argument("xprt", metavar="XPRT", nargs=1,
+ help="Name of the xprt to remove")
+ remove.set_defaults(func=Xprt.set_property, property="remove")
+
+ show = subparser.add_parser("show", help="Show xprts")
+ show.add_argument("xprt", metavar="XPRT", nargs='?',
+ help="Name of a specific xprt to show")
+ show.set_defaults(func=Xprt.show)
+
+ set = subparser.add_parser("set", help="Change an xprt property")
+ set.add_argument("xprt", metavar="XPRT", nargs=1,
+ help="Name of a specific xprt to modify")
+ subparser = set.add_subparsers(required=True)
+ online = subparser.add_parser("online", help="Set an xprt online")
+ online.set_defaults(func=Xprt.set_property, property="online")
+ offline = subparser.add_parser("offline", help="Set an xprt offline")
+ offline.set_defaults(func=Xprt.set_property, property="offline")
+ dstaddr = subparser.add_parser("dstaddr", help="Change an xprt's dstaddr")
+ dstaddr.add_argument("newaddr", metavar="NEWADDR", nargs=1,
+ help="The new address for the xprt")
+ dstaddr.set_defaults(func=Xprt.set_property, property="dstaddr")
+
+ def get_by_name(name):
+ glob = f"**/{name}-*" if name else "**/xprt-*"
+ res = [ Xprt(x) for x in (sunrpc / "xprt-switches").glob(glob) ]
+ if name and len(res) == 0:
+ raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT),
+ f"{sunrpc / 'xprt-switches' / glob}")
+ return sorted(res)
+
+ def show(args):
+ for xprt in Xprt.get_by_name(args.xprt):
+ print(xprt)
+
+ def set_property(args):
+ for xprt in Xprt.get_by_name(args.xprt[0]):
+ if args.property == "dstaddr":
+ xprt.set_dstaddr(socket.gethostbyname(args.newaddr[0]))
+ elif args.property == "remove":
+ xprt.remove()
+ else:
+ xprt.set_state(args.property)
+ print(xprt)
+
+
+class XprtSwitch:
+ def __init__(self, path, sep=":"):
+ self.path = path
+ self.name = path.stem
+ self.info = read_info_file(path / "xprt_switch_info")
+ self.xprts = sorted([ Xprt(p) for p in self.path.iterdir() if p.is_dir() ])
+ self.sep = sep
+
+ def __lt__(self, rhs):
+ return self.name < rhs.name
+
+ def __str__(self):
+ switch = f"{self.name}{self.sep} " \
+ f"xprts {self.info['num_xprts']}, " \
+ f"active {self.info['num_active']}, " \
+ f"queue {self.info['queue_len']}"
+ xprts = [ f" {x.small_str()}" for x in self.xprts ]
+ return "\n".join([ switch ] + xprts)
+
+ def add_command(subparser):
+ parser = subparser.add_parser("switch", help="Commands for xprt switches")
+ parser.set_defaults(func=XprtSwitch.show, switch=None)
+ subparser = parser.add_subparsers()
+
+ show = subparser.add_parser("show", help="Show xprt switches")
+ show.add_argument("switch", metavar="SWITCH", nargs='?',
+ help="Name of a specific switch to show")
+ show.set_defaults(func=XprtSwitch.show)
+
+ set = subparser.add_parser("set", help="Change an xprt switch property")
+ set.add_argument("switch", metavar="SWITCH", nargs=1,
+ help="Name of a specific xprt switch to modify")
+ subparser = set.add_subparsers(required=True)
+ dstaddr = subparser.add_parser("dstaddr", help="Change an xprt switch's dstaddr")
+ dstaddr.add_argument("newaddr", metavar="NEWADDR", nargs=1,
+ help="The new address for the xprt switch")
+ dstaddr.set_defaults(func=XprtSwitch.set_property, property="dstaddr")
+
+ def get_by_name(name):
+ xprt_switches = sunrpc / "xprt-switches"
+ if name:
+ return [ XprtSwitch(xprt_switches / name) ]
+ return [ XprtSwitch(f) for f in sorted(xprt_switches.iterdir()) ]
+
+ def show(args):
+ for switch in XprtSwitch.get_by_name(args.switch):
+ print(switch)
+
+ def set_property(args):
+ for switch in XprtSwitch.get_by_name(args.switch[0]):
+ resolved = socket.gethostbyname(args.newaddr[0])
+ for xprt in switch.xprts:
+ xprt.set_dstaddr(resolved)
+ print(switch)
+
+
+class RpcClient:
+ def __init__(self, path):
+ self.path = path
+ self.name = path.stem
+ self.switch = XprtSwitch(path / (path / "switch").readlink(), sep=",")
+
+ def __lt__(self, rhs):
+ return self.name < rhs.name
+
+ def __str__(self):
+ return f"{self.name}: {self.switch}"
+
+ def add_command(subparser):
+ parser = subparser.add_parser("client", help="Commands for rpc clients")
+ parser.set_defaults(func=RpcClient.show, client=None)
+ subparser = parser.add_subparsers()
+
+ show = subparser.add_parser("show", help="Show rpc clients")
+ show.add_argument("client", metavar="CLIENT", nargs='?',
+ help="Name of a specific rpc client to show")
+ parser.set_defaults(func=RpcClient.show)
+
+ def get_by_name(name):
+ rpc_clients = sunrpc / "rpc-clients"
+ if name:
+ return [ RpcClient(rpc_clients / name) ]
+ return [ RpcClient(f) for f in sorted(rpc_clients.iterdir()) ]
+
+ def show(args):
+ for client in RpcClient.get_by_name(args.client):
+ print(client)
+
+
+parser = argparse.ArgumentParser()
+
+def show_small_help(args):
+ parser.print_usage()
+ print("sunrpc dir:", sunrpc)
+parser.set_defaults(func=show_small_help)
+
+subparser = parser.add_subparsers(title="commands")
+RpcClient.add_command(subparser)
+XprtSwitch.add_command(subparser)
+Xprt.add_command(subparser)
+
+args = parser.parse_args()
+try:
+ args.func(args)
+except Exception as e:
+ print(str(e))
+ sys.exit(1)
diff --git a/tools/rpcdebug/Makefile.am b/tools/rpcdebug/Makefile.am
new file mode 100644
index 0000000..b0a3e1f
--- /dev/null
+++ b/tools/rpcdebug/Makefile.am
@@ -0,0 +1,9 @@
+## Process this file with automake to produce Makefile.in
+
+man8_MANS = rpcdebug.man
+EXTRA_DIST = $(man8_MANS)
+
+sbin_PROGRAMS = rpcdebug
+rpcdebug_SOURCES = rpcdebug.c
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/tools/rpcdebug/Makefile.in b/tools/rpcdebug/Makefile.in
new file mode 100644
index 0000000..f612b53
--- /dev/null
+++ b/tools/rpcdebug/Makefile.in
@@ -0,0 +1,806 @@
+# Makefile.in generated by automake 1.16.5 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+sbin_PROGRAMS = rpcdebug$(EXEEXT)
+subdir = tools/rpcdebug
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/aclocal/ax_gcc_func_attribute.m4 \
+ $(top_srcdir)/aclocal/bsdsignals.m4 \
+ $(top_srcdir)/aclocal/getrandom.m4 \
+ $(top_srcdir)/aclocal/ipv6.m4 \
+ $(top_srcdir)/aclocal/kerberos5.m4 \
+ $(top_srcdir)/aclocal/keyutils.m4 \
+ $(top_srcdir)/aclocal/libblkid.m4 \
+ $(top_srcdir)/aclocal/libcap.m4 \
+ $(top_srcdir)/aclocal/libevent.m4 \
+ $(top_srcdir)/aclocal/libpthread.m4 \
+ $(top_srcdir)/aclocal/libsqlite3.m4 \
+ $(top_srcdir)/aclocal/libtirpc.m4 \
+ $(top_srcdir)/aclocal/libxml2.m4 \
+ $(top_srcdir)/aclocal/nfs-utils.m4 \
+ $(top_srcdir)/aclocal/rpcsec_vers.m4 \
+ $(top_srcdir)/aclocal/tcp-wrappers.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/support/include/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"
+PROGRAMS = $(sbin_PROGRAMS)
+am_rpcdebug_OBJECTS = rpcdebug.$(OBJEXT)
+rpcdebug_OBJECTS = $(am_rpcdebug_OBJECTS)
+rpcdebug_LDADD = $(LDADD)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/rpcdebug.Po
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(rpcdebug_SOURCES)
+DIST_SOURCES = $(rpcdebug_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(man8_MANS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
+AM_CPPFLAGS = @AM_CPPFLAGS@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CXXFLAGS_FOR_BUILD = @CXXFLAGS_FOR_BUILD@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ETAGS = @ETAGS@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FILECMD = @FILECMD@
+GREP = @GREP@
+GSSAPI_CFLAGS = @GSSAPI_CFLAGS@
+GSSAPI_LIBS = @GSSAPI_LIBS@
+GSSD = @GSSD@
+GSSGLUE_CFLAGS = @GSSGLUE_CFLAGS@
+GSSGLUE_LIBS = @GSSGLUE_LIBS@
+GSSKRB_CFLAGS = @GSSKRB_CFLAGS@
+GSSKRB_LIBS = @GSSKRB_LIBS@
+HAVE_GETRANDOM = @HAVE_GETRANDOM@
+HAVE_LIBWRAP = @HAVE_LIBWRAP@
+HAVE_TCP_WRAPPER = @HAVE_TCP_WRAPPER@
+IDMAPD = @IDMAPD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+K5VERS = @K5VERS@
+KRBCFLAGS = @KRBCFLAGS@
+KRBDIR = @KRBDIR@
+KRBLDFLAGS = @KRBLDFLAGS@
+KRBLIBS = @KRBLIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@
+LIBBLKID = @LIBBLKID@
+LIBBSD = @LIBBSD@
+LIBCAP = @LIBCAP@
+LIBCRYPT = @LIBCRYPT@
+LIBEVENT = @LIBEVENT@
+LIBKEYUTILS = @LIBKEYUTILS@
+LIBMOUNT = @LIBMOUNT@
+LIBMOUNT_CFLAGS = @LIBMOUNT_CFLAGS@
+LIBMOUNT_LIBS = @LIBMOUNT_LIBS@
+LIBNSL = @LIBNSL@
+LIBOBJS = @LIBOBJS@
+LIBPTHREAD = @LIBPTHREAD@
+LIBS = @LIBS@
+LIBSOCKET = @LIBSOCKET@
+LIBSQLITE = @LIBSQLITE@
+LIBTIRPC = @LIBTIRPC@
+LIBTOOL = @LIBTOOL@
+LIBWRAP = @LIBWRAP@
+LIBXML2 = @LIBXML2@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_PLUGINS = @PATH_PLUGINS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
+RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
+RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SVCGSSD = @SVCGSSD@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+VERSION = @VERSION@
+XML2_CFLAGS = @XML2_CFLAGS@
+XML2_LIBS = @XML2_LIBS@
+_rpc_pipefsmount = @_rpc_pipefsmount@
+_statedir = @_statedir@
+_sysconfdir = @_sysconfdir@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
+enable_mountconfig = @enable_mountconfig@
+enable_nfsv4 = @enable_nfsv4@
+enable_nfsv41 = @enable_nfsv41@
+enable_svcgss = @enable_svcgss@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+kprefix = @kprefix@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+mountfile = @mountfile@
+nfsconfig = @nfsconfig@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+rpc_pipefsmount = @rpc_pipefsmount@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+startstatd = @startstatd@
+statdpath = @statdpath@
+statduser = @statduser@
+statedir = @statedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+unitdir = @unitdir@
+man8_MANS = rpcdebug.man
+EXTRA_DIST = $(man8_MANS)
+rpcdebug_SOURCES = rpcdebug.c
+MAINTAINERCLEANFILES = Makefile.in
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tools/rpcdebug/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu tools/rpcdebug/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-sbinPROGRAMS: $(sbin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \
+ fi; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p \
+ || test -f $$p1 \
+ ; then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' \
+ -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-sbinPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' \
+ `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(sbindir)" && rm -f $$files
+
+clean-sbinPROGRAMS:
+ @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+rpcdebug$(EXEEXT): $(rpcdebug_OBJECTS) $(rpcdebug_DEPENDENCIES) $(EXTRA_rpcdebug_DEPENDENCIES)
+ @rm -f rpcdebug$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(rpcdebug_OBJECTS) $(rpcdebug_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rpcdebug.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(man8_MANS)
+ @$(NORMAL_INSTALL)
+ @list1='$(man8_MANS)'; \
+ list2=''; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list='$(man8_MANS)'; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(MANS)
+installdirs:
+ for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/rpcdebug.Po
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-sbinPROGRAMS
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/rpcdebug.Po
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-sbinPROGRAMS
+
+uninstall-man: uninstall-man8
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
+ clean-generic clean-libtool clean-sbinPROGRAMS cscopelist-am \
+ ctags ctags-am distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am install-sbinPROGRAMS \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \
+ uninstall-man uninstall-man8 uninstall-sbinPROGRAMS
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tools/rpcdebug/rpcdebug.c b/tools/rpcdebug/rpcdebug.c
new file mode 100644
index 0000000..ec05179
--- /dev/null
+++ b/tools/rpcdebug/rpcdebug.c
@@ -0,0 +1,364 @@
+/*
+ * Get or set RPC debug flags.
+ *
+ * I would have loved to write this without recourse to the sysctl
+ * interface, but the only plausible approach (reading and writing
+ * /dev/kmem at the offsets indicated by the _debug symbols from
+ * /proc/ksyms) didn't work, because /dev/kmem doesn't translate virtual
+ * addresses on write. Unfortunately, modules are stuffed into memory
+ * allocated via vmalloc.
+ *
+ * Copyright (C) 1996, 1997, Olaf Kirch <okir@monad.swb.de>
+ * (C) 2004 <frederic.jolly@bull.ext.net>
+ *
+ * 06/15/2004: updated for NFSv4
+ *
+ */
+
+/* #include "config.h" */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <string.h>
+#include <malloc.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <libgen.h>
+/* RPC debug flags
+ #include <sunrpc/debug.h> */
+/* NFS debug flags
+ #include <nfs_fs.h> */
+/* NFSD and NLM debug flags
+ #include <nfsd/debug.h> */
+#include <nfs/debug.h>
+
+static int verbose = 0;
+static char* cdename;
+
+static unsigned int find_flag(char **module, char *name);
+static unsigned int get_flags(char *);
+static unsigned int set_flags(char *, unsigned int value);
+static void print_flags(FILE *, char *, unsigned int, int);
+static char * strtolower(char *str);
+static void usage(int excode, char *module);
+
+int
+main(int argc, char **argv)
+{
+ int opt_s = 0,
+ opt_c = 0;
+ unsigned int flags = 0, oflags;
+ char * module = NULL;
+ int c;
+
+ cdename = malloc(strlen(basename(argv[0])));
+ if (cdename == NULL) {
+ fprintf(stderr, "failed in malloc\n");
+ exit(1);
+ }
+ strcpy(cdename, basename(argv[0]));
+
+ if (!strcmp(cdename, "nfsdebug")) {
+ module = "nfs";
+ }
+ else if (!strcmp(cdename, "nfsddebug")) {
+ module = "nfsd";
+ }
+
+ while ((c = getopt(argc, argv, "chm:sv")) != EOF) {
+ switch (c) {
+ case 'c':
+ opt_c = 1;
+ break;
+ case 'h':
+ usage(0, module); /* usage does not return */
+ break;
+ case 'm':
+ module = optarg;
+ break;
+ case 's':
+ opt_s = 1;
+ break;
+ case 'v':
+ verbose++;
+ break;
+ default:
+ fprintf(stderr, "%s: unknown option -%c\n", cdename, optopt);
+ usage(1, module);
+ }
+ }
+
+ if (opt_c + opt_s > 1) {
+ fprintf(stderr, "You can use at most one of -c and -s\n");
+ usage(1, module);
+ }
+
+ if (!module) {
+ fprintf(stderr, "%s: no module name specified.\n", cdename);
+ usage(1, module);
+ }
+
+ if (strcmp(module, "nfsd") &&
+ strcmp(module, "nfs") &&
+ strcmp(module, "nlm") &&
+ strcmp(module, "rpc")) {
+ fprintf(stderr, "%s: unknown module: %s\n", cdename, module);
+ usage(1, module);
+ }
+
+ if (argc == optind) {
+ flags = ~(unsigned int) 0;
+ } else {
+ for (; optind < argc; optind++)
+ flags |= find_flag(&module, argv[optind]);
+ if (flags && !opt_c)
+ opt_s = 1;
+ }
+
+ oflags = get_flags(module);
+
+ if (opt_c) {
+ oflags = set_flags(module, oflags & ~flags);
+ } else if (opt_s) {
+ oflags = set_flags(module, oflags | flags);
+ }
+ print_flags(stdout, module, oflags, 0);
+ if (verbose) {
+ fprintf(stdout, "\nModule Valid flags\n");
+ print_flags(stdout, module, ~(unsigned int) 0, 1);
+ }
+
+ return 0;
+}
+
+#define FLAG(mname, fname) \
+ { #mname, #fname, mname##DBG_##fname }
+
+static struct flagmap {
+ char * module;
+ char * name;
+ unsigned int value;
+} flagmap[] = {
+ /* rpc */
+ FLAG(RPC, XPRT),
+ FLAG(RPC, CALL),
+ FLAG(RPC, DEBUG),
+ FLAG(RPC, NFS),
+ FLAG(RPC, AUTH),
+ FLAG(RPC, BIND),
+ FLAG(RPC, SCHED),
+ FLAG(RPC, TRANS),
+ FLAG(RPC, SVCSOCK),
+ FLAG(RPC, SVCDSP),
+ FLAG(RPC, MISC),
+ FLAG(RPC, CACHE),
+ FLAG(RPC, ALL),
+
+ /* nfs */
+ FLAG(NFS, VFS),
+ FLAG(NFS, DIRCACHE),
+ FLAG(NFS, LOOKUPCACHE),
+ FLAG(NFS, PAGECACHE),
+ FLAG(NFS, PROC),
+ FLAG(NFS, XDR),
+ FLAG(NFS, FILE),
+ FLAG(NFS, ROOT),
+ FLAG(NFS, CALLBACK),
+ FLAG(NFS, CLIENT),
+ FLAG(NFS, MOUNT),
+ FLAG(NFS, FSCACHE),
+ FLAG(NFS, PNFS),
+ FLAG(NFS, PNFS_LD),
+ FLAG(NFS, STATE),
+ FLAG(NFS, ALL),
+
+ /* nfsd */
+ FLAG(NFSD, SOCK),
+ FLAG(NFSD, FH),
+ FLAG(NFSD, EXPORT),
+ FLAG(NFSD, SVC),
+ FLAG(NFSD, PROC),
+ FLAG(NFSD, FILEOP),
+ FLAG(NFSD, AUTH),
+ FLAG(NFSD, REPCACHE),
+ FLAG(NFSD, XDR),
+ FLAG(NFSD, LOCKD),
+ FLAG(NFSD, ALL),
+
+ /* lockd */
+ FLAG(NLM, SVC),
+ FLAG(NLM, CLIENT),
+ FLAG(NLM, CLNTLOCK),
+ FLAG(NLM, SVCLOCK),
+ FLAG(NLM, MONITOR),
+ FLAG(NLM, CLNTSUBS),
+ FLAG(NLM, SVCSUBS),
+ FLAG(NLM, HOSTCACHE),
+ FLAG(NLM, XDR),
+ FLAG(NLM, ALL),
+
+ { NULL, NULL, 0 }
+};
+
+static unsigned int
+find_flag(char **module, char *name)
+{
+ char *mod = *module;
+ unsigned int value = 0;
+ int i;
+
+ for (i = 0; flagmap[i].module; i++) {
+ if ((mod && strcasecmp(mod, flagmap[i].module))
+ || strcasecmp(name, flagmap[i].name))
+ continue;
+ if (value) {
+ fprintf(stderr,
+ "%s: ambiguous symbol name %s.\n"
+ "This name is used by more than one module, "
+ "please specify the module name using\n"
+ "the -m option.\n",
+ cdename, name);
+ exit(1);
+ }
+ value = flagmap[i].value;
+ if (*module)
+ return value;
+ mod = flagmap[i].module;
+ }
+
+ if (!value) {
+ if (*module)
+ fprintf(stderr,
+ "%s: unknown module or flag %s/%s\n",
+ cdename, *module, name);
+ else
+ fprintf(stderr,
+ "%s: unknown flag %s\n",
+ cdename, name);
+ exit(1);
+ }
+
+ *module = mod;
+ return value;
+}
+
+static unsigned int
+get_flags(char *module)
+{
+ char buffer[256], filename[256];
+ int sysfd, len;
+
+ snprintf(filename, 256, "/proc/sys/sunrpc/%s_debug", module);
+
+ if ((sysfd = open(filename, O_RDONLY)) < 0) {
+ perror(filename);
+ exit(1);
+ }
+ if ((len = read(sysfd, buffer, sizeof(buffer))) <= 0) {
+ perror("read");
+ exit(1);
+ }
+ close(sysfd);
+ buffer[len - 1] = '\0';
+
+ return strtoul(buffer, NULL, 0);
+}
+
+static unsigned int
+set_flags(char *module, unsigned int value)
+{
+ char buffer[64], filename[256];
+ int sysfd, len, ret;
+
+ snprintf(filename, 256, "/proc/sys/sunrpc/%s_debug", module);
+
+ len = sprintf(buffer, "%d", value);
+ if ((sysfd = open(filename, O_WRONLY)) < 0) {
+ perror(filename);
+ exit(1);
+ }
+ if ((ret = write(sysfd, buffer, len)) < 0) {
+ perror("write");
+ exit(1);
+ }
+ if (ret < len) {
+ fprintf(stderr, "error: short write in set_flags!\n");
+ exit(1);
+ }
+ close(sysfd);
+ return value;
+}
+
+
+static char *
+strtolower(char *str)
+{
+ static char temp[64];
+ char *sp;
+
+ strcpy(temp, str);
+ for (sp = temp; *sp; sp++)
+ *sp = tolower(*sp);
+ return temp;
+}
+
+static void
+print_flags(FILE *ofp, char *module, unsigned int flags, int show_all)
+{
+ char *lastmod = NULL;
+ unsigned int shown = 0;
+ int i;
+
+ if (module) {
+ fprintf(ofp, "%-10s", strtolower(module));
+ if (!flags) {
+ fprintf(ofp, "<no flags set>\n");
+ return;
+ }
+ }
+
+ for (i = 0, shown = 0; flagmap[i].module; i++) {
+ if (module) {
+ if (strcasecmp(flagmap[i].module, module))
+ continue;
+ } else if (!lastmod || strcmp(lastmod, flagmap[i].module)) {
+ if (lastmod) {
+ fprintf(ofp, "\n");
+ shown = 0;
+ }
+ fprintf(ofp, "%-10s", strtolower(flagmap[i].module));
+ lastmod = flagmap[i].module;
+ }
+ if (!(flags & flagmap[i].value)
+ || (!show_all && (shown & flagmap[i].value))
+ || (module && !strcasecmp(flagmap[i].name, "all")))
+ continue;
+ fprintf(ofp, " %s", strtolower(flagmap[i].name));
+ shown |= flagmap[i].value;
+ }
+ fprintf(ofp, "\n");
+}
+
+static void
+usage(int excode, char *module)
+{
+ if (module)
+ fprintf(stderr, "usage: %s [-v] [-h] [-s flags...|-c flags...]\n", cdename);
+ else
+ fprintf(stderr, "usage: %s [-v] [-h] [-m module] [-s flags...|-c flags...]\n", cdename);
+ fprintf(stderr, " set or cancel debug flags.\n");
+ if (verbose) {
+ fprintf(stderr, "\nModule Valid flags\n");
+ print_flags(stderr, module, ~(unsigned int) 0, 1);
+ } else {
+ if (module)
+ fprintf(stderr, " (use %s -vh to get a list of valid flags)\n", cdename);
+ else
+ fprintf(stderr, " (use %s -vh to get a list of modules and valid flags)\n", cdename);
+ }
+ exit (excode);
+}
+
diff --git a/tools/rpcdebug/rpcdebug.man b/tools/rpcdebug/rpcdebug.man
new file mode 100644
index 0000000..e65598a
--- /dev/null
+++ b/tools/rpcdebug/rpcdebug.man
@@ -0,0 +1,88 @@
+.\"
+.\" rpcdebug(8)
+.\"
+.\" By Greg Banks <gnb@melbourne.sgi.com>
+.\" Copyright (c) 2006 Silicon Graphics, Inc.
+.\" Derived from nfsstat.man which bore the message:
+.\" Copyright (C) 1996-2005 Olaf Kirch <okir@suse.de>
+.TH rpcdebug 8 "5 Jul 2006"
+.SH NAME
+rpcdebug \- set and clear NFS and RPC kernel debug flags
+.SH SYNOPSIS
+\fBrpcdebug\fP \fB\-vh\fP
+.br
+\fBrpcdebug\fP \fB\-m\fP \fImodule\fP
+.br
+\fBrpcdebug\fP \fB\-m\fP \fImodule\fP \fB\-s\fP \fIflags\fP...
+.br
+\fBrpcdebug\fP \fB\-m\fP \fImodule\fP \fB\-c\fP \fIflags\fP...
+.br
+.SH DESCRIPTION
+The \fBrpcdebug\fP command allows an administrator to set and clear
+the Linux kernel's NFS client and server debug flags. Setting these
+flags causes the kernel to emit messages to the system log in response
+to NFS activity; this is typically useful when debugging NFS problems.
+.PP
+The first form in the synopsis can be used to list all available
+debug flags. The second form shows the currently set debug flags
+for the given module. The third form sets one or more flags, and
+the fourth form clears one or more flags.
+.PP
+The value \fBall\fP may be used to set or clear all the flags for
+the given module.
+.SH OPTIONS
+.\" -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+.TP
+.B \-c
+Clear the given debug flags.
+.\" -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+.TP
+.B \-h
+Print a help message and exit. When combined with the \fB\-v\fP
+option, also prints the available debug flags.
+.\" -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+.TP
+.BI \-m " module"
+Specify which module's flags to set or clear. Available
+modules are:
+.RS
+.TP
+.BR nfsd
+The NFS server.
+.TP
+.BR nfs
+The NFS client.
+.TP
+.BR nlm
+The Network Lock Manager, in either an NFS client or server.
+.TP
+.BR rpc
+The Remote Procedure Call module, in either an NFS client or server.
+.RE
+.\" -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+.TP
+.B \-s
+Set the given debug flags.
+.\" -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+.TP
+.B \-v
+Increase the verbosity of \fBrpcdebug\fP's output.
+.\" -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+.SH FILES
+.TP
+.B /proc/sys/sunrpc/{rpc,nfs,nfsd,nlm}_debug
+procfs\-based interface to kernel debug flags.
+.\" -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+.SH SEE ALSO
+.BR rpc.nfsd (8),
+.BR nfs (5),
+.BR syslogd (8).
+.\" -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+.SH BUGS
+Bugs can be found or reported at
+.BR http://nfs.sf.net/ .
+.\" -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+.SH AUTHOR
+Program by Olaf Kirch <okir@suse.de> and
+<frederic.jolly@bull.ext.net>.
+Manpage by Greg Banks <gnb@melbourne.sgi.com>.
diff --git a/tools/rpcgen/Makefile.am b/tools/rpcgen/Makefile.am
new file mode 100644
index 0000000..457cd50
--- /dev/null
+++ b/tools/rpcgen/Makefile.am
@@ -0,0 +1,13 @@
+CLEANFILES = *~
+
+bin_PROGRAMS = rpcgen
+man_MANS = rpcgen.1
+
+EXTRA_DIST=${MANS}
+
+noinst_HEADERS = proto.h rpc_parse.h rpc_scan.h rpc_util.h
+
+rpcgen_SOURCES = rpc_clntout.c rpc_cout.c rpc_hout.c rpc_main.c \
+ rpc_parse.c rpc_sample.c rpc_scan.c rpc_svcout.c rpc_tblout.c \
+ rpc_util.c
+rpcgen_LDADD = $(LIBINTL)
diff --git a/tools/rpcgen/Makefile.in b/tools/rpcgen/Makefile.in
new file mode 100644
index 0000000..85bd78a
--- /dev/null
+++ b/tools/rpcgen/Makefile.in
@@ -0,0 +1,850 @@
+# Makefile.in generated by automake 1.16.5 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+bin_PROGRAMS = rpcgen$(EXEEXT)
+subdir = tools/rpcgen
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/aclocal/ax_gcc_func_attribute.m4 \
+ $(top_srcdir)/aclocal/bsdsignals.m4 \
+ $(top_srcdir)/aclocal/getrandom.m4 \
+ $(top_srcdir)/aclocal/ipv6.m4 \
+ $(top_srcdir)/aclocal/kerberos5.m4 \
+ $(top_srcdir)/aclocal/keyutils.m4 \
+ $(top_srcdir)/aclocal/libblkid.m4 \
+ $(top_srcdir)/aclocal/libcap.m4 \
+ $(top_srcdir)/aclocal/libevent.m4 \
+ $(top_srcdir)/aclocal/libpthread.m4 \
+ $(top_srcdir)/aclocal/libsqlite3.m4 \
+ $(top_srcdir)/aclocal/libtirpc.m4 \
+ $(top_srcdir)/aclocal/libxml2.m4 \
+ $(top_srcdir)/aclocal/nfs-utils.m4 \
+ $(top_srcdir)/aclocal/rpcsec_vers.m4 \
+ $(top_srcdir)/aclocal/tcp-wrappers.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \
+ $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/support/include/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"
+PROGRAMS = $(bin_PROGRAMS)
+am_rpcgen_OBJECTS = rpc_clntout.$(OBJEXT) rpc_cout.$(OBJEXT) \
+ rpc_hout.$(OBJEXT) rpc_main.$(OBJEXT) rpc_parse.$(OBJEXT) \
+ rpc_sample.$(OBJEXT) rpc_scan.$(OBJEXT) rpc_svcout.$(OBJEXT) \
+ rpc_tblout.$(OBJEXT) rpc_util.$(OBJEXT)
+rpcgen_OBJECTS = $(am_rpcgen_OBJECTS)
+rpcgen_DEPENDENCIES =
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/rpc_clntout.Po \
+ ./$(DEPDIR)/rpc_cout.Po ./$(DEPDIR)/rpc_hout.Po \
+ ./$(DEPDIR)/rpc_main.Po ./$(DEPDIR)/rpc_parse.Po \
+ ./$(DEPDIR)/rpc_sample.Po ./$(DEPDIR)/rpc_scan.Po \
+ ./$(DEPDIR)/rpc_svcout.Po ./$(DEPDIR)/rpc_tblout.Po \
+ ./$(DEPDIR)/rpc_util.Po
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(rpcgen_SOURCES)
+DIST_SOURCES = $(rpcgen_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+man1dir = $(mandir)/man1
+NROFF = nroff
+MANS = $(man_MANS)
+HEADERS = $(noinst_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp README
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
+AM_CPPFLAGS = @AM_CPPFLAGS@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CXXFLAGS_FOR_BUILD = @CXXFLAGS_FOR_BUILD@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ETAGS = @ETAGS@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FILECMD = @FILECMD@
+GREP = @GREP@
+GSSAPI_CFLAGS = @GSSAPI_CFLAGS@
+GSSAPI_LIBS = @GSSAPI_LIBS@
+GSSD = @GSSD@
+GSSGLUE_CFLAGS = @GSSGLUE_CFLAGS@
+GSSGLUE_LIBS = @GSSGLUE_LIBS@
+GSSKRB_CFLAGS = @GSSKRB_CFLAGS@
+GSSKRB_LIBS = @GSSKRB_LIBS@
+HAVE_GETRANDOM = @HAVE_GETRANDOM@
+HAVE_LIBWRAP = @HAVE_LIBWRAP@
+HAVE_TCP_WRAPPER = @HAVE_TCP_WRAPPER@
+IDMAPD = @IDMAPD@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+K5VERS = @K5VERS@
+KRBCFLAGS = @KRBCFLAGS@
+KRBDIR = @KRBDIR@
+KRBLDFLAGS = @KRBLDFLAGS@
+KRBLIBS = @KRBLIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@
+LIBBLKID = @LIBBLKID@
+LIBBSD = @LIBBSD@
+LIBCAP = @LIBCAP@
+LIBCRYPT = @LIBCRYPT@
+LIBEVENT = @LIBEVENT@
+LIBKEYUTILS = @LIBKEYUTILS@
+LIBMOUNT = @LIBMOUNT@
+LIBMOUNT_CFLAGS = @LIBMOUNT_CFLAGS@
+LIBMOUNT_LIBS = @LIBMOUNT_LIBS@
+LIBNSL = @LIBNSL@
+LIBOBJS = @LIBOBJS@
+LIBPTHREAD = @LIBPTHREAD@
+LIBS = @LIBS@
+LIBSOCKET = @LIBSOCKET@
+LIBSQLITE = @LIBSQLITE@
+LIBTIRPC = @LIBTIRPC@
+LIBTOOL = @LIBTOOL@
+LIBWRAP = @LIBWRAP@
+LIBXML2 = @LIBXML2@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_PLUGINS = @PATH_PLUGINS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+RANLIB = @RANLIB@
+RELEASE = @RELEASE@
+RPCGEN_PATH = @RPCGEN_PATH@
+RPCSECGSS_CFLAGS = @RPCSECGSS_CFLAGS@
+RPCSECGSS_LIBS = @RPCSECGSS_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SVCGSSD = @SVCGSSD@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+VERSION = @VERSION@
+XML2_CFLAGS = @XML2_CFLAGS@
+XML2_LIBS = @XML2_LIBS@
+_rpc_pipefsmount = @_rpc_pipefsmount@
+_statedir = @_statedir@
+_sysconfdir = @_sysconfdir@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
+enable_mountconfig = @enable_mountconfig@
+enable_nfsv4 = @enable_nfsv4@
+enable_nfsv41 = @enable_nfsv41@
+enable_svcgss = @enable_svcgss@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+kprefix = @kprefix@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+mountfile = @mountfile@
+nfsconfig = @nfsconfig@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+rpc_pipefsmount = @rpc_pipefsmount@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+startstatd = @startstatd@
+statdpath = @statdpath@
+statduser = @statduser@
+statedir = @statedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+unitdir = @unitdir@
+CLEANFILES = *~
+man_MANS = rpcgen.1
+EXTRA_DIST = ${MANS}
+noinst_HEADERS = proto.h rpc_parse.h rpc_scan.h rpc_util.h
+rpcgen_SOURCES = rpc_clntout.c rpc_cout.c rpc_hout.c rpc_main.c \
+ rpc_parse.c rpc_sample.c rpc_scan.c rpc_svcout.c rpc_tblout.c \
+ rpc_util.c
+
+rpcgen_LDADD = $(LIBINTL)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tools/rpcgen/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu tools/rpcgen/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+ fi; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p \
+ || test -f $$p1 \
+ ; then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' \
+ -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' \
+ `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+ @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+rpcgen$(EXEEXT): $(rpcgen_OBJECTS) $(rpcgen_DEPENDENCIES) $(EXTRA_rpcgen_DEPENDENCIES)
+ @rm -f rpcgen$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(rpcgen_OBJECTS) $(rpcgen_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rpc_clntout.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rpc_cout.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rpc_hout.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rpc_main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rpc_parse.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rpc_sample.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rpc_scan.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rpc_svcout.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rpc_tblout.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rpc_util.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man1: $(man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(man_MANS)'; \
+ test -n "$(man1dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.1[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man1:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man1dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.1[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(MANS) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/rpc_clntout.Po
+ -rm -f ./$(DEPDIR)/rpc_cout.Po
+ -rm -f ./$(DEPDIR)/rpc_hout.Po
+ -rm -f ./$(DEPDIR)/rpc_main.Po
+ -rm -f ./$(DEPDIR)/rpc_parse.Po
+ -rm -f ./$(DEPDIR)/rpc_sample.Po
+ -rm -f ./$(DEPDIR)/rpc_scan.Po
+ -rm -f ./$(DEPDIR)/rpc_svcout.Po
+ -rm -f ./$(DEPDIR)/rpc_tblout.Po
+ -rm -f ./$(DEPDIR)/rpc_util.Po
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man1
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/rpc_clntout.Po
+ -rm -f ./$(DEPDIR)/rpc_cout.Po
+ -rm -f ./$(DEPDIR)/rpc_hout.Po
+ -rm -f ./$(DEPDIR)/rpc_main.Po
+ -rm -f ./$(DEPDIR)/rpc_parse.Po
+ -rm -f ./$(DEPDIR)/rpc_sample.Po
+ -rm -f ./$(DEPDIR)/rpc_scan.Po
+ -rm -f ./$(DEPDIR)/rpc_svcout.Po
+ -rm -f ./$(DEPDIR)/rpc_tblout.Po
+ -rm -f ./$(DEPDIR)/rpc_util.Po
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-man
+
+uninstall-man: uninstall-man1
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
+ clean-binPROGRAMS clean-generic clean-libtool cscopelist-am \
+ ctags ctags-am distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-binPROGRAMS \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-man1 \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \
+ uninstall-binPROGRAMS uninstall-man uninstall-man1
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tools/rpcgen/README b/tools/rpcgen/README
new file mode 100644
index 0000000..2f6bbf3
--- /dev/null
+++ b/tools/rpcgen/README
@@ -0,0 +1,8 @@
+
+ This directory contains the source for rpcgen.new from Sun TIRPC
+ source distribution. I cleaned it up a little so that it will
+ compile with gcc (without using -traditional), and modified the
+ output to avoid those silly warnings you usually get when compiling
+ an rpcgen-generated C file.
+
+ Olaf Kirch <okir@monad.swb.de> 8 Oct 1996
diff --git a/tools/rpcgen/proto.h b/tools/rpcgen/proto.h
new file mode 100644
index 0000000..ea28565
--- /dev/null
+++ b/tools/rpcgen/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/tools/rpcgen/rpc_clntout.c b/tools/rpcgen/rpc_clntout.c
new file mode 100644
index 0000000..9b6a4aa
--- /dev/null
+++ b/tools/rpcgen/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;
+ int 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/tools/rpcgen/rpc_cout.c b/tools/rpcgen/rpc_cout.c
new file mode 100644
index 0000000..4627110
--- /dev/null
+++ b/tools/rpcgen/rpc_cout.c
@@ -0,0 +1,813 @@
+/*
+ * 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 ();
+ }
+}
+
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+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");
+}
+#pragma GCC diagnostic warning "-Wformat-nonliteral"
+
+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/tools/rpcgen/rpc_hout.c b/tools/rpcgen/rpc_hout.c
new file mode 100644
index 0000000..10f793d
--- /dev/null
+++ b/tools/rpcgen/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/tools/rpcgen/rpc_main.c b/tools/rpcgen/rpc_main.c
new file mode 100644
index 0000000..277adc6
--- /dev/null
+++ b/tools/rpcgen/rpc_main.c
@@ -0,0 +1,1459 @@
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.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 "nls.h"
+
+#ifndef _
+#define _(String) gettext (String)
+#endif
+
+#define EXTEND 1 /* alias for TRUE */
+#define DONT_EXTEND 0 /* alias for FALSE */
+
+#ifdef __APPLE__
+# if __DARWIN_ONLY_64_BIT_INO_T
+# define stat64 stat
+# endif
+#endif
+
+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, default is backward compatibility */
+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 (PACKAGE);
+
+ (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'];
+
+ 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"));
+
+ exit (status);
+}
+
+static void
+print_version (void)
+{
+ printf ("rpcgen (%s) %s\n", PACKAGE, VERSION);
+ exit (0);
+}
diff --git a/tools/rpcgen/rpc_output.h b/tools/rpcgen/rpc_output.h
new file mode 100644
index 0000000..eb25a60
--- /dev/null
+++ b/tools/rpcgen/rpc_output.h
@@ -0,0 +1,16 @@
+/*
+ * rpc_output.h
+ *
+ * Declarations for output functions
+ *
+ */
+
+#ifndef RPCGEN_NEW_OUTPUT_H
+#define RPCGEN_NEW_OUTPUT_H
+
+void write_msg_out(void);
+int nullproc(proc_list *);
+void printarglist(proc_list *, char *, char *);
+void pdeclaration(char *, declaration *, int, char *);
+
+#endif /* RPCGEN_NEW_OUTPUT_H */
diff --git a/tools/rpcgen/rpc_parse.c b/tools/rpcgen/rpc_parse.c
new file mode 100644
index 0000000..ee37430
--- /dev/null
+++ b/tools/rpcgen/rpc_parse.c
@@ -0,0 +1,686 @@
+/*
+ * 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_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;
+ int isvoid = 0; /* 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 = 0;
+ /* 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 = 1;
+ 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 = 1;
+ 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[MAXLINESIZE]; /* 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/tools/rpcgen/rpc_parse.h b/tools/rpcgen/rpc_parse.h
new file mode 100644
index 0000000..e2e2f1e
--- /dev/null
+++ b/tools/rpcgen/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/tools/rpcgen/rpc_sample.c b/tools/rpcgen/rpc_sample.c
new file mode 100644
index 0000000..e90b58c
--- /dev/null
+++ b/tools/rpcgen/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/tools/rpcgen/rpc_scan.c b/tools/rpcgen/rpc_scan.c
new file mode 100644
index 0000000..7de6112
--- /dev/null
+++ b/tools/rpcgen/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>
+#include "rpc_scan.h"
+#include "rpc_parse.h"
+#include "rpc_util.h"
+#include "proto.h"
+#include "nls.h"
+
+#ifndef _
+#define _(String) gettext (String)
+#endif
+
+#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/tools/rpcgen/rpc_scan.h b/tools/rpcgen/rpc_scan.h
new file mode 100644
index 0000000..9786a51
--- /dev/null
+++ b/tools/rpcgen/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/tools/rpcgen/rpc_svcout.c b/tools/rpcgen/rpc_svcout.c
new file mode 100644
index 0000000..4f12a81
--- /dev/null
+++ b/tools/rpcgen/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 saddr;\n");
+ f_print (fout, "\tint asize = sizeof (saddr);\n");
+ f_print (fout, "\n");
+ f_print (fout,
+ "\tif (getsockname (0, (struct sockaddr *)&saddr, &asize) == 0) {\n");
+ f_print (fout, "\t\tint ssize = sizeof (int);\n\n");
+ f_print (fout, "\t\tif (saddr.sin_family != AF_INET)\n");
+ f_print (fout, "\t\t\texit (1);\n");
+ f_print (fout, "\t\tif (getsockopt (0, SOL_SOCKET, SO_TYPE,\n");
+ f_print (fout, "\t\t\t\t(char *)&_rpcfdtype, &ssize) == -1)\n");
+ f_print (fout, "\t\t\texit (1);\n");
+ f_print (fout, "\t\tsock = 0;\n");
+ f_print (fout, "\t\t_rpcpmstart = 1;\n");
+ f_print (fout, "\t\tproto = 0;\n");
+ open_log_file (infile, "\t\t");
+ f_print (fout, "\t} else {\n");
+ write_rpc_svc_fg (infile, "\t\t");
+ f_print (fout, "\t\tsock = RPC_ANYSOCK;\n");
+ print_pmapunset ("\t\t");
+ f_print (fout, "\t}\n");
+}
+
+static void
+print_return (const char *space)
+{
+ if (exitnow)
+ f_print (fout, "%sexit (0);\n", space);
+ else
+ {
+ if (timerflag)
+ {
+#if 0
+ f_print (fout, "%s_rpcsvcdirty = 0;\n", space);
+#else
+ if (mtflag)
+ f_print(fout, "%smutex_lock(&_svcstate_lock);\n", space);
+ f_print(fout, "%s_rpcsvcstate = _SERVED;\n", space);
+ if (mtflag)
+ f_print(fout, "%smutex_unlock(&_svcstate_lock);\n", space);
+#endif
+ }
+ f_print (fout, "%sreturn;\n", space);
+ }
+}
+
+static void
+print_pmapunset (const char *space)
+{
+ list *l;
+ definition *def;
+ version_list *vp;
+
+ for (l = defined; l != NULL; l = l->next)
+ {
+ def = (definition *) l->val;
+ if (def->def_kind == DEF_PROGRAM)
+ {
+ for (vp = def->def.pr.versions; vp != NULL;
+ vp = vp->next)
+ {
+ f_print (fout, "%spmap_unset (%s, %s);\n",
+ space, def->def_name, vp->vers_name);
+ }
+ }
+ }
+}
+
+static void
+print_err_message (const char *space)
+{
+ if (logflag)
+ f_print (fout, "%ssyslog (LOG_ERR, \"%%s\", \"%s\");\n", space, _errbuf);
+ else if (inetdflag || pmflag)
+ f_print (fout, "%s_msgout (\"%s\");\n", space, _errbuf);
+ else
+ f_print (fout, "%sfprintf (stderr, \"%%s\", \"%s\");\n", space, _errbuf);
+}
+
+/*
+ * Write the server auxiliary function ( _msgout, timeout)
+ */
+void
+write_svc_aux (int nomain)
+{
+ if (!logflag)
+ write_msg_out ();
+ if (!nomain)
+ write_timeout_func ();
+}
+
+/*
+ * Write the _msgout function
+ */
+
+void
+write_msg_out (void)
+{
+ f_print (fout, "\n");
+ f_print (fout, "static\n");
+ if (!Cflag)
+ {
+ f_print (fout, "void _msgout (msg)\n");
+ f_print (fout, "\tchar *msg;\n");
+ }
+ else
+ {
+ f_print (fout, "void _msgout (char* msg)\n");
+ }
+ f_print (fout, "{\n");
+ f_print (fout, "#ifdef RPC_SVC_FG\n");
+ if (inetdflag || pmflag)
+ f_print (fout, "\tif (_rpcpmstart)\n");
+ f_print (fout, "\t\tsyslog (LOG_ERR, \"%%s\", msg);\n");
+ f_print (fout, "\telse\n");
+ f_print (fout, "\t\tfprintf (stderr, \"%%s\\n\", msg);\n");
+ f_print (fout, "#else\n");
+ f_print (fout, "\tsyslog (LOG_ERR, \"%%s\", msg);\n");
+ f_print (fout, "#endif\n");
+ f_print (fout, "}\n");
+}
+
+/*
+ * Write the timeout function
+ */
+static void
+write_timeout_func (void)
+{
+ if (!timerflag)
+ return;
+ f_print (fout, "\n");
+ f_print (fout, "static void\n");
+ if (Cflag)
+ f_print (fout, "closedown (int sig)\n");
+ else
+ f_print (fout, "closedown (sig)\n\tint sig;\n");
+ f_print (fout, "{\n");
+
+#if 0
+ f_print (fout, "\t(void) signal (sig, %s closedown);\n",
+ Cflag ? "(SIG_PF)" : "(void(*)())");
+#endif
+ if (mtflag)
+ f_print(fout, "\tmutex_lock(&_svcstate_lock);\n");
+#if 0
+ f_print (fout, "\tif (_rpcsvcdirty == 0) {\n");
+#else
+ f_print(fout, "\tif (_rpcsvcstate == _IDLE) {\n");
+#endif
+ f_print (fout, "\t\textern fd_set svc_fdset;\n");
+ f_print (fout, "\t\tstatic int size;\n");
+ f_print (fout, "\t\tint i, openfd;\n");
+ if (tirpcflag && pmflag)
+ {
+ f_print (fout, "\t\tstruct t_info tinfo;\n\n");
+ f_print (fout, "\t\tif (!t_getinfo(0, &tinfo) && (tinfo.servtype == T_CLTS))\n");
+ }
+ else
+ {
+ f_print (fout, "\n\t\tif (_rpcfdtype == SOCK_DGRAM)\n");
+ }
+ f_print (fout, "\t\t\texit (0);\n");
+ f_print (fout, "\t\tif (size == 0) {\n");
+ if (tirpcflag)
+ {
+ f_print (fout, "\t\t\tstruct rlimit rl;\n\n");
+ f_print (fout, "\t\t\trl.rlim_max = 0;\n");
+ f_print (fout, "\t\t\tgetrlimit(RLIMIT_NOFILE, &rl);\n");
+ f_print (fout, "\t\t\tif ((size = rl.rlim_max) == 0) {\n");
+ if (mtflag)
+ f_print(fout, "\t\t\t\tmutex_unlock(&_svcstate_lock);\n");
+ f_print (fout, "\t\t\t\treturn;\n\t\t\t}\n");
+ }
+ else
+ {
+ f_print (fout, "\t\t\tsize = getdtablesize();\n");
+ }
+ f_print (fout, "\t\t}\n");
+ f_print (fout, "\t\tfor (i = 0, openfd = 0; i < size && openfd < 2; i++)\n");
+ f_print (fout, "\t\t\tif (FD_ISSET(i, &svc_fdset))\n");
+ f_print (fout, "\t\t\t\topenfd++;\n");
+ f_print (fout, "\t\tif (openfd <= 1)\n");
+ f_print (fout, "\t\t\texit (0);\n");
+ f_print (fout, "\t}\n");
+ f_print(fout, "\tif (_rpcsvcstate == _SERVED)\n");
+ f_print(fout, "\t\t_rpcsvcstate = _IDLE;\n\n");
+ if (mtflag)
+ f_print(fout, "\tmutex_unlock(&_svcstate_lock);\n");
+ f_print(fout, "\t(void) signal(SIGALRM, %s closedown);\n",
+ Cflag? "(SIG_PF)" : "(void(*)())");
+ f_print (fout, "\talarm (_RPCSVC_CLOSEDOWN);\n");
+ f_print (fout, "}\n");
+}
+
+/*
+ * Write the most of port monitor support
+ */
+static void
+write_pm_most (const char *infile, int netflag)
+{
+ list *l;
+ definition *def;
+ version_list *vp;
+
+ f_print (fout, "\tif (!ioctl(0, I_LOOK, mname) &&\n");
+ f_print (fout, "\t\t(!strcmp(mname, \"sockmod\") ||");
+ f_print (fout, " !strcmp(mname, \"timod\"))) {\n");
+ f_print (fout, "\t\tchar *netid;\n");
+ if (!netflag)
+ { /* Not included by -n option */
+ f_print (fout, "\t\tstruct netconfig *nconf = NULL;\n");
+ f_print (fout, "\t\tSVCXPRT *%s;\n", TRANSP);
+ }
+ if (timerflag)
+ f_print (fout, "\t\tint pmclose;\n");
+/* not necessary, defined in /usr/include/stdlib */
+/* f_print(fout, "\t\textern char *getenv();\n"); */
+ f_print (fout, "\n");
+ f_print (fout, "\t\t_rpcpmstart = 1;\n");
+ if (logflag)
+ open_log_file (infile, "\t\t");
+ f_print (fout, "\t\tif ((netid = getenv(\"NLSPROVIDER\")) == NULL) {\n");
+ sprintf (_errbuf, "cannot get transport name");
+ print_err_message ("\t\t\t");
+ f_print (fout, "\t\t} else if ((nconf = getnetconfigent(netid)) == NULL) {\n");
+ sprintf (_errbuf, "cannot get transport info");
+ print_err_message ("\t\t\t");
+ f_print (fout, "\t\t}\n");
+ /*
+ * A kludgy support for inetd services. Inetd only works with
+ * sockmod, and RPC works only with timod, hence all this jugglery
+ */
+ f_print (fout, "\t\tif (strcmp(mname, \"sockmod\") == 0) {\n");
+ f_print (fout, "\t\t\tif (ioctl(0, I_POP, 0) || ioctl(0, I_PUSH, \"timod\")) {\n");
+ sprintf (_errbuf, "could not get the right module");
+ print_err_message ("\t\t\t\t");
+ f_print (fout, "\t\t\t\texit(1);\n");
+ f_print (fout, "\t\t\t}\n");
+ f_print (fout, "\t\t}\n");
+ if (timerflag)
+ f_print (fout, "\t\tpmclose = (t_getstate(0) != T_DATAXFER);\n");
+ f_print (fout, "\t\tif ((%s = svc_tli_create(0, nconf, NULL, 0, 0)) == NULL) {\n",
+ TRANSP);
+ sprintf (_errbuf, "cannot create server handle");
+ print_err_message ("\t\t\t");
+ f_print (fout, "\t\t\texit(1);\n");
+ f_print (fout, "\t\t}\n");
+ f_print (fout, "\t\tif (nconf)\n");
+ f_print (fout, "\t\t\tfreenetconfigent(nconf);\n");
+ for (l = defined; l != NULL; l = l->next)
+ {
+ def = (definition *) l->val;
+ if (def->def_kind != DEF_PROGRAM)
+ {
+ continue;
+ }
+ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next)
+ {
+ f_print (fout,
+ "\t\tif (!svc_reg(%s, %s, %s, ",
+ TRANSP, def->def_name, vp->vers_name);
+ pvname (def->def_name, vp->vers_num);
+ f_print (fout, ", 0)) {\n");
+ (void) sprintf (_errbuf, "unable to register (%s, %s).",
+ def->def_name, vp->vers_name);
+ print_err_message ("\t\t\t");
+ f_print (fout, "\t\t\texit(1);\n");
+ f_print (fout, "\t\t}\n");
+ }
+ }
+ if (timerflag)
+ {
+ f_print (fout, "\t\tif (pmclose) {\n");
+ f_print (fout, "\t\t\t(void) signal(SIGALRM, %s closedown);\n",
+ Cflag ? "(SIG_PF)" : "(void(*)())");
+ f_print (fout, "\t\t\t(void) alarm(_RPCSVC_CLOSEDOWN);\n");
+ f_print (fout, "\t\t}\n");
+ }
+ f_print (fout, "\t\tsvc_run();\n");
+ f_print (fout, "\t\texit(1);\n");
+ f_print (fout, "\t\t/* NOTREACHED */\n");
+ f_print (fout, "\t}\n");
+}
+
+/*
+ * Support for backgrounding the server if self started.
+ */
+static void
+write_rpc_svc_fg (const char *infile, const char *sp)
+{
+ f_print (fout, "#ifndef RPC_SVC_FG\n");
+ f_print (fout, "%sint size;\n", sp);
+ if (tirpcflag)
+ f_print (fout, "%sstruct rlimit rl;\n", sp);
+ if (inetdflag)
+ f_print (fout, "%sint pid, i;\n\n", sp);
+ f_print (fout, "%spid = fork();\n", sp);
+ f_print (fout, "%sif (pid < 0) {\n", sp);
+ f_print (fout, "%s\tperror(\"cannot fork\");\n", sp);
+ f_print (fout, "%s\texit(1);\n", sp);
+ f_print (fout, "%s}\n", sp);
+ f_print (fout, "%sif (pid)\n", sp);
+ f_print (fout, "%s\texit(0);\n", sp);
+ /* get number of file descriptors */
+ if (tirpcflag)
+ {
+ f_print (fout, "%srl.rlim_max = 0;\n", sp);
+ f_print (fout, "%sgetrlimit(RLIMIT_NOFILE, &rl);\n", sp);
+ f_print (fout, "%sif ((size = rl.rlim_max) == 0)\n", sp);
+ f_print (fout, "%s\texit(1);\n", sp);
+ }
+ else
+ {
+ f_print (fout, "%ssize = getdtablesize();\n", sp);
+ }
+
+ f_print (fout, "%sfor (i = 0; i < size; i++)\n", sp);
+ f_print (fout, "%s\t(void) close(i);\n", sp);
+ /* Redirect stderr and stdout to console */
+ f_print (fout, "%si = open(\"/dev/console\", 2);\n", sp);
+ f_print (fout, "%s(void) dup2(i, 1);\n", sp);
+ f_print (fout, "%s(void) dup2(i, 2);\n", sp);
+ /* This removes control of the controlling terminal */
+ if (tirpcflag)
+ f_print (fout, "%ssetsid();\n", sp);
+ else
+ {
+ f_print (fout, "%si = open(\"/dev/tty\", 2);\n", sp);
+ f_print (fout, "%sif (i >= 0) {\n", sp);
+ f_print (fout, "%s\t(void) ioctl(i, TIOCNOTTY, (char *)NULL);\n", sp);;
+ f_print (fout, "%s\t(void) close(i);\n", sp);
+ f_print (fout, "%s}\n", sp);
+ }
+ if (!logflag)
+ open_log_file (infile, sp);
+ f_print (fout, "#endif\n");
+ if (logflag)
+ open_log_file (infile, sp);
+}
+
+static void
+open_log_file (const char *infile, const char *sp)
+{
+ char *s;
+
+ s = strrchr (infile, '.');
+ if (s)
+ *s = '\0';
+ f_print (fout, "%sopenlog(\"%s\", LOG_PID, LOG_DAEMON);\n", sp, infile);
+ if (s)
+ *s = '.';
+}
+
+/*
+ * write a registration for the given transport for Inetd
+ */
+void
+write_inetd_register (const char *transp)
+{
+ list *l;
+ definition *def;
+ version_list *vp;
+ const char *sp;
+ int isudp;
+ char tmpbuf[32];
+
+ if (inetdflag)
+ sp = "\t";
+ else
+ sp = "";
+ if (streq (transp, "udp") || streq (transp, "udp6"))
+ isudp = 1;
+ else
+ isudp = 0;
+ f_print (fout, "\n");
+ if (inetdflag)
+ {
+ f_print (fout, "\tif ((_rpcfdtype == 0) || (_rpcfdtype == %s)) {\n",
+ isudp ? "SOCK_DGRAM" : "SOCK_STREAM");
+ }
+ f_print (fout, "%s\t%s = svc%s_create(%s",
+ sp, TRANSP, transp, inetdflag ? "sock" : "RPC_ANYSOCK");
+ if (!isudp)
+ f_print (fout, ", 0, 0");
+ f_print (fout, ");\n");
+ f_print (fout, "%s\tif (%s == NULL) {\n", sp, TRANSP);
+ (void) sprintf (_errbuf, "cannot create %s service.", transp);
+ (void) sprintf (tmpbuf, "%s\t\t", sp);
+ print_err_message (tmpbuf);
+ f_print (fout, "%s\t\texit(1);\n", sp);
+ f_print (fout, "%s\t}\n", sp);
+
+ if (inetdflag)
+ {
+ f_print (fout, "%s\tif (!_rpcpmstart)\n\t", sp);
+ f_print (fout, "%s\tproto = IPPROTO_%s;\n",
+ sp, isudp ? "UDP" : "TCP");
+ }
+ for (l = defined; l != NULL; l = l->next)
+ {
+ def = (definition *) l->val;
+ if (def->def_kind != DEF_PROGRAM)
+ {
+ continue;
+ }
+ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next)
+ {
+ f_print (fout, "%s\tif (!svc_register(%s, %s, %s, ",
+ sp, TRANSP, def->def_name, vp->vers_name);
+ pvname (def->def_name, vp->vers_num);
+ if (inetdflag)
+ f_print (fout, ", proto)) {\n");
+ else
+ f_print (fout, ", IPPROTO_%s)) {\n",
+ isudp ? "UDP" : "TCP");
+ (void) sprintf (_errbuf, "unable to register (%s, %s, %s).",
+ def->def_name, vp->vers_name, transp);
+ print_err_message (tmpbuf);
+ f_print (fout, "%s\t\texit(1);\n", sp);
+ f_print (fout, "%s\t}\n", sp);
+ }
+ }
+ if (inetdflag)
+ f_print (fout, "\t}\n");
+}
diff --git a/tools/rpcgen/rpc_tblout.c b/tools/rpcgen/rpc_tblout.c
new file mode 100644
index 0000000..a7d2f43
--- /dev/null
+++ b/tools/rpcgen/rpc_tblout.c
@@ -0,0 +1,178 @@
+/*
+ * From: @(#)rpc_tblout.c 1.4 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_tblout.c, Dispatch table outputter for the RPC protocol compiler
+ */
+#include <stdio.h>
+#include <string.h>
+#include "rpc_parse.h"
+#include "rpc_util.h"
+#include "proto.h"
+
+#define TABSIZE 8
+#define TABCOUNT 5
+#define TABSTOP (TABSIZE*TABCOUNT)
+
+static const char tabstr[TABCOUNT + 1] = "\t\t\t\t\t";
+
+static const char tbl_hdr[] = "struct rpcgen_table %s_table[] = {\n";
+static const char tbl_end[] = "};\n";
+
+static const char null_entry[] = "\n\t(char *(*)())0,\n\
+ \t(xdrproc_t) xdr_void,\t\t\t0,\n\
+ \t(xdrproc_t) xdr_void,\t\t\t0,\n";
+
+
+static const char tbl_nproc[] = "int %s_nproc =\n\tsizeof(%s_table)/sizeof(%s_table[0]);\n\n";
+
+static void write_table (const definition * def);
+static void printit (const char *prefix, const char *type);
+
+void
+write_tables (void)
+{
+ list *l;
+ definition *def;
+
+ f_print (fout, "\n");
+ for (l = defined; l != NULL; l = l->next)
+ {
+ def = (definition *) l->val;
+ if (def->def_kind == DEF_PROGRAM)
+ {
+ write_table (def);
+ }
+ }
+}
+
+static void
+write_table (const definition * def)
+{
+ version_list *vp;
+ proc_list *proc;
+ int current;
+ int expected;
+ char progvers[100];
+ int warning;
+
+ for (vp = def->def.pr.versions; vp != NULL; vp = vp->next)
+ {
+ warning = 0;
+ s_print (progvers, "%s_%s",
+ locase (def->def_name), vp->vers_num);
+ /* print the table header */
+ f_print (fout, tbl_hdr, progvers);
+
+ if (nullproc (vp->procs))
+ {
+ expected = 0;
+ }
+ else
+ {
+ expected = 1;
+ f_print (fout, null_entry);
+ }
+ for (proc = vp->procs; proc != NULL; proc = proc->next)
+ {
+ current = atoi (proc->proc_num);
+ if (current != expected++)
+ {
+ f_print (fout,
+ "\n/*\n * WARNING: table out of order\n */\n");
+ if (warning == 0)
+ {
+ f_print (stderr,
+ "WARNING %s table is out of order\n",
+ progvers);
+ warning = 1;
+ nonfatalerrors = 1;
+ }
+ expected = current + 1;
+ }
+ f_print (fout, "\n\t(char *(*)())RPCGEN_ACTION(");
+
+ /* routine to invoke */
+ if (Cflag && !newstyle)
+ pvname_svc (proc->proc_name, vp->vers_num);
+ else
+ {
+ if (newstyle)
+ f_print (fout, "_"); /* calls internal func */
+ pvname (proc->proc_name, vp->vers_num);
+ }
+ f_print (fout, "),\n");
+
+ /* argument info */
+ if (proc->arg_num > 1)
+ printit ((char *) NULL, proc->args.argname);
+ else
+ /* do we have to do something special for newstyle */
+ printit (proc->args.decls->decl.prefix,
+ proc->args.decls->decl.type);
+ /* result info */
+ printit (proc->res_prefix, proc->res_type);
+ }
+
+ /* print the table trailer */
+ f_print (fout, tbl_end);
+ f_print (fout, tbl_nproc, progvers, progvers, progvers);
+ }
+}
+
+static void
+printit (const char *prefix, const char *type)
+{
+ int len;
+ int tabs;
+
+
+ len = fprintf (fout, "\txdr_%s,", stringfix (type));
+ /* account for leading tab expansion */
+ len += TABSIZE - 1;
+ /* round up to tabs required */
+ tabs = (TABSTOP - len + TABSIZE - 1) / TABSIZE;
+ f_print (fout, "%s", &tabstr[TABCOUNT - tabs]);
+
+ if (streq (type, "void"))
+ {
+ f_print (fout, "0");
+ }
+ else
+ {
+ f_print (fout, "sizeof ( ");
+ /* XXX: should "follow" be 1 ??? */
+ ptype (prefix, type, 0);
+ f_print (fout, ")");
+ }
+ f_print (fout, ",\n");
+}
diff --git a/tools/rpcgen/rpc_util.c b/tools/rpcgen/rpc_util.c
new file mode 100644
index 0000000..52aa697
--- /dev/null
+++ b/tools/rpcgen/rpc_util.c
@@ -0,0 +1,525 @@
+/*
+ * From: @(#)rpc_util.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_util.c, Utility routines for the RPC protocol compiler
+ */
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <unistd.h>
+#include "rpc_scan.h"
+#include "rpc_parse.h"
+#include "rpc_util.h"
+#include "proto.h"
+
+#define ARGEXT "argument"
+
+char curline[MAXLINESIZE]; /* current read line */
+const char *where = curline; /* current point in line */
+int linenum = 0; /* current line number */
+
+const char *infilename; /* input filename */
+
+#define NFILES 7
+const char *outfiles[NFILES]; /* output file names */
+int nfiles;
+
+FILE *fout; /* file pointer of current output */
+FILE *fin; /* file pointer of current input */
+
+list *defined; /* list of defined things */
+
+static int findit (const definition * def, const char *type);
+static const char *fixit (const char *type, const char *orig);
+static int typedefed (const definition * def, const char *type);
+static const char *toktostr (tok_kind kind);
+static void printbuf (void);
+static void printwhere (void);
+
+/*
+ * Reinitialize the world
+ */
+void
+reinitialize (void)
+{
+ memset (curline, 0, MAXLINESIZE);
+ where = curline;
+ linenum = 0;
+ defined = NULL;
+}
+
+/*
+ * string equality
+ */
+int
+streq (const char *a, const char *b)
+{
+ return strcmp (a, b) == 0;
+}
+
+/*
+ * find a value in a list
+ */
+definition *
+findval (list *lst, const char *val,
+ int (*cmp) (const definition *, const char *))
+{
+
+ for (; lst != NULL; lst = lst->next)
+ {
+ if (cmp (lst->val, val))
+ {
+ return lst->val;
+ }
+ }
+ return NULL;
+}
+
+/*
+ * store a value in a list
+ */
+void
+storeval (list **lstp, definition *val)
+{
+ list **l;
+ list *lst;
+
+
+ for (l = lstp; *l != NULL; l = (list **) & (*l)->next);
+ lst = ALLOC (list);
+ lst->val = val;
+ lst->next = NULL;
+ *l = lst;
+}
+
+static int
+findit (const definition * def, const char *type)
+{
+ return streq (def->def_name, type);
+}
+
+static const char *
+fixit (const char *type, const char *orig)
+{
+ definition *def;
+
+ def = findval (defined, type, findit);
+ if (def == NULL || def->def_kind != DEF_TYPEDEF)
+ {
+ return orig;
+ }
+ switch (def->def.ty.rel)
+ {
+ case REL_VECTOR:
+ if (streq (def->def.ty.old_type, "opaque"))
+ return ("char");
+ else
+ return (def->def.ty.old_type);
+ case REL_ALIAS:
+ return (fixit (def->def.ty.old_type, orig));
+ default:
+ return orig;
+ }
+}
+
+const char *
+fixtype (const char *type)
+{
+ return fixit (type, type);
+}
+
+const char *
+stringfix (const char *type)
+{
+ if (streq (type, "string"))
+ {
+ return "wrapstring";
+ }
+ else
+ {
+ return type;
+ }
+}
+
+void
+ptype (const char *prefix, const char *type, int follow)
+{
+ if (prefix != NULL)
+ {
+ if (streq (prefix, "enum"))
+ {
+ f_print (fout, "enum ");
+ }
+ else
+ {
+ f_print (fout, "struct ");
+ }
+ }
+ if (streq (type, "bool"))
+ {
+ f_print (fout, "bool_t ");
+ }
+ else if (streq (type, "string"))
+ {
+ f_print (fout, "char *");
+ }
+ else
+ {
+ f_print (fout, "%s ", follow ? fixtype (type) : type);
+ }
+}
+
+static int
+typedefed (const definition * def, const char *type)
+{
+ if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL)
+ {
+ return 0;
+ }
+ else
+ {
+ return streq (def->def_name, type);
+ }
+}
+
+int
+isvectordef (const char *type, relation rel)
+{
+ definition *def;
+
+ for (;;)
+ {
+ switch (rel)
+ {
+ case REL_VECTOR:
+ return !streq (type, "string");
+ case REL_ARRAY:
+ return 0;
+ case REL_POINTER:
+ return 0;
+ case REL_ALIAS:
+ def = findval (defined, type, typedefed);
+ if (def == NULL)
+ {
+ return 0;
+ }
+ type = def->def.ty.old_type;
+ rel = def->def.ty.rel;
+ }
+ }
+}
+
+char *
+locase (const char *str)
+{
+ char c;
+ static char buf[100];
+ char *p = buf;
+
+ while ((c = *str++) != 0)
+ {
+ *p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c;
+ }
+ *p = 0;
+ return buf;
+}
+
+void
+pvname_svc (const char *pname, const char *vnum)
+{
+ f_print (fout, "%s_%s_svc", locase (pname), vnum);
+}
+
+void
+pvname (const char *pname, const char *vnum)
+{
+ f_print (fout, "%s_%s", locase (pname), vnum);
+}
+
+/*
+ * print a useful (?) error message, and then die
+ */
+void
+error (const char *msg)
+{
+ printwhere ();
+ f_print (stderr, "%s, line %d: ", infilename, linenum);
+ f_print (stderr, "%s\n", msg);
+ crash ();
+}
+
+/*
+ * Something went wrong, unlink any files that we may have created and then
+ * die.
+ */
+void
+crash (void)
+{
+ int i;
+
+ for (i = 0; i < nfiles; i++)
+ {
+ unlink (outfiles[i]);
+ }
+ exit (1);
+}
+
+void
+record_open (const char *file)
+{
+ if (nfiles < NFILES)
+ {
+ outfiles[nfiles++] = file;
+ }
+ else
+ {
+ f_print (stderr, "too many files!\n");
+ crash ();
+ }
+}
+
+static char expectbuf[100];
+
+/*
+ * error, token encountered was not the expected one
+ */
+void
+expected1 (tok_kind exp1)
+{
+ s_print (expectbuf, "expected '%s'",
+ toktostr (exp1));
+ error (expectbuf);
+}
+
+/*
+ * error, token encountered was not one of two expected ones
+ */
+void
+expected2 (tok_kind exp1, tok_kind exp2)
+{
+ s_print (expectbuf, "expected '%s' or '%s'",
+ toktostr (exp1),
+ toktostr (exp2));
+ error (expectbuf);
+}
+
+/*
+ * error, token encountered was not one of 3 expected ones
+ */
+void
+expected3 (tok_kind exp1, tok_kind exp2, tok_kind exp3)
+{
+ s_print (expectbuf, "expected '%s', '%s' or '%s'",
+ toktostr (exp1),
+ toktostr (exp2),
+ toktostr (exp3));
+ error (expectbuf);
+}
+
+void
+tabify (FILE * f, int tab)
+{
+ while (tab--)
+ {
+ (void) fputc ('\t', f);
+ }
+}
+
+
+static const token tokstrings[] =
+{
+ {TOK_IDENT, "identifier"},
+ {TOK_CONST, "const"},
+ {TOK_RPAREN, ")"},
+ {TOK_LPAREN, "("},
+ {TOK_RBRACE, "}"},
+ {TOK_LBRACE, "{"},
+ {TOK_LBRACKET, "["},
+ {TOK_RBRACKET, "]"},
+ {TOK_STAR, "*"},
+ {TOK_COMMA, ","},
+ {TOK_EQUAL, "="},
+ {TOK_COLON, ":"},
+ {TOK_SEMICOLON, ";"},
+ {TOK_UNION, "union"},
+ {TOK_STRUCT, "struct"},
+ {TOK_SWITCH, "switch"},
+ {TOK_CASE, "case"},
+ {TOK_DEFAULT, "default"},
+ {TOK_ENUM, "enum"},
+ {TOK_TYPEDEF, "typedef"},
+ {TOK_INT, "int"},
+ {TOK_SHORT, "short"},
+ {TOK_LONG, "long"},
+ {TOK_UNSIGNED, "unsigned"},
+ {TOK_DOUBLE, "double"},
+ {TOK_FLOAT, "float"},
+ {TOK_CHAR, "char"},
+ {TOK_STRING, "string"},
+ {TOK_OPAQUE, "opaque"},
+ {TOK_BOOL, "bool"},
+ {TOK_VOID, "void"},
+ {TOK_PROGRAM, "program"},
+ {TOK_VERSION, "version"},
+ {TOK_EOF, "??????"}
+};
+
+static const char *
+toktostr (tok_kind kind)
+{
+ const token *sp;
+
+ for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++);
+ return sp->str;
+}
+
+static void
+printbuf (void)
+{
+ char c;
+ int i;
+ int cnt;
+
+#define TABSIZE 4
+
+ for (i = 0; (c = curline[i]) != 0; i++)
+ {
+ if (c == '\t')
+ {
+ cnt = 8 - (i % TABSIZE);
+ c = ' ';
+ }
+ else
+ {
+ cnt = 1;
+ }
+ while (cnt--)
+ {
+ (void) fputc (c, stderr);
+ }
+ }
+}
+
+static void
+printwhere (void)
+{
+ int i;
+ char c;
+ int cnt;
+
+ printbuf ();
+ for (i = 0; i < where - curline; i++)
+ {
+ c = curline[i];
+ if (c == '\t')
+ {
+ cnt = 8 - (i % TABSIZE);
+ }
+ else
+ {
+ cnt = 1;
+ }
+ while (cnt--)
+ {
+ (void) fputc ('^', stderr);
+ }
+ }
+ (void) fputc ('\n', stderr);
+}
+
+char *
+make_argname (const char *pname, const char *vname)
+{
+ char *name;
+
+ name = malloc (strlen (pname) + strlen (vname) + strlen (ARGEXT) + 3);
+ if (!name)
+ {
+ fprintf (stderr, "failed in malloc");
+ exit (1);
+ }
+ sprintf (name, "%s_%s_%s", locase (pname), vname, ARGEXT);
+ return name;
+}
+
+bas_type *typ_list_h;
+bas_type *typ_list_t;
+
+void
+add_type (int len, const char *type)
+{
+ bas_type *ptr;
+
+
+ if ((ptr = malloc (sizeof (bas_type))) == NULL)
+ {
+ fprintf (stderr, "failed in malloc");
+ exit (1);
+ }
+
+ ptr->name = type;
+ ptr->length = len;
+ ptr->next = NULL;
+ if (typ_list_t == NULL)
+ {
+
+ typ_list_t = ptr;
+ typ_list_h = ptr;
+ }
+ else
+ {
+
+ typ_list_t->next = ptr;
+ typ_list_t = ptr;
+ }
+
+}
+
+
+bas_type *
+find_type (const char *type)
+{
+ bas_type *ptr;
+
+ ptr = typ_list_h;
+
+
+ while (ptr != NULL)
+ {
+ if (strcmp (ptr->name, type) == 0)
+ return ptr;
+ else
+ ptr = ptr->next;
+ };
+ return NULL;
+}
diff --git a/tools/rpcgen/rpc_util.h b/tools/rpcgen/rpc_util.h
new file mode 100644
index 0000000..53316d9
--- /dev/null
+++ b/tools/rpcgen/rpc_util.h
@@ -0,0 +1,154 @@
+/* @(#)rpc_util.h 1.5 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_util.h, Useful definitions for the RPC protocol compiler
+ */
+
+#include <stdlib.h>
+
+#define alloc(size) malloc((unsigned)(size))
+#define ALLOC(object) (object *) malloc(sizeof(object))
+
+#define s_print (void) sprintf
+#define f_print (void) fprintf
+
+struct list {
+ definition *val;
+ struct list *next;
+};
+typedef struct list list;
+
+struct xdrfunc {
+ char *name;
+ int pointerp;
+ struct xdrfunc *next;
+};
+typedef struct xdrfunc xdrfunc;
+
+#define PUT 1
+#define GET 2
+
+/*
+ * Global variables
+ */
+#define MAXLINESIZE 1024
+extern char curline[MAXLINESIZE];
+extern const char *where;
+extern int linenum;
+
+extern const char *infilename;
+extern FILE *fout;
+extern FILE *fin;
+
+extern list *defined;
+
+extern bas_type *typ_list_h;
+extern bas_type *typ_list_t;
+extern xdrfunc *xdrfunc_head, *xdrfunc_tail;
+
+/*
+ * All the option flags
+ */
+extern int inetdflag;
+extern int pmflag;
+extern int tblflag;
+extern int logflag;
+extern int newstyle;
+extern int Cflag; /* C++ flag */
+extern int CCflag; /* C++ flag */
+extern int tirpcflag; /* flag for generating tirpc code */
+extern int inlineflag; /* if this is 0, then do not generate inline code */
+extern int mtflag;
+
+/*
+ * Other flags related with inetd jumpstart.
+ */
+extern int indefinitewait;
+extern int exitnow;
+extern int timerflag;
+
+extern int nonfatalerrors;
+
+/*
+ * rpc_util routines
+ */
+void storeval(list **lstp, definition *val);
+#define STOREVAL(list,item) storeval(list,item)
+
+definition *findval(list *lst, const char *val,
+ int (*cmp)(const definition *, const char *));
+#define FINDVAL(list,item,finder) findval(list, item, finder)
+
+const char *fixtype(const char *type);
+const char *stringfix(const char *type);
+char *locase(const char *str);
+void pvname_svc(const char *pname, const char *vnum);
+void pvname(const char *pname, const char *vnum);
+void ptype(const char *prefix, const char *type, int follow);
+int isvectordef(const char *type, relation rel);
+int streq(const char *a, const char *b);
+void error(const char *msg);
+void tabify(FILE *f, int tab);
+void record_open(const char *file);
+bas_type *find_type(const char *type);
+
+
+/*
+ * rpc_cout routines
+ */
+void emit(definition *def);
+
+/*
+ * rpc_hout routines
+ */
+void print_datadef(definition *def);
+void print_funcdef(definition *def);
+
+/*
+ * rpc_svcout routines
+ */
+void write_most(const char *infile, int netflag, int nomain);
+void write_register(void);
+void write_rest(void);
+void write_programs(const char *storage);
+void write_svc_aux(int nomain);
+void write_inetd_register(const char *transp);
+void write_netid_register(const char *);
+void write_nettype_register(const char *);
+/*
+ * rpc_clntout routines
+ */
+void write_stubs(void);
+
+/*
+ * rpc_tblout routines
+ */
+void write_tables(void);
diff --git a/tools/rpcgen/rpcgen.1 b/tools/rpcgen/rpcgen.1
new file mode 100644
index 0000000..9db1b4a
--- /dev/null
+++ b/tools/rpcgen/rpcgen.1
@@ -0,0 +1,442 @@
+.\" @(#)rpcgen.new.1 1.1 90/11/09 TIRPC 1.0; from 40.10 of 10/10/89
+.\" Copyright (c) 1988,1990 Sun Microsystems, Inc. - All Rights Reserved.
+.nr X
+.if \nX=0 .ds x} rpcgen 1 "" "\&"
+.if \nX=1 .ds x} rpcgen 1 ""
+.if \nX=2 .ds x} rpcgen 1 "" "\&"
+.if \nX=3 .ds x} rpcgen "" "" "\&"
+.TH \*(x}
+.SH NAME
+\f4rpcgen\f1 \- an RPC protocol compiler
+.SH SYNOPSIS
+.ft 4
+.nf
+rpcgen \f2infile\f4
+.fi
+.ft 1
+.br
+.ft 4
+.nf
+rpcgen [\-D\f2name\f4[=\f2value\f4]] [\-T] [\-K \f2secs\fP] \f2infile\f4
+.fi
+.ft 1
+.br
+.ft 4
+.nf
+rpcgen \-c|\-h|\-l|\-m|\-M|\-t [\-o \f2outfile\f4 ] \f2infile\f4
+.fi
+.ft 1
+.br
+.ft 4
+.nf
+rpcgen [\-I] \-s \f2nettype\f4 [\-o \f2outfile\f4] \f2infile\f4
+.fi
+.ft 1
+.br
+.ft 4
+.nf
+rpcgen \-n \f2netid\f4 [\-o \f2outfile\f4] \f2infile\f4
+.ft 1
+.SH DESCRIPTION
+.P
+\f4rpcgen\f1
+is a tool that generates C code to implement an RPC protocol.
+The input to
+\f4rpcgen\f1
+is a language similar to C known as
+RPC Language (Remote Procedure Call Language).
+.P
+\f4rpcgen\f1
+is normally used as in the first synopsis where
+it takes an input file and generates up to four output files.
+If the
+\f2infile\f1
+is named
+\f4proto.x\f1,
+then
+\f4rpcgen\f1
+will generate a header file in
+\f4proto.h\f1,
+XDR routines in
+\f4proto_xdr.c\f1,
+server-side stubs in
+\f4proto_svc.c\f1,
+and client-side stubs in
+\f4proto_clnt.c\f1.
+With the
+\f4\-T\f1
+option,
+it will also generate the RPC dispatch table in
+\f4proto_tbl.i\f1.
+With the
+\f4\-Sc\f1
+option,
+it will also generate sample code which would illustrate how to use the
+remote procedures on the client side. This code would be created in
+\f4proto_client.c\f1.
+With the
+\f4\-Ss\f1
+option,
+it will also generate a sample server code which would illustrate how to write
+the remote procedures. This code would be created in
+\f4proto_server.c\f1.
+.P
+The server created can be started both by the port monitors
+(for example, \f4inetd\f1 or \f4listen\f1)
+or by itself.
+When it is started by a port monitor,
+it creates servers only for the transport for which
+the file descriptor \f40\fP was passed.
+The name of the transport must be specified
+by setting up the environmental variable
+\f4PM_TRANSPORT\f1.
+When the server generated by
+\f4rpcgen\f1
+is executed,
+it creates server handles for all the transports
+specified in
+\f4NETPATH\f1
+environment variable,
+or if it is unset,
+it creates server handles for all the visible transports from
+\f4/etc/netconfig\f1
+file.
+Note:
+the transports are chosen at run time and not at compile time.
+.P
+When built for a port monitor (\f4rpcgen\f1 \f4\-I\f1), and that the server
+is self-started, it backgrounds itself by default. A special define symbol
+\f4RPC_SVC_FG\f1 can be used to run the server process in foreground.
+.P
+The second synopsis provides special features which allow
+for the creation of more sophisticated RPC servers.
+These features include support for user provided
+\f4#defines\f1
+and RPC dispatch tables.
+The entries in the RPC dispatch table contain:
+.RS
+.PD 0
+.TP 3
+\(bu
+pointers to the service routine corresponding to that procedure,
+.TP
+\(bu
+a pointer to the input and output arguments
+.TP
+\(bu
+the size of these routines
+.PD
+.RE
+A server can use the dispatch table to check authorization
+and then to execute the service routine;
+a client library may use it to deal with the details of storage
+management and XDR data conversion.
+.P
+The other three synopses shown above are used when
+one does not want to generate all the output files,
+but only a particular one.
+Some examples of their usage is described in the
+EXAMPLE
+section below.
+When
+\f4rpcgen\f1
+is executed with the
+\f4\-s\f1
+option,
+it creates servers for that particular class of transports.
+When
+executed with the
+\f4\-n\f1
+option,
+it creates a server for the transport specified by
+\f2netid\f1.
+If
+\f2infile\f1
+is not specified,
+\f4rpcgen\f1
+accepts the standard input.
+.P
+The C preprocessor,
+\f4cc \-E\f1
+[see \f4cc\fP(1)],
+is run on the input file before it is actually interpreted by
+\f4rpcgen\f1.
+For each type of output file,
+\f4rpcgen\f1
+defines a special preprocessor symbol for use by the
+\f4rpcgen\f1
+programmer:
+.P
+.PD 0
+.TP 12
+\f4RPC_HDR\f1
+defined when compiling into header files
+.TP
+\f4RPC_XDR\f1
+defined when compiling into XDR routines
+.TP
+\f4RPC_SVC\f1
+defined when compiling into server-side stubs
+.TP
+\f4RPC_CLNT\f1
+defined when compiling into client-side stubs
+.TP
+\f4RPC_TBL\f1
+defined when compiling into RPC dispatch tables
+.PD
+.P
+Any line beginning with
+`\f4%\f1'
+is passed directly into the output file,
+uninterpreted by
+\f4rpcgen\f1.
+.P
+For every data type referred to in
+\f2infile\f1,
+\f4rpcgen\f1
+assumes that there exists a
+routine with the string
+\f4xdr_\f1
+prepended to the name of the data type.
+If this routine does not exist in the RPC/XDR
+library, it must be provided.
+Providing an undefined data type
+allows customization of XDR routines.
+.br
+.ne 10
+.P
+The following options are available:
+.TP
+\f4\-a\f1
+Generate all the files including sample code for client and server side.
+.TP
+\f4\-b\f1
+This generates code for the SunOS4.1 style of rpc. It is
+for backward compatibility. This is the default.
+.TP
+\f4\-5\f1
+This generates code for the SysVr4 style of rpc. It is used by the
+Transport Independent RPC that is in Svr4 systems.
+By default rpcgen generates code for SunOS4.1 stype of rpc.
+.TP
+\f4\-c\f1
+Compile into XDR routines.
+.TP
+\f4\-C\f1
+Generate code in ANSI C. This option also generates code that could be
+compiled with the C++ compiler. This is the default.
+.TP
+\f4\-k\f1
+Generate code in K&R C. The default is ANSI C.
+.TP
+\f4\-D\f2name\f4[=\f2value\f4]\f1
+Define a symbol
+\f2name\f1.
+Equivalent to the
+\f4#define\f1
+directive in the source.
+If no
+\f2value\f1
+is given,
+\f2value\f1
+is defined as \f41\f1.
+This option may be specified more than once.
+.TP
+\f4\-h\f1
+Compile into
+\f4C\f1
+data-definitions (a header file).
+\f4\-T\f1
+option can be used in conjunction to produce a
+header file which supports RPC dispatch tables.
+.TP
+\f4\-I\f1
+Generate a service that can be started from inetd. The default is
+to generate a static service that handles transports selected with \f4\-s\f1.
+Using \f4\-I\f1 allows starting a service by either method.
+.TP
+\f4-K\f2 secs\f1
+By default, services created using \f4rpcgen\fP wait \f4120\fP seconds
+after servicing a request before exiting.
+That interval can be changed using the \f4-K\fP flag.
+To create a server that exits immediately upon servicing a request,
+\f4-K\ 0\fP can be used.
+To create a server that never exits, the appropriate argument is
+\f4-K\ -1\fP.
+.IP
+When monitoring for a server,
+some portmonitors, like
+\f4listen\fP(1M),
+.I always
+spawn a new process in response to a service request.
+If it is known that a server will be used with such a monitor, the
+server should exit immediately on completion.
+For such servers, \f4rpcgen\fP should be used with \f4-K\ -1\fP.
+.TP
+\f4\-l\f1
+Compile into client-side stubs.
+.TP
+\f4\-m\f1
+Compile into server-side stubs,
+but do not generate a \(lqmain\(rq routine.
+This option is useful for doing callback-routines
+and for users who need to write their own
+\(lqmain\(rq routine to do initialization.
+.TP
+\f4\-M\f1
+Generate multithread-safe stubs for passing arguments
+and results between rpcgen-generated code and user written code.
+This option is useful for users who want to use threads in their code.
+.TP
+\f4\-n \f2netid\f1
+Compile into server-side stubs for the transport
+specified by
+\f2netid\f1.
+There should be an entry for
+\f2netid\f1
+in the
+netconfig database.
+This option may be specified more than once,
+so as to compile a server that serves multiple transports.
+.TP
+\f4\-N\f1
+Use the newstyle of rpcgen. This allows procedures to have multiple arguments.
+It also uses the style of parameter passing that closely resembles C. So, when
+passing an argument to a remote procedure you do not have to pass a pointer to
+the argument but the argument itself. This behaviour is different from the oldstyle
+of rpcgen generated code. The newstyle is not the default case because of
+backward compatibility.
+.TP
+\f4\-o \f2outfile\f1
+Specify the name of the output file.
+If none is specified,
+standard output is used
+(\f4\-c\f1,
+\f4\-h\f1,
+\f4\-l\f1,
+\f4\-m\f1,
+\f4\-n\f1,
+\f4\-s\f1,
+\f4\-Sc\f1,
+\f4\-Sm\f1,
+\f4\-Ss\f1,
+and
+\f4\-t\f1
+modes only).
+.TP
+\f4\-s \f2nettype\f1
+Compile into server-side stubs for all the
+transports belonging to the class
+\f2nettype\f1.
+The supported classes are
+\f4netpath\f1,
+\f4visible\f1,
+\f4circuit_n\f1,
+\f4circuit_v\f1,
+\f4datagram_n\f1,
+\f4datagram_v\f1,
+\f4tcp\f1,
+and
+\f4udp\f1
+[see \f4rpc\fP(3N)
+for the meanings associated with these classes].
+This option may be specified more than once.
+Note:
+the transports are chosen at run time and not at compile time.
+.TP
+\f4\-Sc\f1
+Generate sample code to show the use of remote procedure and how to bind
+to the server before calling the client side stubs generated by rpcgen.
+.TP
+\f4\-Sm\f1
+Generate a sample Makefile which can be used for compiling the application.
+.TP
+\f4\-Ss\f1
+Generate skeleton code for the remote procedures on the server side. You would need
+to fill in the actual code for the remote procedures.
+.TP
+\f4\-t\f1
+Compile into RPC dispatch table.
+.TP
+\f4\-T\f1
+Generate the code to support RPC dispatch tables.
+.P
+The options
+\f4\-c\f1,
+\f4\-h\f1,
+\f4\-l\f1,
+\f4\-m\f1,
+\f4\-s\f1
+and
+\f4\-t\f1
+are used exclusively to generate a particular type of file,
+while the options
+\f4\-D\f1
+and
+\f4\-T\f1
+are global and can be used with the other options.
+.br
+.ne 5
+.SH NOTES
+The RPC Language does not support nesting of structures.
+As a work-around,
+structures can be declared at the top-level,
+and their name used inside other structures in
+order to achieve the same effect.
+.P
+Name clashes can occur when using program definitions,
+since the apparent scoping does not really apply.
+Most of these can be avoided by giving
+unique names for programs,
+versions,
+procedures and types.
+.P
+The server code generated with
+\f4\-n\f1
+option refers to the transport indicated by
+\f2netid\f1
+and hence is very site specific.
+.SH EXAMPLE
+The following example:
+.IP
+.ft 4
+$ rpcgen \-T prot.x
+.ft 1
+.P
+generates the five files:
+\f4prot.h\f1,
+\f4prot_clnt.c\f1,
+\f4prot_svc.c\f1,
+\f4prot_xdr.c\f1
+and
+\f4prot_tbl.i\f1.
+.P
+The following example sends the C data-definitions (header file)
+to the standard output.
+.IP
+.ft 4
+$ rpcgen \-h prot.x
+.ft 1
+.P
+To send the test version of the
+\f4-DTEST\f1,
+server side stubs for
+all the transport belonging to the class
+\f4datagram_n\f1
+to standard output, use:
+.IP
+.ft 4
+$ rpcgen \-s datagram_n \-DTEST prot.x
+.ft 1
+.P
+To create the server side stubs for the transport indicated
+by
+\f2netid\f1
+\f4tcp\f1,
+use:
+.IP
+.ft 4
+$ rpcgen \-n tcp \-o prot_svc.c prot.x
+.ft 1
+.SH "SEE ALSO"
+\f4cc\fP(1).