]> git.decadent.org.uk Git - nfs-utils.git/commitdiff
Merge branch 'upstream'
authorBen Hutchings <ben@decadent.org.uk>
Wed, 14 Jul 2010 02:01:57 +0000 (03:01 +0100)
committerBen Hutchings <ben@decadent.org.uk>
Wed, 14 Jul 2010 02:01:57 +0000 (03:01 +0100)
Conflicts:
Makefile.in
aclocal.m4
configure
depcomp
install-sh
linux-nfs/Makefile.in
support/Makefile.in
support/export/Makefile.in
support/include/Makefile.in
support/include/config.h.in
support/include/nfs/Makefile.in
support/include/rpcsvc/Makefile.in
support/include/sys/Makefile.in
support/include/sys/fs/Makefile.in
support/misc/Makefile.in
support/nfs/Makefile.in
tools/Makefile.in
tools/locktest/Makefile.in
tools/nlmtest/Makefile.in
tools/rpcdebug/Makefile.in
tools/rpcgen/Makefile.in
utils/Makefile.in
utils/exportfs/Makefile.in
utils/gssd/Makefile.in
utils/idmapd/Makefile.in
utils/mount/Makefile.in
utils/mountd/Makefile.in
utils/nfsd/Makefile.in
utils/nfsstat/Makefile.in
utils/showmount/Makefile.in
utils/statd/Makefile.in

71 files changed:
Makefile.in
aclocal.m4
configure
configure.ac
depcomp
install-sh
linux-nfs/Makefile.in
support/Makefile.in
support/export/Makefile.in
support/export/rmtab.c
support/include/Makefile.in
support/include/config.h.in
support/include/nfs/Makefile.in
support/include/rpcsvc/Makefile.in
support/include/sys/Makefile.in
support/include/sys/fs/Makefile.in
support/misc/Makefile.in
support/misc/tcpwrapper.c
support/nfs/Makefile.in
support/nfs/xio.c
tools/Makefile.in
tools/locktest/Makefile.in
tools/mountstats/mountstats.py [new file with mode: 0644]
tools/nfs-iostat/nfs-iostat.py [new file with mode: 0644]
tools/nlmtest/Makefile.in
tools/rpcdebug/Makefile.in
tools/rpcgen/Makefile.in
utils/Makefile.in
utils/exportfs/Makefile.in
utils/exportfs/exportfs.man
utils/gssd/Makefile.in
utils/gssd/err_util.c
utils/gssd/err_util.h
utils/gssd/gssd.c
utils/gssd/gssd.h
utils/gssd/gssd.man
utils/gssd/gssd_proc.c
utils/gssd/krb5_util.c
utils/gssd/krb5_util.h
utils/idmapd/Makefile.in
utils/mount/Makefile.am
utils/mount/Makefile.in
utils/mount/error.c
utils/mount/error.h
utils/mount/fstab.c
utils/mount/fstab.h
utils/mount/mount.c
utils/mount/mount_constants.h
utils/mount/network.c
utils/mount/network.h
utils/mount/nfs.man
utils/mount/nfs4mount.c
utils/mount/nfs_mount.h
utils/mount/nfsmount.c
utils/mount/nfsumount.c
utils/mount/parse_dev.c [new file with mode: 0644]
utils/mount/parse_dev.h [new file with mode: 0644]
utils/mount/parse_opt.h
utils/mount/stropts.c
utils/mount/stropts.h
utils/mount/token.h
utils/mount/version.h [new file with mode: 0644]
utils/mountd/Makefile.in
utils/mountd/mountd.c
utils/nfsd/Makefile.in
utils/nfsstat/Makefile.in
utils/nfsstat/nfsstat.c
utils/showmount/Makefile.in
utils/showmount/showmount.c
utils/statd/Makefile.in
utils/statd/sm-notify.c

index 78fe62ff79dd27ba22b37d73f2014c292c267983..0727a94e6380a958912c782414fe3282362af3b9 100644 (file)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -188,6 +188,7 @@ datarootdir = @datarootdir@
 docdir = @docdir@
 dvidir = @dvidir@
 enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
 enable_nfsv3 = @enable_nfsv3@
 enable_nfsv4 = @enable_nfsv4@
 exec_prefix = @exec_prefix@
@@ -382,8 +383,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        mkid -fID $$unique
 tags: TAGS
 
@@ -408,8 +409,8 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
          test -n "$$unique" || unique=$$empty_fix; \
          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -419,13 +420,12 @@ ctags: CTAGS
 CTAGS: ctags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
                $(TAGS_FILES) $(LISP)
        tags=; \
-       here=`pwd`; \
        list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        test -z "$(CTAGS_ARGS)$$tags$$unique" \
          || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
             $$tags $$unique
@@ -496,6 +496,10 @@ dist-bzip2: distdir
        tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
        $(am__remove_distdir)
 
+dist-lzma: distdir
+       tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
+       $(am__remove_distdir)
+
 dist-tarZ: distdir
        tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
        $(am__remove_distdir)
@@ -522,6 +526,8 @@ distcheck: dist
          GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
        *.tar.bz2*) \
          bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
+       *.tar.lzma*) \
+         unlzma -c $(distdir).tar.lzma | $(am__untar) ;;\
        *.tar.Z*) \
          uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
        *.shar.gz*) \
@@ -678,8 +684,8 @@ uninstall-am:
 .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
        all all-am am--refresh check check-am clean clean-generic \
        clean-libtool ctags ctags-recursive dist dist-all dist-bzip2 \
-       dist-gzip dist-shar dist-tarZ dist-zip distcheck distclean \
-       distclean-generic distclean-libtool distclean-tags \
+       dist-gzip dist-lzma dist-shar dist-tarZ dist-zip distcheck \
+       distclean distclean-generic distclean-libtool distclean-tags \
        distcleancheck distdir distuninstallcheck 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 \
index f8644c611cba029b83612d744077bfd67d63ceb0..162a7f423413906275b569f2b626f365f249a7ee 100644 (file)
@@ -1,7 +1,7 @@
-# generated automatically by aclocal 1.10 -*- Autoconf -*-
+# generated automatically by aclocal 1.10.1 -*- Autoconf -*-
 
 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006  Free Software Foundation, Inc.
+# 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
 # This file 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.
 # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 # PARTICULAR PURPOSE.
 
-m4_if(m4_PACKAGE_VERSION, [2.61],,
-[m4_fatal([this file was generated for autoconf 2.61.
-You have another version of autoconf.  If you want to use that,
-you should regenerate the build system entirely.], [63])])
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(AC_AUTOCONF_VERSION, [2.61],,
+[m4_warning([this file was generated for autoconf 2.61.
+You have another version of autoconf.  It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically `autoreconf'.])])
 
 # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
 
@@ -6652,16 +6655,14 @@ fi])
 # _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
 # ---------------------------------------------
 m4_define([_PKG_CONFIG],
-[if test -n "$PKG_CONFIG"; then
-    if test -n "$$1"; then
-        pkg_cv_[]$1="$$1"
-    else
-        PKG_CHECK_EXISTS([$3],
-                         [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`],
-                        [pkg_failed=yes])
-    fi
-else
-       pkg_failed=untried
+[if test -n "$$1"; then
+    pkg_cv_[]$1="$$1"
+ elif test -n "$PKG_CONFIG"; then
+    PKG_CHECK_EXISTS([$3],
+                     [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`],
+                    [pkg_failed=yes])
+ else
+    pkg_failed=untried
 fi[]dnl
 ])# _PKG_CONFIG
 
@@ -6705,9 +6706,9 @@ See the pkg-config man page for more details.])
 if test $pkg_failed = yes; then
         _PKG_SHORT_ERRORS_SUPPORTED
         if test $_pkg_short_errors_supported = yes; then
-               $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$2"`
+               $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "$2" 2>&1`
         else 
-               $1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
+               $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors "$2" 2>&1`
         fi
        # Put the nasty error message in config.log where it belongs
        echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
@@ -6742,7 +6743,7 @@ else
 fi[]dnl
 ])# PKG_CHECK_MODULES
 
-# Copyright (C) 2002, 2003, 2005, 2006  Free Software Foundation, Inc.
+# Copyright (C) 2002, 2003, 2005, 2006, 2007  Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -6757,7 +6758,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION],
 [am__api_version='1.10'
 dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
 dnl require some minimum version.  Point them to the right macro.
-m4_if([$1], [1.10], [],
+m4_if([$1], [1.10.1], [],
       [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
 ])
 
@@ -6773,8 +6774,10 @@ m4_define([_AM_AUTOCONF_VERSION], [])
 # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
 # This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.10])dnl
-_AM_AUTOCONF_VERSION(m4_PACKAGE_VERSION)])
+[AM_AUTOMAKE_VERSION([1.10.1])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(AC_AUTOCONF_VERSION)])
 
 # AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
 
@@ -7046,7 +7049,7 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
   # each Makefile.in and add a new line on top of each file to say so.
   # Grep'ing the whole file is not good either: AIX grep has a line
   # limit of 2048, but all sed's we know have understand at least 4000.
-  if sed 10q "$mf" | grep '^#.*generated by automake' > /dev/null 2>&1; then
+  if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
     dirpart=`AS_DIRNAME("$mf")`
   else
     continue
@@ -7094,13 +7097,13 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
 # Do all the work for Automake.                             -*- Autoconf -*-
 
 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006 Free Software Foundation, Inc.
+# 2005, 2006, 2008 Free Software Foundation, Inc.
 #
 # This file 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.
 
-# serial 12
+# serial 13
 
 # This macro actually does too much.  Some checks are only needed if
 # your package does certain things.  But this isn't really a big deal.
@@ -7205,16 +7208,17 @@ AC_PROVIDE_IFELSE([AC_PROG_OBJC],
 # our stamp files there.
 AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
 [# Compute $1's index in $config_headers.
+_am_arg=$1
 _am_stamp_count=1
 for _am_header in $config_headers :; do
   case $_am_header in
-    $1 | $1:* )
+    $_am_arg | $_am_arg:* )
       break ;;
     * )
       _am_stamp_count=`expr $_am_stamp_count + 1` ;;
   esac
 done
-echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
 
 # Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
 #
@@ -7549,7 +7553,7 @@ AC_SUBST([INSTALL_STRIP_PROGRAM])])
 
 # _AM_SUBST_NOTMAKE(VARIABLE)
 # ---------------------------
-# Prevent Automake from outputing VARIABLE = @VARIABLE@ in Makefile.in.
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
 # This macro is traced by Automake.
 AC_DEFUN([_AM_SUBST_NOTMAKE])
 
index 2ab50b173acd87025442f1149844ada6487f4210..8570599bbf96109e479312488c631a492e761fb3 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.61 for linux nfs-utils 1.1.2.
+# Generated by GNU Autoconf 2.61 for linux nfs-utils 1.1.3.
 #
 # Report bugs to <linux-nfs@vger.kernel.org>.
 #
@@ -728,8 +728,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
 # Identity of this package.
 PACKAGE_NAME='linux nfs-utils'
 PACKAGE_TARNAME='nfs-utils'
-PACKAGE_VERSION='1.1.2'
-PACKAGE_STRING='linux nfs-utils 1.1.2'
+PACKAGE_VERSION='1.1.3'
+PACKAGE_STRING='linux nfs-utils 1.1.3'
 PACKAGE_BUGREPORT='linux-nfs@vger.kernel.org'
 
 ac_default_prefix=/usr
@@ -861,6 +861,9 @@ CONFIG_RPCGEN_TRUE
 CONFIG_RPCGEN_FALSE
 CONFIG_MOUNT_TRUE
 CONFIG_MOUNT_FALSE
+enable_ipv6
+CONFIG_IPV6_TRUE
+CONFIG_IPV6_FALSE
 CC
 CFLAGS
 LDFLAGS
@@ -1449,7 +1452,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures linux nfs-utils 1.1.2 to adapt to many kinds of systems.
+\`configure' configures linux nfs-utils 1.1.3 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1519,7 +1522,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of linux nfs-utils 1.1.2:";;
+     short | recursive ) echo "Configuration of linux nfs-utils 1.1.3:";;
    esac
   cat <<\_ACEOF
 
@@ -1537,6 +1540,7 @@ Optional Features:
                           libblkid
   --enable-mount          Create mount.nfs and don't use the util-linux
                           mount(8) functionality. [default=yes]
+  --enable-ipv6           enable support for IPv6 [default=no]
   --disable-dependency-tracking  speeds up one-time build
   --enable-dependency-tracking   do not reject slow dependency extractors
   --disable-largefile     omit support for large files
@@ -1653,7 +1657,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-linux nfs-utils configure 1.1.2
+linux nfs-utils configure 1.1.3
 generated by GNU Autoconf 2.61
 
 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1667,7 +1671,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by linux nfs-utils $as_me 1.1.2, which was
+It was created by linux nfs-utils $as_me 1.1.3, which was
 generated by GNU Autoconf 2.61.  Invocation command line was
 
   $ $0 $@
@@ -2441,7 +2445,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='nfs-utils'
- VERSION='1.1.2'
+ VERSION='1.1.3'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -2807,6 +2811,31 @@ else
   CONFIG_MOUNT_FALSE=
 fi
 
+# Check whether --enable-ipv6 was given.
+if test "${enable_ipv6+set}" = set; then
+  enableval=$enable_ipv6; enable_ipv6=$enableval
+else
+  enable_ipv6=no
+fi
+
+       if test "$enable_ipv6" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define IPV6_SUPPORTED 1
+_ACEOF
+
+       else
+               enable_ipv6=
+       fi
+
+        if test "$enable_ipv6" = "yes"; then
+  CONFIG_IPV6_TRUE=
+  CONFIG_IPV6_FALSE='#'
+else
+  CONFIG_IPV6_TRUE='#'
+  CONFIG_IPV6_FALSE=
+fi
+
 
 # Check whether user wants TCP wrappers support
 DEPDIR="${am__leading_dot}deps"
@@ -6692,7 +6721,7 @@ ia64-*-hpux*)
   ;;
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 6695 "configure"' > conftest.$ac_ext
+  echo '#line 6724 "configure"' > conftest.$ac_ext
   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -8733,11 +8762,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8736: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:8765: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:8740: \$? = $ac_status" >&5
+   echo "$as_me:8769: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -9023,11 +9052,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:9026: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:9055: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:9030: \$? = $ac_status" >&5
+   echo "$as_me:9059: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -9127,11 +9156,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:9130: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:9159: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:9134: \$? = $ac_status" >&5
+   echo "$as_me:9163: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -11478,7 +11507,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 11481 "configure"
+#line 11510 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11578,7 +11607,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 11581 "configure"
+#line 11610 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -13998,11 +14027,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:14001: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:14030: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:14005: \$? = $ac_status" >&5
+   echo "$as_me:14034: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -14102,11 +14131,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:14105: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:14134: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:14109: \$? = $ac_status" >&5
+   echo "$as_me:14138: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -15666,11 +15695,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:15669: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:15698: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:15673: \$? = $ac_status" >&5
+   echo "$as_me:15702: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -15770,11 +15799,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:15773: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:15802: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:15777: \$? = $ac_status" >&5
+   echo "$as_me:15806: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -17959,11 +17988,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:17962: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:17991: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:17966: \$? = $ac_status" >&5
+   echo "$as_me:17995: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -18249,11 +18278,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:18252: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:18281: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:18256: \$? = $ac_status" >&5
+   echo "$as_me:18285: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -18353,11 +18382,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:18356: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:18385: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:18360: \$? = $ac_status" >&5
+   echo "$as_me:18389: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
 fi
 
 
+{ echo "$as_me:$LINENO: checking for getaddrinfo" >&5
+echo $ECHO_N "checking for getaddrinfo... $ECHO_C" >&6; }
+if test "${ac_cv_func_getaddrinfo+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define getaddrinfo to an innocuous variant, in case <limits.h> declares getaddrinfo.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define getaddrinfo innocuous_getaddrinfo
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char getaddrinfo (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef getaddrinfo
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getaddrinfo ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_getaddrinfo || defined __stub___getaddrinfo
+choke me
+#endif
+
+int
+main ()
+{
+return getaddrinfo ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_func_getaddrinfo=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_func_getaddrinfo=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_func_getaddrinfo" >&5
+echo "${ECHO_T}$ac_cv_func_getaddrinfo" >&6; }
+
+
 { echo "$as_me:$LINENO: checking for crypt in -lcrypt" >&5
 echo $ECHO_N "checking for crypt in -lcrypt... $ECHO_C" >&6; }
 if test "${ac_cv_lib_crypt_crypt+set}" = set; then
@@ -22588,11 +22700,10 @@ pkg_failed=no
 { echo "$as_me:$LINENO: checking for RPCSECGSS" >&5
 echo $ECHO_N "checking for RPCSECGSS... $ECHO_C" >&6; }
 
-if test -n "$PKG_CONFIG"; then
-    if test -n "$RPCSECGSS_CFLAGS"; then
-        pkg_cv_RPCSECGSS_CFLAGS="$RPCSECGSS_CFLAGS"
-    else
-        if test -n "$PKG_CONFIG" && \
+if test -n "$RPCSECGSS_CFLAGS"; then
+    pkg_cv_RPCSECGSS_CFLAGS="$RPCSECGSS_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
     { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"librpcsecgss >= 0.16\"") >&5
   ($PKG_CONFIG --exists --print-errors "librpcsecgss >= 0.16") 2>&5
   ac_status=$?
@@ -22602,15 +22713,13 @@ if test -n "$PKG_CONFIG"; then
 else
   pkg_failed=yes
 fi
-    fi
-else
-       pkg_failed=untried
+ else
+    pkg_failed=untried
 fi
-if test -n "$PKG_CONFIG"; then
-    if test -n "$RPCSECGSS_LIBS"; then
-        pkg_cv_RPCSECGSS_LIBS="$RPCSECGSS_LIBS"
-    else
-        if test -n "$PKG_CONFIG" && \
+if test -n "$RPCSECGSS_LIBS"; then
+    pkg_cv_RPCSECGSS_LIBS="$RPCSECGSS_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
     { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"librpcsecgss >= 0.16\"") >&5
   ($PKG_CONFIG --exists --print-errors "librpcsecgss >= 0.16") 2>&5
   ac_status=$?
@@ -22620,9 +22729,8 @@ if test -n "$PKG_CONFIG"; then
 else
   pkg_failed=yes
 fi
-    fi
-else
-       pkg_failed=untried
+ else
+    pkg_failed=untried
 fi
 
 
@@ -22635,9 +22743,9 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-               RPCSECGSS_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "librpcsecgss >= 0.16"`
+               RPCSECGSS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "librpcsecgss >= 0.16" 2>&1`
         else
-               RPCSECGSS_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "librpcsecgss >= 0.16"`
+               RPCSECGSS_PKG_ERRORS=`$PKG_CONFIG --print-errors "librpcsecgss >= 0.16" 2>&1`
         fi
        # Put the nasty error message in config.log where it belongs
        echo "$RPCSECGSS_PKG_ERRORS" >&5
@@ -22667,11 +22775,10 @@ pkg_failed=no
 { echo "$as_me:$LINENO: checking for GSSGLUE" >&5
 echo $ECHO_N "checking for GSSGLUE... $ECHO_C" >&6; }
 
-if test -n "$PKG_CONFIG"; then
-    if test -n "$GSSGLUE_CFLAGS"; then
-        pkg_cv_GSSGLUE_CFLAGS="$GSSGLUE_CFLAGS"
-    else
-        if test -n "$PKG_CONFIG" && \
+if test -n "$GSSGLUE_CFLAGS"; then
+    pkg_cv_GSSGLUE_CFLAGS="$GSSGLUE_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
     { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"libgssglue >= 0.1\"") >&5
   ($PKG_CONFIG --exists --print-errors "libgssglue >= 0.1") 2>&5
   ac_status=$?
@@ -22681,15 +22788,13 @@ if test -n "$PKG_CONFIG"; then
 else
   pkg_failed=yes
 fi
-    fi
-else
-       pkg_failed=untried
+ else
+    pkg_failed=untried
 fi
-if test -n "$PKG_CONFIG"; then
-    if test -n "$GSSGLUE_LIBS"; then
-        pkg_cv_GSSGLUE_LIBS="$GSSGLUE_LIBS"
-    else
-        if test -n "$PKG_CONFIG" && \
+if test -n "$GSSGLUE_LIBS"; then
+    pkg_cv_GSSGLUE_LIBS="$GSSGLUE_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
     { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"libgssglue >= 0.1\"") >&5
   ($PKG_CONFIG --exists --print-errors "libgssglue >= 0.1") 2>&5
   ac_status=$?
@@ -22699,9 +22804,8 @@ if test -n "$PKG_CONFIG"; then
 else
   pkg_failed=yes
 fi
-    fi
-else
-       pkg_failed=untried
+ else
+    pkg_failed=untried
 fi
 
 
@@ -22714,9 +22818,9 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-               GSSGLUE_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "libgssglue >= 0.1"`
+               GSSGLUE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "libgssglue >= 0.1" 2>&1`
         else
-               GSSGLUE_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "libgssglue >= 0.1"`
+               GSSGLUE_PKG_ERRORS=`$PKG_CONFIG --print-errors "libgssglue >= 0.1" 2>&1`
         fi
        # Put the nasty error message in config.log where it belongs
        echo "$GSSGLUE_PKG_ERRORS" >&5
 
 fi
 
+if test "$enable_ipv6" = yes; then
+  { echo "$as_me:$LINENO: checking for inet_ntop" >&5
+echo $ECHO_N "checking for inet_ntop... $ECHO_C" >&6; }
+if test "${ac_cv_func_inet_ntop+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define inet_ntop to an innocuous variant, in case <limits.h> declares inet_ntop.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define inet_ntop innocuous_inet_ntop
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char inet_ntop (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef inet_ntop
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_ntop ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_inet_ntop || defined __stub___inet_ntop
+choke me
+#endif
+
+int
+main ()
+{
+return inet_ntop ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_func_inet_ntop=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_func_inet_ntop=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_func_inet_ntop" >&5
+echo "${ECHO_T}$ac_cv_func_inet_ntop" >&6; }
+
+  { echo "$as_me:$LINENO: checking for getnameinfo" >&5
+echo $ECHO_N "checking for getnameinfo... $ECHO_C" >&6; }
+if test "${ac_cv_func_getnameinfo+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define getnameinfo to an innocuous variant, in case <limits.h> declares getnameinfo.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define getnameinfo innocuous_getnameinfo
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char getnameinfo (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef getnameinfo
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getnameinfo ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_getnameinfo || defined __stub___getnameinfo
+choke me
+#endif
+
+int
+main ()
+{
+return getnameinfo ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_func_getnameinfo=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_func_getnameinfo=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_func_getnameinfo" >&5
+echo "${ECHO_T}$ac_cv_func_getnameinfo" >&6; }
+
+
+{ echo "$as_me:$LINENO: checking for clnt_tli_create in -ltirpc" >&5
+echo $ECHO_N "checking for clnt_tli_create in -ltirpc... $ECHO_C" >&6; }
+if test "${ac_cv_lib_tirpc_clnt_tli_create+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ltirpc  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char clnt_tli_create ();
+int
+main ()
+{
+return clnt_tli_create ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_tirpc_clnt_tli_create=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_lib_tirpc_clnt_tli_create=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_tirpc_clnt_tli_create" >&5
+echo "${ECHO_T}$ac_cv_lib_tirpc_clnt_tli_create" >&6; }
+if test $ac_cv_lib_tirpc_clnt_tli_create = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBTIRPC 1
+_ACEOF
+
+  LIBS="-ltirpc $LIBS"
+
+else
+  { { echo "$as_me:$LINENO: error: libtirpc needed for IPv6 support" >&5
+echo "$as_me: error: libtirpc needed for IPv6 support" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+
+for ac_header in tirpc/netconfig.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       }; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    ( cat <<\_ASBOX
+## ---------------------------------------- ##
+## Report this to linux-nfs@vger.kernel.org ##
+## ---------------------------------------- ##
+_ASBOX
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+else
+  { { echo "$as_me:$LINENO: error: libtirpc-devel needed for IPv6 support" >&5
+echo "$as_me: error: libtirpc-devel needed for IPv6 support" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+done
+
+fi
+
+
 
 
 
@@ -24145,7 +24641,7 @@ for ac_header in arpa/inet.h fcntl.h libintl.h limits.h \
                  stdlib.h string.h sys/file.h sys/ioctl.h sys/mount.h \
                  sys/param.h sys/socket.h sys/time.h sys/vfs.h \
                  syslog.h unistd.h com_err.h et/com_err.h \
-                 ifaddrs.h
+                 ifaddrs.h tirpc/netconfig.h
 do
 as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
 if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
@@ -27758,6 +28254,17 @@ done
 
 
 
+
+
+
+
+
+
+
+
+
+
+
 
 
 
@@ -27771,6 +28278,10 @@ done
 
 for ac_func in alarm atexit dup2 fdatasync ftruncate getcwd \
                gethostbyaddr gethostbyname gethostname getmntent \
+               inet_ntop getnameinfo getrpcbyname \
+               bindresvport_sa getnetconfig \
+               clnt_create clnt_create_timed \
+               clnt_tli_create clnt_vc_create clnt_dg_create xdr_rpcb \
                gettimeofday hasmntopt inet_ntoa innetgr memset mkdir pathconf \
                realpath rmdir select socket strcasecmp strchr strdup \
                strerror strrchr strtol strtoul sigprocmask
@@ -30072,6 +30583,13 @@ echo "$as_me: error: conditional \"CONFIG_MOUNT\" was never defined.
 Usually this means the macro was only invoked conditionally." >&2;}
    { (exit 1); exit 1; }; }
 fi
+if test -z "${CONFIG_IPV6_TRUE}" && test -z "${CONFIG_IPV6_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"CONFIG_IPV6\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"CONFIG_IPV6\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
 if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
   { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined.
 Usually this means the macro was only invoked conditionally." >&5
@@ -30400,7 +30918,7 @@ exec 6>&1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by linux nfs-utils $as_me 1.1.2, which was
+This file was extended by linux nfs-utils $as_me 1.1.3, which was
 generated by GNU Autoconf 2.61.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -30453,7 +30971,7 @@ Report bugs to <bug-autoconf@gnu.org>."
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
 ac_cs_version="\\
-linux nfs-utils config.status 1.1.2
+linux nfs-utils config.status 1.1.3
 configured by $0, generated by GNU Autoconf 2.61,
   with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 
@@ -30748,12 +31266,12 @@ CONFIG_RPCGEN_TRUE!$CONFIG_RPCGEN_TRUE$ac_delim
 CONFIG_RPCGEN_FALSE!$CONFIG_RPCGEN_FALSE$ac_delim
 CONFIG_MOUNT_TRUE!$CONFIG_MOUNT_TRUE$ac_delim
 CONFIG_MOUNT_FALSE!$CONFIG_MOUNT_FALSE$ac_delim
+enable_ipv6!$enable_ipv6$ac_delim
+CONFIG_IPV6_TRUE!$CONFIG_IPV6_TRUE$ac_delim
+CONFIG_IPV6_FALSE!$CONFIG_IPV6_FALSE$ac_delim
 CC!$CC$ac_delim
 CFLAGS!$CFLAGS$ac_delim
 LDFLAGS!$LDFLAGS$ac_delim
-CPPFLAGS!$CPPFLAGS$ac_delim
-ac_ct_CC!$ac_ct_CC$ac_delim
-EXEEXT!$EXEEXT$ac_delim
 _ACEOF
 
   if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
@@ -30795,6 +31313,9 @@ _ACEOF
 ac_delim='%!_!# '
 for ac_last_try in false false false false false :; do
   cat >conf$$subs.sed <<_ACEOF
+CPPFLAGS!$CPPFLAGS$ac_delim
+ac_ct_CC!$ac_ct_CC$ac_delim
+EXEEXT!$EXEEXT$ac_delim
 OBJEXT!$OBJEXT$ac_delim
 DEPDIR!$DEPDIR$ac_delim
 am__include!$am__include$ac_delim
@@ -30856,7 +31377,7 @@ ACLOCAL_AMFLAGS!$ACLOCAL_AMFLAGS$ac_delim
 LTLIBOBJS!$LTLIBOBJS$ac_delim
 _ACEOF
 
-  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 59; then
+  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 62; then
     break
   elif $ac_last_try; then
     { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
@@ -31257,21 +31778,22 @@ echo "$as_me: $ac_file is unchanged" >&6;}
   fi
   rm -f "$tmp/out12"
 # Compute $ac_file's index in $config_headers.
+_am_arg=$ac_file
 _am_stamp_count=1
 for _am_header in $config_headers :; do
   case $_am_header in
-    $ac_file | $ac_file:* )
+    $_am_arg | $_am_arg:* )
       break ;;
     * )
       _am_stamp_count=`expr $_am_stamp_count + 1` ;;
   esac
 done
-echo "timestamp for $ac_file" >`$as_dirname -- $ac_file ||
-$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-        X$ac_file : 'X\(//\)[^/]' \| \
-        X$ac_file : 'X\(//\)$' \| \
-        X$ac_file : 'X\(/\)' \| . 2>/dev/null ||
-echo X$ac_file |
+echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
+$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$_am_arg" : 'X\(//\)[^/]' \| \
+        X"$_am_arg" : 'X\(//\)$' \| \
+        X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
+echo X"$_am_arg" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
            s//\1/
            q
@@ -31308,7 +31830,7 @@ echo "$as_me: executing $ac_file commands" >&6;}
   # each Makefile.in and add a new line on top of each file to say so.
   # Grep'ing the whole file is not good either: AIX grep has a line
   # limit of 2048, but all sed's we know have understand at least 4000.
-  if sed 10q "$mf" | grep '^#.*generated by automake' > /dev/null 2>&1; then
+  if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
     dirpart=`$as_dirname -- "$mf" ||
 $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
         X"$mf" : 'X\(//\)[^/]' \| \
index 6ecbf55c9adf314c5bd8e4e93c73384108f77b3b..6ae6c6df4ceb86f2a0575d9bbe14696581de9234 100644 (file)
@@ -1,6 +1,6 @@
 dnl Process this file with autoconf to produce a configure script.
 dnl
-AC_INIT([linux nfs-utils],[1.1.2],[linux-nfs@vger.kernel.org],[nfs-utils])
+AC_INIT([linux nfs-utils],[1.1.3],[linux-nfs@vger.kernel.org],[nfs-utils])
 AC_CANONICAL_BUILD([])
 AC_CANONICAL_HOST([])
 AC_CONFIG_MACRO_DIR(aclocal)
@@ -127,6 +127,18 @@ AC_ARG_ENABLE(mount,
        enable_mount=$enableval,
        enable_mount=yes)
        AM_CONDITIONAL(CONFIG_MOUNT, [test "$enable_mount" = "yes"])
+AC_ARG_ENABLE(ipv6,
+       [AC_HELP_STRING([--enable-ipv6],
+                        [enable support for IPv6 @<:@default=no@:>@])],
+       enable_ipv6=$enableval,
+       enable_ipv6=no)
+       if test "$enable_ipv6" = yes; then
+               AC_DEFINE(IPV6_SUPPORTED, 1, [Define this if you want IPv6 support compiled in])
+       else
+               enable_ipv6=
+       fi
+       AC_SUBST(enable_ipv6)
+       AM_CONDITIONAL(CONFIG_IPV6, [test "$enable_ipv6" = "yes"])
 
 # Check whether user wants TCP wrappers support
 AC_TCP_WRAPPERS
@@ -172,6 +184,9 @@ AC_CHECK_FUNC(connect, ,
       AC_CHECK_LIB(socket, connect, [LIBSOCKET="-lsocket"],
                 AC_MSG_ERROR(Function 'socket' not found.), $LIBNSL))
 
+AC_CHECK_FUNC(getaddrinfo, , ,
+                AC_MSG_ERROR(Function 'getaddrinfo' not found.))
+
 AC_CHECK_LIB(crypt, crypt, [LIBCRYPT="-lcrypt"])
 if test "$enable_nfsv4" = yes; then
     AC_CHECK_LIB(event, event_dispatch, [libevent=1], AC_MSG_ERROR([libevent needed for nfsv4 support]))
@@ -234,6 +249,17 @@ if test "$enable_gss" = yes; then
 
 fi
 
+if test "$enable_ipv6" = yes; then
+  AC_CHECK_FUNC(inet_ntop, , ,
+               AC_MSG_ERROR(Function 'inet_ntop' not found.))
+  AC_CHECK_FUNC(getnameinfo, , ,
+               AC_MSG_ERROR(Function 'getnameinfo' not found.))
+  AC_CHECK_LIB(tirpc, clnt_tli_create, ,
+               AC_MSG_ERROR([libtirpc needed for IPv6 support]))
+  AC_CHECK_HEADERS(tirpc/netconfig.h, ,
+               AC_MSG_ERROR([libtirpc-devel needed for IPv6 support]))
+fi
+
 dnl *************************************************************
 dnl Check for headers
 dnl *************************************************************
@@ -242,7 +268,7 @@ AC_CHECK_HEADERS([arpa/inet.h fcntl.h libintl.h limits.h \
                  stdlib.h string.h sys/file.h sys/ioctl.h sys/mount.h \
                  sys/param.h sys/socket.h sys/time.h sys/vfs.h \
                  syslog.h unistd.h com_err.h et/com_err.h \
-                 ifaddrs.h])
+                 ifaddrs.h tirpc/netconfig.h])
 
 dnl *************************************************************
 dnl Checks for typedefs, structures, and compiler characteristics
@@ -278,6 +304,10 @@ AC_FUNC_STAT
 AC_FUNC_VPRINTF
 AC_CHECK_FUNCS([alarm atexit dup2 fdatasync ftruncate getcwd \
                gethostbyaddr gethostbyname gethostname getmntent \
+               inet_ntop getnameinfo getrpcbyname \
+               bindresvport_sa getnetconfig \
+               clnt_create clnt_create_timed \
+               clnt_tli_create clnt_vc_create clnt_dg_create xdr_rpcb \
                gettimeofday hasmntopt inet_ntoa innetgr memset mkdir pathconf \
                realpath rmdir select socket strcasecmp strchr strdup \
                strerror strrchr strtol strtoul sigprocmask])
diff --git a/depcomp b/depcomp
index ca5ea4e1ef9c125b1cb1fc7d51c93d8747637deb..e5f9736c7239301c765e2d7abefb9bb9b9237ac5 100755 (executable)
--- a/depcomp
+++ b/depcomp
@@ -1,9 +1,9 @@
 #! /bin/sh
 # depcomp - compile a program generating dependencies as side-effects
 
-scriptversion=2006-10-15.18
+scriptversion=2007-03-29.01
 
-# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006 Free Software
+# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007 Free Software
 # Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
@@ -215,34 +215,39 @@ aix)
   # current directory.  Also, the AIX compiler puts `$object:' at the
   # start of each line; $object doesn't have directory information.
   # Version 6 uses the directory in both cases.
-  stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
-  tmpdepfile="$stripped.u"
+  dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+  test "x$dir" = "x$object" && dir=
+  base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
   if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$base.u
+    tmpdepfile3=$dir.libs/$base.u
     "$@" -Wc,-M
   else
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$dir$base.u
+    tmpdepfile3=$dir$base.u
     "$@" -M
   fi
   stat=$?
 
-  if test -f "$tmpdepfile"; then :
-  else
-    stripped=`echo "$stripped" | sed 's,^.*/,,'`
-    tmpdepfile="$stripped.u"
-  fi
-
   if test $stat -eq 0; then :
   else
-    rm -f "$tmpdepfile"
+    rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
     exit $stat
   fi
 
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+  do
+    test -f "$tmpdepfile" && break
+  done
   if test -f "$tmpdepfile"; then
-    outname="$stripped.o"
     # Each line is of the form `foo.o: dependent.h'.
     # Do two passes, one to just change these to
     # `$object: dependent.h' and one to simply `dependent.h:'.
-    sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
-    sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
+    sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+    # That's a tab and a space in the [].
+    sed -e 's,^.*\.[a-z]*:[     ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
   else
     # The sourcefile does not contain any dependencies, so just
     # store a dummy comment line, to avoid errors with the Makefile
index 4fbbae7b7ff932e5af542dbe9612f193a68ed4d1..a5897de6ea7f74f83fd793474bb4738d32884719 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 # install - install a program, script, or datafile
 
-scriptversion=2006-10-14.15
+scriptversion=2006-12-25.00
 
 # This originates from X11R5 (mit/util/scripts/install.sh), which was
 # later released in X11R6 (xc/config/util/install.sh) with the
@@ -48,7 +48,7 @@ IFS=" ""      $nl"
 # set DOITPROG to echo to test this script
 
 # Don't use :- since 4.3BSD and earlier shells don't like it.
-doit="${DOITPROG-}"
+doit=${DOITPROG-}
 if test -z "$doit"; then
   doit_exec=exec
 else
@@ -58,34 +58,49 @@ fi
 # Put in absolute file names if you don't have them in your path;
 # or use environment vars.
 
-mvprog="${MVPROG-mv}"
-cpprog="${CPPROG-cp}"
-chmodprog="${CHMODPROG-chmod}"
-chownprog="${CHOWNPROG-chown}"
-chgrpprog="${CHGRPPROG-chgrp}"
-stripprog="${STRIPPROG-strip}"
-rmprog="${RMPROG-rm}"
-mkdirprog="${MKDIRPROG-mkdir}"
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+  test "$posix_glob" != "?" || {
+    if (set -f) 2>/dev/null; then
+      posix_glob=
+    else
+      posix_glob=:
+    fi
+  }
+'
 
-posix_glob=
 posix_mkdir=
 
 # Desired mode of installed file.
 mode=0755
 
+chgrpcmd=
 chmodcmd=$chmodprog
 chowncmd=
-chgrpcmd=
-stripcmd=
+mvcmd=$mvprog
 rmcmd="$rmprog -f"
-mvcmd="$mvprog"
+stripcmd=
+
 src=
 dst=
 dir_arg=
-dstarg=
+dst_arg=
+
+copy_on_change=false
 no_target_directory=
 
-usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
    or: $0 [OPTION]... SRCFILES... DIRECTORY
    or: $0 [OPTION]... -t DIRECTORY SRCFILES...
    or: $0 [OPTION]... -d DIRECTORIES...
@@ -95,65 +110,55 @@ In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
 In the 4th, create DIRECTORIES.
 
 Options:
--c         (ignored)
--d         create directories instead of installing files.
--g GROUP   $chgrpprog installed files to GROUP.
--m MODE    $chmodprog installed files to MODE.
--o USER    $chownprog installed files to USER.
--s         $stripprog installed files.
--t DIRECTORY  install into DIRECTORY.
--T         report an error if DSTFILE is a directory.
---help     display this help and exit.
---version  display version info and exit.
+     --help     display this help and exit.
+     --version  display version info and exit.
+
+  -c            (ignored)
+  -C            install only if different (preserve the last data modification time)
+  -d            create directories instead of installing files.
+  -g GROUP      $chgrpprog installed files to GROUP.
+  -m MODE       $chmodprog installed files to MODE.
+  -o USER       $chownprog installed files to USER.
+  -s            $stripprog installed files.
+  -t DIRECTORY  install into DIRECTORY.
+  -T            report an error if DSTFILE is a directory.
 
 Environment variables override the default commands:
-  CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
+  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+  RMPROG STRIPPROG
 "
 
 while test $# -ne 0; do
   case $1 in
-    -c) shift
-        continue;;
+    -c) ;;
+
+    -C) copy_on_change=true;;
 
-    -d) dir_arg=true
-        shift
-        continue;;
+    -d) dir_arg=true;;
 
     -g) chgrpcmd="$chgrpprog $2"
-        shift
-        shift
-        continue;;
+       shift;;
 
     --help) echo "$usage"; exit $?;;
 
     -m) mode=$2
-        shift
-        shift
        case $mode in
          *' '* | *'    '* | *'
 '*       | *'*'* | *'?'* | *'['*)
            echo "$0: invalid mode: $mode" >&2
            exit 1;;
        esac
-        continue;;
+       shift;;
 
     -o) chowncmd="$chownprog $2"
-        shift
-        shift
-        continue;;
+       shift;;
 
-    -s) stripcmd=$stripprog
-        shift
-        continue;;
+    -s) stripcmd=$stripprog;;
 
-    -t) dstarg=$2
-       shift
-       shift
-       continue;;
+    -t) dst_arg=$2
+       shift;;
 
-    -T) no_target_directory=true
-       shift
-       continue;;
+    -T) no_target_directory=true;;
 
     --version) echo "$0 $scriptversion"; exit $?;;
 
@@ -165,21 +170,22 @@ while test $# -ne 0; do
 
     *)  break;;
   esac
+  shift
 done
 
-if test $# -ne 0 && test -z "$dir_arg$dstarg"; then
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
   # When -d is used, all remaining arguments are directories to create.
   # When -t is used, the destination is already specified.
   # Otherwise, the last argument is the destination.  Remove it from $@.
   for arg
   do
-    if test -n "$dstarg"; then
+    if test -n "$dst_arg"; then
       # $@ is not empty: it contains at least $arg.
-      set fnord "$@" "$dstarg"
+      set fnord "$@" "$dst_arg"
       shift # fnord
     fi
     shift # arg
-    dstarg=$arg
+    dst_arg=$arg
   done
 fi
 
@@ -224,7 +230,7 @@ for src
 do
   # Protect names starting with `-'.
   case $src in
-    -*) src=./$src ;;
+    -*) src=./$src;;
   esac
 
   if test -n "$dir_arg"; then
@@ -242,22 +248,22 @@ do
       exit 1
     fi
 
-    if test -z "$dstarg"; then
+    if test -z "$dst_arg"; then
       echo "$0: no destination specified." >&2
       exit 1
     fi
 
-    dst=$dstarg
+    dst=$dst_arg
     # Protect names starting with `-'.
     case $dst in
-      -*) dst=./$dst ;;
+      -*) dst=./$dst;;
     esac
 
     # If destination is a directory, append the input filename; won't work
     # if double slashes aren't ignored.
     if test -d "$dst"; then
       if test -n "$no_target_directory"; then
-       echo "$0: $dstarg: Is a directory" >&2
+       echo "$0: $dst_arg: Is a directory" >&2
        exit 1
       fi
       dstdir=$dst
@@ -378,26 +384,19 @@ do
       # directory the slow way, step by step, checking for races as we go.
 
       case $dstdir in
-       /*) prefix=;;
-       -*) prefix=./ ;;
-       *)  prefix= ;;
+       /*) prefix='/';;
+       -*) prefix='./';;
+       *)  prefix='';;
       esac
 
-      case $posix_glob in
-        '')
-         if (set -f) 2>/dev/null; then
-           posix_glob=true
-         else
-           posix_glob=false
-         fi ;;
-      esac
+      eval "$initialize_posix_glob"
 
       oIFS=$IFS
       IFS=/
-      $posix_glob && set -f
+      $posix_glob set -f
       set fnord $dstdir
       shift
-      $posix_glob && set +f
+      $posix_glob set +f
       IFS=$oIFS
 
       prefixes=
@@ -459,41 +458,54 @@ do
     # ignore errors from any of these, just make sure not to ignore
     # errors from the above "$doit $cpprog $src $dsttmp" command.
     #
-    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
-      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
-      && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
-      && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
-
-    # Now rename the file to the real destination.
-    { $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \
-      || {
-          # The rename failed, perhaps because mv can't rename something else
-          # to itself, or perhaps because mv is so ancient that it does not
-          # support -f.
-
-          # Now remove or move aside any old file at destination location.
-          # We try this two ways since rm can't unlink itself on some
-          # systems and the destination file might be busy for other
-          # reasons.  In this case, the final cleanup might fail but the new
-          # file should still install successfully.
-          {
-            if test -f "$dst"; then
-              $doit $rmcmd -f "$dst" 2>/dev/null \
-              || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \
-                    && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\
-              || {
-                echo "$0: cannot unlink or rename $dst" >&2
-                (exit 1); exit 1
-              }
-            else
-              :
-            fi
-          } &&
-
-          # Now rename the file to the real destination.
-          $doit $mvcmd "$dsttmp" "$dst"
-        }
-    } || exit 1
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+    # If -C, don't bother to copy if it wouldn't change the file.
+    if $copy_on_change &&
+       old=`LC_ALL=C ls -dlL "$dst"    2>/dev/null` &&
+       new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
+
+       eval "$initialize_posix_glob" &&
+       $posix_glob set -f &&
+       set X $old && old=:$2:$4:$5:$6 &&
+       set X $new && new=:$2:$4:$5:$6 &&
+       $posix_glob set +f &&
+
+       test "$old" = "$new" &&
+       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+    then
+      rm -f "$dsttmp"
+    else
+      # Rename the file to the real destination.
+      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+      # The rename failed, perhaps because mv can't rename something else
+      # to itself, or perhaps because mv is so ancient that it does not
+      # support -f.
+      {
+       # Now remove or move aside any old file at destination location.
+       # We try this two ways since rm can't unlink itself on some
+       # systems and the destination file might be busy for other
+       # reasons.  In this case, the final cleanup might fail but the new
+       # file should still install successfully.
+       {
+         test ! -f "$dst" ||
+         $doit $rmcmd -f "$dst" 2>/dev/null ||
+         { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+           { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+         } ||
+         { echo "$0: cannot unlink or rename $dst" >&2
+           (exit 1); exit 1
+         }
+       } &&
+
+       # Now rename the file to the real destination.
+       $doit $mvcmd "$dsttmp" "$dst"
+      }
+    fi || exit 1
 
     trap '' 0
   fi
index d8bd3fdc4fe772ece47437b7bd32127068c0857a..a25399b4b31eeef306171e9d84a59d822e9241f9 100644 (file)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -162,6 +162,7 @@ datarootdir = @datarootdir@
 docdir = @docdir@
 dvidir = @dvidir@
 enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
 enable_nfsv3 = @enable_nfsv3@
 enable_nfsv4 = @enable_nfsv4@
 exec_prefix = @exec_prefix@
index c7305ff515c1f7be6da3d1c2064cbf5ac49cba6c..2bde2ec59871effbad24df05c72eebf41ca8c8ac 100644 (file)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -173,6 +173,7 @@ datarootdir = @datarootdir@
 docdir = @docdir@
 dvidir = @dvidir@
 enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
 enable_nfsv3 = @enable_nfsv3@
 enable_nfsv4 = @enable_nfsv4@
 exec_prefix = @exec_prefix@
@@ -324,8 +325,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        mkid -fID $$unique
 tags: TAGS
 
@@ -350,8 +351,8 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
          test -n "$$unique" || unique=$$empty_fix; \
          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -361,13 +362,12 @@ ctags: CTAGS
 CTAGS: ctags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
                $(TAGS_FILES) $(LISP)
        tags=; \
-       here=`pwd`; \
        list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        test -z "$(CTAGS_ARGS)$$tags$$unique" \
          || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
             $$tags $$unique
index dcddec6939461e58fcb9a0d3b58ca14ad8aaa087..00b10152a413e16bf2563ab203d51ac9b589c628 100644 (file)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -56,7 +56,7 @@ am_libexport_a_OBJECTS = client.$(OBJEXT) export.$(OBJEXT) \
        hostname.$(OBJEXT) nfsctl.$(OBJEXT) rmtab.$(OBJEXT) \
        xtab.$(OBJEXT) mount_clnt.$(OBJEXT) mount_xdr.$(OBJEXT)
 libexport_a_OBJECTS = $(am_libexport_a_OBJECTS)
-DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -187,6 +187,7 @@ datarootdir = @datarootdir@
 docdir = @docdir@
 dvidir = @dvidir@
 enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
 enable_nfsv3 = @enable_nfsv3@
 enable_nfsv4 = @enable_nfsv4@
 exec_prefix = @exec_prefix@
@@ -326,8 +327,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        mkid -fID $$unique
 tags: TAGS
 
@@ -339,8 +340,8 @@ TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
          test -n "$$unique" || unique=$$empty_fix; \
          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -350,13 +351,12 @@ ctags: CTAGS
 CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
                $(TAGS_FILES) $(LISP)
        tags=; \
-       here=`pwd`; \
        list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        test -z "$(CTAGS_ARGS)$$tags$$unique" \
          || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
             $$tags $$unique
index 8f392a7e83ffc614bd170b2bc4bead0f59464888..e11a22a8dd0d96fd18247c5375443c6c4b95eea0 100644 (file)
@@ -23,7 +23,7 @@ int
 rmtab_read(void)
 {
        struct rmtabent         *rep;
-       nfs_export              *exp;
+       nfs_export              *exp = NULL;
 
        setrmtabent("r");
        while ((rep = getrmtabent(1, NULL)) != NULL) {
@@ -31,7 +31,7 @@ rmtab_read(void)
                int                     htype;
                
                htype = client_gettype(rep->r_client);
-               if (htype == MCL_FQDN || htype == MCL_SUBNETWORK
+               if ((htype == MCL_FQDN || htype == MCL_SUBNETWORK)
                    && (hp = gethostbyname (rep->r_client))
                    && (hp = hostent_dup (hp),
                        exp = export_allowed (hp, rep->r_path))) {
index 0eace0badeef71c1dfe806f803f9b60ee71cbb0a..131eff9fec2d40e1e39ad88f21cf57112b6feaa7 100644 (file)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -176,6 +176,7 @@ datarootdir = @datarootdir@
 docdir = @docdir@
 dvidir = @dvidir@
 enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
 enable_nfsv3 = @enable_nfsv3@
 enable_nfsv4 = @enable_nfsv4@
 exec_prefix = @exec_prefix@
@@ -359,8 +360,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        mkid -fID $$unique
 tags: TAGS
 
@@ -385,8 +386,8 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
          test -n "$$unique" || unique=$$empty_fix; \
          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -396,13 +397,12 @@ ctags: CTAGS
 CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
                $(TAGS_FILES) $(LISP)
        tags=; \
-       here=`pwd`; \
        list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        test -z "$(CTAGS_ARGS)$$tags$$unique" \
          || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
             $$tags $$unique
index 33fc54710fbe8af7c6d92d9952573d77bfdc4770..dcf16cb5d8862da987ec92cc77640f8909c4e48c 100644 (file)
    authgss_set_debug_level */
 #undef HAVE_AUTHGSS_SET_DEBUG_LEVEL
 
+/* Define to 1 if you have the `bindresvport_sa' function. */
+#undef HAVE_BINDRESVPORT_SA
+
 /* Define this if you want to use BSD signal semantics */
 #undef HAVE_BSD_SIGNALS
 
+/* Define to 1 if you have the `clnt_create' function. */
+#undef HAVE_CLNT_CREATE
+
+/* Define to 1 if you have the `clnt_create_timed' function. */
+#undef HAVE_CLNT_CREATE_TIMED
+
+/* Define to 1 if you have the `clnt_dg_create' function. */
+#undef HAVE_CLNT_DG_CREATE
+
+/* Define to 1 if you have the `clnt_tli_create' function. */
+#undef HAVE_CLNT_TLI_CREATE
+
+/* Define to 1 if you have the `clnt_vc_create' function. */
+#undef HAVE_CLNT_VC_CREATE
+
 /* Define to 1 if you have the <com_err.h> header file. */
 #undef HAVE_COM_ERR_H
 
 /* Define to 1 if you have the `getmntent' function. */
 #undef HAVE_GETMNTENT
 
+/* Define to 1 if you have the `getnameinfo' function. */
+#undef HAVE_GETNAMEINFO
+
+/* Define to 1 if you have the `getnetconfig' function. */
+#undef HAVE_GETNETCONFIG
+
+/* Define to 1 if you have the `getrpcbyname' function. */
+#undef HAVE_GETRPCBYNAME
+
 /* Define to 1 if you have the `gettimeofday' function. */
 #undef HAVE_GETTIMEOFDAY
 
 /* Define to 1 if you have the `inet_ntoa' function. */
 #undef HAVE_INET_NTOA
 
+/* Define to 1 if you have the `inet_ntop' function. */
+#undef HAVE_INET_NTOP
+
 /* Define to 1 if you have the `innetgr' function. */
 #undef HAVE_INNETGR
 
 /* Define to 1 if you have the <libintl.h> header file. */
 #undef HAVE_LIBINTL_H
 
+/* Define to 1 if you have the `tirpc' library (-ltirpc). */
+#undef HAVE_LIBTIRPC
+
 /* tcp-wrapper */
 #undef HAVE_LIBWRAP
 
 /* tcp-wrapper */
 #undef HAVE_TCP_WRAPPER
 
+/* Define to 1 if you have the <tirpc/netconfig.h> header file. */
+#undef HAVE_TIRPC_NETCONFIG_H
+
 /* Define to 1 if you have the <unistd.h> header file. */
 #undef HAVE_UNISTD_H
 
 /* Define to 1 if `vfork' works. */
 #undef HAVE_WORKING_VFORK
 
+/* Define to 1 if you have the `xdr_rpcb' function. */
+#undef HAVE_XDR_RPCB
+
+/* Define this if you want IPv6 support compiled in */
+#undef IPV6_SUPPORTED
+
 /* Define this as the Kerberos version number */
 #undef KRB5_VERSION
 
index 3837d2638e6c70de3b85f8780028fae34a4d6972..2f3143d4703830cf8fea52c90abce57a5d6b0f92 100644 (file)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -166,6 +166,7 @@ datarootdir = @datarootdir@
 docdir = @docdir@
 dvidir = @dvidir@
 enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
 enable_nfsv3 = @enable_nfsv3@
 enable_nfsv4 = @enable_nfsv4@
 exec_prefix = @exec_prefix@
@@ -247,8 +248,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        mkid -fID $$unique
 tags: TAGS
 
@@ -260,8 +261,8 @@ TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
          test -n "$$unique" || unique=$$empty_fix; \
          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -271,13 +272,12 @@ ctags: CTAGS
 CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
                $(TAGS_FILES) $(LISP)
        tags=; \
-       here=`pwd`; \
        list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        test -z "$(CTAGS_ARGS)$$tags$$unique" \
          || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
             $$tags $$unique
index 909c414f3968dea87369f2ec13884d0085b9ee4d..74c097025ddf12a63d9f6ab47a7212818468b80e 100644 (file)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -166,6 +166,7 @@ datarootdir = @datarootdir@
 docdir = @docdir@
 dvidir = @dvidir@
 enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
 enable_nfsv3 = @enable_nfsv3@
 enable_nfsv4 = @enable_nfsv4@
 exec_prefix = @exec_prefix@
@@ -247,8 +248,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        mkid -fID $$unique
 tags: TAGS
 
@@ -260,8 +261,8 @@ TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
          test -n "$$unique" || unique=$$empty_fix; \
          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -271,13 +272,12 @@ ctags: CTAGS
 CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
                $(TAGS_FILES) $(LISP)
        tags=; \
-       here=`pwd`; \
        list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        test -z "$(CTAGS_ARGS)$$tags$$unique" \
          || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
             $$tags $$unique
index 9bde9c09f70cdbd911bfffee9dfa6e1c844b8ddc..a849c6a29de0d78c1c942e2886d3c6ee92b21ed6 100644 (file)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -173,6 +173,7 @@ datarootdir = @datarootdir@
 docdir = @docdir@
 dvidir = @dvidir@
 enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
 enable_nfsv3 = @enable_nfsv3@
 enable_nfsv4 = @enable_nfsv4@
 exec_prefix = @exec_prefix@
@@ -324,8 +325,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        mkid -fID $$unique
 tags: TAGS
 
@@ -350,8 +351,8 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
          test -n "$$unique" || unique=$$empty_fix; \
          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -361,13 +362,12 @@ ctags: CTAGS
 CTAGS: ctags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
                $(TAGS_FILES) $(LISP)
        tags=; \
-       here=`pwd`; \
        list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        test -z "$(CTAGS_ARGS)$$tags$$unique" \
          || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
             $$tags $$unique
index d6a00b1ca63df1d5a200a45631ee6c6f990b35a3..90b1efcac5a52f952d94b5a8287eb00d91402da7 100644 (file)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -166,6 +166,7 @@ datarootdir = @datarootdir@
 docdir = @docdir@
 dvidir = @dvidir@
 enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
 enable_nfsv3 = @enable_nfsv3@
 enable_nfsv4 = @enable_nfsv4@
 exec_prefix = @exec_prefix@
@@ -247,8 +248,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        mkid -fID $$unique
 tags: TAGS
 
@@ -260,8 +261,8 @@ TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
          test -n "$$unique" || unique=$$empty_fix; \
          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -271,13 +272,12 @@ ctags: CTAGS
 CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
                $(TAGS_FILES) $(LISP)
        tags=; \
-       here=`pwd`; \
        list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        test -z "$(CTAGS_ARGS)$$tags$$unique" \
          || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
             $$tags $$unique
index e1517300714eb2c82a42b411e649b8291e385abb..4c1974b2d955a48e63296298757002203cf67092 100644 (file)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -53,7 +53,7 @@ libmisc_a_LIBADD =
 am_libmisc_a_OBJECTS = tcpwrapper.$(OBJEXT) from_local.$(OBJEXT) \
        mountpoint.$(OBJEXT)
 libmisc_a_OBJECTS = $(am_libmisc_a_OBJECTS)
-DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -183,6 +183,7 @@ datarootdir = @datarootdir@
 docdir = @docdir@
 dvidir = @dvidir@
 enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
 enable_nfsv3 = @enable_nfsv3@
 enable_nfsv4 = @enable_nfsv4@
 exec_prefix = @exec_prefix@
@@ -304,8 +305,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        mkid -fID $$unique
 tags: TAGS
 
@@ -317,8 +318,8 @@ TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
          test -n "$$unique" || unique=$$empty_fix; \
          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -328,13 +329,12 @@ ctags: CTAGS
 CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
                $(TAGS_FILES) $(LISP)
        tags=; \
-       here=`pwd`; \
        list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        test -z "$(CTAGS_ARGS)$$tags$$unique" \
          || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
             $$tags $$unique
index 0cc93357086941b799bfeceb6bb85896c0407d05..e4f453bc93c6a95ca2de560b865037064751ae54 100644 (file)
@@ -125,12 +125,12 @@ struct sockaddr_in *addr;
           return 0;
 
    /* Check the official name first. */
-   if (hosts_ctl(daemon, "", hp->h_name, ""))
+   if (hosts_ctl(daemon, hp->h_name, "", ""))
        return 1;
 
    /* Check aliases. */
    for (sp = hp->h_aliases; *sp ; sp++) {
-       if (hosts_ctl(daemon, "", *sp, ""))
+       if (hosts_ctl(daemon, *sp, "", ""))
            return 1;
    }
 
index b4d588a40a754a9c1f00fd41b46cf3e44fcbf2e7..604a48e98a7436d454f052fbdac1383bce92737b 100644 (file)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -57,7 +57,7 @@ am_libnfs_a_OBJECTS = exports.$(OBJEXT) rmtab.$(OBJEXT) xio.$(OBJEXT) \
        nfsctl.$(OBJEXT) svc_socket.$(OBJEXT) cacheio.$(OBJEXT) \
        closeall.$(OBJEXT) nfs_mntent.$(OBJEXT)
 libnfs_a_OBJECTS = $(am_libnfs_a_OBJECTS)
-DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -187,6 +187,7 @@ datarootdir = @datarootdir@
 docdir = @docdir@
 dvidir = @dvidir@
 enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
 enable_nfsv3 = @enable_nfsv3@
 enable_nfsv4 = @enable_nfsv4@
 exec_prefix = @exec_prefix@
@@ -326,8 +327,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        mkid -fID $$unique
 tags: TAGS
 
@@ -339,8 +340,8 @@ TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
          test -n "$$unique" || unique=$$empty_fix; \
          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -350,13 +351,12 @@ ctags: CTAGS
 CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
                $(TAGS_FILES) $(LISP)
        tags=; \
-       here=`pwd`; \
        list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        test -z "$(CTAGS_ARGS)$$tags$$unique" \
          || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
             $$tags $$unique
index 0453ca7c0ba305122ff5353267659336fd16f9ab..f21f5f058f9d15c5fdccb601cc68e7a44fab4a7f 100644 (file)
@@ -54,13 +54,19 @@ xflock(char *fname, char *type)
 {
        struct sigaction sa, oldsa;
        int             readonly = !strcmp(type, "r");
+       mode_t  mode = (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
        struct flock    fl = { readonly? F_RDLCK : F_WRLCK, SEEK_SET, 0, 0, 0 };
        int             fd;
 
-       if ((fd = open(fname, readonly? O_RDONLY : (O_RDWR|O_CREAT), 0644)) < 0) {
+       if (readonly)
+               fd = open(fname, O_RDONLY);
+       else
+               fd = open(fname, (O_RDWR|O_CREAT), mode);
+       if (fd < 0) {
                xlog(L_WARNING, "could not open %s for locking", fname);
                return -1;
        }
+
        sa.sa_handler = doalarm;
        sa.sa_flags = 0;
        sigemptyset(&sa.sa_mask);
index e73e448337c1552fcb7183cfa2f1c9b50f5bf59b..a13afc0a4bae96cbc56d593a4bc4014c8d718476 100644 (file)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -174,6 +174,7 @@ datarootdir = @datarootdir@
 docdir = @docdir@
 dvidir = @dvidir@
 enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
 enable_nfsv3 = @enable_nfsv3@
 enable_nfsv4 = @enable_nfsv4@
 exec_prefix = @exec_prefix@
@@ -326,8 +327,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        mkid -fID $$unique
 tags: TAGS
 
@@ -352,8 +353,8 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
          test -n "$$unique" || unique=$$empty_fix; \
          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -363,13 +364,12 @@ ctags: CTAGS
 CTAGS: ctags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
                $(TAGS_FILES) $(LISP)
        tags=; \
-       here=`pwd`; \
        list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        test -z "$(CTAGS_ARGS)$$tags$$unique" \
          || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
             $$tags $$unique
index 2a9bb30c46eed49f66307cdd2259a39d6c10e429..e0743758913dc58f7c449c91fef4a955302bf2ba 100644 (file)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -54,7 +54,7 @@ testlk_LDADD = $(LDADD)
 testlk_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
        --mode=link $(CCLD) $(testlk_CFLAGS) $(CFLAGS) \
        $(testlk_LDFLAGS) $(LDFLAGS) -o $@
-DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -184,6 +184,7 @@ datarootdir = @datarootdir@
 docdir = @docdir@
 dvidir = @dvidir@
 enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
 enable_nfsv3 = @enable_nfsv3@
 enable_nfsv4 = @enable_nfsv4@
 exec_prefix = @exec_prefix@
@@ -322,8 +323,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        mkid -fID $$unique
 tags: TAGS
 
@@ -335,8 +336,8 @@ TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
          test -n "$$unique" || unique=$$empty_fix; \
          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -346,13 +347,12 @@ ctags: CTAGS
 CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
                $(TAGS_FILES) $(LISP)
        tags=; \
-       here=`pwd`; \
        list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        test -z "$(CTAGS_ARGS)$$tags$$unique" \
          || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
             $$tags $$unique
diff --git a/tools/mountstats/mountstats.py b/tools/mountstats/mountstats.py
new file mode 100644 (file)
index 0000000..c475c9e
--- /dev/null
@@ -0,0 +1,604 @@
+#!/usr/bin/env python
+# -*- python-mode -*-
+"""Parse /proc/self/mountstats and display it in human readable form
+"""
+
+__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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+import sys, os, time
+
+Mountstats_version = '0.2'
+
+def difference(x, y):
+    """Used for a map() function
+    """
+    return x - y
+
+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:
+                self.__nfs_data['statvers'] = words[8]
+        elif words[0] == 'age:':
+            self.__nfs_data['age'] = long(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:':
+            self.__nfs_data['inoderevalidates'] = int(words[1])
+            self.__nfs_data['dentryrevalidates'] = int(words[2])
+            self.__nfs_data['datainvalidates'] = int(words[3])
+            self.__nfs_data['attrinvalidates'] = int(words[4])
+            self.__nfs_data['syncinodes'] = int(words[5])
+            self.__nfs_data['vfsopen'] = int(words[6])
+            self.__nfs_data['vfslookup'] = int(words[7])
+            self.__nfs_data['vfspermission'] = int(words[8])
+            self.__nfs_data['vfsreadpage'] = int(words[9])
+            self.__nfs_data['vfsreadpages'] = int(words[10])
+            self.__nfs_data['vfswritepage'] = int(words[11])
+            self.__nfs_data['vfswritepages'] = int(words[12])
+            self.__nfs_data['vfsreaddir'] = int(words[13])
+            self.__nfs_data['vfsflush'] = int(words[14])
+            self.__nfs_data['vfsfsync'] = int(words[15])
+            self.__nfs_data['vfslock'] = int(words[16])
+            self.__nfs_data['vfsrelease'] = int(words[17])
+            self.__nfs_data['setattrtrunc'] = int(words[18])
+            self.__nfs_data['extendwrite'] = int(words[19])
+            self.__nfs_data['sillyrenames'] = int(words[20])
+            self.__nfs_data['shortreads'] = int(words[21])
+            self.__nfs_data['shortwrites'] = int(words[22])
+            self.__nfs_data['delay'] = int(words[23])
+        elif words[0] == 'bytes:':
+            self.__nfs_data['normalreadbytes'] = long(words[1])
+            self.__nfs_data['normalwritebytes'] = long(words[2])
+            self.__nfs_data['directreadbytes'] = long(words[3])
+            self.__nfs_data['directwritebytes'] = long(words[4])
+            self.__nfs_data['serverreadbytes'] = long(words[5])
+            self.__nfs_data['serverwritebytes'] = long(words[6])
+
+    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'] = long(words[7])
+                self.__rpc_data['backlogutil'] = long(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'] = long(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] = [long(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 display_nfs_options(self):
+        """Pretty-print the NFS options
+        """
+        print 'Stats for %s mounted on %s:' % \
+            (self.__nfs_data['export'], self.__nfs_data['mountpoint'])
+
+        print '  NFS mount options: %s' % ','.join(self.__nfs_data['mountoptions'])
+        print '  NFS server capabilities: %s' % ','.join(self.__nfs_data['servercapabilities'])
+        if self.__nfs_data.has_key('nfsv4flags'):
+            print '  NFSv4 capability flags: %s' % ','.join(self.__nfs_data['nfsv4flags'])
+        if self.__nfs_data.has_key('pseudoflavor'):
+            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 '  inodes synced %d times' % self.__nfs_data['syncinodes']
+        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']
+
+    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
+        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']
+
+        # XXX: these should be sorted by 'count'
+        print
+        for op in self.__rpc_data['ops']:
+            stats = self.__rpc_data[op]
+            count = stats[0]
+            retrans = stats[1] - count
+            if count != 0:
+                print '%s:' % op
+                print '\t%d ops (%d%%)' % \
+                    (count, ((count * 100) / sends)),
+                print '\t%d retrans (%d%%)' % (retrans, ((retrans * 100) / count)),
+                print '\t%d major timeouts' % stats[2]
+                print '\tavg bytes sent per op: %d\tavg bytes received per op: %d' % \
+                    (stats[3] / count, stats[4] / count)
+                print '\tbacklog wait: %f' % (float(stats[5]) / count),
+                print '\tRTT: %f' % (float(stats[6]) / count),
+                print '\ttotal execute time: %f (milliseconds)' % \
+                    (float(stats[7]) / count)
+
+    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.iteritems():
+            result.__nfs_data[key] = value
+        for key, value in self.__rpc_data.iteritems():
+            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']:
+            result.__rpc_data[op] = map(difference, self.__rpc_data[op], old_stats.__rpc_data[op])
+
+        # 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']
+        result.__nfs_data['serverreadbytes'] -= old_stats.__nfs_data['serverreadbytes']
+        result.__nfs_data['serverwritebytes'] -= old_stats.__nfs_data['serverwritebytes']
+
+        return result
+
+    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'])
+
+        print
+        print '%s mounted on %s:' % \
+            (self.__nfs_data['export'], self.__nfs_data['mountpoint'])
+
+        print '\top/s\trpc bklog'
+        print '\t%.2f' % (sends / sample_time), 
+        if sends != 0:
+            print '\t%.2f' % \
+                ((float(self.__rpc_data['backlogutil']) / sends) / sample_time)
+        else:
+            print '\t0.00'
+
+        # reads:  ops/s, kB/s, avg rtt, and avg exe
+        # XXX: include avg xfer size and retransmits?
+        read_rpc_stats = self.__rpc_data['READ']
+        ops = float(read_rpc_stats[0])
+        kilobytes = float(self.__nfs_data['serverreadbytes']) / 1024
+        rtt = float(read_rpc_stats[6])
+        exe = float(read_rpc_stats[7])
+
+        print '\treads:\tops/s\t\tkB/s\t\tavg RTT (ms)\tavg exe (ms)'
+        print '\t\t%.2f' % (ops / sample_time),
+        print '\t\t%.2f' % (kilobytes / sample_time),
+        if ops != 0:
+            print '\t\t%.2f' % (rtt / ops),
+            print '\t\t%.2f' % (exe / ops)
+        else:
+            print '\t\t0.00',
+            print '\t\t0.00'
+
+        # writes:  ops/s, kB/s, avg rtt, and avg exe
+        # XXX: include avg xfer size and retransmits?
+        write_rpc_stats = self.__rpc_data['WRITE']
+        ops = float(write_rpc_stats[0])
+        kilobytes = float(self.__nfs_data['serverwritebytes']) / 1024
+        rtt = float(write_rpc_stats[6])
+        exe = float(write_rpc_stats[7])
+
+        print '\twrites:\tops/s\t\tkB/s\t\tavg RTT (ms)\tavg exe (ms)'
+        print '\t\t%.2f' % (ops / sample_time),
+        print '\t\t%.2f' % (kilobytes / sample_time),
+        if ops != 0:
+            print '\t\t%.2f' % (rtt / ops),
+            print '\t\t%.2f' % (exe / ops)
+        else:
+            print '\t\t0.00',
+            print '\t\t0.00'
+
+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 = file(filename)
+    for line in f.readlines():
+        words = line.split()
+        if len(words) == 0:
+            continue
+        if words[0] == 'device':
+            key = words[4]
+            new = [ line.strip() ]
+        else:
+            new += [ line.strip() ]
+        ms_dict[key] = new
+    f.close
+
+    return ms_dict
+
+def print_mountstats_help(name):
+    print 'usage: %s [ options ] <mount point>' % name
+    print
+    print ' Version %s' % Mountstats_version
+    print
+    print ' Display NFS client per-mount statistics.'
+    print
+    print '  --version    display the version of this command'
+    print '  --nfs        display only the NFS statistics'
+    print '  --rpc        display only the RPC statistics'
+    print '  --start      sample and save statistics'
+    print '  --end        resample statistics and compare them with saved'
+    print
+
+def mountstats_command():
+    """Mountstats command
+    """
+    mountpoints = []
+    nfs_only = False
+    rpc_only = False
+
+    for arg in sys.argv:
+        if arg in ['-h', '--help', 'help', 'usage']:
+            print_mountstats_help(prog)
+            return
+
+        if arg in ['-v', '--version', 'version']:
+            print '%s version %s' % (sys.argv[0], Mountstats_version)
+            sys.exit(0)
+
+        if arg in ['-n', '--nfs']:
+            nfs_only = True
+            continue
+
+        if arg in ['-r', '--rpc']:
+            rpc_only = True
+            continue
+
+        if arg in ['-s', '--start']:
+            raise Exception, 'Sampling is not yet implemented'
+
+        if arg in ['-e', '--end']:
+            raise Exception, 'Sampling is not yet implemented'
+
+        if arg == sys.argv[0]:
+            continue
+
+        mountpoints += [arg]
+
+    if mountpoints == []:
+        print_mountstats_help(prog)
+        return
+
+    if rpc_only == True and nfs_only == True:
+        print_mountstats_help(prog)
+        return
+
+    mountstats = parse_stats_file('/proc/self/mountstats')
+
+    for mp in mountpoints:
+        if mp not in mountstats:
+            print 'Statistics for mount point %s not found' % mp
+            continue
+
+        stats = DeviceData()
+        stats.parse_stats(mountstats[mp])
+
+        if not stats.is_nfs_mountpoint():
+            print 'Mount point %s exists but is not an NFS mount' % mp
+            continue
+
+        if nfs_only:
+           stats.display_nfs_options()
+           stats.display_nfs_events()
+           stats.display_nfs_bytes()
+        elif rpc_only:
+           stats.display_rpc_generic_stats()
+           stats.display_rpc_op_stats()
+        else:
+           stats.display_nfs_options()
+           stats.display_nfs_bytes()
+           stats.display_rpc_generic_stats()
+           stats.display_rpc_op_stats()
+
+def print_nfsstat_help(name):
+    print 'usage: %s [ options ]' % name
+    print
+    print ' Version %s' % Mountstats_version
+    print
+    print ' nfsstat-like program that uses NFS client per-mount statistics.'
+    print
+
+def nfsstat_command():
+    print_nfsstat_help(prog)
+
+def print_iostat_help(name):
+    print 'usage: %s [ <interval> [ <count> ] ] [ <mount point> ] ' % name
+    print
+    print ' Version %s' % Mountstats_version
+    print
+    print ' iostat-like program to display NFS client per-mount statistics.'
+    print
+    print ' The <interval> parameter specifies the amount of time in seconds between'
+    print ' each report.  The first report contains statistics for the time since each'
+    print ' file system was mounted.  Each subsequent report contains statistics'
+    print ' collected during the interval since the previous report.'
+    print
+    print ' If the <count> parameter is specified, the value of <count> determines the'
+    print ' number of reports generated at <interval> seconds apart.  If the interval'
+    print ' parameter is specified without the <count> parameter, the command generates'
+    print ' reports continuously.'
+    print
+    print ' If one or more <mount point> names are specified, statistics for only these'
+    print ' mount points will be displayed.  Otherwise, all NFS mount points on the'
+    print ' client are listed.'
+    print
+
+def print_iostat_summary(old, new, devices, time):
+    for device in devices:
+        stats = DeviceData()
+        stats.parse_stats(new[device])
+        if not old:
+            stats.display_iostats(time)
+        else:
+            old_stats = DeviceData()
+            old_stats.parse_stats(old[device])
+            diff_stats = stats.compare_iostats(old_stats)
+            diff_stats.display_iostats(time)
+
+def iostat_command():
+    """iostat-like command for NFS mount points
+    """
+    mountstats = parse_stats_file('/proc/self/mountstats')
+    devices = []
+    interval_seen = False
+    count_seen = False
+
+    for arg in sys.argv:
+        if arg in ['-h', '--help', 'help', 'usage']:
+            print_iostat_help(prog)
+            return
+
+        if arg in ['-v', '--version', 'version']:
+            print '%s version %s' % (sys.argv[0], Mountstats_version)
+            return
+
+        if arg == sys.argv[0]:
+            continue
+
+        if arg in mountstats:
+            devices += [arg]
+        elif not interval_seen:
+            interval = int(arg)
+            if interval > 0:
+                interval_seen = True
+            else:
+                print 'Illegal <interval> value'
+                return
+        elif not count_seen:
+            count = int(arg)
+            if count > 0:
+                count_seen = True
+            else:
+                print 'Illegal <count> value'
+                return
+
+    # make certain devices contains only NFS mount points
+    if len(devices) > 0:
+        check = []
+        for device in devices:
+            stats = DeviceData()
+            stats.parse_stats(mountstats[device])
+            if stats.is_nfs_mountpoint():
+                check += [device]
+        devices = check
+    else:
+        for device, descr in mountstats.iteritems():
+            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
+
+    old_mountstats = None
+    sample_time = 0
+
+    if not interval_seen:
+        print_iostat_summary(old_mountstats, mountstats, devices, sample_time)
+        return
+
+    if count_seen:
+        while count != 0:
+            print_iostat_summary(old_mountstats, mountstats, devices, sample_time)
+            old_mountstats = mountstats
+            time.sleep(interval)
+            sample_time = interval
+            mountstats = parse_stats_file('/proc/self/mountstats')
+            count -= 1
+    else: 
+        while True:
+            print_iostat_summary(old_mountstats, mountstats, devices, sample_time)
+            old_mountstats = mountstats
+            time.sleep(interval)
+            sample_time = interval
+            mountstats = parse_stats_file('/proc/self/mountstats')
+
+#
+# Main
+#
+prog = os.path.basename(sys.argv[0])
+
+try:
+    if prog == 'mountstats':
+        mountstats_command()
+    elif prog == 'ms-nfsstat':
+        nfsstat_command()
+    elif prog == 'ms-iostat':
+        iostat_command()
+except KeyboardInterrupt:
+    print 'Caught ^C... exiting'
+    sys.exit(1)
+
+sys.exit(0)
diff --git a/tools/nfs-iostat/nfs-iostat.py b/tools/nfs-iostat/nfs-iostat.py
new file mode 100644 (file)
index 0000000..9626d42
--- /dev/null
@@ -0,0 +1,564 @@
+#!/usr/bin/env python
+# -*- python-mode -*-
+"""Emulate iostat for NFS mount points using /proc/self/mountstats
+"""
+
+__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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+import sys, os, time
+
+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',
+    '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':
+                self.__nfs_data['statvers'] = words[8]
+        elif words[0] == 'age:':
+            self.__nfs_data['age'] = long(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] = long(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'] = long(words[7])
+                self.__rpc_data['backlogutil'] = long(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'] = long(words[10])
+                self.__rpc_data['backlogutil'] = long(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] = [long(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.iteritems():
+            result.__nfs_data[key] = value
+        for key, value in self.__rpc_data.iteritems():
+            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']:
+            result.__rpc_data[op] = map(difference, self.__rpc_data[op], old_stats.__rpc_data[op])
+
+        # 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
+        getattr_stats = self.__rpc_data['GETATTR']
+
+        if nfs_stats['inoderevalidates'] != 0:
+            getattr_ops = float(getattr_stats[1])
+            opens = float(nfs_stats['vfsopen'])
+            revalidates = float(nfs_stats['inoderevalidates']) - opens
+            if revalidates != 0:
+                ratio = ((revalidates - getattr_ops) * 100) / revalidates
+            else:
+                ratio = 0.0
+
+            data_invalidates = float(nfs_stats['datainvalidates'])
+            attr_invalidates = float(nfs_stats['attrinvalidates'])
+
+            print
+            print '%d inode revalidations, hitting in cache %4.2f%% of the time' % \
+                (revalidates, ratio)
+            print '%d open operations (mandatory GETATTR requests)' % opens
+            if getattr_ops != 0:
+                print '%4.2f%% of GETATTRs resulted in data cache invalidations' % \
+                   ((data_invalidates * 100) / getattr_ops)
+
+    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 self.__rpc_data.has_key('READDIRPLUS'):
+            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)
+        print '%d nfs_readpages() calls read %d pages' % \
+            (vfsreadpages, 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 not self.__rpc_data.has_key(op):
+            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
+        rtt = float(rpc_stats[6])
+        exe = float(rpc_stats[7])
+
+        # 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
+        else:
+            kb_per_op = 0.0
+            retrans_percent = 0.0
+            rtt_per_op = 0.0
+            exe_per_op = 0.0
+
+        op += ':'
+        print '%s' % op.lower().ljust(15),
+        print '  ops/s\t\t   kB/s\t\t  kB/op\t\tretrans\t\tavg RTT (ms)\tavg exe (ms)'
+
+        print '\t\t%7.3f' % (ops / sample_time),
+        print '\t%7.3f' % (kilobytes / sample_time),
+        print '\t%7.3f' % kb_per_op,
+        print ' %7d (%3.1f%%)' % (retrans, retrans_percent),
+        print '\t%7.3f' % rtt_per_op,
+        print '\t%7.3f' % exe_per_op
+
+    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'])
+        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 '   op/s\t\trpc bklog'
+        print '%7.2f' % (sends / sample_time), 
+        print '\t%7.2f' % backlog
+
+        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 self.__rpc_data.has_key('READDIRPLUS'):
+                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)
+
+#
+# Functions
+#
+
+def print_iostat_help(name):
+    print 'usage: %s [ <interval> [ <count> ] ] [ <options> ] [ <mount point> ] ' % name
+    print
+    print ' Version %s' % Iostats_version
+    print
+    print ' Sample iostat-like program to display NFS client per-mount statistics.'
+    print
+    print ' The <interval> parameter specifies the amount of time in seconds between'
+    print ' each report.  The first report contains statistics for the time since each'
+    print ' file system was mounted.  Each subsequent report contains statistics'
+    print ' collected during the interval since the previous report.'
+    print
+    print ' If the <count> parameter is specified, the value of <count> determines the'
+    print ' number of reports generated at <interval> seconds apart.  If the interval'
+    print ' parameter is specified without the <count> parameter, the command generates'
+    print ' reports continuously.'
+    print
+    print ' Options include "--attr", which displays statistics related to the attribute'
+    print ' cache, "--dir", which displays statistics related to directory operations,'
+    print ' and "--page", which displays statistics related to the page cache.'
+    print ' By default, if no option is specified, statistics related to file I/O are'
+    print ' displayed.'
+    print
+    print ' If one or more <mount point> names are specified, statistics for only these'
+    print ' mount points will be displayed.  Otherwise, all NFS mount points on the'
+    print ' client are listed.'
+
+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 = file(filename)
+    for line in f.readlines():
+        words = line.split()
+        if len(words) == 0:
+            continue
+        if words[0] == 'device':
+            key = words[4]
+            new = [ line.strip() ]
+        else:
+            new += [ line.strip() ]
+        ms_dict[key] = new
+    f.close
+
+    return ms_dict
+
+def print_iostat_summary(old, new, devices, time, ac):
+    for device in devices:
+        stats = DeviceData()
+        stats.parse_stats(new[device])
+        if not old:
+            stats.display_iostats(time, ac)
+        else:
+            old_stats = DeviceData()
+            old_stats.parse_stats(old[device])
+            diff_stats = stats.compare_iostats(old_stats)
+            diff_stats.display_iostats(time, ac)
+
+def iostat_command(name):
+    """iostat-like command for NFS mount points
+    """
+    mountstats = parse_stats_file('/proc/self/mountstats')
+    devices = []
+    which = 0
+    interval_seen = False
+    count_seen = False
+
+    for arg in sys.argv:
+        if arg in ['-h', '--help', 'help', 'usage']:
+            print_iostat_help(name)
+            return
+
+        if arg in ['-v', '--version', 'version']:
+            print '%s version %s' % (name, Iostats_version)
+            return
+
+        if arg in ['-a', '--attr']:
+            which = 1
+            continue
+
+        if arg in ['-d', '--dir']:
+            which = 2
+            continue
+
+        if arg in ['-p', '--page']:
+            which = 3
+            continue
+
+        if arg == sys.argv[0]:
+            continue
+
+        if arg in mountstats:
+            devices += [arg]
+        elif not interval_seen:
+            interval = int(arg)
+            if interval > 0:
+                interval_seen = True
+            else:
+                print 'Illegal <interval> value'
+                return
+        elif not count_seen:
+            count = int(arg)
+            if count > 0:
+                count_seen = True
+            else:
+                print 'Illegal <count> value'
+                return
+
+    # make certain devices contains only NFS mount points
+    if len(devices) > 0:
+        check = []
+        for device in devices:
+            stats = DeviceData()
+            stats.parse_stats(mountstats[device])
+            if stats.is_nfs_mountpoint():
+                check += [device]
+        devices = check
+    else:
+        for device, descr in mountstats.iteritems():
+            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
+
+    old_mountstats = None
+    sample_time = 0.0
+
+    if not interval_seen:
+        print_iostat_summary(old_mountstats, mountstats, devices, sample_time, which)
+        return
+
+    if count_seen:
+        while count != 0:
+            print_iostat_summary(old_mountstats, mountstats, devices, sample_time, which)
+            old_mountstats = mountstats
+            time.sleep(interval)
+            sample_time = interval
+            mountstats = parse_stats_file('/proc/self/mountstats')
+            count -= 1
+    else: 
+        while True:
+            print_iostat_summary(old_mountstats, mountstats, devices, sample_time, which)
+            old_mountstats = mountstats
+            time.sleep(interval)
+            sample_time = interval
+            mountstats = parse_stats_file('/proc/self/mountstats')
+
+#
+# Main
+#
+prog = os.path.basename(sys.argv[0])
+
+try:
+    iostat_command(prog)
+except KeyboardInterrupt:
+    print 'Caught ^C... exiting'
+    sys.exit(1)
+
+sys.exit(0)
index e936cfb44363856e1f98bc18e33b97eca24eb32d..783c5193ceda5fcfc7523173d682eec6b095e29c 100644 (file)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -161,6 +161,7 @@ datarootdir = @datarootdir@
 docdir = @docdir@
 dvidir = @dvidir@
 enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
 enable_nfsv3 = @enable_nfsv3@
 enable_nfsv4 = @enable_nfsv4@
 exec_prefix = @exec_prefix@
index 2c8b40841020d852f070e46ed74e732612c7fb3a..ebd86d3abf72384fc44a966d32428231d30f0e5f 100644 (file)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -56,7 +56,7 @@ rpcdebug_LDADD = $(LDADD)
 rpcdebug_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
        --mode=link $(CCLD) $(rpcdebug_CFLAGS) $(CFLAGS) \
        $(rpcdebug_LDFLAGS) $(LDFLAGS) -o $@
-DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -189,6 +189,7 @@ datarootdir = @datarootdir@
 docdir = @docdir@
 dvidir = @dvidir@
 enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
 enable_nfsv3 = @enable_nfsv3@
 enable_nfsv4 = @enable_nfsv4@
 exec_prefix = @exec_prefix@
@@ -273,8 +274,8 @@ install-sbinPROGRAMS: $(sbin_PROGRAMS)
             || test -f $$p1 \
          ; then \
            f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
-          echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
-          $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \
+          echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
+          $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \
          else :; fi; \
        done
 
@@ -395,8 +396,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        mkid -fID $$unique
 tags: TAGS
 
@@ -408,8 +409,8 @@ TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
          test -n "$$unique" || unique=$$empty_fix; \
          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -419,13 +420,12 @@ ctags: CTAGS
 CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
                $(TAGS_FILES) $(LISP)
        tags=; \
-       here=`pwd`; \
        list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        test -z "$(CTAGS_ARGS)$$tags$$unique" \
          || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
             $$tags $$unique
index c3993f28109b918ab4e51c2c383766fb27dea563..ef534011bdc6203ab0f14d48a5c7ad4062ac9f51 100644 (file)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -59,7 +59,7 @@ rpcgen_LDADD = $(LDADD)
 rpcgen_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
        --mode=link $(CCLD) $(rpcgen_CFLAGS) $(CFLAGS) \
        $(rpcgen_LDFLAGS) $(LDFLAGS) -o $@
-DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -189,6 +189,7 @@ datarootdir = @datarootdir@
 docdir = @docdir@
 dvidir = @dvidir@
 enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
 enable_nfsv3 = @enable_nfsv3@
 enable_nfsv4 = @enable_nfsv4@
 exec_prefix = @exec_prefix@
@@ -467,8 +468,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        mkid -fID $$unique
 tags: TAGS
 
@@ -480,8 +481,8 @@ TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
          test -n "$$unique" || unique=$$empty_fix; \
          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -491,13 +492,12 @@ ctags: CTAGS
 CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
                $(TAGS_FILES) $(LISP)
        tags=; \
-       here=`pwd`; \
        list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        test -z "$(CTAGS_ARGS)$$tags$$unique" \
          || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
             $$tags $$unique
index dfb16d05b9bef20d73aa59eda706869a37889c2c..75ec603d57dade9e728feec37672df58c3218baf 100644 (file)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -177,6 +177,7 @@ datarootdir = @datarootdir@
 docdir = @docdir@
 dvidir = @dvidir@
 enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
 enable_nfsv3 = @enable_nfsv3@
 enable_nfsv4 = @enable_nfsv4@
 exec_prefix = @exec_prefix@
@@ -337,8 +338,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        mkid -fID $$unique
 tags: TAGS
 
@@ -363,8 +364,8 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
          test -n "$$unique" || unique=$$empty_fix; \
          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -374,13 +375,12 @@ ctags: CTAGS
 CTAGS: ctags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
                $(TAGS_FILES) $(LISP)
        tags=; \
-       here=`pwd`; \
        list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        test -z "$(CTAGS_ARGS)$$tags$$unique" \
          || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
             $$tags $$unique
index 32c0116ab56fba3f0b6d8cd1c2b3044fbd40e9b3..84ed403073b168a771692e3469af79c9681c000e 100644 (file)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -57,7 +57,7 @@ am__DEPENDENCIES_1 =
 exportfs_DEPENDENCIES = ../../support/export/libexport.a \
        ../../support/nfs/libnfs.a ../../support/misc/libmisc.a \
        $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
-DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -192,6 +192,7 @@ datarootdir = @datarootdir@
 docdir = @docdir@
 dvidir = @dvidir@
 enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
 enable_nfsv3 = @enable_nfsv3@
 enable_nfsv4 = @enable_nfsv4@
 exec_prefix = @exec_prefix@
@@ -280,8 +281,8 @@ install-sbinPROGRAMS: $(sbin_PROGRAMS)
             || test -f $$p1 \
          ; then \
            f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
-          echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
-          $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \
+          echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
+          $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \
          else :; fi; \
        done
 
@@ -478,8 +479,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        mkid -fID $$unique
 tags: TAGS
 
@@ -491,8 +492,8 @@ TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
          test -n "$$unique" || unique=$$empty_fix; \
          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -502,13 +503,12 @@ ctags: CTAGS
 CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
                $(TAGS_FILES) $(LISP)
        tags=; \
-       here=`pwd`; \
        list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        test -z "$(CTAGS_ARGS)$$tags$$unique" \
          || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
             $$tags $$unique
index 59789cc43d930e12f55c46bc03d845a77ddd34f9..c7b230a291c0fd12185fb0218163d061672932da 100644 (file)
@@ -22,14 +22,14 @@ The
 .B exportfs
 command is used to maintain the current table of exported file systems for
 NFS. This list is kept in a separate file named
-.BR /var/lib/nfs/xtab
+.BR /var/lib/nfs/etab
 which is read by
 .B mountd
 when a remote host requests access to mount a file tree, and parts of
 the list which are active are kept in the kernel's export table.
 .P
 Normally this 
-.B xtab
+.B etab
 file is initialized with the list of all file systems named in
 .B /etc/exports 
 by invoking
@@ -59,7 +59,7 @@ In the new mode,
 does not give any information to the kernel but only provides it to
 .B mountd
 through the
-.B /var/lib/nfs/xtab
+.B /var/lib/nfs/etab
 file.
 .B mountd
 will listen to requests from the kernel and will provide information
@@ -69,7 +69,7 @@ In the legacy mode,
 any export requests which identify a specific host (rather than a
 subnet or netgroup etc) are entered directly into the kernel's export
 table as well as being written to
-.BR /var/lib/nfs/xtab .
+.BR /var/lib/nfs/etab .
 Further, any mount points listed in
 .B /var/lib/nfs/rmtab
 which match a non host-specific export request will cause an
@@ -93,8 +93,8 @@ file, so that only default options and options given on the command
 line are used.
 .TP
 .B -r
-Reexport all directories. It synchronizes /var/lib/nfs/xtab
-with /etc/exports. It removes entries in /var/lib/nfs/xtab
+Reexport all directories. It synchronizes /var/lib/nfs/etab
+with /etc/exports. It removes entries in /var/lib/nfs/etab
 which are deleted from /etc/exports, and remove any entries from the
 kernel export table which are no longer valid.
 .TP
@@ -120,7 +120,7 @@ entries to the export table.  When using
 all directories in
 .B exports(5)
 are added to
-.B xtab
+.B etab
 and the resulting list is pushed into the kernel.
 .P
 The
@@ -152,7 +152,7 @@ directory.
 Modifications of the kernel export table used by
 .B nfsd(8)
 take place immediately after parsing the command line and updating the
-.B xtab
+.B etab
 file.
 .P
 The default export options are
@@ -163,14 +163,14 @@ The third synopsis shows how to unexported a currently exported directory.
 When using
 .BR "exportfs -ua" ,
 all entries listed in
-.B xtab
+.B etab
 are removed from the kernel export tables, and the file is cleared. This
 effectively shuts down all NFS activity.
 .P
 To remove an export to a host, specify a
 .I host:/path
 pair. This deletes the specified entry from
-.B xtab
+.B etab
 and removes the corresponding kernel entry (if any).
 To remove one or more exports to several hosts, use
 .BR "exportfs -ua" .
@@ -198,7 +198,7 @@ and pushes the resulting export entries into the kernel:
 To export the
 .B /usr/tmp
 directory to host 
-.BR djando ,
+.BR django ,
 allowing asynchronous writes, one would do this:
 .P
 .nf
index 1441131d563db9e7d65b13a102d0c7e2f2c23219..fa6cccbc5a91f1dc59f049292f2b8acae9b204eb 100644 (file)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -93,7 +93,7 @@ svcgssd_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
        $(svcgssd_LDFLAGS) $(LDFLAGS) -o $@
 sbinSCRIPT_INSTALL = $(INSTALL_SCRIPT)
 SCRIPTS = $(sbin_SCRIPTS)
-DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -228,6 +228,7 @@ datarootdir = @datarootdir@
 docdir = @docdir@
 dvidir = @dvidir@
 enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
 enable_nfsv3 = @enable_nfsv3@
 enable_nfsv4 = @enable_nfsv4@
 exec_prefix = @exec_prefix@
@@ -370,8 +371,8 @@ install-sbinPROGRAMS: $(sbin_PROGRAMS)
             || test -f $$p1 \
          ; then \
            f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
-          echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
-          $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \
+          echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
+          $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \
          else :; fi; \
        done
 
@@ -877,8 +878,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        mkid -fID $$unique
 tags: TAGS
 
@@ -890,8 +891,8 @@ TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
          test -n "$$unique" || unique=$$empty_fix; \
          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -901,13 +902,12 @@ ctags: CTAGS
 CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
                $(TAGS_FILES) $(LISP)
        tags=; \
-       here=`pwd`; \
        list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        test -z "$(CTAGS_ARGS)$$tags$$unique" \
          || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
             $$tags $$unique
index 5644db68b73961ff1f0da47a245a4fef44523a2f..2583e06621906e4652c9274f135a2e0e52c1b55d 100644 (file)
@@ -60,3 +60,8 @@ void printerr(int priority, char *format, ...)
                xlog_backend(L_ERROR, format, args);
        va_end(args);
 }
+
+int get_verbosity(void)
+{
+       return verbosity;
+}
index 5e5af48d494cf2d6b4fc82db02b0c192ff28dccd..c4df32dab60dacf7134b6b3aa4e7fe3d3154603f 100644 (file)
@@ -33,5 +33,6 @@
 
 void initerr(char *progname, int verbosity, int fg);
 void printerr(int priority, char *format, ...);
+int get_verbosity(void);
 
 #endif /* _ERR_UTIL_H_ */
index bbcad20d1c7ae50882edd8f6afba93141c475c09..6d8f3b90d7d11e48de887a5387745fbda363675e 100644 (file)
@@ -57,8 +57,11 @@ char pipefs_dir[PATH_MAX] = GSSD_PIPEFS_DIR;
 char pipefs_nfsdir[PATH_MAX] = GSSD_PIPEFS_DIR;
 char keytabfile[PATH_MAX] = GSSD_DEFAULT_KEYTAB_FILE;
 char ccachedir[PATH_MAX] = GSSD_DEFAULT_CRED_DIR;
+char *ccachesearch[GSSD_MAX_CCACHE_SEARCH + 1];
 int  use_memcache = 0;
 int  root_uses_machine_creds = 1;
+unsigned int  context_timeout = 0;
+char *preferred_realm = NULL;
 
 void
 sig_die(int signal)
@@ -81,7 +84,7 @@ sig_hup(int signal)
 static void
 usage(char *progname)
 {
-       fprintf(stderr, "usage: %s [-f] [-M] [-n] [-v] [-r] [-p pipefsdir] [-k keytab] [-d ccachedir]\n",
+       fprintf(stderr, "usage: %s [-f] [-M] [-n] [-v] [-r] [-p pipefsdir] [-k keytab] [-d ccachedir] [-t timeout] [-R preferred realm]\n",
                progname);
        exit(1);
 }
@@ -93,10 +96,12 @@ main(int argc, char *argv[])
        int verbosity = 0;
        int rpc_verbosity = 0;
        int opt;
+       int i;
        extern char *optarg;
        char *progname;
 
-       while ((opt = getopt(argc, argv, "fvrmnMp:k:d:")) != -1) {
+       memset(ccachesearch, 0, sizeof(ccachesearch));
+       while ((opt = getopt(argc, argv, "fvrmnMp:k:d:t:R:")) != -1) {
                switch (opt) {
                        case 'f':
                                fg = 1;
@@ -131,11 +136,27 @@ main(int argc, char *argv[])
                                if (ccachedir[sizeof(ccachedir)-1] != '\0')
                                        errx(1, "ccachedir path name too long");
                                break;
+                       case 't':
+                               context_timeout = atoi(optarg);
+                               break;
+                       case 'R':
+                               preferred_realm = strdup(optarg);
+                               break;
                        default:
                                usage(argv[0]);
                                break;
                }
        }
+
+       i = 0;
+       ccachesearch[i++] = strtok(ccachedir, ":");
+       do {
+               ccachesearch[i++] = strtok(NULL, ":");
+       } while (ccachesearch[i-1] != NULL && i < GSSD_MAX_CCACHE_SEARCH);
+
+       if (preferred_realm == NULL)
+               gssd_k5_get_default_realm(&preferred_realm);
+
        snprintf(pipefs_nfsdir, sizeof(pipefs_nfsdir), "%s/%s",
                 pipefs_dir, GSSD_SERVICE_NAME);
        if (pipefs_nfsdir[sizeof(pipefs_nfsdir)-1] != '\0')
index e17edde9e796ce8a206b5c098b7e92fd72c84879..082039a6783ba1343d480d0ebefc41eb19489347 100644 (file)
@@ -50,6 +50,7 @@
 #define GSSD_DEFAULT_KEYTAB_FILE               "/etc/krb5.keytab"
 #define GSSD_SERVICE_NAME                      "nfs"
 #define GSSD_SERVICE_NAME_LEN                  3
+#define GSSD_MAX_CCACHE_SEARCH                 16
 
 /*
  * The gss mechanisms that we can handle
@@ -61,9 +62,11 @@ enum {AUTHTYPE_KRB5, AUTHTYPE_SPKM3, AUTHTYPE_LIPKEY};
 extern char                    pipefs_dir[PATH_MAX];
 extern char                    pipefs_nfsdir[PATH_MAX];
 extern char                    keytabfile[PATH_MAX];
-extern char                    ccachedir[PATH_MAX];
+extern char                    *ccachesearch[];
 extern int                     use_memcache;
 extern int                     root_uses_machine_creds;
+extern unsigned int            context_timeout;
+extern char                    *preferred_realm;
 
 TAILQ_HEAD(clnt_list_head, clnt_info) clnt_list;
 
@@ -80,6 +83,7 @@ struct clnt_info {
        int                     krb5_poll_index;
        int                     spkm3_fd;
        int                     spkm3_poll_index;
+       int                     port;
 };
 
 void init_client_list(void);
index 2fa749e15343acd9cb53c72cabe6a83bf7b77d30..0a23cd6316745926d30d6237e399383564a10c5c 100644 (file)
@@ -74,7 +74,11 @@ where to look for the rpc_pipefs filesystem.  The default value is
 .B -d directory
 Tells
 .B rpc.gssd
-where to look for kerberos credential files.  The default value is "/tmp".
+where to look for Kerberos credential files.  The default value is "/tmp".
+This can also be a colon separated list of directories to be searched
+for Kerberos credential files.  Note that if machine credentials are being
+stored in files, then the first directory on this list is where the
+machine credentials are stored.
 .TP
 .B -v
 Increases the verbosity of the output (can be specified multiple times).
@@ -82,6 +86,21 @@ Increases the verbosity of the output (can be specified multiple times).
 .B -r
 If the rpcsec_gss library supports setting debug level,
 increases the verbosity of the output (can be specified multiple times).
+.TP
+.B -R realm
+Kerberos tickets from this
+.I realm
+will be preferred when scanning available credentials cache files to be
+used to create a context.  By default, the default realm, as configured
+in the Kerberos configuration file, is preferred.
+.TP
+.B -t timeout
+Timeout, in seconds, for kernel gss contexts. This option allows you to force 
+new kernel contexts to be negotiated after
+.I timeout
+seconds, which allows changing Kerberos tickets and identities frequently.
+The default is no explicit timeout, which means the kernel context will live
+the lifetime of the Kerberos service ticket used in its creation.
 .SH SEE ALSO
 .BR rpc.svcgssd(8)
 .SH AUTHORS
index 6860cc852e844f87dbaf6d53d6106578f093d942..f415a10005229b7c04f77e2f0bf0defab329e304 100644 (file)
@@ -102,7 +102,7 @@ int pollsize;  /* the size of pollaray (in pollfd's) */
 /* XXX buffer problems: */
 static int
 read_service_info(char *info_file_name, char **servicename, char **servername,
-                 int *prog, int *vers, char **protocol) {
+                 int *prog, int *vers, char **protocol, int *port) {
 #define INFOBUFLEN 256
        char            buf[INFOBUFLEN];
        static char     dummy[128];
@@ -112,6 +112,8 @@ read_service_info(char *info_file_name, char **servicename, char **servername,
        char            program[16];
        char            version[16];
        char            protoname[16];
+       char            cb_port[128];
+       char            *p;
        in_addr_t       inaddr;
        int             fd = -1;
        struct hostent  *ent = NULL;
@@ -143,6 +145,10 @@ read_service_info(char *info_file_name, char **servicename, char **servername,
                goto fail;
        }
 
+       cb_port[0] = '\0';
+       if ((p = strstr(buf, "port")) != NULL)
+               sscanf(p, "port: %127s\n", cb_port);
+
        /* check service, program, and version */
        if(memcmp(service, "nfs", 3)) return -1;
        *prog = atoi(program + 1); /* skip open paren */
@@ -163,6 +169,8 @@ read_service_info(char *info_file_name, char **servicename, char **servername,
        if (!(*servicename = calloc(strlen(buf) + 1, 1)))
                goto fail;
        memcpy(*servicename, buf, strlen(buf));
+       if (cb_port[0] != '\0')
+               *port = atoi(cb_port);
 
        if (!(*protocol = strdup(protoname)))
                goto fail;
@@ -238,7 +246,7 @@ process_clnt_dir_files(struct clnt_info * clp)
        if ((clp->servicename == NULL) &&
             read_service_info(info_file_name, &clp->servicename,
                                &clp->servername, &clp->prog, &clp->vers,
-                               &clp->protocol))
+                               &clp->protocol, &clp->port))
                return -1;
        return 0;
 }
@@ -419,7 +427,7 @@ do_downcall(int k5_fd, uid_t uid, struct authgss_private_data *pd,
            gss_buffer_desc *context_token)
 {
        char    *buf = NULL, *p = NULL, *end = NULL;
-       unsigned int timeout = 0; /* XXX decide on a reasonable value */
+       unsigned int timeout = context_timeout;
        unsigned int buf_size = 0;
 
        printerr(1, "doing downcall\n");
@@ -430,7 +438,6 @@ do_downcall(int k5_fd, uid_t uid, struct authgss_private_data *pd,
        end = buf + buf_size;
 
        if (WRITE_BYTES(&p, end, uid)) goto out_err;
-       /* Not setting any timeout for now: */
        if (WRITE_BYTES(&p, end, timeout)) goto out_err;
        if (WRITE_BYTES(&p, end, pd->pd_seq_win)) goto out_err;
        if (write_buffer(&p, end, &pd->pd_ctx_hndl)) goto out_err;
@@ -587,6 +594,8 @@ int create_auth_rpc_client(struct clnt_info *clp,
                         clp->servername, uid);
                goto out_fail;
        }
+       if (clp->port)
+               ((struct sockaddr_in *)a->ai_addr)->sin_port = htons(clp->port);
        if (a->ai_protocol == IPPROTO_TCP) {
                if ((rpc_clnt = clnttcp_create(
                                        (struct sockaddr_in *) a->ai_addr,
@@ -675,6 +684,7 @@ handle_krb5_upcall(struct clnt_info *clp)
        gss_buffer_desc         token;
        char                    **credlist = NULL;
        char                    **ccname;
+       char                    **dirname;
        int                     create_resp = -1;
 
        printerr(1, "handling krb5 upcall\n");
@@ -691,10 +701,13 @@ handle_krb5_upcall(struct clnt_info *clp)
 
        if (uid != 0 || (uid == 0 && root_uses_machine_creds == 0)) {
                /* Tell krb5 gss which credentials cache to use */
-               gssd_setup_krb5_user_gss_ccache(uid, clp->servername);
-
-               create_resp = create_auth_rpc_client(clp, &rpc_clnt, &auth, uid,
-                                                    AUTHTYPE_KRB5);
+               for (dirname = ccachesearch; *dirname != NULL; dirname++) {
+                       if (gssd_setup_krb5_user_gss_ccache(uid, clp->servername, *dirname) == 0)
+                               create_resp = create_auth_rpc_client(clp, &rpc_clnt, &auth, uid,
+                                                            AUTHTYPE_KRB5);
+                       if (create_resp == 0)
+                               break;
+               }
        }
        if (create_resp != 0) {
                if (uid == 0 && root_uses_machine_creds == 1) {
index 3cf27ca88439bdc0fcde326ae75b3de95eb43f9c..77814bc3d91892777a398a990d0a79315de7a902 100644 (file)
@@ -131,10 +131,12 @@ struct gssd_k5_kt_princ *gssd_k5_kt_princ_list = NULL;
 /*==========================*/
 
 static int select_krb5_ccache(const struct dirent *d);
-static int gssd_find_existing_krb5_ccache(uid_t uid, struct dirent **d);
+static int gssd_find_existing_krb5_ccache(uid_t uid, char *dirname,
+               struct dirent **d);
 static int gssd_get_single_krb5_cred(krb5_context context,
                krb5_keytab kt, struct gssd_k5_kt_princ *ple);
-
+static int query_krb5_ccache(const char* cred_cache, char **ret_princname,
+               char **ret_realm);
 
 /*
  * Called from the scandir function to weed out potential krb5
@@ -159,7 +161,7 @@ select_krb5_ccache(const struct dirent *d)
 }
 
 /*
- * Look in the ccachedir for files that look like they
+ * Look in directory "dirname" for files that look like they
  * are Kerberos Credential Cache files for a given UID.  Return
  * non-zero and the dirent pointer for the entry most likely to be
  * what we want. Otherwise, return zero and no dirent pointer.
@@ -170,7 +172,7 @@ select_krb5_ccache(const struct dirent *d)
  *     1 => found an existing entry
  */
 static int
-gssd_find_existing_krb5_ccache(uid_t uid, struct dirent **d)
+gssd_find_existing_krb5_ccache(uid_t uid, char *dirname, struct dirent **d)
 {
        struct dirent **namelist;
        int n;
@@ -178,20 +180,29 @@ gssd_find_existing_krb5_ccache(uid_t uid, struct dirent **d)
        int found = 0;
        struct dirent *best_match_dir = NULL;
        struct stat best_match_stat, tmp_stat;
+       char buf[1030];
+       char *princname = NULL;
+       char *realm = NULL;
+       int score, best_match_score = 0;
 
        memset(&best_match_stat, 0, sizeof(best_match_stat));
        *d = NULL;
-       n = scandir(ccachedir, &namelist, select_krb5_ccache, 0);
+       n = scandir(dirname, &namelist, select_krb5_ccache, 0);
        if (n < 0) {
-               perror("scandir looking for krb5 credentials caches");
+               printerr(1, "Error doing scandir on directory '%s': %s\n",
+                       dirname, strerror(errno));
        }
        else if (n > 0) {
                char statname[1024];
                for (i = 0; i < n; i++) {
-                       printerr(3, "CC file '%s' being considered\n",
-                                namelist[i]->d_name);
                        snprintf(statname, sizeof(statname),
-                                "%s/%s", ccachedir, namelist[i]->d_name);
+                                "%s/%s", dirname, namelist[i]->d_name);
+                       printerr(3, "CC file '%s' being considered, "
+                                "with preferred realm '%s'\n",
+                                statname, preferred_realm ?
+                                       preferred_realm : "<none selected>");
+                       snprintf(buf, sizeof(buf), "FILE:%s/%s", dirname, 
+                                       namelist[i]->d_name);
                        if (lstat(statname, &tmp_stat)) {
                                printerr(0, "Error doing stat on file '%s'\n",
                                         statname);
@@ -200,20 +211,33 @@ gssd_find_existing_krb5_ccache(uid_t uid, struct dirent **d)
                        }
                        /* Only pick caches owned by the user (uid) */
                        if (tmp_stat.st_uid != uid) {
-                               printerr(3, "'%s' owned by %u, not %u\n",
+                               printerr(3, "CC file '%s' owned by %u, not %u\n",
                                         statname, tmp_stat.st_uid, uid);
                                free(namelist[i]);
                                continue;
                        }
                        if (!S_ISREG(tmp_stat.st_mode)) {
-                               printerr(3, "'%s' is not a regular file\n",
+                               printerr(3, "CC file '%s' is not a regular file\n",
                                         statname);
                                free(namelist[i]);
                                continue;
                        }
-                       printerr(3, "CC file '%s' matches owner check and has "
-                                "mtime of %u\n",
-                                namelist[i]->d_name, tmp_stat.st_mtime);
+                       if (!query_krb5_ccache(buf, &princname, &realm)) {
+                               printerr(3, "CC file '%s' is expired or corrupt\n",
+                                        statname);
+                               free(namelist[i]);
+                               continue;
+                       }
+
+                       score = 0;
+                       if (preferred_realm &&
+                                       strcmp(realm, preferred_realm) == 0) 
+                               score++;
+
+                       printerr(3, "CC file '%s'(%s@%s) passed all checks and"
+                                   " has mtime of %u\n",
+                                statname, princname, realm, 
+                                tmp_stat.st_mtime);
                        /*
                         * if more than one match is found, return the most
                         * recent (the one with the latest mtime), and
@@ -222,30 +246,38 @@ gssd_find_existing_krb5_ccache(uid_t uid, struct dirent **d)
                        if (!found) {
                                best_match_dir = namelist[i];
                                best_match_stat = tmp_stat;
+                               best_match_score = score;
                                found++;
                        }
                        else {
                                /*
-                                * If the current match has an mtime later
+                                * If current score is higher than best match 
+                                * score, we use the current match. Otherwise,
+                                * if the current match has an mtime later
                                 * than the one we are looking at, then use
                                 * the current match.  Otherwise, we still
                                 * have the best match.
                                 */
-                               if (tmp_stat.st_mtime >
-                                           best_match_stat.st_mtime) {
+                               if (best_match_score < score ||
+                                   (best_match_score == score && 
+                                      tmp_stat.st_mtime >
+                                           best_match_stat.st_mtime)) {
                                        free(best_match_dir);
                                        best_match_dir = namelist[i];
                                        best_match_stat = tmp_stat;
+                                       best_match_score = score;
                                }
                                else {
                                        free(namelist[i]);
                                }
-                               printerr(3, "CC file '%s' is our "
+                               printerr(3, "CC file '%s/%s' is our "
                                            "current best match "
                                            "with mtime of %u\n",
-                                        best_match_dir->d_name,
+                                        dirname, best_match_dir->d_name,
                                         best_match_stat.st_mtime);
                        }
+                       free(princname);
+                       free(realm);
                }
                free(namelist);
        }
@@ -277,7 +309,9 @@ limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid)
        u_int maj_stat, min_stat;
        gss_cred_id_t credh;
        gss_OID_set_desc  desired_mechs;
-       krb5_enctype enctypes[] = { ENCTYPE_DES_CBC_CRC };
+       krb5_enctype enctypes[] = { ENCTYPE_DES_CBC_CRC,
+                                   ENCTYPE_DES_CBC_MD5,
+                                   ENCTYPE_DES_CBC_MD4 };
        int num_enctypes = sizeof(enctypes) / sizeof(enctypes[0]);
 
        /* We only care about getting a krb5 cred */
@@ -289,8 +323,9 @@ limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid)
                                    &credh, NULL, NULL);
 
        if (maj_stat != GSS_S_COMPLETE) {
-               pgsserr("gss_acquire_cred",
-                       maj_stat, min_stat, &krb5oid);
+               if (get_verbosity() > 0)
+                       pgsserr("gss_acquire_cred",
+                               maj_stat, min_stat, &krb5oid);
                return -1;
        }
 
@@ -404,7 +439,7 @@ gssd_get_single_krb5_cred(krb5_context context,
            cache_type = "FILE";
        snprintf(cc_name, sizeof(cc_name), "%s:%s/%s%s_%s",
                cache_type,
-               ccachedir, GSSD_DEFAULT_CRED_PREFIX,
+               ccachesearch[0], GSSD_DEFAULT_CRED_PREFIX,
                GSSD_DEFAULT_MACHINE_CRED_SUFFIX, ple->realm);
        ple->endtime = my_creds.times.endtime;
        if (ple->ccname != NULL)
@@ -879,6 +914,94 @@ out:
        return retval;
 }
 
+
+static inline int data_is_equal(krb5_data d1, krb5_data d2)
+{
+       return (d1.length == d2.length
+               && memcmp(d1.data, d2.data, d1.length) == 0);
+}
+
+static int
+check_for_tgt(krb5_context context, krb5_ccache ccache,
+             krb5_principal principal)
+{
+       krb5_error_code ret;
+       krb5_creds creds;
+       krb5_cc_cursor cur;
+       int found = 0;
+
+       ret = krb5_cc_start_seq_get(context, ccache, &cur);
+       if (ret) 
+               return 0;
+
+       while (!found &&
+               (ret = krb5_cc_next_cred(context, ccache, &cur, &creds)) == 0) {
+               if (creds.server->length == 2 &&
+                               data_is_equal(creds.server->realm,
+                                             principal->realm) &&
+                               creds.server->data[0].length == 6 &&
+                               memcmp(creds.server->data[0].data,
+                                               "krbtgt", 6) == 0 &&
+                               data_is_equal(creds.server->data[1],
+                                             principal->realm) &&
+                               creds.times.endtime > time(NULL))
+                       found = 1;
+               krb5_free_cred_contents(context, &creds);
+       }
+       krb5_cc_end_seq_get(context, ccache, &cur);
+
+       return found;
+}
+
+static int
+query_krb5_ccache(const char* cred_cache, char **ret_princname,
+                 char **ret_realm)
+{
+       krb5_error_code ret;
+       krb5_context context;
+       krb5_ccache ccache;
+       krb5_principal principal;
+       int found = 0;
+       char *str = NULL;
+       char *princstring;
+
+       ret = krb5_init_context(&context);
+       if (ret) 
+               return 0;
+
+       if(!cred_cache || krb5_cc_resolve(context, cred_cache, &ccache))
+               goto err_cache;
+
+       if (krb5_cc_set_flags(context, ccache, 0))
+               goto err_princ;
+
+       ret = krb5_cc_get_principal(context, ccache, &principal);
+       if (ret) 
+               goto err_princ;
+
+       found = check_for_tgt(context, ccache, principal);
+       if (found) {
+               ret = krb5_unparse_name(context, principal, &princstring);
+               if (ret == 0) {
+                   if ((str = strchr(princstring, '@')) != NULL) {
+                           *str = '\0';
+                           *ret_princname = strdup(princstring);
+                           *ret_realm = strdup(str+1);
+                   }
+                   k5_free_unparsed_name(context, princstring);
+               } else {
+                       found = 0;
+               }
+       }
+       krb5_free_principal(context, principal);
+err_princ:
+       krb5_cc_set_flags(context, ccache,  KRB5_TC_OPENCLOSE);
+       krb5_cc_close(context, ccache);
+err_cache:
+       krb5_free_context(context);
+       return found;
+}
+
 /*==========================*/
 /*===  External routines ===*/
 /*==========================*/
@@ -889,10 +1012,11 @@ out:
  * do the best we can.
  *
  * Returns:
- *     void
+ *     0 => a ccache was found
+ *     1 => no ccache was found
  */
-void
-gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername)
+int
+gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername, char *dirname)
 {
        char                    buf[MAX_NETOBJ_SZ];
        struct dirent           *d;
@@ -900,17 +1024,16 @@ gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername)
        printerr(2, "getting credentials for client with uid %u for "
                    "server %s\n", uid, servername);
        memset(buf, 0, sizeof(buf));
-       if (gssd_find_existing_krb5_ccache(uid, &d)) {
-               snprintf(buf, sizeof(buf), "FILE:%s/%s",
-                       ccachedir, d->d_name);
+       if (gssd_find_existing_krb5_ccache(uid, dirname, &d)) {
+               snprintf(buf, sizeof(buf), "FILE:%s/%s", dirname, d->d_name);
                free(d);
        }
        else
-               snprintf(buf, sizeof(buf), "FILE:%s/%s%u",
-                       ccachedir, GSSD_DEFAULT_CRED_PREFIX, uid);
+               return 1;
        printerr(2, "using %s as credentials cache for client with "
                    "uid %u for server %s\n", buf, uid, servername);
        gssd_set_krb5_ccache_name(buf);
+       return 0;
 }
 
 /*
@@ -1129,3 +1252,19 @@ gssd_k5_err_msg(krb5_context context, krb5_error_code code)
                return error_message(code);
 #endif
 }
+
+/*
+ * Return default Kerberos realm
+ */
+void
+gssd_k5_get_default_realm(char **def_realm)
+{
+       krb5_context context;
+
+       if (krb5_init_context(&context))
+               return;
+
+       krb5_get_default_realm(context, def_realm);
+
+       krb5_free_context(context);
+}
index 78ad45c040cd59881f82e98ab7a7c68522f0e395..4b2da6bb90f3d2d5e45d2602f16f7af616013fe9 100644 (file)
@@ -17,7 +17,8 @@ struct gssd_k5_kt_princ {
 };
 
 
-void gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername);
+int gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername,
+                                    char *dirname);
 int  gssd_get_krb5_machine_cred_list(char ***list);
 void gssd_free_krb5_machine_cred_list(char **list);
 void gssd_setup_krb5_machine_gss_ccache(char *servername);
@@ -26,6 +27,7 @@ int  gssd_refresh_krb5_machine_credential(char *hostname,
                                          struct gssd_k5_kt_princ *ple);
 const char *
 gssd_k5_err_msg(krb5_context context, krb5_error_code code);
+void gssd_k5_get_default_realm(char **def_realm);
 
 #ifdef HAVE_SET_ALLOWABLE_ENCTYPES
 int limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid);
index a31cd5e0be42ba509881187141be238b7ecd31f8..057e80cc154eff287afae7d860183eaa39cd7f26 100644 (file)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -55,7 +55,7 @@ am_idmapd_OBJECTS = atomicio.$(OBJEXT) cfg.$(OBJEXT) idmapd.$(OBJEXT) \
        strlcat.$(OBJEXT) strlcpy.$(OBJEXT)
 idmapd_OBJECTS = $(am_idmapd_OBJECTS)
 idmapd_DEPENDENCIES = ../../support/nfs/libnfs.a
-DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -189,6 +189,7 @@ datarootdir = @datarootdir@
 docdir = @docdir@
 dvidir = @dvidir@
 enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
 enable_nfsv3 = @enable_nfsv3@
 enable_nfsv4 = @enable_nfsv4@
 exec_prefix = @exec_prefix@
@@ -288,8 +289,8 @@ install-sbinPROGRAMS: $(sbin_PROGRAMS)
             || test -f $$p1 \
          ; then \
            f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
-          echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
-          $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \
+          echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
+          $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \
          else :; fi; \
        done
 
@@ -445,8 +446,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        mkid -fID $$unique
 tags: TAGS
 
@@ -458,8 +459,8 @@ TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
          test -n "$$unique" || unique=$$empty_fix; \
          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -469,13 +470,12 @@ ctags: CTAGS
 CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
                $(TAGS_FILES) $(LISP)
        tags=; \
-       here=`pwd`; \
        list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        test -z "$(CTAGS_ARGS)$$tags$$unique" \
          || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
             $$tags $$unique
index 27a01dec8d0481ba69b120b384901181ea2ff3f7..459fa45e21c92e56e6150df4bdb2a9f75b0d56a2 100644 (file)
@@ -9,11 +9,13 @@ man5_MANS     = nfs.man
 
 sbin_PROGRAMS  = mount.nfs
 EXTRA_DIST = nfsmount.x $(man8_MANS) $(man5_MANS)
-mount_nfs_SOURCES = mount.c error.c network.c fstab.c token.c parse_opt.c \
+mount_nfs_SOURCES = mount.c error.c network.c fstab.c token.c \
+                   parse_opt.c parse_dev.c \
                    nfsmount.c nfs4mount.c stropts.c\
                    nfsumount.c \
-                   mount_constants.h error.h network.h fstab.h token.h parse_opt.h \
-                   nfs4_mount.h nfs_mount4.h stropts.h
+                   mount_constants.h error.h network.h fstab.h token.h \
+                   parse_opt.h parse_dev.h \
+                   nfs4_mount.h nfs_mount4.h stropts.h version.h
 
 mount_nfs_LDADD = ../../support/nfs/libnfs.a \
                  ../../support/export/libexport.a
index f1c341dbd44ac3ef7de0843d5e6f1d76dfaa15a4..876fb692ef15135c0df6d62a3a1b5f6404c9c13a 100644 (file)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -53,12 +53,12 @@ sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
 PROGRAMS = $(sbin_PROGRAMS)
 am_mount_nfs_OBJECTS = mount.$(OBJEXT) error.$(OBJEXT) \
        network.$(OBJEXT) fstab.$(OBJEXT) token.$(OBJEXT) \
-       parse_opt.$(OBJEXT) nfsmount.$(OBJEXT) nfs4mount.$(OBJEXT) \
-       stropts.$(OBJEXT) nfsumount.$(OBJEXT)
+       parse_opt.$(OBJEXT) parse_dev.$(OBJEXT) nfsmount.$(OBJEXT) \
+       nfs4mount.$(OBJEXT) stropts.$(OBJEXT) nfsumount.$(OBJEXT)
 mount_nfs_OBJECTS = $(am_mount_nfs_OBJECTS)
 mount_nfs_DEPENDENCIES = ../../support/nfs/libnfs.a \
        ../../support/export/libexport.a
-DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -192,6 +192,7 @@ datarootdir = @datarootdir@
 docdir = @docdir@
 dvidir = @dvidir@
 enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
 enable_nfsv3 = @enable_nfsv3@
 enable_nfsv4 = @enable_nfsv4@
 exec_prefix = @exec_prefix@
@@ -233,11 +234,13 @@ top_srcdir = @top_srcdir@
 man8_MANS = mount.nfs.man umount.nfs.man
 man5_MANS = nfs.man
 EXTRA_DIST = nfsmount.x $(man8_MANS) $(man5_MANS)
-mount_nfs_SOURCES = mount.c error.c network.c fstab.c token.c parse_opt.c \
+mount_nfs_SOURCES = mount.c error.c network.c fstab.c token.c \
+                   parse_opt.c parse_dev.c \
                    nfsmount.c nfs4mount.c stropts.c\
                    nfsumount.c \
-                   mount_constants.h error.h network.h fstab.h token.h parse_opt.h \
-                   nfs4_mount.h nfs_mount4.h stropts.h
+                   mount_constants.h error.h network.h fstab.h token.h \
+                   parse_opt.h parse_dev.h \
+                   nfs4_mount.h nfs_mount4.h stropts.h version.h
 
 mount_nfs_LDADD = ../../support/nfs/libnfs.a \
                  ../../support/export/libexport.a
@@ -285,8 +288,8 @@ install-sbinPROGRAMS: $(sbin_PROGRAMS)
             || test -f $$p1 \
          ; then \
            f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
-          echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
-          $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \
+          echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
+          $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \
          else :; fi; \
        done
 
@@ -321,6 +324,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nfs4mount.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nfsmount.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nfsumount.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parse_dev.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parse_opt.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stropts.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/token.Po@am__quote@
@@ -447,8 +451,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        mkid -fID $$unique
 tags: TAGS
 
@@ -460,8 +464,8 @@ TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
          test -n "$$unique" || unique=$$empty_fix; \
          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -471,13 +475,12 @@ ctags: CTAGS
 CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
                $(TAGS_FILES) $(LISP)
        tags=; \
-       here=`pwd`; \
        list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        test -z "$(CTAGS_ARGS)$$tags$$unique" \
          || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
             $$tags $$unique
index 23a91ff792d719e38b22a46730009e49c303b28d..5c9d3f2f69a3952131516d44fac8d6b4e202cf5a 100644 (file)
@@ -35,8 +35,6 @@
 #include <fcntl.h>
 #include <syslog.h>
 #include <rpc/rpc.h>
-#include <rpc/pmap_prot.h>
-#include <rpc/pmap_clnt.h>
 
 #include "xcommon.h"
 #include "nls.h"
@@ -227,9 +225,17 @@ void mount_error(const char *spec, const char *mount_point, int error)
                        nfs_error(_("%s: mount point %s does not exist"),
                                progname, mount_point);
                break;
+       case ESPIPE:
+               rpc_mount_errors((char *)spec, 0, 0);
+               break;
        case EIO:
+               nfs_error(_("%s: mount system call failed"), progname);
+               break;
        case EFAULT:
-               nfs_error(_("%s: internal error"), progname);
+               nfs_error(_("%s: encountered unexpected error condition."),
+                               progname);
+               nfs_error(_("%s: please report the error to" PACKAGE_BUGREPORT),
+                               progname);
                break;
        default:
                nfs_error(_("%s: %s"),
index 8b8e9ae40ca8295cb7fe0598058555bdad04e1ef..7126de531d5bec05079154f09478faca8f4d4beb 100644 (file)
@@ -21,6 +21,9 @@
  *
  */
 
+#ifndef _NFS_UTILS_MOUNT_ERROR_H
+#define _NFS_UTILS_MOUNT_ERROR_H
+
 char *nfs_strerror(int);
 
 void mount_error(const char *, const char *, int);
@@ -28,3 +31,5 @@ void rpc_mount_errors(char *, int, int);
 void sys_mount_errors(char *, int, int, int);
 
 void umount_error(int, const char *);
+
+#endif /* _NFS_UTILS_MOUNT_ERROR_H */
index ec7ab528bac720ffa251a728960d3f9552caddad..e19e58b0d95fa9d246e6a0034adf5480644bf6c2 100644 (file)
@@ -46,6 +46,11 @@ get_mtab_info(void) {
        }
 }
 
+void
+reset_mtab_info(void) {
+        have_mtab_info = 0;
+}
+
 int
 mtab_does_not_exist(void) {
        get_mtab_info();
index 64c8355396338af69d3bc5c4f84e6c2791b312c4..dc7c9fc8d73bdc854e78c5c87a68dbb76e71445d 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _NFS_FSTAB_H
-#define _NFS_FSTAB_H
+#ifndef _NFS_UTILS_MOUNT_FSTAB_H
+#define _NFS_UTILS_MOUNT_FSTAB_H
 
 #include "nfs_mntent.h"
 
@@ -9,6 +9,7 @@
 
 int mtab_is_writable(void);
 int mtab_does_not_exist(void);
+void reset_mtab_info(void);
 
 struct mntentchn {
        struct mntentchn *nxt, *prev;
@@ -26,5 +27,4 @@ void lock_mtab (void);
 void unlock_mtab (void);
 void update_mtab (const char *special, struct mntent *with);
 
-#endif /* _NFS_FSTAB_H */
-
+#endif /* _NFS_UTILS_MOUNT_FSTAB_H */
index 5076468db8cc29384d22c2a99225934643709be0..06e2804f3cff43580a96888fab32f59290b73964 100644 (file)
@@ -29,7 +29,6 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <sys/mount.h>
-#include <sys/utsname.h>
 #include <getopt.h>
 #include <mntent.h>
 #include <pwd.h>
@@ -45,8 +44,8 @@
 #include "nfs4_mount.h"
 #include "mount.h"
 #include "error.h"
-#include "network.h"
 #include "stropts.h"
+#include "version.h"
 
 char *progname;
 int nfs_mount_data_version;
@@ -146,21 +145,7 @@ static const struct opt_map opt_map[] = {
   { NULL,      0, 0, 0         }
 };
 
-#define MAKE_VERSION(p,q,r)    (65536 * (p) + 256 * (q) + (r))
-
-int linux_version_code(void)
-{
-       struct utsname my_utsname;
-       int p, q, r;
-
-       if (uname(&my_utsname) == 0) {
-               p = atoi(strtok(my_utsname.release, "."));
-               q = atoi(strtok(NULL, "."));
-               r = atoi(strtok(NULL, "."));
-               return MAKE_VERSION(p,q,r);
-       }
-       return 0;
-}
+static void parse_opts(const char *options, int *flags, char **extra_opts);
 
 /*
  * Choose the version of the nfs_mount_data structure that is appropriate
@@ -237,12 +222,59 @@ static char *fix_opts_string(int flags, const char *extra_opts)
        return new_opts;
 }
 
+/* Create mtab with a root entry.  */
+static void
+create_mtab (void) {
+       struct mntentchn *fstab;
+       struct mntent mnt;
+       int flags;
+       mntFILE *mfp;
+
+       lock_mtab();
+
+       mfp = nfs_setmntent (MOUNTED, "a+");
+       if (mfp == NULL || mfp->mntent_fp == NULL) {
+               int errsv = errno;
+               die (EX_FILEIO, _("mount: can't open %s for writing: %s"),
+                    MOUNTED, strerror (errsv));
+       }
+
+       /* Find the root entry by looking it up in fstab */
+       if ((fstab = getfsfile ("/")) || (fstab = getfsfile ("root"))) {
+               char *extra_opts;
+               parse_opts (fstab->m.mnt_opts, &flags, &extra_opts);
+               mnt.mnt_dir = "/";
+               mnt.mnt_fsname = xstrdup(fstab->m.mnt_fsname);
+               mnt.mnt_type = fstab->m.mnt_type;
+               mnt.mnt_opts = fix_opts_string (flags, extra_opts);
+               mnt.mnt_freq = mnt.mnt_passno = 0;
+               free(extra_opts);
+
+               if (nfs_addmntent (mfp, &mnt) == 1) {
+                       int errsv = errno;
+                       die (EX_FILEIO, _("mount: error writing %s: %s"),
+                            _PATH_MOUNTED, strerror (errsv));
+               }
+       }
+       if (fchmod (fileno (mfp->mntent_fp), 0644) < 0)
+               if (errno != EROFS) {
+                       int errsv = errno;
+                       die (EX_FILEIO,
+                            _("mount: error changing mode of %s: %s"),
+                            _PATH_MOUNTED, strerror (errsv));
+               }
+       nfs_endmntent (mfp);
+
+       unlock_mtab();
+
+       reset_mtab_info();
+}
+
 static int add_mtab(char *spec, char *mount_point, char *fstype,
                        int flags, char *opts, int freq, int pass)
 {
        struct mntent ment;
-       mntFILE *mtab;
-       int result = EX_FILEIO;
+       int result = EX_SUCCESS;
 
        ment.mnt_fsname = spec;
        ment.mnt_dir = mount_point;
@@ -251,39 +283,37 @@ static int add_mtab(char *spec, char *mount_point, char *fstype,
        ment.mnt_freq = freq;
        ment.mnt_passno = pass;
 
-       if (flags & MS_REMOUNT) {
-               update_mtab(ment.mnt_dir, &ment);
-               free(ment.mnt_opts);
-               return EX_SUCCESS;
-       }
-
-       lock_mtab();
-
-       mtab = nfs_setmntent(MOUNTED, "a+");
-       if (mtab == NULL || mtab->mntent_fp == NULL) {
-               nfs_error(_("Can't open mtab: %s"),
-                               strerror(errno));
-               goto fail_unlock;
-       }
-
-       if (nfs_addmntent(mtab, &ment) == 1) {
-               nfs_error(_("Can't write mount entry to mtab: %s"),
-                               strerror(errno));
-               goto fail_close;
+       if (!nomtab && mtab_does_not_exist()) {
+               if (verbose > 1)
+                       printf(_("mount: no %s found - creating it..\n"),
+                              MOUNTED);
+               create_mtab ();
        }
 
-       if (fchmod(fileno(mtab->mntent_fp), 0644) == -1) {
-               nfs_error(_("Can't set permissions on mtab: %s"),
-                               strerror(errno));
-               goto fail_close;
+       if (!nomtab && mtab_is_writable()) {
+               if (flags & MS_REMOUNT)
+                       update_mtab(ment.mnt_dir, &ment);
+               else {
+                       mntFILE *mtab;
+                       
+                       lock_mtab();
+                       mtab = nfs_setmntent(MOUNTED, "a+");
+                       if (mtab == NULL || mtab->mntent_fp == NULL) {
+                               nfs_error(_("Can't open mtab: %s"),
+                                               strerror(errno));
+                               result = EX_FILEIO;
+                       } else {
+                               if (nfs_addmntent(mtab, &ment) == 1) {
+                                       nfs_error(_("Can't write mount entry to mtab: %s"),
+                                                       strerror(errno));
+                                       result = EX_FILEIO;
+                               }
+                       }
+                       nfs_endmntent(mtab);
+                       unlock_mtab();
+               }
        }
 
-       result = EX_SUCCESS;
-
-fail_close:
-       nfs_endmntent(mtab);
-fail_unlock:
-       unlock_mtab();
        free(ment.mnt_opts);
 
        return result;
@@ -409,9 +439,8 @@ static int try_mount(char *spec, char *mount_point, int flags,
        if (!fake)
                print_one(spec, mount_point, fs_type, mount_opts);
 
-       if (!nomtab)
-               ret = add_mtab(spec, mount_point, fs_type, flags, *extra_opts,
-                               0, 0 /* these are always zero for NFS */ );
+       ret = add_mtab(spec, mount_point, fs_type, flags, *extra_opts,
+                       0, 0 /* these are always zero for NFS */ );
        return ret;
 }
 
@@ -539,6 +568,12 @@ int main(int argc, char *argv[])
                        mnt_err = EX_USAGE;
                        goto out;
                }
+
+               if (geteuid() != 0) {
+                       nfs_error(_("%s: not installed setuid - "
+                                   "\"user\" NFS mounts not supported."), progname);
+                       exit(EX_FAIL);
+               }
        }
 
        if (chk_mountpoint(mount_point)) {
index 4f3c729d8738128faf20eb68a733f017f74ec815..cbfb099df99a0458fcd12ff0d180573a78814bdf 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _NFS_MOUNT_CONSTANTS_H
-#define _NFS_MOUNT_CONSTANTS_H
+#ifndef _NFS_UTILS_MOUNT_CONSTANTS_H
+#define _NFS_UTILS_MOUNT_CONSTANTS_H
 
 #ifndef MS_DIRSYNC
 #define MS_DIRSYNC     128     /* Directory modifications are synchronous */
@@ -64,4 +64,4 @@ if we have a stack or plain mount - mount atop of it, forming a stack. */
 #define MS_MGC_MSK 0xffff0000  /* magic flag number mask */
 #endif
 
-#endif /* _NFS_MOUNT_CONSTANTS_H */
+#endif /* _NFS_UTILS_MOUNT_CONSTANTS_H */
index ab7f6d01072b73ae918fcada746bf50583f69f28..75354a7a62f044b2fec594beeb9a0c57ccddc1ec 100644 (file)
 #include <errno.h>
 #include <netdb.h>
 #include <time.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
 #include <rpc/rpc.h>
 #include <rpc/pmap_prot.h>
 #include <rpc/pmap_clnt.h>
-#include <sys/socket.h>
 
 #include "xcommon.h"
 #include "mount.h"
 #include "mount_constants.h"
 #include "network.h"
 
-#ifdef HAVE_RPCSVC_NFS_PROT_H
-#include <rpcsvc/nfs_prot.h>
-#else
-#include <linux/nfs.h>
-#define nfsstat nfs_stat
-#endif
-
-#ifndef NFS_PORT
-#define NFS_PORT 2049
-#endif
-
 #define PMAP_TIMEOUT   (10)
 #define CONNECT_TIMEOUT        (20)
 #define MOUNT_TIMEOUT  (30)
@@ -143,6 +135,60 @@ static const unsigned long probe_mnt3_first[] = {
        0,
 };
 
+/**
+ * nfs_name_to_address - resolve hostname to an IPv4 or IPv6 socket address
+ * @hostname: pointer to C string containing DNS hostname to resolve
+ * @sap: pointer to buffer to fill with socket address
+ * @len: IN: size of buffer to fill; OUT: size of socket address
+ *
+ * Returns 1 and places a socket address at @sap if successful;
+ * otherwise zero.
+ */
+int nfs_name_to_address(const char *hostname,
+                       const sa_family_t af_hint,
+                       struct sockaddr *sap, socklen_t *salen)
+{
+       struct addrinfo *gai_results;
+       struct addrinfo gai_hint = {
+               .ai_family      = af_hint,
+               .ai_flags       = AI_ADDRCONFIG,
+       };
+       socklen_t len = *salen;
+       int error, ret = 0;
+
+       if (af_hint == AF_INET6)
+               gai_hint.ai_flags |= AI_V4MAPPED|AI_ALL;
+
+       *salen = 0;
+
+       error = getaddrinfo(hostname, NULL, &gai_hint, &gai_results);
+       if (error) {
+               nfs_error(_("%s: DNS resolution failed for %s: %s"),
+                       progname, hostname, (error == EAI_SYSTEM ?
+                               strerror(errno) : gai_strerror(error)));
+               return ret;
+       }
+
+       switch (gai_results->ai_addr->sa_family) {
+       case AF_INET:
+       case AF_INET6:
+               if (len >= gai_results->ai_addrlen) {
+                       *salen = gai_results->ai_addrlen;
+                       memcpy(sap, gai_results->ai_addr, *salen);
+                       ret = 1;
+               }
+               break;
+       default:
+               /* things are really broken if we get here, so warn */
+               nfs_error(_("%s: unrecognized DNS resolution results for %s"),
+                               progname, hostname);
+               break;
+       }
+
+       freeaddrinfo(gai_results);
+       return ret;
+}
+
 /**
  * nfs_gethostbyname - resolve a hostname to an IPv4 address
  * @hostname: pointer to a C string containing a DNS hostname
@@ -150,26 +196,104 @@ static const unsigned long probe_mnt3_first[] = {
  *
  * Returns 1 if successful, otherwise zero.
  */
-int nfs_gethostbyname(const char *hostname, struct sockaddr_in *saddr)
+int nfs_gethostbyname(const char *hostname, struct sockaddr_in *sin)
 {
-       struct hostent *hp;
+       socklen_t len = sizeof(*sin);
 
-       saddr->sin_family = AF_INET;
-       if (!inet_aton(hostname, &saddr->sin_addr)) {
-               if ((hp = gethostbyname(hostname)) == NULL) {
-                       nfs_error(_("%s: can't get address for %s\n"),
-                                       progname, hostname);
-                       return 0;
-               } else {
-                       if (hp->h_length > sizeof(*saddr)) {
-                               nfs_error(_("%s: got bad hp->h_length\n"),
-                                               progname);
-                               hp->h_length = sizeof(*saddr);
+       return nfs_name_to_address(hostname, AF_INET,
+                                       (struct sockaddr *)sin, &len);
+}
+
+/**
+ * nfs_string_to_sockaddr - convert string address to sockaddr
+ * @address:   pointer to presentation format address to convert
+ * @addrlen:   length of presentation address
+ * @sap:       pointer to socket address buffer to fill in
+ * @salen:     IN: length of address buffer
+ *             OUT: length of converted socket address
+ *
+ * Convert a presentation format address string to a socket address.
+ * Similar to nfs_name_to_address(), but the DNS query is squelched,
+ * and won't make any noise if the getaddrinfo() call fails.
+ *
+ * Returns 1 and fills in @sap and @salen if successful; otherwise zero.
+ *
+ * See RFC 4038 section 5.1 or RFC 3513 section 2.2 for more details
+ * on presenting IPv6 addresses as text strings.
+ */
+int nfs_string_to_sockaddr(const char *address, const size_t addrlen,
+                          struct sockaddr *sap, socklen_t *salen)
+{
+       struct addrinfo *gai_results;
+       struct addrinfo gai_hint = {
+               .ai_flags       = AI_NUMERICHOST,
+       };
+       socklen_t len = *salen;
+       int ret = 0;
+
+       *salen = 0;
+
+       if (getaddrinfo(address, NULL, &gai_hint, &gai_results) == 0) {
+               switch (gai_results->ai_addr->sa_family) {
+               case AF_INET:
+               case AF_INET6:
+                       if (len >= gai_results->ai_addrlen) {
+                               *salen = gai_results->ai_addrlen;
+                               memcpy(sap, gai_results->ai_addr, *salen);
+                               ret = 1;
                        }
-                       memcpy(&saddr->sin_addr, hp->h_addr, hp->h_length);
+                       break;
                }
+               freeaddrinfo(gai_results);
        }
-       return 1;
+
+       return ret;
+}
+
+/**
+ * nfs_present_sockaddr - convert sockaddr to string
+ * @sap: pointer to socket address to convert
+ * @salen: length of socket address
+ * @buf: pointer to buffer to fill in
+ * @buflen: length of buffer
+ *
+ * Convert the passed-in sockaddr-style address to presentation format.
+ * The presentation format address is placed in @buf and is
+ * '\0'-terminated.
+ *
+ * Returns 1 if successful; otherwise zero.
+ *
+ * See RFC 4038 section 5.1 or RFC 3513 section 2.2 for more details
+ * on presenting IPv6 addresses as text strings.
+ */
+int nfs_present_sockaddr(const struct sockaddr *sap, const socklen_t salen,
+                        char *buf, const size_t buflen)
+{
+#ifdef HAVE_GETNAMEINFO
+       int result;
+
+       result = getnameinfo(sap, salen, buf, buflen,
+                                       NULL, 0, NI_NUMERICHOST);
+       if (!result)
+               return 1;
+
+       nfs_error(_("%s: invalid server address: %s"), progname,
+                       gai_strerror(result));
+       return 0;
+#else  /* HAVE_GETNAMEINFO */
+       char *addr;
+
+       if (sap->sa_family == AF_INET) {
+               addr = inet_ntoa(((struct sockaddr_in *)sap)->sin_addr);
+               if (addr && strlen(addr) < buflen) {
+                       strcpy(buf, addr);
+                       return 1;
+               }
+       }
+
+       nfs_error(_("%s: invalid server address"), progname);
+       return 0;
+#endif /* HAVE_GETNAMEINFO */
 }
 
 /*
@@ -408,11 +532,10 @@ static int probe_port(clnt_addr_t *server, const unsigned long *versions,
                                 }
                                if (clnt_ping(saddr, prog, *p_vers, *p_prot, NULL))
                                        goto out_ok;
-                               if (rpc_createerr.cf_stat == RPC_TIMEDOUT)
-                                       goto out_bad;
                        }
                }
                if (rpc_createerr.cf_stat != RPC_PROGNOTREGISTERED &&
+                   rpc_createerr.cf_stat != RPC_TIMEDOUT &&
                    rpc_createerr.cf_stat != RPC_PROGVERSMISMATCH)
                        goto out_bad;
 
@@ -421,6 +544,9 @@ static int probe_port(clnt_addr_t *server, const unsigned long *versions,
                                continue;
                        p_prot = protos;
                }
+               if (rpc_createerr.cf_stat == RPC_TIMEDOUT)
+                       goto out_bad;
+
                if (vers || !*++p_vers)
                        break;
        }
@@ -751,35 +877,120 @@ int clnt_ping(struct sockaddr_in *saddr, const unsigned long prog,
                return 0;
 }
 
-/**
- * get_client_address - acquire our local network address
- * @saddr: server's address
- * @caddr: filled in with our network address
- *
- * Discover a network address that the server will use to call us back.
- * On multi-homed clients, this address depends on which NIC we use to
- * route requests to the server.
+/*
+ * Try a getsockname() on a connected datagram socket.
  *
- * Use a connected datagram socket so as not to leave a socket in TIME_WAIT.
+ * Returns 1 and fills in @buf if successful; otherwise, zero.
  *
- * Returns one if successful, otherwise zero.
+ * A connected datagram socket prevents leaving a socket in TIME_WAIT.
+ * This conserves the ephemeral port number space, helping reduce failed
+ * socket binds during mount storms.
  */
-int get_client_address(struct sockaddr_in *saddr, struct sockaddr_in *caddr)
+static int nfs_ca_sockname(const struct sockaddr *sap, const socklen_t salen,
+                          struct sockaddr *buf, socklen_t *buflen)
 {
-       socklen_t len = sizeof(*caddr);
-       int socket, err;
+       struct sockaddr_in sin = {
+               .sin_family             = AF_INET,
+               .sin_addr.s_addr        = htonl(INADDR_ANY),
+       };
+       struct sockaddr_in6 sin6 = {
+               .sin6_family            = AF_INET6,
+               .sin6_addr              = IN6ADDR_ANY_INIT,
+       };
+       int sock;
 
-       socket = get_socket(saddr, IPPROTO_UDP, CONNECT_TIMEOUT, FALSE, TRUE);
-       if (socket == RPC_ANYSOCK)
+       sock = socket(sap->sa_family, SOCK_DGRAM, IPPROTO_UDP);
+       if (sock < 0)
                return 0;
 
-       err = getsockname(socket, caddr, &len);
-       close(socket);
+       switch (sap->sa_family) {
+       case AF_INET:
+               if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
+                       close(sock);
+                       return 0;
+               }
+               break;
+       case AF_INET6:
+               if (bind(sock, (struct sockaddr *)&sin6, sizeof(sin6)) < 0) {
+                       close(sock);
+                       return 0;
+               }
+               break;
+       default:
+               errno = EAFNOSUPPORT;
+               return 0;
+       }
 
-       if (err && verbose) {
-               nfs_error(_("%s: getsockname failed: %s"),
-                               progname, strerror(errno));
+       if (connect(sock, sap, salen) < 0) {
+               close(sock);
                return 0;
        }
+
+       return !getsockname(sock, buf, buflen);
+}
+
+/*
+ * Try to generate an address that prevents the server from calling us.
+ *
+ * Returns 1 and fills in @buf if successful; otherwise, zero.
+ */
+static int nfs_ca_gai(const struct sockaddr *sap, const socklen_t salen,
+                     struct sockaddr *buf, socklen_t *buflen)
+{
+       struct addrinfo *gai_results;
+       struct addrinfo gai_hint = {
+               .ai_family      = sap->sa_family,
+               .ai_flags       = AI_PASSIVE,   /* ANYADDR */
+       };
+
+       if (getaddrinfo(NULL, "", &gai_hint, &gai_results))
+               return 0;
+
+       *buflen = gai_results->ai_addrlen;
+       memcpy(buf, gai_results->ai_addr, *buflen);
+
+       freeaddrinfo(gai_results);
+
+       return 1;
+}
+
+/**
+ * nfs_callback_address - acquire our local network address
+ * @sap: pointer to address of remote
+ * @sap_len: length of address
+ * @buf: pointer to buffer to be filled in with local network address
+ * @buflen: IN: length of buffer to fill in; OUT: length of filled-in address
+ *
+ * Discover a network address that an NFSv4 server can use to call us back.
+ * On multi-homed clients, this address depends on which NIC we use to
+ * route requests to the server.
+ *
+ * Returns 1 and fills in @buf if an unambiguous local address is
+ * available; returns 1 and fills in an appropriate ANYADDR address
+ * if a local address isn't available; otherwise, returns zero.
+ */
+int nfs_callback_address(const struct sockaddr *sap, const socklen_t salen,
+                        struct sockaddr *buf, socklen_t *buflen)
+{
+       struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)buf;
+
+       if (nfs_ca_sockname(sap, salen, buf, buflen) == 0)
+               if (nfs_ca_gai(sap, salen, buf, buflen) == 0)
+                       goto out_failed;
+
+       /*
+        * The server can't use an interface ID that was generated
+        * here on the client, so always clear sin6_scope_id.
+        */
+       if (sin6->sin6_family == AF_INET6)
+               sin6->sin6_scope_id = 0;
+
        return 1;
+
+out_failed:
+       *buflen = 0;
+       if (verbose)
+               nfs_error(_("%s: failed to construct callback address"));
+       return 0;
+
 }
index 99ecc1ece6c753d6c8de99e2fa4dda6b6727675f..a4dba1b69e3a314a4b544b561e0f7b3ad0aeedfd 100644 (file)
  *
  */
 
-#include <rpc/pmap_prot.h>
-#include <rpc/clnt.h>
-
-#include "mount.h"
+#ifndef _NFS_UTILS_MOUNT_NETWORK_H
+#define _NFS_UTILS_MOUNT_NETWORK_H
 
-#ifdef HAVE_RPCSVC_NFS_PROT_H
-#include <rpcsvc/nfs_prot.h>
-#else
-#include <linux/nfs.h>
-#define nfsstat nfs_stat
-#endif
+#include <rpc/pmap_prot.h>
 
 #define MNT_SENDBUFSIZE (2048U)
 #define MNT_RECVBUFSIZE (1024U)
@@ -48,7 +41,14 @@ static const struct timeval RETRY_TIMEOUT = { 3, 0 };
 
 int probe_bothports(clnt_addr_t *, clnt_addr_t *);
 int nfs_gethostbyname(const char *, struct sockaddr_in *);
-int get_client_address(struct sockaddr_in *, struct sockaddr_in *);
+int nfs_name_to_address(const char *, const sa_family_t,
+               struct sockaddr *, socklen_t *);
+int nfs_string_to_sockaddr(const char *, const size_t,
+                          struct sockaddr *, socklen_t *);
+int nfs_present_sockaddr(const struct sockaddr *,
+                        const socklen_t, char *, const size_t);
+int nfs_callback_address(const struct sockaddr *, const socklen_t,
+               struct sockaddr *, socklen_t *);
 int nfs_call_umount(clnt_addr_t *, dirpath *);
 int clnt_ping(struct sockaddr_in *, const unsigned long,
                const unsigned long, const unsigned int,
@@ -60,3 +60,5 @@ unsigned long nfsvers_to_mnt(const unsigned long);
 
 CLIENT *mnt_openclnt(clnt_addr_t *, int *);
 void mnt_closeclnt(CLIENT *, int);
+
+#endif /* _NFS_UTILS_MOUNT_NETWORK_H */
index 2c0b6878e50147ab666d4e7454ba54c8ddddd740..0fc507902f435c759623716380c27137e6a73f85 100644 (file)
@@ -489,6 +489,25 @@ or the server's mountd service is not available on the advertised port.
 This option can be used when mounting an NFS server
 through a firewall that blocks the rpcbind protocol.
 .TP 1.5i
+.BI mountproto= netid
+The transport protocol used by the NFS client
+to transmit requests to the NFS server's mountd service when performing
+this mount request, and when later unmounting this mount point.
+.I netid
+can be either
+.B udp
+or
+.BR tcp .
+.IP
+This option can be used when mounting an NFS server
+through a firewall that blocks a particular transport protocol.
+When used in combination with the
+.B proto
+option, different transports for mountd requests and NFS requests
+can be specified.
+If the server's mountd service is not available via the specified
+transport, the mount request fails.
+.TP 1.5i
 .BI mounthost= name
 The hostname of the host running mountd.
 If this option is not specified, the
index 311e5a07b0b04c6ac4c42ed84fb47e0ab7f29161..a2f318fa47da13b3af4885ee514bd7d6e1fc7703 100644 (file)
@@ -34,6 +34,7 @@
 #include <arpa/inet.h>
 #include <rpc/auth.h>
 #include <rpc/rpc.h>
+
 #ifdef HAVE_RPCSVC_NFS_PROT_H
 #include <rpcsvc/nfs_prot.h>
 #else
@@ -45,6 +46,7 @@
 #include "nls.h"
 #include "xcommon.h"
 
+#include "mount.h"
 #include "mount_constants.h"
 #include "nfs4_mount.h"
 #include "nfs_mount.h"
@@ -188,10 +190,9 @@ int nfs4mount(const char *spec, const char *node, int flags,
        int bg, soft, intr;
        int nocto, noac, unshared;
        int retry;
-       int retval;
+       int retval = EX_FAIL;
        time_t timeout, t;
 
-       retval = EX_FAIL;
        if (strlen(spec) >= sizeof(hostdir)) {
                nfs_error(_("%s: excessively long host:dir argument\n"),
                                progname);
@@ -238,7 +239,7 @@ int nfs4mount(const char *spec, const char *node, int flags,
        nocto = 0;
        noac = 0;
        unshared = 0;
-       retry = 10000;          /* 10000 minutes ~ 1 week */
+       retry = -1;
 
        /*
         * NFSv4 specifies that the default port should be 2049
@@ -332,6 +333,14 @@ int nfs4mount(const char *spec, const char *node, int flags,
                }
        }
 
+       /* if retry is still -1, then it wasn't set via an option */
+       if (retry == -1) {
+               if (bg)
+                       retry = 10000;  /* 10000 mins == ~1 week */
+               else
+                       retry = 2;      /* 2 min default on fg mounts */
+       }
+
        data.flags = (soft ? NFS4_MOUNT_SOFT : 0)
                | (intr ? NFS4_MOUNT_INTR : 0)
                | (nocto ? NFS4_MOUNT_NOCTO : 0)
@@ -435,6 +444,13 @@ int nfs4mount(const char *spec, const char *node, int flags,
                        rpc_mount_errors(hostname, 0, bg);
                        goto fail;
                }
+
+               if (bg && !running_bg) {
+                       if (retry > 0)
+                               retval = EX_BG;
+                       goto fail;
+               }
+
                t = time(NULL);
                if (t >= timeout) {
                        rpc_mount_errors(hostname, 0, bg);
index 7df8fb262f97f7925a4839bd99ce10f9226c7f89..2becfb1a0d655093385f47571b026124218fcf46 100644 (file)
@@ -8,8 +8,8 @@
  * so it is easiest to ignore the kernel altogether (at compile time).
  */
 
-#ifndef _NFS_MOUNT_H
-#define _NFS_MOUNT_H
+#ifndef _NFS_UTILS_MOUNT_NFS_MOUNT_H
+#define _NFS_UTILS_MOUNT_NFS_MOUNT_H
 
 #include <netinet/in.h>
 #include <arpa/inet.h>
@@ -83,4 +83,4 @@ struct nfs_mount_data {
 int    nfsmount(const char *, const char *, int , char **, int, int);
 int    nfsumount(int, char **);
 
-#endif /* _NFS_MOUNT_H */
+#endif /* _NFS_UTILS_MOUNT_NFS_MOUNT_H */
index d1d43c661e41555eb7ea6aa0448f69e5c8ffefb4..6355681d4b520eeb3bdeacb26ed81cf797ea33cc 100644 (file)
 #include "nls.h"
 #include "error.h"
 #include "network.h"
+#include "version.h"
+
+#ifdef HAVE_RPCSVC_NFS_PROT_H
+#include <rpcsvc/nfs_prot.h>
+#else
+#include <linux/nfs.h>
+#define nfsstat nfs_stat
+#endif
 
 #ifndef NFS_PORT
 #define NFS_PORT 2049
@@ -95,8 +103,6 @@ extern char *progname;
 extern int verbose;
 extern int sloppy;
 
-extern int linux_version_code(void);
-
 static inline enum clnt_stat
 nfs3_mount(CLIENT *clnt, mnt3arg_t *mnt3arg, mnt3res_t *mnt3res)
 {
@@ -479,7 +485,7 @@ static int nfsmnt_check_compat(const struct pmap *nfs_pmap,
        }
 
        if (mnt_pmap->pm_vers > max_mnt_vers) {
-               nfs_error(_("%s: NFS mount version %ld s not supported"),
+               nfs_error(_("%s: NFS mount version %ld is not supported"),
                                progname, mnt_pmap->pm_vers);
                goto out_bad;
        }
@@ -494,7 +500,6 @@ int
 nfsmount(const char *spec, const char *node, int flags,
         char **extra_opts, int fake, int running_bg)
 {
-       static char *prev_bg_host;
        char hostdir[1024];
        char *hostname, *dirname, *old_opts, *mounthost = NULL;
        char new_opts[1024], cbuf[1024];
@@ -571,7 +576,7 @@ nfsmount(const char *spec, const char *node, int flags,
 #endif
 
        bg = 0;
-       retry = 10000;          /* 10000 minutes ~ 1 week */
+       retry = -1;
 
        memset(mnt_pmap, 0, sizeof(*mnt_pmap));
        mnt_pmap->pm_prog = MOUNTPROG;
@@ -585,9 +590,13 @@ nfsmount(const char *spec, const char *node, int flags,
                goto fail;
        if (!nfsmnt_check_compat(nfs_pmap, mnt_pmap))
                goto fail;
-       
-       if (retry == 10000 && !bg)
-               retry = 2; /* reset for fg mounts */
+
+       if (retry == -1) {
+               if (bg)
+                       retry = 10000;  /* 10000 mins == ~1 week*/
+               else
+                       retry = 2;      /* 2 min default on fg mounts */
+       }
 
 #ifdef NFS_MOUNT_DEBUG
        printf(_("rsize = %d, wsize = %d, timeo = %d, retrans = %d\n"),
@@ -624,18 +633,6 @@ nfsmount(const char *spec, const char *node, int flags,
        if (flags & MS_REMOUNT)
                goto out_ok;
 
-       /*
-        * If the previous mount operation on the same host was
-        * backgrounded, and the "bg" for this mount is also set,
-        * give up immediately, to avoid the initial timeout.
-        */
-       if (bg && !running_bg &&
-           prev_bg_host && strcmp(hostname, prev_bg_host) == 0) {
-               if (retry > 0)
-                       retval = EX_BG;
-               return retval;
-       }
-
        /* create mount deamon client */
 
        /*
@@ -704,7 +701,6 @@ nfsmount(const char *spec, const char *node, int flags,
                        continue;
                }
                if (!running_bg) {
-                       prev_bg_host = xstrdup(hostname);
                        if (retry > 0)
                                retval = EX_BG;
                        goto fail;
@@ -738,7 +734,7 @@ nfsmount(const char *spec, const char *node, int flags,
 #if NFS_MOUNT_VERSION >= 4
                mountres3_ok *mountres;
                fhandle3 *fhandle;
-               int i, *flavor, yum = 0;
+               int i,  n_flavors, *flavor, yum = 0;
                if (mntres.nfsv3.fhs_status != 0) {
                        nfs_error(_("%s: %s:%s failed, reason given by server: %s"),
                                        progname, hostname, dirname,
@@ -747,13 +743,16 @@ nfsmount(const char *spec, const char *node, int flags,
                }
 #if NFS_MOUNT_VERSION >= 5
                mountres = &mntres.nfsv3.mountres3_u.mountinfo;
-               i = mountres->auth_flavors.auth_flavors_len;
-               if (i <= 0)
+               n_flavors = mountres->auth_flavors.auth_flavors_len;
+               if (n_flavors <= 0)
                        goto noauth_flavors;
 
                flavor = mountres->auth_flavors.auth_flavors_val;
-               while (--i >= 0) {
-                       /* If no flavour requested, use first simple
+               for (i = 0; i < n_flavors; ++i) {
+                       /*
+                        * Per RFC2623, section 2.7, we should prefer the
+                        * flavour listed first.
+                        * If no flavour requested, use the first simple
                         * flavour that is offered.
                         */
                        if (! (data.flags & NFS_MOUNT_SECFLAVOUR) &&
@@ -815,7 +814,7 @@ noauth_flavors:
         * to avoid problems with multihomed hosts.
         * --Swen
         */
-       if (linux_version_code() <= 0x01030a && fsock != -1
+       if (linux_version_code() <= MAKE_VERSION(1, 3, 10) && fsock != -1
            && connect(fsock, (struct sockaddr *) nfs_saddr,
                       sizeof (*nfs_saddr)) < 0) {
                perror(_("nfs connect"));
index 285273b9ee56c1e3601ba482bfbc8708d3ba3f74..b2327e03561d9fc41bb4f69a875551b1abd3f864 100644 (file)
@@ -34,6 +34,7 @@
 #include "mount.h"
 #include "error.h"
 #include "network.h"
+#include "parse_dev.h"
 
 #if !defined(MNT_FORCE)
 /* dare not try to include <linux/mount.h> -- lots of errors */
@@ -150,21 +151,11 @@ static int do_nfs_umount23(const char *spec, char *opts)
        struct mntent mnt = { .mnt_opts = opts };
        struct pmap *pmap = &mnt_server.pmap;
        char *p;
+       int result = EX_USAGE;
+
+       if (!nfs_parse_devname(spec, &hostname, &dirname))
+               return result;
 
-       if (spec == NULL) {
-               nfs_error(_("%s: No NFS export name was provided"),
-                               progname);
-               return EX_USAGE;
-       }
-       
-       p = strchr(spec, ':');
-       if (p == NULL) {
-               nfs_error(_("%s: '%s' is not a legal NFS export name"),
-                               progname, spec);
-               return EX_USAGE;
-       }
-       hostname = xstrndup(spec, p - spec);
-       dirname = xstrdup(p + 1);
 #ifdef NFS_MOUNT_DEBUG
        printf(_("host: %s, directory: %s\n"), hostname, dirname);
 #endif
@@ -203,24 +194,36 @@ static int do_nfs_umount23(const char *spec, char *opts)
                pmap->pm_vers = nfsvers_to_mnt(atoi(p+5));
        if (opts && (p = strstr(opts, "mountvers=")) && isdigit(*(p+10)))
                pmap->pm_vers = atoi(p+10);
-       if (opts && (hasmntopt(&mnt, "udp") || hasmntopt(&mnt, "proto=udp")))
+       if (opts && (hasmntopt(&mnt, "udp")
+                    || hasmntopt(&mnt, "proto=udp")
+                    || hasmntopt(&mnt, "mountproto=udp")
+                   ))
                pmap->pm_prot = IPPROTO_UDP;
-       if (opts && (hasmntopt(&mnt, "tcp") || hasmntopt(&mnt, "proto=tcp")))
+       if (opts && (hasmntopt(&mnt, "tcp")
+                    || hasmntopt(&mnt, "proto=tcp")
+                    || hasmntopt(&mnt, "mountproto=tcp")
+                   ))
                pmap->pm_prot = IPPROTO_TCP;
 
        if (!nfs_gethostbyname(hostname, &mnt_server.saddr)) {
-               nfs_error(_("%s: '%s' does not contain a recognized hostname"),
-                               progname, spec);
-               return EX_USAGE;
+               nfs_error(_("%s: DNS resolution of '%s' failed"),
+                               progname, hostname);
+               goto out;
        }
 
        if (!nfs_call_umount(&mnt_server, &dirname)) {
                nfs_error(_("%s: Server failed to unmount '%s'"),
                                progname, spec);
-               return EX_USAGE;
+               result = EX_FAIL;
+               goto out;
        }
 
-       return EX_SUCCESS;
+       result = EX_SUCCESS;
+
+out:
+       free(hostname);
+       free(dirname);
+       return result;
 }
 
 static struct option umount_longopts[] =
@@ -347,8 +350,13 @@ int nfsumount(int argc, char *argv[])
        ret = 0;
        if (mc) {
                if (!lazy && strcmp(mc->m.mnt_type, "nfs4") != 0)
-                       ret = do_nfs_umount23(mc->m.mnt_fsname, mc->m.mnt_opts);
-               ret = del_mtab(mc->m.mnt_fsname, mc->m.mnt_dir) ?: ret;
+                       /* We ignore the error from do_nfs_umount23.
+                        * If the actual umount succeeds (in del_mtab),
+                        * we don't want to signal an error, as that
+                        * could cause /sbin/mount to retry!
+                        */
+                       do_nfs_umount23(mc->m.mnt_fsname, mc->m.mnt_opts);
+               ret = del_mtab(mc->m.mnt_fsname, mc->m.mnt_dir);
        } else if (*spec != '/') {
                if (!lazy)
                        ret = do_nfs_umount23(spec, "tcp,v3");
diff --git a/utils/mount/parse_dev.c b/utils/mount/parse_dev.c
new file mode 100644 (file)
index 0000000..c0a8e18
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+ * parse_dev.c -- parse device name into hostname and export path
+ *
+ * Copyright (C) 2008 Oracle.  All rights reserved.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "xcommon.h"
+#include "nls.h"
+#include "parse_dev.h"
+
+#ifndef NFS_MAXHOSTNAME
+#define NFS_MAXHOSTNAME                (255)
+#endif
+
+#ifndef NFS_MAXPATHNAME
+#define NFS_MAXPATHNAME                (1024)
+#endif
+
+extern char *progname;
+extern int verbose;
+
+static int nfs_pdn_no_devname_err(void)
+{
+       nfs_error(_("%s: no device name was provided"), progname);
+       return 0;
+}
+
+static int nfs_pdn_hostname_too_long_err(void)
+{
+       nfs_error(_("%s: server hostname is too long"), progname);
+       return 0;
+}
+
+static int nfs_pdn_pathname_too_long_err(void)
+{
+       nfs_error(_("%s: export pathname is too long"), progname);
+       return 0;
+}
+
+static int nfs_pdn_bad_format_err(void)
+{
+       nfs_error(_("%s: remote share not in 'host:dir' format"), progname);
+       return 0;
+}
+
+static int nfs_pdn_nomem_err(void)
+{
+       nfs_error(_("%s: no memory available to parse devname"), progname);
+       return 0;
+}
+
+static int nfs_pdn_missing_brace_err(void)
+{
+       nfs_error(_("%s: closing bracket missing from server address"),
+                               progname);
+       return 0;
+}
+
+/*
+ * Standard hostname:path format
+ */
+static int nfs_parse_simple_hostname(const char *dev,
+                                    char **hostname, char **pathname)
+{
+       size_t host_len, path_len;
+       char *colon, *comma;
+
+       /* Must have a colon */
+       colon = strchr(dev, ':');
+       if (colon == NULL)
+               return nfs_pdn_bad_format_err();
+       *colon = '\0';
+       host_len = colon - dev;
+
+       if (host_len > NFS_MAXHOSTNAME)
+               return nfs_pdn_hostname_too_long_err();
+
+       /* If there's a comma before the colon, take only the
+        * first name in list */
+       comma = strchr(dev, ',');
+       if (comma != NULL) {
+               *comma = '\0';
+               host_len = comma - dev;
+               nfs_error(_("%s: warning: multiple hostnames not supported"),
+                               progname);
+       } else
+
+       colon++;
+       path_len = strlen(colon);
+       if (path_len > NFS_MAXPATHNAME)
+               return nfs_pdn_pathname_too_long_err();
+
+       if (hostname) {
+               *hostname = strndup(dev, host_len);
+               if (*hostname == NULL)
+                       return nfs_pdn_nomem_err();
+       }
+       if (pathname) {
+               *pathname = strndup(colon, path_len);
+               if (*pathname == NULL) {
+                       free(*hostname);
+                       return nfs_pdn_nomem_err();
+               }
+       }
+       return 1;
+}
+
+/*
+ * To handle raw IPv6 addresses (which contain colons), the
+ * server's address is enclosed in square brackets.  Return
+ * what's between the brackets.
+ *
+ * There could be anything in between the brackets, but we'll
+ * let DNS resolution sort it out later.
+ */
+static int nfs_parse_square_bracket(const char *dev,
+                                   char **hostname, char **pathname)
+{
+       size_t host_len, path_len;
+       char *cbrace;
+
+       dev++;
+
+       /* Must have a closing square bracket */
+       cbrace = strchr(dev, ']');
+       if (cbrace == NULL)
+               return nfs_pdn_missing_brace_err();
+       *cbrace = '\0';
+       host_len = cbrace - dev;
+
+       /* Must have a colon just after the closing bracket */
+       cbrace++;
+       if (*cbrace != ':')
+               return nfs_pdn_bad_format_err();
+
+       if (host_len > NFS_MAXHOSTNAME)
+               return nfs_pdn_hostname_too_long_err();
+
+       cbrace++;
+       path_len = strlen(cbrace);
+       if (path_len > NFS_MAXPATHNAME)
+               return nfs_pdn_pathname_too_long_err();
+
+       if (hostname) {
+               *hostname = strndup(dev, host_len);
+               if (*hostname == NULL)
+                       return nfs_pdn_nomem_err();
+       }
+       if (pathname) {
+               *pathname = strndup(cbrace, path_len);
+               if (*pathname == NULL) {
+                       free(*hostname);
+                       return nfs_pdn_nomem_err();
+               }
+       }
+       return 1;
+}
+
+/*
+ * RFC 2224 says an NFS client must grok "public file handles" to
+ * support NFS URLs.  Linux doesn't do that yet.  Print a somewhat
+ * helpful error message in this case instead of pressing forward
+ * with the mount request and failing with a cryptic error message
+ * later.
+ */
+static int nfs_parse_nfs_url(const char *dev,
+                            char **hostname, char **pathname)
+{
+       nfs_error(_("%s: NFS URLs are not supported"), progname);
+       return 0;
+}
+
+/**
+ * nfs_parse_devname - Determine the server's hostname by looking at "devname".
+ * @devname: pointer to mounted device name (first argument of mount command)
+ * @hostname: OUT: pointer to server's hostname
+ * @pathname: OUT: pointer to export path on server
+ *
+ * Returns 1 if succesful, or zero if some error occurred.  On success,
+ * @hostname and @pathname point to dynamically allocated buffers containing
+ * the hostname of the server and the export pathname (both '\0'-terminated).
+ *
+ * @hostname or @pathname may be NULL if caller doesn't want a copy of those
+ * parts of @devname.
+ *
+ * Note that this will not work if @devname is a wide-character string.
+ */
+int nfs_parse_devname(const char *devname,
+                     char **hostname, char **pathname)
+{
+       char *dev;
+       int result;
+
+       if (devname == NULL)
+               return nfs_pdn_no_devname_err();
+
+       /* Parser is destructive, so operate on a copy of the device name. */
+       dev = strdup(devname);
+       if (dev == NULL)
+               return nfs_pdn_nomem_err();
+       if (*dev == '[')
+               result = nfs_parse_square_bracket(dev, hostname, pathname);
+       else if (strncmp(dev, "nfs://", 6) == 0)
+               result = nfs_parse_nfs_url(dev, hostname, pathname);
+       else
+               result = nfs_parse_simple_hostname(dev, hostname, pathname);
+
+       free(dev);
+       return result;
+}
diff --git a/utils/mount/parse_dev.h b/utils/mount/parse_dev.h
new file mode 100644 (file)
index 0000000..a1288c2
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * parse_dev.c -- parse device name into hostname and export path
+ *
+ * Copyright (C) 2008 Oracle.  All rights reserved.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ */
+
+#ifndef __NFS_UTILS_PARSE_DEV_HEADER
+#define __NFS_UTILS_PARSE_DEV_HEADER
+
+extern int     nfs_parse_devname(const char *, char **, char **);
+
+#endif /* __NFS_UTILS_PARSE_DEV */
index e7924ddf078ade1c0c337c00f96d66f468b89973..fb003c3030a8839200bb03e0b1e808b8b03a55a0 100644 (file)
@@ -21,6 +21,9 @@
  *
  */
 
+#ifndef _NFS_UTILS_PARSE_OPT_H
+#define _NFS_UTILS_PARSE_OPT_H
+
 typedef enum {
        PO_FAILED = 0,
        PO_SUCCEEDED = 1,
@@ -50,3 +53,5 @@ char *                        po_get(struct mount_options *, char *);
 po_rightmost_t         po_rightmost(struct mount_options *, char *, char *);
 po_found_t             po_remove_all(struct mount_options *, char *);
 void                   po_destroy(struct mount_options *);
+
+#endif /* _NFS_UTILS_PARSE_OPT_H */
index cadb1f473e4b4383eedbd58060648f9cf7b560d3..09fca86d1e1705a72e8a6bfb805a9d861f8fdfb8 100644 (file)
 #include <config.h>
 #endif
 
-#include <ctype.h>
 #include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
 #include <errno.h>
 #include <netdb.h>
 #include <time.h>
+
 #include <sys/socket.h>
 #include <sys/mount.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
 
 #include "xcommon.h"
 #include "mount.h"
 #include "nls.h"
-#include "nfs_mount.h"
 #include "mount_constants.h"
 #include "stropts.h"
 #include "error.h"
 #include "network.h"
 #include "parse_opt.h"
+#include "version.h"
+#include "parse_dev.h"
 
-#ifdef HAVE_RPCSVC_NFS_PROT_H
-#include <rpcsvc/nfs_prot.h>
-#else
-#include <linux/nfs.h>
-#define nfsstat nfs_stat
+#ifndef NFS_PROGRAM
+#define NFS_PROGRAM    (100003)
 #endif
 
 #ifndef NFS_PORT
-#define NFS_PORT 2049
+#define NFS_PORT       (2049)
 #endif
 
 #ifndef NFS_MAXHOSTNAME
 #define NFS_MAXPATHNAME                (1024)
 #endif
 
+#ifndef NFS_DEF_FG_TIMEOUT_MINUTES
+#define NFS_DEF_FG_TIMEOUT_MINUTES     (2u)
+#endif
+
+#ifndef NFS_DEF_BG_TIMEOUT_MINUTES
+#define NFS_DEF_BG_TIMEOUT_MINUTES     (10000u)
+#endif
+
 extern int nfs_mount_data_version;
 extern char *progname;
 extern int verbose;
+extern int sloppy;
 
-static int parse_devname(const char *spec, char **hostname)
-{
-       int ret = 0;
-       char *dev, *pathname, *s;
+struct nfsmount_info {
+       const char              *spec,          /* server:/path */
+                               *node,          /* mounted-on dir */
+                               *type;          /* "nfs" or "nfs4" */
+       char                    *hostname;      /* server's hostname */
 
-       dev = xstrdup(spec);
+       struct mount_options    *options;       /* parsed mount options */
+       char                    **extra_opts;   /* string for /etc/mtab */
 
-       if (!(pathname = strchr(dev, ':'))) {
-               nfs_error(_("%s: remote share not in 'host:dir' format"),
-                               progname);
-               goto out;
-       }
-       *pathname = '\0';
-       pathname++;
+       int                     flags,          /* MS_ flags */
+                               fake,           /* actually do the mount? */
+                               child;          /* forked bg child? */
 
-       /*
-        * We don't need a copy of the pathname, but let's
-        * sanity check it anyway.
-        */
-       if (strlen(pathname) > NFS_MAXPATHNAME) {
-               nfs_error(_("%s: export pathname is too long"),
-                               progname);
-               goto out;
-       }
+       sa_family_t             family;         /* supported address family */
+};
 
-       /*
-        * Ignore all but first hostname in replicated mounts
-        * until they can be fully supported. (mack@sgi.com)
-        */
-       if ((s = strchr(dev, ','))) {
-               *s = '\0';
-               nfs_error(_("%s: warning: multiple hostnames not supported"),
-                               progname);
-               nfs_error(_("%s: ignoring hostnames that follow the first one"),
-                               progname);
-       }
-       *hostname = xstrdup(dev);
-       if (strlen(*hostname) > NFS_MAXHOSTNAME) {
-               nfs_error(_("%s: server hostname is too long"),
-                               progname);
-               free(*hostname);
-               goto out;
+/*
+ * Obtain a retry timeout value based on the value of the "retry=" option.
+ *
+ * Returns a time_t timeout timestamp, in seconds.
+ */
+static time_t nfs_parse_retry_option(struct mount_options *options,
+                                    unsigned int timeout_minutes)
+{
+       char *retry_option, *endptr;
+
+       retry_option = po_get(options, "retry");
+       if (retry_option) {
+               long tmp;
+
+               errno = 0;
+               tmp = strtol(retry_option, &endptr, 10);
+               if (errno == 0 && endptr != retry_option && tmp >= 0)
+                       timeout_minutes = tmp;
+               else if (verbose)
+                       nfs_error(_("%s: invalid retry timeout was specified; "
+                                       "using default timeout"), progname);
        }
 
-       ret = 1;
-
-out:
-       free(dev);
-       return ret;
+       return time(NULL) + (time_t)(timeout_minutes * 60);
 }
 
-static int fill_ipv4_sockaddr(const char *hostname, struct sockaddr_in *addr)
+/*
+ * Convert the passed-in sockaddr-style address to presentation
+ * format, then append an option of the form "keyword=address".
+ *
+ * Returns 1 if the option was appended successfully; otherwise zero.
+ */
+static int nfs_append_generic_address_option(const struct sockaddr *sap,
+                                            const socklen_t salen,
+                                            const char *keyword,
+                                            struct mount_options *options)
 {
-       struct hostent *hp;
-       addr->sin_family = AF_INET;
+       char address[NI_MAXHOST];
+       char new_option[512];
+
+       if (!nfs_present_sockaddr(sap, salen, address, sizeof(address)))
+               goto out_err;
+
+       if (snprintf(new_option, sizeof(new_option), "%s=%s",
+                                       keyword, address) >= sizeof(new_option))
+               goto out_err;
+
+       if (po_append(options, new_option) != PO_SUCCEEDED)
+               goto out_err;
 
-       if (inet_aton(hostname, &addr->sin_addr))
-               return 1;
-       if ((hp = gethostbyname(hostname)) == NULL) {
-               nfs_error(_("%s: can't get address for %s\n"),
-                               progname, hostname);
-               return 0;
-       }
-       if (hp->h_length > sizeof(struct in_addr)) {
-               nfs_error(_("%s: got bad hp->h_length"), progname);
-               hp->h_length = sizeof(struct in_addr);
-       }
-       memcpy(&addr->sin_addr, hp->h_addr, hp->h_length);
        return 1;
+
+out_err:
+       nfs_error(_("%s: failed to construct %s option"), progname, keyword);
+       return 0;
 }
 
 /*
@@ -152,19 +160,12 @@ static int fill_ipv4_sockaddr(const char *hostname, struct sockaddr_in *addr)
  * Returns 1 if 'addr=' option appended successfully;
  * otherwise zero.
  */
-static int append_addr_option(struct sockaddr_in *saddr,
-                          struct mount_options *options)
+static int nfs_append_addr_option(const struct sockaddr *sap,
+                                 socklen_t salen,
+                                 struct mount_options *options)
 {
-       char new_option[24];
-
        po_remove_all(options, "addr");
-
-       snprintf(new_option, sizeof(new_option) - 1,
-                       "addr=%s", inet_ntoa(saddr->sin_addr));
-
-       if (po_append(options, new_option) == PO_SUCCEEDED)
-               return 1;
-       return 0;
+       return nfs_append_generic_address_option(sap, salen, "addr", options);
 }
 
 /*
@@ -174,71 +175,110 @@ static int append_addr_option(struct sockaddr_in *saddr,
  * Returns 1 if 'clientaddr=' option created successfully or if
  * 'clientaddr=' option is already present; otherwise zero.
  */
-static int append_clientaddr_option(struct sockaddr_in *saddr,
-                                   struct mount_options *options)
+static int nfs_append_clientaddr_option(const struct sockaddr *sap,
+                                       socklen_t salen,
+                                       struct mount_options *options)
 {
-       struct sockaddr_in my_addr;
-       char new_option[32];
+       struct sockaddr_storage dummy;
+       struct sockaddr *my_addr = (struct sockaddr *)&dummy;
+       socklen_t my_len = sizeof(dummy);
 
-       if (po_contains(options, "clientaddr") == PO_SUCCEEDED)
+       if (po_contains(options, "clientaddr") == PO_FOUND)
                return 1;
 
-       if (!get_client_address(saddr, &my_addr))
-               return 0;
-
-       snprintf(new_option, sizeof(new_option) - 1,
-                       "clientaddr=%s", inet_ntoa(my_addr.sin_addr));
+       nfs_callback_address(sap, salen, my_addr, &my_len);
 
-       if (po_append(options, new_option) == PO_SUCCEEDED)
-               return 1;
-       return 0;
+       return nfs_append_generic_address_option(my_addr, my_len,
+                                                       "clientaddr", options);
 }
 
 /*
  * Resolve the 'mounthost=' hostname and append a new option using
- * the resulting IPv4 address.
+ * the resulting address.
  */
-static int fix_mounthost_option(struct mount_options *options)
+static int nfs_fix_mounthost_option(const sa_family_t family,
+                                   struct mount_options *options)
 {
-       struct sockaddr_in maddr;
-       char *mounthost, new_option[32];
+       struct sockaddr_storage dummy;
+       struct sockaddr *sap = (struct sockaddr *)&dummy;
+       socklen_t salen = sizeof(dummy);
+       char *mounthost;
 
        mounthost = po_get(options, "mounthost");
        if (!mounthost)
                return 1;
 
-       if (!fill_ipv4_sockaddr(mounthost, &maddr))
+       if (!nfs_name_to_address(mounthost, family, sap, &salen)) {
+               nfs_error(_("%s: unable to determine mount server's address"),
+                               progname);
                return 0;
+       }
 
-       snprintf(new_option, sizeof(new_option) - 1,
-                       "mountaddr=%s", inet_ntoa(maddr.sin_addr));
+       return nfs_append_generic_address_option(sap, salen,
+                                                       "mountaddr", options);
+}
 
-       if (po_append(options, new_option) == PO_SUCCEEDED)
+/*
+ * Returns zero if the "lock" option is in effect, but statd
+ * can't be started.  Otherwise, returns 1.
+ */
+static int nfs_verify_lock_option(struct mount_options *options)
+{
+       if (po_rightmost(options, "nolock", "lock") == PO_KEY1_RIGHTMOST)
                return 1;
-       return 0;
+
+       if (!start_statd()) {
+               nfs_error(_("%s: rpc.statd is not running but is "
+                           "required for remote locking."), progname);
+               nfs_error(_("%s: Either use '-o nolock' to keep "
+                           "locks local, or start statd."), progname);
+               return 0;
+       }
+
+       return 1;
+}
+
+static int nfs_append_sloppy_option(struct mount_options *options)
+{
+       if (!sloppy || linux_version_code() < MAKE_VERSION(2, 6, 27))
+               return 1;
+
+       if (po_append(options, "sloppy") == PO_FAILED)
+               return 0;
+       return 1;
 }
 
 /*
- * Set up mandatory mount options.
+ * Set up mandatory NFS mount options.
  *
  * Returns 1 if successful; otherwise zero.
  */
-static int set_mandatory_options(const char *type,
-                                struct sockaddr_in *saddr,
-                                struct mount_options *options)
+static int nfs_validate_options(struct nfsmount_info *mi)
 {
-       if (!append_addr_option(saddr, options))
+       struct sockaddr_storage dummy;
+       struct sockaddr *sap = (struct sockaddr *)&dummy;
+       socklen_t salen = sizeof(dummy);
+
+       if (!nfs_parse_devname(mi->spec, &mi->hostname, NULL))
                return 0;
 
-       if (strncmp(type, "nfs4", 4) == 0) {
-               if (!append_clientaddr_option(saddr, options))
+       if (!nfs_name_to_address(mi->hostname, mi->family, sap, &salen))
+               return 0;
+
+       if (strncmp(mi->type, "nfs4", 4) == 0) {
+               if (!nfs_append_clientaddr_option(sap, salen, mi->options))
                        return 0;
        } else {
-               if (!fix_mounthost_option(options))
+               if (!nfs_fix_mounthost_option(mi->family, mi->options))
+                       return 0;
+               if (!mi->fake && !nfs_verify_lock_option(mi->options))
                        return 0;
        }
 
-       return 1;
+       if (!nfs_append_sloppy_option(mi->options))
+               return 0;
+
+       return nfs_append_addr_option(sap, salen, mi->options);
 }
 
 /*
@@ -249,10 +289,9 @@ static int set_mandatory_options(const char *type,
  * passed-in error is permanent, thus the mount system call
  * should not be retried.
  */
-static int is_permanent_error(int error)
+static int nfs_is_permanent_error(int error)
 {
        switch (error) {
-       case EACCES:
        case ESTALE:
        case ETIMEDOUT:
        case ECONNREFUSED:
@@ -269,13 +308,13 @@ static int is_permanent_error(int error)
  *
  * To handle version and transport protocol fallback properly, we
  * need to parse some of the mount options in order to set up a
- * portmap probe.  Mount options that rewrite_mount_options()
+ * portmap probe.  Mount options that nfs_rewrite_mount_options()
  * doesn't recognize are left alone.
  *
  * Returns a new group of mount options if successful; otherwise
  * NULL is returned if some failure occurred.
  */
-static struct mount_options *rewrite_mount_options(char *str)
+static struct mount_options *nfs_rewrite_mount_options(char *str)
 {
        struct mount_options *options;
        char *option, new_option[64];
@@ -284,9 +323,12 @@ static struct mount_options *rewrite_mount_options(char *str)
        int p;
 
        options = po_split(str);
-       if (!options)
+       if (!options) {
+               errno = EFAULT;
                return NULL;
+       }
 
+       errno = EINVAL;
        option = po_get(options, "addr");
        if (option) {
                nfs_server.saddr.sin_family = AF_INET;
@@ -311,6 +353,17 @@ static struct mount_options *rewrite_mount_options(char *str)
        option = po_get(options, "mountvers");
        if (option)
                mnt_server.pmap.pm_vers = atoi(option);
+       option = po_get(options, "mountproto");
+       if (option) {
+               if (strcmp(option, "tcp") == 0) {
+                       mnt_server.pmap.pm_prot = IPPROTO_TCP;
+                       po_remove_all(options, "mountproto");
+               }
+               if (strcmp(option, "udp") == 0) {
+                       mnt_server.pmap.pm_prot = IPPROTO_UDP;
+                       po_remove_all(options, "mountproto");
+               }
+       }
 
        option = po_get(options, "port");
        if (option) {
@@ -353,7 +406,7 @@ static struct mount_options *rewrite_mount_options(char *str)
        po_remove_all(options, "udp");
 
        if (!probe_bothports(&mnt_server, &nfs_server)) {
-               rpc_mount_errors("rpcbind", 0, 0);
+               errno = ESPIPE;
                goto err;
        }
 
@@ -379,6 +432,21 @@ static struct mount_options *rewrite_mount_options(char *str)
 
        }
 
+       if (mnt_server.pmap.pm_prot == IPPROTO_TCP)
+               snprintf(new_option, sizeof(new_option) - 1,
+                        "mountproto=tcp");
+       else
+               snprintf(new_option, sizeof(new_option) - 1,
+                        "mountproto=udp");
+       if (po_append(options, new_option) == PO_FAILED)
+               goto err;
+
+       snprintf(new_option, sizeof(new_option) - 1,
+                "mountport=%lu", mnt_server.pmap.pm_port);
+       if (po_append(options, new_option) == PO_FAILED)
+               goto err;
+
+       errno = 0;
        return options;
 
 err:
@@ -386,6 +454,27 @@ err:
        return NULL;
 }
 
+/*
+ * Do the mount(2) system call.
+ *
+ * Returns 1 if successful, otherwise zero.
+ * "errno" is set to reflect the individual error.
+ */
+static int nfs_sys_mount(const struct nfsmount_info *mi, const char *type,
+                        const char *options)
+{
+       int result;
+
+       result = mount(mi->spec, mi->node, type,
+                               mi->flags & ~(MS_USER|MS_USERS), options);
+       if (verbose && result) {
+               int save = errno;
+               nfs_error(_("%s: mount(2): %s"), progname, strerror(save));
+               errno = save;
+       }
+       return !result;
+}
+
 /*
  * Retry an NFS mount that failed because the requested service isn't
  * available on the server.
@@ -397,18 +486,15 @@ err:
  * 'extra_opts' are updated to reflect the mount options that worked.
  * If the retry fails, 'options' and 'extra_opts' are left unchanged.
  */
-static int retry_nfsmount(const char *spec, const char *node,
-                       int flags, struct mount_options *options,
-                       int fake, char **extra_opts)
+static int nfs_retry_nfs23mount(struct nfsmount_info *mi)
 {
        struct mount_options *retry_options;
        char *retry_str = NULL;
+       char **extra_opts = mi->extra_opts;
 
-       retry_options = rewrite_mount_options(*extra_opts);
-       if (!retry_options) {
-               errno = EIO;
+       retry_options = nfs_rewrite_mount_options(*extra_opts);
+       if (!retry_options)
                return 0;
-       }
 
        if (po_join(retry_options, &retry_str) == PO_FAILED) {
                po_destroy(retry_options);
@@ -420,17 +506,16 @@ static int retry_nfsmount(const char *spec, const char *node,
                printf(_("%s: text-based options (retry): '%s'\n"),
                        progname, retry_str);
 
-       if (!mount(spec, node, "nfs",
-                               flags & ~(MS_USER|MS_USERS), retry_str)) {
-               free(*extra_opts);
-               *extra_opts = retry_str;
-               po_replace(options, retry_options);
-               return 1;
+       if (!nfs_sys_mount(mi, "nfs", retry_str)) {
+               po_destroy(retry_options);
+               free(retry_str);
+               return 0;
        }
 
-       po_destroy(retry_options);
-       free(retry_str);
-       return 0;
+       free(*extra_opts);
+       *extra_opts = retry_str;
+       po_replace(mi->options, retry_options);
+       return 1;
 }
 
 /*
@@ -446,11 +531,11 @@ static int retry_nfsmount(const char *spec, const char *node,
  * 'extra_opts' are updated to reflect the mount options that worked.
  * If the retry fails, 'options' and 'extra_opts' are left unchanged.
  */
-static int try_nfs23mount(const char *spec, const char *node,
-                         int flags, struct mount_options *options,
-                         int fake, char **extra_opts)
+static int nfs_try_nfs23mount(struct nfsmount_info *mi)
 {
-       if (po_join(options, extra_opts) == PO_FAILED) {
+       char **extra_opts = mi->extra_opts;
+
+       if (po_join(mi->options, extra_opts) == PO_FAILED) {
                errno = EIO;
                return 0;
        }
@@ -459,11 +544,10 @@ static int try_nfs23mount(const char *spec, const char *node,
                printf(_("%s: text-based options: '%s'\n"),
                        progname, *extra_opts);
 
-       if (fake)
+       if (mi->fake)
                return 1;
 
-       if (!mount(spec, node, "nfs",
-                               flags & ~(MS_USER|MS_USERS), *extra_opts))
+       if (nfs_sys_mount(mi, "nfs", *extra_opts))
                return 1;
 
        /*
@@ -473,7 +557,7 @@ static int try_nfs23mount(const char *spec, const char *node,
        if (errno != EOPNOTSUPP && errno != EPROTONOSUPPORT)
                return 0;
 
-       return retry_nfsmount(spec, node, flags, options, fake, extra_opts);
+       return nfs_retry_nfs23mount(mi);
 }
 
 /*
@@ -482,11 +566,11 @@ static int try_nfs23mount(const char *spec, const char *node,
  * Returns 1 if successful.  Otherwise, returns zero.
  * "errno" is set to reflect the individual error.
  */
-static int try_nfs4mount(const char *spec, const char *node,
-                        int flags, struct mount_options *options,
-                        int fake, char **extra_opts)
+static int nfs_try_nfs4mount(struct nfsmount_info *mi)
 {
-       if (po_join(options, extra_opts) == PO_FAILED) {
+       char **extra_opts = mi->extra_opts;
+
+       if (po_join(mi->options, extra_opts) == PO_FAILED) {
                errno = EIO;
                return 0;
        }
@@ -495,31 +579,24 @@ static int try_nfs4mount(const char *spec, const char *node,
                printf(_("%s: text-based options: '%s'\n"),
                        progname, *extra_opts);
 
-       if (fake)
+       if (mi->fake)
                return 1;
 
-       if (!mount(spec, node, "nfs4",
-                               flags & ~(MS_USER|MS_USERS), *extra_opts))
-               return 1;
-       return 0;
+       return nfs_sys_mount(mi, "nfs4", *extra_opts);
 }
 
 /*
- * Try the mount(2) system call.
+ * Perform either an NFSv2/3 mount, or an NFSv4 mount system call.
  *
  * Returns 1 if successful.  Otherwise, returns zero.
  * "errno" is set to reflect the individual error.
  */
-static int try_mount(const char *spec, const char *node, const char *type,
-                    int flags, struct mount_options *options, int fake,
-                    char **extra_opts)
+static int nfs_try_mount(struct nfsmount_info *mi)
 {
-       if (strncmp(type, "nfs4", 4) == 0)
-               return try_nfs4mount(spec, node, flags,
-                                       options, fake, extra_opts);
+       if (strncmp(mi->type, "nfs4", 4) == 0)
+               return nfs_try_nfs4mount(mi);
        else
-               return try_nfs23mount(spec, node, flags,
-                                       options, fake, extra_opts);
+               return nfs_try_nfs23mount(mi);
 }
 
 /*
@@ -529,30 +606,22 @@ static int try_mount(const char *spec, const char *node, const char *type,
  *
  * Returns a valid mount command exit code.
  */
-static int nfsmount_fg(const char *spec, const char *node,
-                      const char *type, int flags,
-                      struct mount_options *options, int fake,
-                      char **extra_opts)
+static int nfsmount_fg(struct nfsmount_info *mi)
 {
        unsigned int secs = 1;
-       time_t timeout = time(NULL);
-       char *retry;
-
-       timeout += 60 * 2;              /* default: 2 minutes */
-       retry = po_get(options, "retry");
-       if (retry)
-               timeout += 60 * atoi(retry);
+       time_t timeout;
 
+       timeout = nfs_parse_retry_option(mi->options,
+                                        NFS_DEF_FG_TIMEOUT_MINUTES);
        if (verbose)
                printf(_("%s: timeout set for %s"),
                        progname, ctime(&timeout));
 
        for (;;) {
-               if (try_mount(spec, node, type, flags,
-                                       options, fake, extra_opts))
+               if (nfs_try_mount(mi))
                        return EX_SUCCESS;
 
-               if (is_permanent_error(errno))
+               if (nfs_is_permanent_error(errno))
                        break;
 
                if (time(NULL) > timeout) {
@@ -569,7 +638,7 @@ static int nfsmount_fg(const char *spec, const char *node,
                }
        };
 
-       mount_error(spec, node, errno);
+       mount_error(mi->spec, mi->node, errno);
        return EX_FAIL;
 }
 
@@ -580,21 +649,17 @@ static int nfsmount_fg(const char *spec, const char *node,
  *
  * EX_BG should cause the caller to fork and invoke nfsmount_child.
  */
-static int nfsmount_parent(const char *spec, const char *node,
-                          const char *type, char *hostname, int flags,
-                          struct mount_options *options,
-                          int fake, char **extra_opts)
+static int nfsmount_parent(struct nfsmount_info *mi)
 {
-       if (try_mount(spec, node, type, flags, options,
-                                       fake, extra_opts))
+       if (nfs_try_mount(mi))
                return EX_SUCCESS;
 
-       if (is_permanent_error(errno)) {
-               mount_error(spec, node, errno);
+       if (nfs_is_permanent_error(errno)) {
+               mount_error(mi->spec, mi->node, errno);
                return EX_FAIL;
        }
 
-       sys_mount_errors(hostname, errno, 1, 1);
+       sys_mount_errors(mi->hostname, errno, 1, 1);
        return EX_BG;
 }
 
@@ -606,19 +671,13 @@ static int nfsmount_parent(const char *spec, const char *node,
  * error return, though, so we use sys_mount_errors to log the
  * failure.
  */
-static int nfsmount_child(const char *spec, const char *node,
-                         const char *type, char *hostname, int flags,
-                         struct mount_options *options,
-                         int fake, char **extra_opts)
+static int nfsmount_child(struct nfsmount_info *mi)
 {
        unsigned int secs = 1;
-       time_t timeout = time(NULL);
-       char *retry;
+       time_t timeout;
 
-       timeout += 60 * 10000;          /* default: 10,000 minutes */
-       retry = po_get(options, "retry");
-       if (retry)
-               timeout += 60 * atoi(retry);
+       timeout = nfs_parse_retry_option(mi->options,
+                                        NFS_DEF_BG_TIMEOUT_MINUTES);
 
        for (;;) {
                if (sleep(secs))
@@ -627,20 +686,19 @@ static int nfsmount_child(const char *spec, const char *node,
                if (secs > 120)
                        secs = 120;
 
-               if (try_mount(spec, node, type, flags, options,
-                                                       fake, extra_opts))
+               if (nfs_try_mount(mi))
                        return EX_SUCCESS;
 
-               if (is_permanent_error(errno))
+               if (nfs_is_permanent_error(errno))
                        break;
 
                if (time(NULL) > timeout)
                        break;
 
-               sys_mount_errors(hostname, errno, 1, 1);
+               sys_mount_errors(mi->hostname, errno, 1, 1);
        };
 
-       sys_mount_errors(hostname, errno, 1, 0);
+       sys_mount_errors(mi->hostname, errno, 1, 0);
        return EX_FAIL;
 }
 
@@ -649,17 +707,28 @@ static int nfsmount_child(const char *spec, const char *node,
  *
  * Returns a valid mount command exit code.
  */
-static int nfsmount_bg(const char *spec, const char *node,
-                         const char *type, char *hostname, int flags,
-                         struct mount_options *options,
-                         int fake, int child, char **extra_opts)
+static int nfsmount_bg(struct nfsmount_info *mi)
 {
-       if (!child)
-               return nfsmount_parent(spec, node, type, hostname, flags,
-                                       options, fake, extra_opts);
+       if (!mi->child)
+               return nfsmount_parent(mi);
        else
-               return nfsmount_child(spec, node, type, hostname, flags,
-                                       options, fake, extra_opts);
+               return nfsmount_child(mi);
+}
+
+/*
+ * Process mount options and try a mount system call.
+ *
+ * Returns a valid mount command exit code.
+ */
+static int nfsmount_start(struct nfsmount_info *mi)
+{
+       if (!nfs_validate_options(mi))
+               return EX_FAIL;
+
+       if (po_rightmost(mi->options, "bg", "fg") == PO_KEY1_RIGHTMOST)
+               return nfsmount_bg(mi);
+       else
+               return nfsmount_fg(mi);
 }
 
 /**
@@ -676,35 +745,29 @@ static int nfsmount_bg(const char *spec, const char *node,
 int nfsmount_string(const char *spec, const char *node, const char *type,
                    int flags, char **extra_opts, int fake, int child)
 {
-       struct mount_options *options = NULL;
-       struct sockaddr_in saddr;
-       char *hostname;
+       struct nfsmount_info mi = {
+               .spec           = spec,
+               .node           = node,
+               .type           = type,
+               .extra_opts     = extra_opts,
+               .flags          = flags,
+               .fake           = fake,
+               .child          = child,
+#ifdef IPV6_SUPPORTED
+               .family         = AF_UNSPEC,    /* either IPv4 or v6 */
+#else
+               .family         = AF_INET,      /* only IPv4 */
+#endif
+       };
        int retval = EX_FAIL;
 
-       if (!parse_devname(spec, &hostname))
-               return retval;
-       if (!fill_ipv4_sockaddr(hostname, &saddr))
-               goto fail;
-
-       options = po_split(*extra_opts);
-       if (!options) {
+       mi.options = po_split(*extra_opts);
+       if (mi.options) {
+               retval = nfsmount_start(&mi);
+               po_destroy(mi.options);
+       } else
                nfs_error(_("%s: internal option parsing error"), progname);
-               goto fail;
-       }
 
-       if (!set_mandatory_options(type, &saddr, options))
-               goto out;
-
-       if (po_rightmost(options, "bg", "fg") == PO_KEY1_RIGHTMOST)
-               retval = nfsmount_bg(spec, node, type, hostname, flags,
-                                       options, fake, child, extra_opts);
-       else
-               retval = nfsmount_fg(spec, node, type, flags, options,
-                                                       fake, extra_opts);
-
-out:
-       po_destroy(options);
-fail:
-       free(hostname);
+       free(mi.hostname);
        return retval;
 }
index b926d688612675d7eec70c67e620994b7f00c0de..b4fd88878d088e30aa0020c5c975092e648a0006 100644 (file)
  *
  */
 
+#ifndef _NFS_UTILS_MOUNT_STROPTS_H
+#define _NFS_UTILS_MOUNT_STROPTS_H
+
 int nfsmount_string(const char *, const char *, const char *, int,
                        char **, int, int);
+
+#endif /* _NFS_UTILS_MOUNT_STROPTS_H */
index 47762dc4d3e5680e347375a0f4c37d7c53c826d9..5a675ed0f62d66ce66c8d61134d4fad241597e5c 100644 (file)
  *
  */
 
+#ifndef _NFS_UTILS_MOUNT_TOKEN_H
+#define _NFS_UTILS_MOUNT_TOKEN_H
+
 struct tokenizer_state;
 
 char *next_token(struct tokenizer_state *);
 struct tokenizer_state *init_tokenizer(char *, char);
 int tokenizer_error(struct tokenizer_state *);
 void end_tokenizer(struct tokenizer_state *);
+
+#endif /* _NFS_UTILS_MOUNT_TOKEN_H */
diff --git a/utils/mount/version.h b/utils/mount/version.h
new file mode 100644 (file)
index 0000000..46552a1
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * version.h -- get running kernel version
+ *
+ * Copyright (C) 2008 Oracle.  All rights reserved.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ */
+
+#ifndef _NFS_UTILS_MOUNT_VERSION_H
+#define _NFS_UTILS_MOUNT_VERSION_H
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/utsname.h>
+
+static inline unsigned int MAKE_VERSION(unsigned int p, unsigned int q,
+                                       unsigned int r)
+{
+       return (65536 * p) + (256 * q) + r;
+}
+
+static inline unsigned int linux_version_code(void)
+{
+       struct utsname my_utsname;
+       unsigned int p, q, r;
+
+       if (uname(&my_utsname))
+               return 0;
+
+       p = atoi(strtok(my_utsname.release, "."));
+       q = atoi(strtok(NULL, "."));
+       r = atoi(strtok(NULL, "."));
+       return MAKE_VERSION(p, q, r);
+}
+
+#endif /* _NFS_UTILS_MOUNT_VERSION_H */
index ef54e76fee45c75188c1bfbd346a7d152c581dae..a5e76779b0a0fcb6606c6a77f07ac51b042169c0 100644 (file)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -60,7 +60,7 @@ mountd_DEPENDENCIES = ../../support/export/libexport.a \
        ../../support/nfs/libnfs.a ../../support/misc/libmisc.a \
        $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
        $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
-DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -193,6 +193,7 @@ datarootdir = @datarootdir@
 docdir = @docdir@
 dvidir = @dvidir@
 enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
 enable_nfsv3 = @enable_nfsv3@
 enable_nfsv4 = @enable_nfsv4@
 exec_prefix = @exec_prefix@
@@ -287,8 +288,8 @@ install-sbinPROGRAMS: $(sbin_PROGRAMS)
             || test -f $$p1 \
          ; then \
            f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
-          echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
-          $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \
+          echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
+          $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \
          else :; fi; \
        done
 
@@ -499,8 +500,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        mkid -fID $$unique
 tags: TAGS
 
@@ -512,8 +513,8 @@ TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
          test -n "$$unique" || unique=$$empty_fix; \
          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -523,13 +524,12 @@ ctags: CTAGS
 CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
                $(TAGS_FILES) $(LISP)
        tags=; \
-       here=`pwd`; \
        list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        test -z "$(CTAGS_ARGS)$$tags$$unique" \
          || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
             $$tags $$unique
index 63d5ce1797edd65e01f5d38819377ab4d5eb2ae8..8137f7f7329f40d1cbab352c23ff311e34acee06 100644 (file)
@@ -342,7 +342,14 @@ mount_mnt_3_svc(struct svc_req *rqstp, dirpath *path, mountres3 *res)
 #define AUTH_GSS_KRB5 390003
 #define AUTH_GSS_KRB5I 390004
 #define AUTH_GSS_KRB5P 390005
-       static int      flavors[] = { AUTH_NULL, AUTH_UNIX, AUTH_GSS_KRB5, AUTH_GSS_KRB5I, AUTH_GSS_KRB5P};
+       static int      flavors[] = { AUTH_UNIX, AUTH_GSS_KRB5, AUTH_GSS_KRB5I, AUTH_GSS_KRB5P};
+       /*
+        * We should advertise the preferred flavours first. (See RFC 2623
+        * section 2.7.) AUTH_UNIX is arbitrarily ranked over the GSS's.
+        * AUTH_NULL is dropped from the list to avoid backward compatibility
+        * issue with older Linux clients, who inspect the list in reversed
+        * order.
+        */
        struct nfs_fh_len *fh;
 
        xlog(D_CALL, "MNT3(%s) called", *path);
index abb03e4f883ca7434292885a7bb277327b5eb995..37183fdebae8ef46b1f9cbd43a889487b5527799 100644 (file)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -54,7 +54,7 @@ am_nfsd_OBJECTS = nfsd.$(OBJEXT)
 nfsd_OBJECTS = $(am_nfsd_OBJECTS)
 nfsd_DEPENDENCIES = ../../support/export/libexport.a \
        ../../support/nfs/libnfs.a ../../support/misc/libmisc.a
-DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -187,6 +187,7 @@ datarootdir = @datarootdir@
 docdir = @docdir@
 dvidir = @dvidir@
 enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
 enable_nfsv3 = @enable_nfsv3@
 enable_nfsv4 = @enable_nfsv4@
 exec_prefix = @exec_prefix@
@@ -274,8 +275,8 @@ install-sbinPROGRAMS: $(sbin_PROGRAMS)
             || test -f $$p1 \
          ; then \
            f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
-          echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
-          $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \
+          echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
+          $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \
          else :; fi; \
        done
 
@@ -382,8 +383,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        mkid -fID $$unique
 tags: TAGS
 
@@ -395,8 +396,8 @@ TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
          test -n "$$unique" || unique=$$empty_fix; \
          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -406,13 +407,12 @@ ctags: CTAGS
 CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
                $(TAGS_FILES) $(LISP)
        tags=; \
-       here=`pwd`; \
        list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        test -z "$(CTAGS_ARGS)$$tags$$unique" \
          || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
             $$tags $$unique
index 0da76b4677c9499de6f6845f0da9e83a8c319927..1cfccb03b09caf3d153c74f7bd38e49927947485 100644 (file)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -54,7 +54,7 @@ am_nfsstat_OBJECTS = nfsstat.$(OBJEXT)
 nfsstat_OBJECTS = $(am_nfsstat_OBJECTS)
 nfsstat_DEPENDENCIES = ../../support/export/libexport.a \
        ../../support/nfs/libnfs.a ../../support/misc/libmisc.a
-DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -187,6 +187,7 @@ datarootdir = @datarootdir@
 docdir = @docdir@
 dvidir = @dvidir@
 enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
 enable_nfsv3 = @enable_nfsv3@
 enable_nfsv4 = @enable_nfsv4@
 exec_prefix = @exec_prefix@
@@ -272,8 +273,8 @@ install-sbinPROGRAMS: $(sbin_PROGRAMS)
             || test -f $$p1 \
          ; then \
            f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
-          echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
-          $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \
+          echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
+          $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \
          else :; fi; \
        done
 
@@ -380,8 +381,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        mkid -fID $$unique
 tags: TAGS
 
@@ -393,8 +394,8 @@ TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
          test -n "$$unique" || unique=$$empty_fix; \
          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -404,13 +405,12 @@ ctags: CTAGS
 CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
                $(TAGS_FILES) $(LISP)
        tags=; \
-       here=`pwd`; \
        list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        test -z "$(CTAGS_ARGS)$$tags$$unique" \
          || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
             $$tags $$unique
index aa6c961cefdae65ae7012c43a41865aa1ba04ea9..1517414fa0e596bcab9b5c4e3ff46bfc6c49ceb3 100644 (file)
@@ -539,7 +539,7 @@ print_numbers(const char *hdr, unsigned int *info, unsigned int nr)
 
        fputs(hdr, stdout);
        for (i = 0; i < nr; i++)
-               printf("%s%-8d", i? "   " : "", info[i]);
+               printf("%s%-8u", i? "   " : "", info[i]);
        printf("\n");
 }
 
@@ -562,7 +562,7 @@ print_callstats(const char *hdr, const char **names,
                printf("\n");
                for (j = 0; j < 6 && i + j < nr; j++) {
                        pct = ((unsigned long long) info[i+j]*100)/total;
-                       printf("%-8d%3llu%% ", info[i+j], pct);
+                       printf("%-8u%3llu%% ", info[i+j], pct);
                }
                printf("\n");
        }
@@ -604,7 +604,7 @@ parse_raw_statfile(const char *name, struct statinfo *statp)
                for (i = 0; i < cnt; i++) {
                        if (!(sp = strtok(NULL, " \t")))
                                break;
-                       ip->valptr[i] = atoi(sp);
+                       ip->valptr[i] = (unsigned int) strtoul(sp, NULL, 0);
                        total += ip->valptr[i];
                }
                ip->valptr[cnt - 1] = total;
@@ -618,7 +618,8 @@ parse_raw_statfile(const char *name, struct statinfo *statp)
 static int
 parse_pretty_statfile(const char *filename, struct statinfo *info)
 {
-       int numvals, curindex, numconsumed, n, sum, err = 1;
+       int numvals, curindex, numconsumed, n, err = 1;
+       unsigned int sum;
        char buf[4096], *bufp, *fmt, is_proc;
        FILE *fp = NULL;
        struct statinfo *ip;
@@ -716,7 +717,7 @@ mounts(const char *name)
                if (!(type = strtok(NULL, " \t")))
                        continue;
 
-               if (strcmp(type, "nfs")) {
+               if (strcmp(type, "nfs") && strcmp(type,"nfs4")) {
                    continue;
                }
 
index b5b572554510da942ea1a45d6f200012de483225..557b07f8aa89949154eea273d58c4890e7163478 100644 (file)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -54,7 +54,7 @@ am_showmount_OBJECTS = showmount-showmount.$(OBJEXT)
 showmount_OBJECTS = $(am_showmount_OBJECTS)
 showmount_DEPENDENCIES = ../../support/export/libexport.a \
        ../../support/nfs/libnfs.a ../../support/misc/libmisc.a
-DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -187,6 +187,7 @@ datarootdir = @datarootdir@
 docdir = @docdir@
 dvidir = @dvidir@
 enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
 enable_nfsv3 = @enable_nfsv3@
 enable_nfsv4 = @enable_nfsv4@
 exec_prefix = @exec_prefix@
@@ -275,8 +276,8 @@ install-sbinPROGRAMS: $(sbin_PROGRAMS)
             || test -f $$p1 \
          ; then \
            f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
-          echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
-          $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \
+          echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
+          $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \
          else :; fi; \
        done
 
@@ -397,8 +398,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        mkid -fID $$unique
 tags: TAGS
 
@@ -410,8 +411,8 @@ TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
          test -n "$$unique" || unique=$$empty_fix; \
          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -421,13 +422,12 @@ ctags: CTAGS
 CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
                $(TAGS_FILES) $(LISP)
        tags=; \
-       here=`pwd`; \
        list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        test -z "$(CTAGS_ARGS)$$tags$$unique" \
          || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
             $$tags $$unique
index 4e10a292846c50610ab636e2b2c6e618ec66d95b..213a573613c3215314e71543e9d762ad012f8f30 100644 (file)
@@ -82,6 +82,8 @@ static void usage(FILE *fp, int n)
  *
  *  tout contains the timeout.  It will be modified to contain the time
  *  remaining (i.e. time provided - time elasped).
+ *
+ *  Returns 0 for success 
  */
 static int connect_nb(int fd, struct sockaddr_in *addr, struct timeval *tout)
 {
@@ -177,7 +179,7 @@ static unsigned short getport(struct sockaddr_in *addr,
                tout.tv_sec = TIMEOUT_TCP;
 
                ret = connect_nb(sock, &saddr, &tout);
-               if (ret == -1) {
+               if (ret < 0) {
                        close(sock);
                        rpc_createerr.cf_stat = RPC_SYSTEMERROR;
                        rpc_createerr.cf_error.re_errno = errno;
@@ -240,6 +242,8 @@ static unsigned short getport(struct sockaddr_in *addr,
                rpc_createerr.cf_stat = status;
                clnt_destroy(client);
                return 0;
+       } else if (port == 0) {
+               rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
        }
 
        clnt_destroy(client);
@@ -350,7 +354,7 @@ int main(int argc, char **argv)
                                         MOUNTPROG, MOUNTVERS, IPPROTO_TCP);
                if (server_addr.sin_port) {
                        ret = connect_nb(msock, &server_addr, 0);
-                       if (ret != -1)
+                       if (ret == 0) /* success */
                                mclient = clnttcp_create(&server_addr,
                                                MOUNTPROG, MOUNTVERS, &msock,
                                                0, 0);
@@ -364,7 +368,7 @@ int main(int argc, char **argv)
                server_addr.sin_port = getport(&server_addr,
                                         MOUNTPROG, MOUNTVERS, IPPROTO_UDP);
                if (!server_addr.sin_port) {
-                       clnt_pcreateerror("portmap getport");
+                       clnt_pcreateerror("showmount");
                        exit(1);
                }
                msock = RPC_ANYSOCK;
index 7e190a820a69ad60914f4b75d8f71c5f3d37e3dc..3467931299040cc94d1095bbbc38a80c75e5dada 100644 (file)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -68,7 +68,7 @@ statd_DEPENDENCIES = ../../support/export/libexport.a \
        $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
 dist_sbinSCRIPT_INSTALL = $(INSTALL_SCRIPT)
 SCRIPTS = $(dist_sbin_SCRIPTS)
-DEFAULT_INCLUDES = -I. -I$(top_builddir)/support/include@am__isrc@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/support/include
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -201,6 +201,7 @@ datarootdir = @datarootdir@
 docdir = @docdir@
 dvidir = @dvidir@
 enable_gss = @enable_gss@
+enable_ipv6 = @enable_ipv6@
 enable_nfsv3 = @enable_nfsv3@
 enable_nfsv4 = @enable_nfsv4@
 exec_prefix = @exec_prefix@
@@ -306,8 +307,8 @@ install-sbinPROGRAMS: $(sbin_PROGRAMS)
             || test -f $$p1 \
          ; then \
            f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
-          echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
-          $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \
+          echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
+          $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \
          else :; fi; \
        done
 
@@ -449,8 +450,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        mkid -fID $$unique
 tags: TAGS
 
@@ -462,8 +463,8 @@ TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
          test -n "$$unique" || unique=$$empty_fix; \
          $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -473,13 +474,12 @@ ctags: CTAGS
 CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
                $(TAGS_FILES) $(LISP)
        tags=; \
-       here=`pwd`; \
        list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
        unique=`for i in $$list; do \
            if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
          done | \
-         $(AWK) '    { files[$$0] = 1; } \
-              END { for (i in files) print i; }'`; \
+         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+             END { if (nonempty) { for (i in files) print i; }; }'`; \
        test -z "$(CTAGS_ARGS)$$tags$$unique" \
          || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
             $$tags $$unique
index bb67c378e94839254bbb49ec093bef71dda11317..b75f11b365c317a8f4638b6bf4574ab602be86bf 100644 (file)
@@ -24,6 +24,8 @@
 #include <errno.h>
 #include <grp.h>
 
+#include "config.h"
+
 #ifndef BASEDIR
 # ifdef NFS_STATEDIR
 #  define BASEDIR              NFS_STATEDIR
@@ -76,7 +78,7 @@ static int            log_syslog = 0;
 
 static unsigned int    nsm_get_state(int);
 static void            notify(void);
-static void            notify_host(int, struct nsm_host *);
+static int             notify_host(int, struct nsm_host *);
 static void            recv_reply(int);
 static void            backup_hosts(const char *, const char *);
 static void            get_hosts(const char *);
@@ -277,7 +279,7 @@ notify(void)
                if (failtime && now >= failtime)
                        break;
 
-               while ((wait = hosts->send_next - now) <= 0) {
+               while (hosts && ((wait = hosts->send_next - now) <= 0)) {
                        /* Never send more than 10 packets at once */
                        if (sent++ >= 10)
                                break;
@@ -286,7 +288,13 @@ notify(void)
                        hp = hosts;
                        hosts = hp->next;
 
-                       notify_host(sock, hp);
+                       if (notify_host(sock, hp)){
+                               unlink(hp->path);
+                               free(hp->name);
+                               free(hp->path);
+                               free(hp);
+                               continue;
+                       }
 
                        /* Set the timeout for this call, using an
                           exponential timeout strategy */
@@ -298,6 +306,8 @@ notify(void)
 
                        insert_host(hp);
                }
+               if (hosts == NULL)
+                       return;
 
                nsm_log(LOG_DEBUG, "Host %s due in %ld seconds",
                                hosts->name, wait);
@@ -318,7 +328,7 @@ notify(void)
 /*
  * Send notification to a single host
  */
-void
+int
 notify_host(int sock, struct nsm_host *host)
 {
        static unsigned int     xid = 0;
@@ -331,6 +341,16 @@ notify_host(int sock, struct nsm_host *host)
        if (!host->xid)
                host->xid = xid++;
 
+       if (host->ai == NULL) {
+               host->ai = host_lookup(AF_UNSPEC, host->name);
+               if (host->ai == NULL) {
+                       nsm_log(LOG_WARNING,
+                               "%s doesn't seem to be a valid address,"
+                               " skipped", host->name);
+                       return 1;
+               }
+       }
+
        memset(msgbuf, 0, sizeof(msgbuf));
        p = msgbuf;
        *p++ = htonl(host->xid);
@@ -343,14 +363,19 @@ notify_host(int sock, struct nsm_host *host)
         * point.
         */
        if (host->retries >= 4) {
-               struct addrinfo *hold = host->ai;
+               struct addrinfo *first = host->ai;
                struct addrinfo **next = &host->ai;
-               *next = hold->ai_next;
+
+               /* remove the first entry from the list */
+               host->ai = first->ai_next;
+               first->ai_next = NULL;
+               /* find the end of the list */
+               next = &first->ai_next;
                while ( *next )
                        next = & (*next)->ai_next;
-               *next = hold;
-               hold->ai_next = NULL;
-               memcpy(&host->addr, hold->ai_addr, hold->ai_addrlen);
+               /* put first entry at end */
+               *next = first;
+               memcpy(&host->addr, first->ai_addr, first->ai_addrlen);
                addr_set_port(&host->addr, 0);
                host->retries = 0;
        }
@@ -394,7 +419,11 @@ notify_host(int sock, struct nsm_host *host)
        }
        len = (p - msgbuf) << 2;
 
-       sendto(sock, msgbuf, len, 0, (struct sockaddr *) &dest, sizeof(dest));
+       if (sendto(sock, msgbuf, len, 0, (struct sockaddr *) &dest, sizeof(dest)) < 0)
+               nsm_log(LOG_WARNING, "Sending Reboot Notification to "
+                       "'%s' failed: errno %d (%s)", host->name, errno, strerror(errno));
+       
+       return 0;
 }
 
 /*
@@ -504,7 +533,7 @@ backup_hosts(const char *dirname, const char *bakname)
 }
 
 /*
- * Get all entries from sm.bak and convert them to host names
+ * Get all entries from sm.bak and convert them to host entries
  */
 static void
 get_hosts(const char *dirname)
@@ -532,15 +561,6 @@ get_hosts(const char *dirname)
                if (stat(path, &stb) < 0)
                        continue;
 
-               host->ai = host_lookup(AF_UNSPEC, de->d_name);
-               if (! host->ai) {
-                       nsm_log(LOG_WARNING,
-                               "%s doesn't seem to be a valid address, skipped",
-                               de->d_name);
-                       unlink(path);
-                       continue;
-               }
-
                host->last_used = stb.st_mtime;
                host->timeout = NSM_TIMEOUT;
                host->path = strdup(path);