From: Andres Mejia Date: Sun, 8 Jan 2012 18:14:01 +0000 (-0500) Subject: Imported Upstream version 1.2.0 X-Git-Tag: upstream/1.2.0 X-Git-Url: https://git.piment-noir.org/?a=commitdiff_plain;h=49b485c41340affac3ea4887ea60c1cf00f1af94;p=deb_libnfs.git Imported Upstream version 1.2.0 --- diff --git a/Makefile.am b/Makefile.am index 653060d..03e4419 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,2 +1,7 @@ SUBDIRS = mount nfs portmap rquota lib include . $(MAYBE_EXAMPLES) +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libnfs.pc + +EXTRA_DIST = README COPYING libnfs.pc.in + diff --git a/Makefile.in b/Makefile.in index aac9bc2..05d99a7 100644 --- a/Makefile.in +++ b/Makefile.in @@ -14,6 +14,7 @@ # PARTICULAR PURPOSE. @SET_MAKE@ + VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ @@ -36,8 +37,8 @@ host_triplet = @host@ subdir = . DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/config.h.in \ - $(top_srcdir)/configure COPYING compile config.guess \ - config.sub depcomp install-sh ltmain.sh missing + $(srcdir)/libnfs.pc.in $(top_srcdir)/configure COPYING compile \ + config.guess config.sub depcomp install-sh ltmain.sh missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ @@ -46,7 +47,7 @@ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h -CONFIG_CLEAN_FILES = +CONFIG_CLEAN_FILES = libnfs.pc CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = @@ -57,6 +58,29 @@ RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(pkgconfigdir)" +DATA = $(pkgconfig_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ @@ -134,6 +158,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBNFS_PC_REQ_PRIVATE = @LIBNFS_PC_REQ_PRIVATE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ @@ -158,12 +183,17 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RPCGENFLAGS = @RPCGENFLAGS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +TIRPC_CFLAGS = @TIRPC_CFLAGS@ +TIRPC_LIBS = @TIRPC_LIBS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ @@ -218,6 +248,9 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = mount nfs portmap rquota lib include . $(MAYBE_EXAMPLES) +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libnfs.pc +EXTRA_DIST = README COPYING libnfs.pc.in all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive @@ -273,6 +306,8 @@ $(srcdir)/config.h.in: $(am__configure_deps) distclean-hdr: -rm -f config.h stamp-h1 +libnfs.pc: $(top_builddir)/config.status $(srcdir)/libnfs.pc.in + cd $(top_builddir) && $(SHELL) ./config.status $@ mostlyclean-libtool: -rm -f *.lo @@ -282,6 +317,26 @@ clean-libtool: distclean-libtool: -rm -f libtool config.lt +install-pkgconfigDATA: $(pkgconfig_DATA) + @$(NORMAL_INSTALL) + test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ + done + +uninstall-pkgconfigDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(pkgconfigdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(pkgconfigdir)" && rm -f $$files # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. @@ -595,9 +650,12 @@ distcleancheck: distclean exit 1; } >&2 check-am: all-am check: check-recursive -all-am: Makefile config.h +all-am: Makefile $(DATA) config.h installdirs: installdirs-recursive installdirs-am: + for dir in "$(DESTDIR)$(pkgconfigdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive @@ -645,7 +703,7 @@ info: info-recursive info-am: -install-data-am: +install-data-am: install-pkgconfigDATA install-dvi: install-dvi-recursive @@ -691,7 +749,7 @@ ps: ps-recursive ps-am: -uninstall-am: +uninstall-am: uninstall-pkgconfigDATA .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \ ctags-recursive install-am install-strip tags-recursive @@ -706,11 +764,12 @@ uninstall-am: install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - installdirs-am maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ - ps ps-am tags tags-recursive uninstall uninstall-am + install-pdf install-pdf-am install-pkgconfigDATA install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am uninstall-pkgconfigDATA # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/README b/README index cab6aa6..24b1f00 100644 --- a/README +++ b/README @@ -35,6 +35,19 @@ ports from connecting. These servers require you use the "insecure" export option in /etc/exports in order to allow libnfs clients to be able to connect. +Some versions of Linux support special capabilities that can be assigned to +programs to allow non-root users to bind to system ports. +This is set up by running + sudo setcap 'cap_net_bind_service=+ep' /path/to/executable +When libnfs is linked against an executable with this special capability +assigned to it, libnfs may be able to use system ports even when executing +under the privilege of a non-root user account. + +This is highly non-portable so IF this works on your linux system, count +yourself lucky. + + + PLATFORM support ================= As of now this is tested with linux, MacOSX and Apple iOS. @@ -44,6 +57,8 @@ Cygwin: - tested under 64bit win2k8. MacOSX: - tested with SDK 10.4 (under Snow Leopard) - should also work with later SDKs and 64Bit iOS: - tested with iOS SDK 4.2 - running on iOS 4.3.x FreeBSD:- tested with 8.2 +OpenSolaris +Windows:- tested on Windows 7 64 and Windows XP 32 using Visual Studio 10 (see README.win32.txt for build instructions) Cygwin diff --git a/README.win32.txt b/README.win32.txt new file mode 100644 index 0000000..298045e --- /dev/null +++ b/README.win32.txt @@ -0,0 +1,10 @@ +LibNFS requires a oncrpc library and rpcgen compiler that can handle +64 bit types. Link below for one such package, but any 64bit capable oncrpc +package should work with some effort. + + +1. checkout git://github.com/Memphiz/oncrpc-win32.git project (branch hyper!) +2. build oncrpc-win32 project (see README.libnfs in the projects dir) +3. checkout libnfs ("parallel" to oncrpc-win32) +4. load vs2010 project from win32/libnfs/libnfs.sln +5. build libnfs and nfsclient-sync diff --git a/aclocal.m4 b/aclocal.m4 index 1ccfa05..372d649 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -22,8 +22,8 @@ To do so, use the procedure documented by the package, typically `autoreconf'.]) # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008, 2009, 2010 Free Software Foundation, -# Inc. +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives @@ -32,8 +32,8 @@ To do so, use the procedure documented by the package, typically `autoreconf'.]) m4_define([_LT_COPYING], [dnl # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008, 2009, 2010 Free Software Foundation, -# Inc. +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. @@ -167,6 +167,8 @@ AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl +_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl +dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl @@ -652,7 +654,7 @@ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. -Copyright (C) 2010 Free Software Foundation, Inc. +Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." @@ -816,6 +818,7 @@ AC_DEFUN([LT_LANG], m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], + [Go], [_LT_LANG(GO)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], @@ -837,6 +840,29 @@ m4_defun([_LT_LANG], ])# _LT_LANG +m4_ifndef([AC_PROG_GO], [ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_GO. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +m4_defun([AC_PROG_GO], +[AC_LANG_PUSH(Go)dnl +AC_ARG_VAR([GOC], [Go compiler command])dnl +AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl +_AC_ARG_VAR_LDFLAGS()dnl +AC_CHECK_TOOL(GOC, gccgo) +if test -z "$GOC"; then + if test -n "$ac_tool_prefix"; then + AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) + fi +fi +if test -z "$GOC"; then + AC_CHECK_PROG(GOC, gccgo, gccgo, false) +fi +])#m4_defun +])#m4_ifndef + + # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], @@ -867,6 +893,10 @@ AC_PROVIDE_IFELSE([AC_PROG_GCJ], m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) +AC_PROVIDE_IFELSE([AC_PROG_GO], + [LT_LANG(GO)], + [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) + AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) @@ -969,7 +999,13 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? - if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test $_lt_result -eq 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD @@ -977,6 +1013,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ rm -rf libconftest.dylib* rm -f conftest.* fi]) + AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no @@ -988,6 +1025,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ [lt_cv_ld_exported_symbols_list=no]) LDFLAGS="$save_LDFLAGS" ]) + AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF @@ -1005,7 +1043,9 @@ _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? - if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD @@ -1050,8 +1090,8 @@ _LT_EOF ]) -# _LT_DARWIN_LINKER_FEATURES -# -------------------------- +# _LT_DARWIN_LINKER_FEATURES([TAG]) +# --------------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ @@ -1062,6 +1102,8 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES], _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test "$lt_cv_ld_force_load" = "yes"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], + [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi @@ -1345,14 +1387,27 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) CFLAGS="$SAVE_CFLAGS" fi ;; -sparc*-*solaris*) +*-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in - yes*) LD="${LD-ld} -m elf64_sparc" ;; + yes*) + case $host in + i?86-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD="${LD-ld}_sol2" + fi + ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" @@ -1429,13 +1484,13 @@ old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac - old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in @@ -1615,6 +1670,11 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl lt_cv_sys_max_cmd_len=196608 ;; + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not @@ -1654,7 +1714,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. - while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \ + while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do @@ -2200,7 +2260,7 @@ need_version=unknown case $host_os in aix3*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH @@ -2209,7 +2269,7 @@ aix3*) ;; aix[[4-9]]*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes @@ -2274,7 +2334,7 @@ beos*) ;; bsdi[[45]]*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' @@ -2413,7 +2473,7 @@ m4_if([$1], [],[ ;; dgux*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' @@ -2421,10 +2481,6 @@ dgux*) shlibpath_var=LD_LIBRARY_PATH ;; -freebsd1*) - dynamic_linker=no - ;; - freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. @@ -2432,7 +2488,7 @@ freebsd* | dragonfly*) objformat=`/usr/bin/objformat` else case $host_os in - freebsd[[123]]*) objformat=aout ;; + freebsd[[23]].*) objformat=aout ;; *) objformat=elf ;; esac fi @@ -2450,7 +2506,7 @@ freebsd* | dragonfly*) esac shlibpath_var=LD_LIBRARY_PATH case $host_os in - freebsd2*) + freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) @@ -2470,7 +2526,7 @@ freebsd* | dragonfly*) ;; gnu*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' @@ -2481,7 +2537,7 @@ gnu*) ;; haiku*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" @@ -2542,7 +2598,7 @@ hpux9* | hpux10* | hpux11*) ;; interix[[3-9]]*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' @@ -2558,7 +2614,7 @@ irix5* | irix6* | nonstopux*) nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; @@ -2595,9 +2651,9 @@ linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; -# This must be Linux ELF. +# This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -2672,7 +2728,7 @@ netbsd*) ;; newsos6) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes @@ -2741,7 +2797,7 @@ rdos*) ;; solaris*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -2766,7 +2822,7 @@ sunos4*) ;; sysv4 | sysv4.3*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH @@ -2790,7 +2846,7 @@ sysv4 | sysv4.3*) sysv4*MP*) if test -d /usr/nec ;then - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH @@ -2821,7 +2877,7 @@ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -2831,7 +2887,7 @@ tpf*) ;; uts4*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH @@ -3253,7 +3309,7 @@ irix5* | irix6* | nonstopux*) lt_cv_deplibs_check_method=pass_all ;; -# This must be Linux ELF. +# This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) lt_cv_deplibs_check_method=pass_all ;; @@ -3673,6 +3729,7 @@ for ac_symprfx in "" "_"; do # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ @@ -4257,7 +4314,9 @@ m4_if([$1], [CXX], [ case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Xcompiler -fPIC' + if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" + fi ;; esac else @@ -4349,18 +4408,33 @@ m4_if([$1], [CXX], [ ;; *) case `$CC -V 2>&1 | sed 5q` in - *Sun\ F* | *Sun*Fortran*) + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; + *Sun\ F* | *Sun*Fortran*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; + *Intel*\ [[CF]]*Compiler*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + *Portland\ Group*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; esac ;; esac @@ -4520,7 +4594,9 @@ m4_if([$1], [CXX], [ ;; cygwin* | mingw* | cegcc*) case $cc_basename in - cl*) ;; + cl*) + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] @@ -4548,7 +4624,6 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported @@ -4802,8 +4877,7 @@ _LT_EOF xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ @@ -5099,6 +5173,7 @@ _LT_EOF # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' @@ -5145,10 +5220,6 @@ _LT_EOF _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; - freebsd1*) - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little @@ -5161,7 +5232,7 @@ _LT_EOF ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2*) + freebsd2.*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes @@ -5200,7 +5271,6 @@ _LT_EOF fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes @@ -5642,9 +5712,6 @@ _LT_TAGDECL([], [no_undefined_flag], [1], _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) -_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1], - [[If ld is used when linking, flag to hardcode $libdir into a binary - during linking. This must work even if $libdir does not exist]]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], @@ -5798,7 +5865,6 @@ _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported @@ -6168,7 +6234,7 @@ if test "$_lt_caught_CXX_error" != yes; then esac ;; - freebsd[[12]]*) + freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no @@ -6929,12 +6995,18 @@ public class foo { } }; _LT_EOF +], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF +package foo +func foo() { +} +_LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac dnl Parse the compiler output and extract the necessary @@ -7131,7 +7203,6 @@ _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no @@ -7264,7 +7335,6 @@ _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no @@ -7447,6 +7517,73 @@ CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG +# _LT_LANG_GO_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Go compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_GO_CONFIG], +[AC_REQUIRE([LT_PROG_GO])dnl +AC_LANG_SAVE + +# Source file extension for Go test sources. +ac_ext=go + +# Object file extension for compiled Go test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="package main; func main() { }" + +# Code to be used in simple link tests +lt_simple_link_test_code='package main; func main() { }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GOC-"gccgo"} +CFLAGS=$GOFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)="$LD" +_LT_CC_BASENAME([$compiler]) + +# Go did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GO_CONFIG + + # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler @@ -7516,6 +7653,13 @@ dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) +# LT_PROG_GO +# ---------- +AC_DEFUN([LT_PROG_GO], +[AC_CHECK_TOOL(GOC, gccgo,) +]) + + # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], @@ -8180,9 +8324,24 @@ dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # MODE is either `yes' or `no'. If omitted, it defaults to `both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], - [AS_HELP_STRING([--with-pic], + [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], - [pic_mode="$withval"], + [lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for lt_pkg in $withval; do + IFS="$lt_save_ifs" + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], [pic_mode=default]) test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) @@ -8354,15 +8513,15 @@ m4_define([lt_dict_filter], # @configure_input@ -# serial 3293 ltversion.m4 +# serial 3337 ltversion.m4 # This file is part of GNU Libtool -m4_define([LT_PACKAGE_VERSION], [2.4]) -m4_define([LT_PACKAGE_REVISION], [1.3293]) +m4_define([LT_PACKAGE_VERSION], [2.4.2]) +m4_define([LT_PACKAGE_REVISION], [1.3337]) AC_DEFUN([LTVERSION_VERSION], -[macro_version='2.4' -macro_revision='1.3293' +[macro_version='2.4.2' +macro_revision='1.3337' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) @@ -8466,6 +8625,166 @@ m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# serial 1 (pkg-config-0.24) +# +# Copyright © 2004 Scott James Remnant . +# +# 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 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# PKG_PROG_PKG_CONFIG([MIN-VERSION]) +# ---------------------------------- +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) +m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) +AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) +AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi +fi[]dnl +])# PKG_PROG_PKG_CONFIG + +# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# +# Check to see whether a particular set of modules exists. Similar +# to PKG_CHECK_MODULES(), but does not set variables or print errors. +# +# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +# only at the first occurence in configure.ac, so if the first place +# it's called might be skipped (such as if it is within an "if", you +# have to call PKG_CHECK_EXISTS manually +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_default([$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + +# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +# --------------------------------------------- +m4_define([_PKG_CONFIG], +[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` + test "x$?" != "x0" && pkg_failed=yes ], + [pkg_failed=yes]) + else + pkg_failed=untried +fi[]dnl +])# _PKG_CONFIG + +# _PKG_SHORT_ERRORS_SUPPORTED +# ----------------------------- +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])# _PKG_SHORT_ERRORS_SUPPORTED + + +# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +# [ACTION-IF-NOT-FOUND]) +# +# +# Note that if there is a possibility the first call to +# PKG_CHECK_MODULES might not happen, you should be sure to include an +# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +# +# +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $1]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + AC_MSG_RESULT([no]) + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + m4_default([$4], [AC_MSG_ERROR( +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT])[]dnl + ]) +elif test $pkg_failed = untried; then + AC_MSG_RESULT([no]) + m4_default([$4], [AC_MSG_FAILURE( +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see .])[]dnl + ]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + $3 +fi[]dnl +])# PKG_CHECK_MODULES + # Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation diff --git a/config.h.in b/config.h.in index f064e03..54e6804 100644 --- a/config.h.in +++ b/config.h.in @@ -33,6 +33,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_FILIO_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKIO_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H diff --git a/configure b/configure index efa3b78..5088b42 100755 --- a/configure +++ b/configure @@ -1,6 +1,8 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for libnfs 0.0.0. +# Generated by GNU Autoconf 2.68 for libnfs 1.2.0. +# +# Report bugs to . # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -244,10 +246,11 @@ fi $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else - $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, -$0: including any error possibly output before this -$0: message. Then install a modern shell, or manually run -$0: the script under such a shell if you do have one." + $as_echo "$0: Please tell bug-autoconf@gnu.org and +$0: ronniesahlberg@gmail.com about your system, including +$0: any error possibly output before this message. Then +$0: install a modern shell, or manually run the script +$0: under such a shell if you do have one." fi exit 1 fi @@ -567,9 +570,9 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='libnfs' PACKAGE_TARNAME='libnfs' -PACKAGE_VERSION='0.0.0' -PACKAGE_STRING='libnfs 0.0.0' -PACKAGE_BUGREPORT='' +PACKAGE_VERSION='1.2.0' +PACKAGE_STRING='libnfs 1.2.0' +PACKAGE_BUGREPORT='ronniesahlberg@gmail.com' PACKAGE_URL='' # Factoring default headers for most tests. @@ -612,9 +615,15 @@ ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS +LIBNFS_PC_REQ_PRIVATE +TIRPC_LIBS +TIRPC_CFLAGS RPCGENFLAGS MAYBE_EXAMPLES HAVE_RPCGEN +PKG_CONFIG_LIBDIR +PKG_CONFIG_PATH +PKG_CONFIG CPP OTOOL64 OTOOL @@ -744,7 +753,12 @@ CFLAGS LDFLAGS LIBS CPPFLAGS -CPP' +CPP +PKG_CONFIG +PKG_CONFIG_PATH +PKG_CONFIG_LIBDIR +TIRPC_CFLAGS +TIRPC_LIBS' # Initialize some variables set by options. @@ -1287,7 +1301,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 libnfs 0.0.0 to adapt to many kinds of systems. +\`configure' configures libnfs 1.2.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1357,7 +1371,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of libnfs 0.0.0:";; + short | recursive ) echo "Configuration of libnfs 1.2.0:";; esac cat <<\_ACEOF @@ -1378,7 +1392,7 @@ Optional Features: Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-pic try to use only PIC/non-PIC objects [default=use + --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot=DIR Search for dependent libraries within DIR @@ -1393,11 +1407,19 @@ Some influential environment variables: CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor + PKG_CONFIG path to pkg-config utility + PKG_CONFIG_PATH + directories to add to pkg-config's search path + PKG_CONFIG_LIBDIR + path overriding pkg-config's built-in search path + TIRPC_CFLAGS + C compiler flags for TIRPC, overriding pkg-config + TIRPC_LIBS linker flags for TIRPC, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. -Report bugs to the package provider. +Report bugs to . _ACEOF ac_status=$? fi @@ -1460,7 +1482,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -libnfs configure 0.0.0 +libnfs configure 1.2.0 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1805,6 +1827,10 @@ $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( $as_echo "## --------------------------------------- ## +## Report this to ronniesahlberg@gmail.com ## +## --------------------------------------- ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 @@ -1882,7 +1908,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 libnfs $as_me 0.0.0, which was +It was created by libnfs $as_me 1.2.0, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2699,7 +2725,7 @@ fi # Define the identity of the package. PACKAGE='libnfs' - VERSION='0.0.0' + VERSION='1.2.0' cat >>confdefs.h <<_ACEOF @@ -3801,8 +3827,8 @@ esac -macro_version='2.4' -macro_revision='1.3293' +macro_version='2.4.2' +macro_revision='1.3337' @@ -4576,6 +4602,11 @@ else lt_cv_sys_max_cmd_len=196608 ;; + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not @@ -4615,7 +4646,7 @@ else # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. - while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \ + while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do @@ -5044,7 +5075,7 @@ irix5* | irix6* | nonstopux*) lt_cv_deplibs_check_method=pass_all ;; -# This must be Linux ELF. +# This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) lt_cv_deplibs_check_method=pass_all ;; @@ -5685,13 +5716,13 @@ old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac - old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in @@ -5838,6 +5869,7 @@ for ac_symprfx in "" "_"; do # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ @@ -6226,7 +6258,7 @@ $as_echo "$lt_cv_cc_needs_belf" >&6; } CFLAGS="$SAVE_CFLAGS" fi ;; -sparc*-*solaris*) +*-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 @@ -6237,7 +6269,20 @@ sparc*-*solaris*) case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in - yes*) LD="${LD-ld} -m elf64_sparc" ;; + yes*) + case $host in + i?86-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD="${LD-ld}_sol2" + fi + ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" @@ -6877,7 +6922,13 @@ else $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? - if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&5 + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test $_lt_result -eq 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 @@ -6888,6 +6939,7 @@ else fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 $as_echo "$lt_cv_apple_cc_single_mod" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } if ${lt_cv_ld_exported_symbols_list+:} false; then : @@ -6920,6 +6972,7 @@ rm -f core conftest.err conftest.$ac_objext \ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 $as_echo_n "checking for -force_load linker flag... " >&6; } if ${lt_cv_ld_force_load+:} false; then : @@ -6941,7 +6994,9 @@ _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? - if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&5 + elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then lt_cv_ld_force_load=yes else cat conftest.err >&5 @@ -7346,7 +7401,22 @@ fi # Check whether --with-pic was given. if test "${with_pic+set}" = set; then : - withval=$with_pic; pic_mode="$withval" + withval=$with_pic; lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for lt_pkg in $withval; do + IFS="$lt_save_ifs" + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac else pic_mode=default fi @@ -7419,6 +7489,10 @@ LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + @@ -7879,7 +7953,9 @@ lt_prog_compiler_static= case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 lt_prog_compiler_wl='-Xlinker ' - lt_prog_compiler_pic='-Xcompiler -fPIC' + if test -n "$lt_prog_compiler_pic"; then + lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" + fi ;; esac else @@ -7970,18 +8046,33 @@ lt_prog_compiler_static= ;; *) case `$CC -V 2>&1 | sed 5q` in - *Sun\ F* | *Sun*Fortran*) + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; + *Sun\ F* | *Sun*Fortran*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Qoption ld ' + ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; + *Intel*\ [CF]*Compiler*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + *Portland\ Group*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; esac ;; esac @@ -8343,7 +8434,6 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= - hardcode_libdir_flag_spec_ld= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported @@ -8596,8 +8686,7 @@ _LT_EOF xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' - hardcode_libdir_flag_spec= - hardcode_libdir_flag_spec_ld='-rpath $libdir' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ @@ -8977,6 +9066,7 @@ fi # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes + exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' @@ -9022,6 +9112,7 @@ fi hardcode_shlibpath_var=unsupported if test "$lt_cv_ld_force_load" = "yes"; then whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + else whole_archive_flag_spec='' fi @@ -9050,10 +9141,6 @@ fi hardcode_shlibpath_var=no ;; - freebsd1*) - ld_shlibs=no - ;; - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little @@ -9066,7 +9153,7 @@ fi ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2*) + freebsd2.*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes @@ -9105,7 +9192,6 @@ fi fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_flag_spec_ld='+b $libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes @@ -9723,11 +9809,6 @@ esac - - - - - @@ -9823,7 +9904,7 @@ need_version=unknown case $host_os in aix3*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH @@ -9832,7 +9913,7 @@ aix3*) ;; aix[4-9]*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes @@ -9897,7 +9978,7 @@ beos*) ;; bsdi[45]*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' @@ -10036,7 +10117,7 @@ darwin* | rhapsody*) ;; dgux*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' @@ -10044,10 +10125,6 @@ dgux*) shlibpath_var=LD_LIBRARY_PATH ;; -freebsd1*) - dynamic_linker=no - ;; - freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. @@ -10055,7 +10132,7 @@ freebsd* | dragonfly*) objformat=`/usr/bin/objformat` else case $host_os in - freebsd[123]*) objformat=aout ;; + freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi @@ -10073,7 +10150,7 @@ freebsd* | dragonfly*) esac shlibpath_var=LD_LIBRARY_PATH case $host_os in - freebsd2*) + freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) @@ -10093,7 +10170,7 @@ freebsd* | dragonfly*) ;; gnu*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' @@ -10104,7 +10181,7 @@ gnu*) ;; haiku*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" @@ -10165,7 +10242,7 @@ hpux9* | hpux10* | hpux11*) ;; interix[3-9]*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' @@ -10181,7 +10258,7 @@ irix5* | irix6* | nonstopux*) nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; @@ -10218,9 +10295,9 @@ linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; -# This must be Linux ELF. +# This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -10314,7 +10391,7 @@ netbsd*) ;; newsos6) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes @@ -10383,7 +10460,7 @@ rdos*) ;; solaris*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -10408,7 +10485,7 @@ sunos4*) ;; sysv4 | sysv4.3*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH @@ -10432,7 +10509,7 @@ sysv4 | sysv4.3*) sysv4*MP*) if test -d /usr/nec ;then - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH @@ -10463,7 +10540,7 @@ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -10473,7 +10550,7 @@ tpf*) ;; uts4*) - version_type=linux + version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH @@ -11255,6 +11332,8 @@ CC="$lt_save_CC" + + ac_config_commands="$ac_config_commands libtool" @@ -11391,11 +11470,134 @@ fi + + + + + + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKG_CONFIG"; then + ac_pt_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +if test -n "$ac_pt_PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +$as_echo "$ac_pt_PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_PKG_CONFIG" = x; then + PKG_CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_pt_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +fi + +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=0.9.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + PKG_CONFIG="" + fi +fi + # Work around stupid autoconf default cflags. pt 2 if test "$SAVE_CFLAGS" = "x"; then CFLAGS="" fi +# We always want 64 bit file offsets +CFLAGS="${CFLAGS} -D_FILE_OFFSET_BITS=64" + # Extract the first word of "rpcgen", so it can be a program name with args. set dummy rpcgen; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -11478,6 +11680,18 @@ _ACEOF fi +done + + for ac_header in sys/sockio.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sys/sockio.h" "ac_cv_header_sys_sockio_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_sockio_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYS_SOCKIO_H 1 +_ACEOF + +fi + done if test x$ENABLE_EXAMPLES = xyes; then @@ -11584,16 +11798,93 @@ $as_echo "#define HAVE_SOCKADDR_LEN 1" >>confdefs.h fi -echo "Use TI-RPC: $enable_tirpc" +LIBNFS_PC_REQ_PRIVATE= + if test "$enable_tirpc" = "yes"; then - CFLAGS="${CFLAGS} -I /usr/include/tirpc" - LDFLAGS="${LDFLAGS} -ltirpc" + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for TIRPC" >&5 +$as_echo_n "checking for TIRPC... " >&6; } + +if test -n "$TIRPC_CFLAGS"; then + pkg_cv_TIRPC_CFLAGS="$TIRPC_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libtirpc\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libtirpc") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_TIRPC_CFLAGS=`$PKG_CONFIG --cflags "libtirpc" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$TIRPC_LIBS"; then + pkg_cv_TIRPC_LIBS="$TIRPC_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libtirpc\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libtirpc") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_TIRPC_LIBS=`$PKG_CONFIG --libs "libtirpc" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no fi + if test $_pkg_short_errors_supported = yes; then + TIRPC_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libtirpc" 2>&1` + else + TIRPC_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libtirpc" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$TIRPC_PKG_ERRORS" >&5 + + as_fn_error $? "unable to locate libtirpc files" "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + as_fn_error $? "unable to locate libtirpc files" "$LINENO" 5 +else + TIRPC_CFLAGS=$pkg_cv_TIRPC_CFLAGS + TIRPC_LIBS=$pkg_cv_TIRPC_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + CFLAGS="${CFLAGS} ${TIRPC_CFLAGS}" + LIBS="${LIBS} ${TIRPC_LIBS}" + LIBNFS_PC_REQ_PRIVATE="${LIBNFS_PC_REQ_PRIVATE} libtirpc" +fi + + #output ac_config_files="$ac_config_files Makefile include/Makefile lib/Makefile mount/Makefile nfs/Makefile portmap/Makefile rquota/Makefile examples/Makefile" +ac_config_files="$ac_config_files libnfs.pc" + cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure @@ -12128,7 +12419,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by libnfs $as_me 0.0.0, which was +This file was extended by libnfs $as_me 1.2.0, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -12188,13 +12479,13 @@ $config_headers Configuration commands: $config_commands -Report bugs to the package provider." +Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -libnfs config.status 0.0.0 +libnfs config.status 1.2.0 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" @@ -12331,6 +12622,7 @@ pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' @@ -12413,7 +12705,6 @@ with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' -hardcode_libdir_flag_spec_ld='`$ECHO "$hardcode_libdir_flag_spec_ld" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' @@ -12469,6 +12760,7 @@ _LTECHO_EOF' # Quote evaled strings. for var in SHELL \ ECHO \ +PATH_SEPARATOR \ SED \ GREP \ EGREP \ @@ -12519,7 +12811,6 @@ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ -hardcode_libdir_flag_spec_ld \ hardcode_libdir_separator \ exclude_expsyms \ include_expsyms \ @@ -12611,6 +12902,7 @@ do "portmap/Makefile") CONFIG_FILES="$CONFIG_FILES portmap/Makefile" ;; "rquota/Makefile") CONFIG_FILES="$CONFIG_FILES rquota/Makefile" ;; "examples/Makefile") CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;; + "libnfs.pc") CONFIG_FILES="$CONFIG_FILES libnfs.pc" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac @@ -13322,8 +13614,8 @@ $as_echo X"$file" | # NOTE: Changes made to this file will be lost: look at ltmain.sh. # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008, 2009, 2010 Free Software Foundation, -# Inc. +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. @@ -13377,6 +13669,9 @@ SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO +# The PATH separator for the build system. +PATH_SEPARATOR=$lt_PATH_SEPARATOR + # The host system. host_alias=$host_alias host=$host @@ -13678,10 +13973,6 @@ no_undefined_flag=$lt_no_undefined_flag # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec -# If ld is used when linking, flag to hardcode \$libdir into a binary -# during linking. This must work even if \$libdir does not exist. -hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld - # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator diff --git a/configure.ac b/configure.ac index 309f73f..2091618 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ AC_PREREQ(2.50) -AC_INIT([libnfs], [0.0.0]) +AC_INIT([libnfs], [1.2.0], [ronniesahlberg@gmail.com]) AC_CONFIG_HEADERS([config.h]) AM_INIT_AUTOMAKE([foreign]) AC_CANONICAL_HOST @@ -11,12 +11,16 @@ AC_PROG_CC AC_PROG_LIBTOOL AM_PROG_CC_C_O +PKG_PROG_PKG_CONFIG # Work around stupid autoconf default cflags. pt 2 if test "$SAVE_CFLAGS" = "x"; then CFLAGS="" fi +# We always want 64 bit file offsets +CFLAGS="${CFLAGS} -D_FILE_OFFSET_BITS=64" + AC_CHECK_PROG([HAVE_RPCGEN], [rpcgen], [yes], [no]) if test x$HAVE_RPCGEN != xyes; then AC_MSG_ERROR([Can not find required program]) @@ -49,6 +53,7 @@ case $host in ;; *solaris*) AC_CHECK_HEADERS([sys/filio.h]) + AC_CHECK_HEADERS([sys/sockio.h]) if test x$ENABLE_EXAMPLES = xyes; then AC_CHECK_LIB([socket], [main], , [AC_MSG_ERROR([Can not find required library])]) AC_CHECK_LIB([nsl], [main], , [AC_MSG_ERROR([Can not find required library])]) @@ -70,12 +75,18 @@ AC_CHECK_MEMBER([struct sockaddr.sa_len], #include ]) -echo "Use TI-RPC: $enable_tirpc" +LIBNFS_PC_REQ_PRIVATE= + if test "$enable_tirpc" = "yes"; then - CFLAGS="${CFLAGS} -I /usr/include/tirpc" - LDFLAGS="${LDFLAGS} -ltirpc" + PKG_CHECK_MODULES(TIRPC, libtirpc, [], + AC_MSG_ERROR([unable to locate libtirpc files])) + CFLAGS="${CFLAGS} ${TIRPC_CFLAGS}" + LIBS="${LIBS} ${TIRPC_LIBS}" + LIBNFS_PC_REQ_PRIVATE="${LIBNFS_PC_REQ_PRIVATE} libtirpc" fi +AC_SUBST(LIBNFS_PC_REQ_PRIVATE) + #output AC_CONFIG_FILES([Makefile] [include/Makefile] @@ -87,4 +98,4 @@ AC_CONFIG_FILES([Makefile] [examples/Makefile] ) -AC_OUTPUT +AC_OUTPUT([libnfs.pc]) diff --git a/examples/Makefile.in b/examples/Makefile.in index bb065d8..c01b51c 100644 --- a/examples/Makefile.in +++ b/examples/Makefile.in @@ -118,6 +118,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBNFS_PC_REQ_PRIVATE = @LIBNFS_PC_REQ_PRIVATE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ @@ -142,12 +143,17 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RPCGENFLAGS = @RPCGENFLAGS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +TIRPC_CFLAGS = @TIRPC_CFLAGS@ +TIRPC_LIBS = @TIRPC_LIBS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ diff --git a/examples/nfsclient-async.c b/examples/nfsclient-async.c index d8420e1..c5d0df1 100644 --- a/examples/nfsclient-async.c +++ b/examples/nfsclient-async.c @@ -17,7 +17,14 @@ /* Example program using the highlevel async interface. */ - +#ifdef WIN32 +#include "win32_compat.h" +#else +#include +#include +#include +#endif + #define SERVER "10.1.1.27" #define EXPORT "/VIRTUAL" #define NFSFILE "/BOOKS/Classics/Dracula.djvu" @@ -27,10 +34,7 @@ #include #include #include -#include #include -#include -#include #include "libnfs.h" #include "libnfs-raw.h" #include "libnfs-raw-mount.h" diff --git a/examples/nfsclient-raw.c b/examples/nfsclient-raw.c index 7956781..948909f 100644 --- a/examples/nfsclient-raw.c +++ b/examples/nfsclient-raw.c @@ -19,13 +19,17 @@ * This allow accurate control of the exact commands that are being used. */ +#ifdef WIN32 +#include "win32_compat.h" +#else +#include +#endif #define SERVER "10.1.1.27" #define EXPORT "/shared" #include #include #include -#include #include "libnfs.h" #include "libnfs-raw.h" #include "libnfs-raw-mount.h" diff --git a/examples/nfsclient-sync.c b/examples/nfsclient-sync.c index 322bfa2..8563c1e 100644 --- a/examples/nfsclient-sync.c +++ b/examples/nfsclient-sync.c @@ -17,7 +17,14 @@ /* Example program using the highlevel sync interface */ - +#ifdef WIN32 +#include "win32_compat.h" +#else +#include +#include +#include +#endif + #define SERVER "10.1.1.27" #define EXPORT "/VIRTUAL" #define NFSFILE "/BOOKS/Classics/Dracula.djvu.truncated" @@ -26,13 +33,20 @@ #define NFSDIR "/BOOKS/Classics/" #define _GNU_SOURCE + +#if defined(WIN32) +#pragma comment(lib, "ws2_32.lib") +WSADATA wsaData; +#else +#include +#include +#endif + #include #include #include #include #include -#include -#include #include #include "libnfs.h" #include /* for authunix_create() */ @@ -47,23 +61,48 @@ struct client { }; +void PrintServerList() +{ + struct nfs_server_list *srvrs; + struct nfs_server_list *srv; + + srvrs = nfs_find_local_servers(); + + for (srv=srvrs; srv; srv = srv->next) + { + printf("Found nfs server: %s\n", srv->addr); + + } + free_nfs_srvr_list(srvrs); +} + char buf[3*1024*1024+337]; int main(int argc _U_, char *argv[] _U_) { struct nfs_context *nfs; int i, ret; + uint64_t offset; struct client client; struct stat st; struct nfsfh *nfsfh; struct nfsdir *nfsdir; struct nfsdirent *nfsdirent; + struct statvfs svfs; + exports export, tmp; + +#if defined(WIN32) + if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) { + printf("Failed to start Winsock2\n"); + exit(10); + } +#endif + client.server = SERVER; client.export = EXPORT; client.is_finished = 0; - off_t offset; - struct statvfs svfs; - exports export, tmp; + + PrintServerList(); export = mount_getexports(SERVER); if (export != NULL) { @@ -198,11 +237,10 @@ int main(int argc _U_, char *argv[] _U_) exit(10); } while((nfsdirent = nfs_readdir(nfs, nfsdir)) != NULL) { - char *filename = NULL; + char filename[1024]; printf("Inode:%d Name:%s ", (int)nfsdirent->inode, nfsdirent->name); - asprintf(&filename, "%s/%s", NFSDIR, nfsdirent->name); + sprintf(filename, "%s/%s", NFSDIR, nfsdirent->name); ret = nfs_open(nfs, filename, O_RDONLY, &nfsfh); - free(filename); if (ret != 0) { printf("Failed to open(%s) %s\n", filename, nfs_get_error(nfs)); exit(10); @@ -210,7 +248,6 @@ int main(int argc _U_, char *argv[] _U_) ret = nfs_read(nfs, nfsfh, sizeof(buf), buf); if (ret < 0) { printf("Error reading file\n"); - exit(10); } printf("Read %d bytes\n", ret); ret = nfs_close(nfs, nfsfh); diff --git a/include/Makefile.am b/include/Makefile.am index 6efb8f5..1b95508 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -1,9 +1,7 @@ nfscdir = $(includedir)/nfsc dist_nfsc_HEADERS = \ libnfs.h \ - libnfs-private.h \ libnfs-raw.h \ - slist.h \ ${abs_top_srcdir}/mount/libnfs-raw-mount.h \ ${abs_top_srcdir}/portmap/libnfs-raw-portmap.h \ ${abs_top_srcdir}/nfs/libnfs-raw-nfs.h \ diff --git a/include/Makefile.in b/include/Makefile.in index 87157ca..af433c3 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -106,6 +106,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBNFS_PC_REQ_PRIVATE = @LIBNFS_PC_REQ_PRIVATE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ @@ -130,12 +131,17 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RPCGENFLAGS = @RPCGENFLAGS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +TIRPC_CFLAGS = @TIRPC_CFLAGS@ +TIRPC_LIBS = @TIRPC_LIBS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ @@ -192,9 +198,7 @@ top_srcdir = @top_srcdir@ nfscdir = $(includedir)/nfsc dist_nfsc_HEADERS = \ libnfs.h \ - libnfs-private.h \ libnfs-raw.h \ - slist.h \ ${abs_top_srcdir}/mount/libnfs-raw-mount.h \ ${abs_top_srcdir}/portmap/libnfs-raw-portmap.h \ ${abs_top_srcdir}/nfs/libnfs-raw-nfs.h \ diff --git a/include/libnfs-private.h b/include/libnfs-private.h index 3131a20..b1fe134 100644 --- a/include/libnfs-private.h +++ b/include/libnfs-private.h @@ -14,8 +14,15 @@ You should have received a copy of the GNU Lesser General Public License along with this program; if not, see . */ +#include #include +struct rpc_fragment { + struct rpc_fragment *next; + uint64_t size; + char *data; +}; + struct rpc_context { int fd; int is_connected; @@ -44,6 +51,13 @@ struct rpc_context { int is_udp; struct sockaddr *udp_dest; int is_broadcast; + + /* track the address we connect to so we can auto-reconnect on session failure */ + struct sockaddr_storage s; + int auto_reconnect; + + /* fragment reassembly */ + struct rpc_fragment *fragments; }; struct rpc_pdu { @@ -75,6 +89,8 @@ void rpc_set_error(struct rpc_context *rpc, char *error_string, ...); void nfs_set_error(struct nfs_context *nfs, char *error_string, ...); struct rpc_context *nfs_get_rpc_context(struct nfs_context *nfs); +const char *nfs_get_server(struct nfs_context *nfs); +const char *nfs_get_export(struct nfs_context *nfs); /* we dont want to expose UDP to normal applications/users this is private to libnfs to use exclusively for broadcast RPC */ int rpc_bind_udp(struct rpc_context *rpc, char *addr, int port); @@ -82,3 +98,9 @@ int rpc_set_udp_destination(struct rpc_context *rpc, char *addr, int port, int i struct rpc_context *rpc_init_udp_context(void); struct sockaddr *rpc_get_recv_sockaddr(struct rpc_context *rpc); +void rpc_set_autoreconnect(struct rpc_context *rpc); +void rpc_unset_autoreconnect(struct rpc_context *rpc); + +int rpc_add_fragment(struct rpc_context *rpc, char *data, uint64_t size); +void rpc_free_all_fragments(struct rpc_context *rpc); + diff --git a/include/libnfs-raw.h b/include/libnfs-raw.h index 1650a8a..ad6f0a3 100644 --- a/include/libnfs-raw.h +++ b/include/libnfs-raw.h @@ -20,6 +20,8 @@ * protocol as well as the XDR encoded/decoded structures. */ #include +#include +#include struct rpc_data { int size; @@ -30,13 +32,13 @@ struct rpc_context; struct rpc_context *rpc_init_context(void); void rpc_destroy_context(struct rpc_context *rpc); -struct AUTH; -void rpc_set_auth(struct rpc_context *rpc, struct AUTH *auth); +void rpc_set_auth(struct rpc_context *rpc, AUTH *auth); int rpc_get_fd(struct rpc_context *rpc); int rpc_which_events(struct rpc_context *rpc); int rpc_service(struct rpc_context *rpc, int revents); char *rpc_get_error(struct rpc_context *rpc); +int rpc_queue_length(struct rpc_context *rpc); #define RPC_STATUS_SUCCESS 0 @@ -313,7 +315,7 @@ int rpc_nfs_access_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ -int rpc_nfs_read_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, off_t offset, size_t count, void *private_data); +int rpc_nfs_read_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, uint64_t offset, uint64_t count, void *private_data); /* * Call NFS/WRITE @@ -329,7 +331,7 @@ int rpc_nfs_read_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, o * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ -int rpc_nfs_write_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *buf, off_t offset, size_t count, int stable_how, void *private_data); +int rpc_nfs_write_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *buf, uint64_t offset, uint64_t count, int stable_how, void *private_data); /* * Call NFS/COMMIT @@ -423,6 +425,21 @@ int rpc_nfs_rmdir_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, int rpc_nfs_create_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *name, int mode, void *private_data); +/* + * Call NFS/MKNOD + * Function returns + * 0 : The call was initiated. The callback will be invoked when the call completes. + * <0 : An error occured when trying to set up the call. The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. + * data is MKNOD3res * + * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. + * data is the error string. + * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. + * data is NULL. + */ +int rpc_nfs_mknod_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *file, int mode, int major, int minor, void *private_data); /* @@ -444,7 +461,7 @@ int rpc_nfs_remove_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, /* - * Call NFS/REMOVE + * Call NFS/READDIR * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. @@ -459,6 +476,22 @@ int rpc_nfs_remove_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, */ int rpc_nfs_readdir_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, uint64_t cookie, char *cookieverf, int count, void *private_data); +/* + * Call NFS/READDIRPLUS + * Function returns + * 0 : The call was initiated. The callback will be invoked when the call completes. + * <0 : An error occured when trying to set up the call. The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. + * data is READDIRPLUS3res * + * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. + * data is the error string. + * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. + * data is NULL. + */ +int rpc_nfs_readdirplus_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, uint64_t cookie, char *cookieverf, int count, void *private_data); + /* * Call NFS/FSSTAT * Function returns diff --git a/include/libnfs.h b/include/libnfs.h index 0676efa..8621676 100644 --- a/include/libnfs.h +++ b/include/libnfs.h @@ -18,28 +18,59 @@ * This is the highlevel interface to access NFS resources using a posix-like interface */ #include +#include +#include struct nfs_context; struct rpc_context; +#if defined(WIN32) +#define EXTERN __declspec( dllexport ) +#else +#define EXTERN +#endif + +#if defined(WIN32) +struct statvfs { + uint32_t f_bsize; + uint32_t f_frsize; + uint64_t f_blocks; + uint64_t f_bfree; + uint64_t f_bavail; + uint32_t f_files; + uint32_t f_ffree; + uint32_t f_favail; + uint32_t f_fsid; + uint32_t f_flag; + uint32_t f_namemax; +}; +struct utimbuf { + time_t actime; + time_t modtime; +}; +#define R_OK 4 +#define W_OK 2 +#define X_OK 1 +#endif + /* * Used for interfacing the async version of the api into an external eventsystem */ -int nfs_get_fd(struct nfs_context *nfs); -int nfs_which_events(struct nfs_context *nfs); -int nfs_service(struct nfs_context *nfs, int revents); +EXTERN int nfs_get_fd(struct nfs_context *nfs); +EXTERN int nfs_which_events(struct nfs_context *nfs); +EXTERN int nfs_service(struct nfs_context *nfs, int revents); +EXTERN int nfs_queue_length(struct nfs_context *nfs); /* * Used if you need different credentials than the default for the current user. */ -struct AUTH; -void nfs_set_auth(struct nfs_context *nfs, struct AUTH *auth); +EXTERN void nfs_set_auth(struct nfs_context *nfs, AUTH *auth); /* * When an operation failed, this function can extract a detailed error string. */ -char *nfs_get_error(struct nfs_context *nfs); +EXTERN char *nfs_get_error(struct nfs_context *nfs); /* @@ -63,11 +94,11 @@ typedef void (*rpc_cb)(struct rpc_context *rpc, int status, void *data, void *pr * NULL : Failed to create a context. * *nfs : A pointer to an nfs context. */ -struct nfs_context *nfs_init_context(void); +EXTERN struct nfs_context *nfs_init_context(void); /* * Destroy an nfs context. */ -void nfs_destroy_context(struct nfs_context *nfs); +EXTERN void nfs_destroy_context(struct nfs_context *nfs); struct nfsfh; @@ -75,12 +106,12 @@ struct nfsfh; /* * Get the maximum supported READ3 size by the server */ -size_t nfs_get_readmax(struct nfs_context *nfs); +EXTERN uint64_t nfs_get_readmax(struct nfs_context *nfs); /* * Get the maximum supported WRITE3 size by the server */ -size_t nfs_get_writemax(struct nfs_context *nfs); +EXTERN uint64_t nfs_get_writemax(struct nfs_context *nfs); /* @@ -98,14 +129,14 @@ size_t nfs_get_writemax(struct nfs_context *nfs); * -errno : An error occured. * data is the error string. */ -int nfs_mount_async(struct nfs_context *nfs, const char *server, const char *exportname, nfs_cb cb, void *private_data); +EXTERN int nfs_mount_async(struct nfs_context *nfs, const char *server, const char *exportname, nfs_cb cb, void *private_data); /* * Sync nfs mount. * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ -int nfs_mount(struct nfs_context *nfs, const char *server, const char *exportname); +EXTERN int nfs_mount(struct nfs_context *nfs, const char *server, const char *exportname); @@ -126,14 +157,14 @@ int nfs_mount(struct nfs_context *nfs, const char *server, const char *exportnam * data is the error string. */ struct stat; -int nfs_stat_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data); +EXTERN int nfs_stat_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data); /* * Sync stat() * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ -int nfs_stat(struct nfs_context *nfs, const char *path, struct stat *st); +EXTERN int nfs_stat(struct nfs_context *nfs, const char *path, struct stat *st); /* @@ -151,14 +182,14 @@ int nfs_stat(struct nfs_context *nfs, const char *path, struct stat *st); * -errno : An error occured. * data is the error string. */ -int nfs_fstat_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, void *private_data); +EXTERN int nfs_fstat_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, void *private_data); /* * Sync fstat(nfsfh *) * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ -int nfs_fstat(struct nfs_context *nfs, struct nfsfh *nfsfh, struct stat *st); +EXTERN int nfs_fstat(struct nfs_context *nfs, struct nfsfh *nfsfh, struct stat *st); @@ -181,14 +212,14 @@ int nfs_fstat(struct nfs_context *nfs, struct nfsfh *nfsfh, struct stat *st); * -errno : An error occured. * data is the error string. */ -int nfs_open_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb cb, void *private_data); +EXTERN int nfs_open_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb cb, void *private_data); /* * Sync stat() * Function returns * 0 : The operation was successfull. *nfsfh is filled in. * -errno : The command failed. */ -int nfs_open(struct nfs_context *nfs, const char *path, int mode, struct nfsfh **nfsfh); +EXTERN int nfs_open(struct nfs_context *nfs, const char *path, int mode, struct nfsfh **nfsfh); @@ -209,14 +240,14 @@ int nfs_open(struct nfs_context *nfs, const char *path, int mode, struct nfsfh * * -errno : An error occured. * data is the error string. */ -int nfs_close_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, void *private_data); +EXTERN int nfs_close_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, void *private_data); /* * Sync close(nfsfh) * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ -int nfs_close(struct nfs_context *nfs, struct nfsfh *nfsfh); +EXTERN int nfs_close(struct nfs_context *nfs, struct nfsfh *nfsfh); /* @@ -236,14 +267,14 @@ int nfs_close(struct nfs_context *nfs, struct nfsfh *nfsfh); * -errno : An error occured. * data is the error string. */ -int nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, size_t count, nfs_cb cb, void *private_data); +EXTERN int nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset, uint64_t count, nfs_cb cb, void *private_data); /* * Sync pread() * Function returns * >=0 : numer of bytes read. * -errno : An error occured. */ -int nfs_pread(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, size_t count, char *buf); +EXTERN int nfs_pread(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset, uint64_t count, char *buf); @@ -264,14 +295,14 @@ int nfs_pread(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, size_t * -errno : An error occured. * data is the error string. */ -int nfs_read_async(struct nfs_context *nfs, struct nfsfh *nfsfh, size_t count, nfs_cb cb, void *private_data); +EXTERN int nfs_read_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t count, nfs_cb cb, void *private_data); /* * Sync read() * Function returns * >=0 : numer of bytes read. * -errno : An error occured. */ -int nfs_read(struct nfs_context *nfs, struct nfsfh *nfsfh, size_t count, char *buf); +EXTERN int nfs_read(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t count, char *buf); @@ -292,14 +323,14 @@ int nfs_read(struct nfs_context *nfs, struct nfsfh *nfsfh, size_t count, char *b * -errno : An error occured. * data is the error string. */ -int nfs_pwrite_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, size_t count, char *buf, nfs_cb cb, void *private_data); +EXTERN int nfs_pwrite_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset, uint64_t count, char *buf, nfs_cb cb, void *private_data); /* * Sync pwrite() * Function returns * >=0 : numer of bytes written. * -errno : An error occured. */ -int nfs_pwrite(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, size_t count, char *buf); +EXTERN int nfs_pwrite(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset, uint64_t count, char *buf); /* @@ -318,14 +349,14 @@ int nfs_pwrite(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, size_ * -errno : An error occured. * data is the error string. */ -int nfs_write_async(struct nfs_context *nfs, struct nfsfh *nfsfh, size_t count, char *buf, nfs_cb cb, void *private_data); +EXTERN int nfs_write_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t count, char *buf, nfs_cb cb, void *private_data); /* * Sync write() * Function returns * >=0 : numer of bytes written. * -errno : An error occured. */ -int nfs_write(struct nfs_context *nfs, struct nfsfh *nfsfh, size_t count, char *buf); +EXTERN int nfs_write(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t count, char *buf); /* @@ -340,18 +371,18 @@ int nfs_write(struct nfs_context *nfs, struct nfsfh *nfsfh, size_t count, char * * * When the callback is invoked, status indicates the result: * >=0 : Success. - * data is off_t * for the current position. + * data is uint64_t * for the current position. * -errno : An error occured. * data is the error string. */ -int nfs_lseek_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, int whence, nfs_cb cb, void *private_data); +EXTERN int nfs_lseek_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset, int whence, nfs_cb cb, void *private_data); /* * Sync lseek() * Function returns * >=0 : numer of bytes read. * -errno : An error occured. */ -int nfs_lseek(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, int whence, off_t *current_offset); +EXTERN int nfs_lseek(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset, int whence, uint64_t *current_offset); /* @@ -369,14 +400,14 @@ int nfs_lseek(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, int wh * -errno : An error occured. * data is the error string. */ -int nfs_fsync_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, void *private_data); +EXTERN int nfs_fsync_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, void *private_data); /* * Sync fsync() * Function returns * 0 : Success * -errno : An error occured. */ -int nfs_fsync(struct nfs_context *nfs, struct nfsfh *nfsfh); +EXTERN int nfs_fsync(struct nfs_context *nfs, struct nfsfh *nfsfh); @@ -395,14 +426,14 @@ int nfs_fsync(struct nfs_context *nfs, struct nfsfh *nfsfh); * -errno : An error occured. * data is the error string. */ -int nfs_truncate_async(struct nfs_context *nfs, const char *path, off_t length, nfs_cb cb, void *private_data); +EXTERN int nfs_truncate_async(struct nfs_context *nfs, const char *path, uint64_t length, nfs_cb cb, void *private_data); /* * Sync truncate() * Function returns * 0 : Success * -errno : An error occured. */ -int nfs_truncate(struct nfs_context *nfs, const char *path, off_t length); +EXTERN int nfs_truncate(struct nfs_context *nfs, const char *path, uint64_t length); @@ -421,14 +452,14 @@ int nfs_truncate(struct nfs_context *nfs, const char *path, off_t length); * -errno : An error occured. * data is the error string. */ -int nfs_ftruncate_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t length, nfs_cb cb, void *private_data); +EXTERN int nfs_ftruncate_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t length, nfs_cb cb, void *private_data); /* * Sync ftruncate() * Function returns * 0 : Success * -errno : An error occured. */ -int nfs_ftruncate(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t length); +EXTERN int nfs_ftruncate(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t length); @@ -450,14 +481,14 @@ int nfs_ftruncate(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t length); * -errno : An error occured. * data is the error string. */ -int nfs_mkdir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data); +EXTERN int nfs_mkdir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data); /* * Sync mkdir() * Function returns * 0 : Success * -errno : An error occured. */ -int nfs_mkdir(struct nfs_context *nfs, const char *path); +EXTERN int nfs_mkdir(struct nfs_context *nfs, const char *path); @@ -476,14 +507,14 @@ int nfs_mkdir(struct nfs_context *nfs, const char *path); * -errno : An error occured. * data is the error string. */ -int nfs_rmdir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data); +EXTERN int nfs_rmdir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data); /* * Sync rmdir() * Function returns * 0 : Success * -errno : An error occured. */ -int nfs_rmdir(struct nfs_context *nfs, const char *path); +EXTERN int nfs_rmdir(struct nfs_context *nfs, const char *path); @@ -504,16 +535,39 @@ int nfs_rmdir(struct nfs_context *nfs, const char *path); * -errno : An error occured. * data is the error string. */ -int nfs_creat_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb cb, void *private_data); +EXTERN int nfs_creat_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb cb, void *private_data); /* * Sync creat() * Function returns * 0 : Success * -errno : An error occured. */ -int nfs_creat(struct nfs_context *nfs, const char *path, int mode, struct nfsfh **nfsfh); +EXTERN int nfs_creat(struct nfs_context *nfs, const char *path, int mode, struct nfsfh **nfsfh); +/* + * MKNOD() + */ +/* + * Async mknod() + * + * Function returns + * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. + * <0 : An error occured when trying to set up the operation. The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * -errno : An error occured. + * data is the error string. + */ +EXTERN int nfs_mknod_async(struct nfs_context *nfs, const char *path, int mode, int dev, nfs_cb cb, void *private_data); +/* + * Sync mknod() + * Function returns + * 0 : Success + * -errno : An error occured. + */ +EXTERN int nfs_mknod(struct nfs_context *nfs, const char *path, int mode, int dev); @@ -533,14 +587,14 @@ int nfs_creat(struct nfs_context *nfs, const char *path, int mode, struct nfsfh * -errno : An error occured. * data is the error string. */ -int nfs_unlink_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data); +EXTERN int nfs_unlink_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data); /* * Sync unlink() * Function returns * 0 : Success * -errno : An error occured. */ -int nfs_unlink(struct nfs_context *nfs, const char *path); +EXTERN int nfs_unlink(struct nfs_context *nfs, const char *path); @@ -564,14 +618,14 @@ struct nfsdir; * -errno : An error occured. * data is the error string. */ -int nfs_opendir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data); +EXTERN int nfs_opendir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data); /* * Sync opendir() * Function returns * 0 : Success * -errno : An error occured. */ -int nfs_opendir(struct nfs_context *nfs, const char *path, struct nfsdir **nfsdir); +EXTERN int nfs_opendir(struct nfs_context *nfs, const char *path, struct nfsdir **nfsdir); @@ -582,11 +636,19 @@ struct nfsdirent { struct nfsdirent *next; char *name; uint64_t inode; + + /* some extra fields we get for free through the READDIRPLUS3 call. You need libnfs-raw-nfs.h for these */ + uint32_t type; /* NF3REG, NF3DIR, NF3BLK, ... */ + uint32_t mode; + uint64_t size; + struct timeval atime; + struct timeval mtime; + struct timeval ctime; }; /* * nfs_readdir() never blocks, so no special sync/async versions are available */ -struct nfsdirent *nfs_readdir(struct nfs_context *nfs, struct nfsdir *nfsdir); +EXTERN struct nfsdirent *nfs_readdir(struct nfs_context *nfs, struct nfsdir *nfsdir); @@ -596,7 +658,7 @@ struct nfsdirent *nfs_readdir(struct nfs_context *nfs, struct nfsdir *nfsdir); /* * nfs_closedir() never blocks, so no special sync/async versions are available */ -void nfs_closedir(struct nfs_context *nfs, struct nfsdir *nfsdir); +EXTERN void nfs_closedir(struct nfs_context *nfs, struct nfsdir *nfsdir); @@ -616,14 +678,14 @@ void nfs_closedir(struct nfs_context *nfs, struct nfsdir *nfsdir); * data is the error string. */ struct statvfs; -int nfs_statvfs_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data); +EXTERN int nfs_statvfs_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data); /* * Sync statvfs() * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ -int nfs_statvfs(struct nfs_context *nfs, const char *path, struct statvfs *svfs); +EXTERN int nfs_statvfs(struct nfs_context *nfs, const char *path, struct statvfs *svfs); /* @@ -643,14 +705,14 @@ int nfs_statvfs(struct nfs_context *nfs, const char *path, struct statvfs *svfs) * data is the error string. */ struct statvfs; -int nfs_readlink_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data); +EXTERN int nfs_readlink_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data); /* * Sync readlink() * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ -int nfs_readlink(struct nfs_context *nfs, const char *path, char *buf, int bufsize); +EXTERN int nfs_readlink(struct nfs_context *nfs, const char *path, char *buf, int bufsize); @@ -669,14 +731,14 @@ int nfs_readlink(struct nfs_context *nfs, const char *path, char *buf, int bufsi * -errno : An error occured. * data is the error string. */ -int nfs_chmod_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb cb, void *private_data); +EXTERN int nfs_chmod_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb cb, void *private_data); /* * Sync chmod() * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ -int nfs_chmod(struct nfs_context *nfs, const char *path, int mode); +EXTERN int nfs_chmod(struct nfs_context *nfs, const char *path, int mode); @@ -695,14 +757,14 @@ int nfs_chmod(struct nfs_context *nfs, const char *path, int mode); * -errno : An error occured. * data is the error string. */ -int nfs_fchmod_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int mode, nfs_cb cb, void *private_data); +EXTERN int nfs_fchmod_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int mode, nfs_cb cb, void *private_data); /* * Sync fchmod() * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ -int nfs_fchmod(struct nfs_context *nfs, struct nfsfh *nfsfh, int mode); +EXTERN int nfs_fchmod(struct nfs_context *nfs, struct nfsfh *nfsfh, int mode); @@ -721,14 +783,14 @@ int nfs_fchmod(struct nfs_context *nfs, struct nfsfh *nfsfh, int mode); * -errno : An error occured. * data is the error string. */ -int nfs_chown_async(struct nfs_context *nfs, const char *path, int uid, int gid, nfs_cb cb, void *private_data); +EXTERN int nfs_chown_async(struct nfs_context *nfs, const char *path, int uid, int gid, nfs_cb cb, void *private_data); /* * Sync chown() * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ -int nfs_chown(struct nfs_context *nfs, const char *path, int uid, int gid); +EXTERN int nfs_chown(struct nfs_context *nfs, const char *path, int uid, int gid); @@ -747,14 +809,14 @@ int nfs_chown(struct nfs_context *nfs, const char *path, int uid, int gid); * -errno : An error occured. * data is the error string. */ -int nfs_fchown_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int uid, int gid, nfs_cb cb, void *private_data); +EXTERN int nfs_fchown_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int uid, int gid, nfs_cb cb, void *private_data); /* * Sync fchown() * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ -int nfs_fchown(struct nfs_context *nfs, struct nfsfh *nfsfh, int uid, int gid); +EXTERN int nfs_fchown(struct nfs_context *nfs, struct nfsfh *nfsfh, int uid, int gid); @@ -774,14 +836,14 @@ int nfs_fchown(struct nfs_context *nfs, struct nfsfh *nfsfh, int uid, int gid); * -errno : An error occured. * data is the error string. */ -int nfs_utimes_async(struct nfs_context *nfs, const char *path, struct timeval *times, nfs_cb cb, void *private_data); +EXTERN int nfs_utimes_async(struct nfs_context *nfs, const char *path, struct timeval *times, nfs_cb cb, void *private_data); /* * Sync utimes() * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ -int nfs_utimes(struct nfs_context *nfs, const char *path, struct timeval *times); +EXTERN int nfs_utimes(struct nfs_context *nfs, const char *path, struct timeval *times); /* @@ -800,14 +862,14 @@ int nfs_utimes(struct nfs_context *nfs, const char *path, struct timeval *times) * data is the error string. */ struct utimbuf; -int nfs_utime_async(struct nfs_context *nfs, const char *path, struct utimbuf *times, nfs_cb cb, void *private_data); +EXTERN int nfs_utime_async(struct nfs_context *nfs, const char *path, struct utimbuf *times, nfs_cb cb, void *private_data); /* * Sync utime() * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ -int nfs_utime(struct nfs_context *nfs, const char *path, struct utimbuf *times); +EXTERN int nfs_utime(struct nfs_context *nfs, const char *path, struct utimbuf *times); @@ -827,14 +889,14 @@ int nfs_utime(struct nfs_context *nfs, const char *path, struct utimbuf *times); * -errno : An error occured. * data is the error string. */ -int nfs_access_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb cb, void *private_data); +EXTERN int nfs_access_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb cb, void *private_data); /* * Sync access() * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ -int nfs_access(struct nfs_context *nfs, const char *path, int mode); +EXTERN int nfs_access(struct nfs_context *nfs, const char *path, int mode); @@ -854,14 +916,14 @@ int nfs_access(struct nfs_context *nfs, const char *path, int mode); * -errno : An error occured. * data is the error string. */ -int nfs_symlink_async(struct nfs_context *nfs, const char *oldpath, const char *newpath, nfs_cb cb, void *private_data); +EXTERN int nfs_symlink_async(struct nfs_context *nfs, const char *oldpath, const char *newpath, nfs_cb cb, void *private_data); /* * Sync symlink() * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ -int nfs_symlink(struct nfs_context *nfs, const char *oldpath, const char *newpath); +EXTERN int nfs_symlink(struct nfs_context *nfs, const char *oldpath, const char *newpath); /* @@ -879,14 +941,14 @@ int nfs_symlink(struct nfs_context *nfs, const char *oldpath, const char *newpat * -errno : An error occured. * data is the error string. */ -int nfs_rename_async(struct nfs_context *nfs, const char *oldpath, const char *newpath, nfs_cb cb, void *private_data); +EXTERN int nfs_rename_async(struct nfs_context *nfs, const char *oldpath, const char *newpath, nfs_cb cb, void *private_data); /* * Sync rename(, ) * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ -int nfs_rename(struct nfs_context *nfs, const char *oldpath, const char *newpath); +EXTERN int nfs_rename(struct nfs_context *nfs, const char *oldpath, const char *newpath); @@ -905,14 +967,14 @@ int nfs_rename(struct nfs_context *nfs, const char *oldpath, const char *newpath * -errno : An error occured. * data is the error string. */ -int nfs_link_async(struct nfs_context *nfs, const char *oldpath, const char *newpath, nfs_cb cb, void *private_data); +EXTERN int nfs_link_async(struct nfs_context *nfs, const char *oldpath, const char *newpath, nfs_cb cb, void *private_data); /* * Sync link(, ) * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ -int nfs_link(struct nfs_context *nfs, const char *oldpath, const char *newpath); +EXTERN int nfs_link(struct nfs_context *nfs, const char *oldpath, const char *newpath); /* @@ -936,7 +998,7 @@ int nfs_link(struct nfs_context *nfs, const char *oldpath, const char *newpath); * -errno : An error occured. * data is the error string. */ -int mount_getexports_async(struct rpc_context *rpc, const char *server, rpc_cb cb, void *private_data); +EXTERN int mount_getexports_async(struct rpc_context *rpc, const char *server, rpc_cb cb, void *private_data); /* * Sync getexports() * Function returns @@ -945,13 +1007,13 @@ int mount_getexports_async(struct rpc_context *rpc, const char *server, rpc_cb c * * returned data must be freed by calling mount_free_export_list(exportnode); */ -struct exportnode *mount_getexports(const char *server); +EXTERN struct exportnode *mount_getexports(const char *server); -void mount_free_export_list(struct exportnode *exports); +EXTERN void mount_free_export_list(struct exportnode *exports); //qqq replace later with lseek(cur, 0) -off_t nfs_get_current_offset(struct nfsfh *nfsfh); +uint64_t nfs_get_current_offset(struct nfsfh *nfsfh); diff --git a/lib/Makefile.am b/lib/Makefile.am index 221034f..39d150d 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -14,7 +14,7 @@ libnfs_la_SOURCES = \ pdu.c \ socket.c -libnfs_la_LDFLAGS = -version-info 0:0:0 +libnfs_la_LDFLAGS = -version-info 1:2:0 libnfs_la_LIBADD = \ ../mount/libmount.la \ ../nfs/libnfs.la \ diff --git a/lib/Makefile.in b/lib/Makefile.in index 8be604a..d673009 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -126,6 +126,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBNFS_PC_REQ_PRIVATE = @LIBNFS_PC_REQ_PRIVATE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ @@ -150,12 +151,17 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RPCGENFLAGS = @RPCGENFLAGS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +TIRPC_CFLAGS = @TIRPC_CFLAGS@ +TIRPC_LIBS = @TIRPC_LIBS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ @@ -224,7 +230,7 @@ libnfs_la_SOURCES = \ pdu.c \ socket.c -libnfs_la_LDFLAGS = -version-info 0:0:0 +libnfs_la_LDFLAGS = -version-info 1:2:0 libnfs_la_LIBADD = \ ../mount/libmount.la \ ../nfs/libnfs.la \ diff --git a/lib/init.c b/lib/init.c index 5663f25..4c8f84f 100644 --- a/lib/init.c +++ b/lib/init.c @@ -1,10 +1,7 @@ /* Copyright (C) 2010 by Ronnie Sahlberg - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -15,12 +12,17 @@ along with this program; if not, see . */ +#ifdef WIN32 +#include "win32_compat.h" +#else +#include +#include +#endif/*WIN32*/ #define _GNU_SOURCE + #include #include -#include #include -#include #include #include #include @@ -37,7 +39,7 @@ struct rpc_context *rpc_init_context(void) if (rpc == NULL) { return NULL; } - bzero(rpc, sizeof(struct rpc_context)); + memset(rpc, 0, sizeof(struct rpc_context)); rpc->encodebuflen = 65536; rpc->encodebuf = malloc(rpc->encodebuflen); @@ -46,7 +48,11 @@ struct rpc_context *rpc_init_context(void) return NULL; } - rpc->auth = authunix_create_default(); +#if defined(WIN32) + rpc->auth = authunix_create("LibNFS", 65535, 65535, 0, NULL); +#else + rpc->auth = authunix_create_default(); +#endif if (rpc->auth == NULL) { free(rpc->encodebuf); free(rpc); @@ -71,7 +77,7 @@ struct rpc_context *rpc_init_udp_context(void) return rpc; } -void rpc_set_auth(struct rpc_context *rpc, struct AUTH *auth) +void rpc_set_auth(struct rpc_context *rpc, AUTH *auth) { if (rpc->auth != NULL) { auth_destroy(rpc->auth); @@ -83,14 +89,13 @@ void rpc_set_auth(struct rpc_context *rpc, struct AUTH *auth) void rpc_set_error(struct rpc_context *rpc, char *error_string, ...) { va_list ap; - char *str; if (rpc->error_string != NULL) { free(rpc->error_string); } va_start(ap, error_string); - vasprintf(&str, error_string, ap); - rpc->error_string = str; + rpc->error_string = malloc(1024); + vsnprintf(rpc->error_string, 1024, error_string, ap); va_end(ap); } @@ -115,6 +120,44 @@ void rpc_error_all_pdus(struct rpc_context *rpc, char *error) } } +static void rpc_free_fragment(struct rpc_fragment *fragment) +{ + if (fragment->data != NULL) { + free(fragment->data); + } + free(fragment); +} + +void rpc_free_all_fragments(struct rpc_context *rpc) +{ + while (rpc->fragments != NULL) { + struct rpc_fragment *fragment = rpc->fragments; + + SLIST_REMOVE(&rpc->fragments, fragment); + rpc_free_fragment(fragment); + } +} + +int rpc_add_fragment(struct rpc_context *rpc, char *data, uint64_t size) +{ + struct rpc_fragment *fragment; + + fragment = malloc(sizeof(struct rpc_fragment)); + if (fragment == NULL) { + return -1; + } + + fragment->size = size; + fragment->data = malloc(fragment->size); + if(fragment->data == NULL) { + free(fragment); + return -1; + } + + memcpy(fragment->data, data, fragment->size); + SLIST_ADD_END(&rpc->fragments, fragment); + return 0; +} void rpc_destroy_context(struct rpc_context *rpc) { @@ -131,11 +174,17 @@ void rpc_destroy_context(struct rpc_context *rpc) rpc_free_pdu(rpc, pdu); } + rpc_free_all_fragments(rpc); + auth_destroy(rpc->auth); rpc->auth =NULL; if (rpc->fd != -1) { - close(rpc->fd); +#if defined(WIN32) + closesocket(rpc->fd); +#else + close(rpc->fd); +#endif } if (rpc->encodebuf != NULL) { diff --git a/lib/libnfs-sync.c b/lib/libnfs-sync.c index e964c14..09e197a 100644 --- a/lib/libnfs-sync.c +++ b/lib/libnfs-sync.c @@ -17,23 +17,36 @@ /* * High level api to nfs filesystems */ +#ifdef WIN32 +#include "win32_compat.h" +#define DllExport +#else +#include +#include +#include +#include +#include +#include +#include +#include +#endif +#ifdef HAVE_CONFIG_H #include "config.h" +#endif + #include #include #include -#include #include #include -#include -#include -#include #include #include -#include -#include -#include -#include + +#ifdef HAVE_SYS_SOCKIO_H +#include +#endif + #include "libnfs.h" #include "libnfs-raw.h" #include "libnfs-raw-mount.h" @@ -43,7 +56,7 @@ struct sync_cb_data { int is_finished; int status; - off_t offset; + uint64_t offset; void *return_data; int return_int; }; @@ -53,13 +66,10 @@ static void wait_for_reply(struct rpc_context *rpc, struct sync_cb_data *cb_data { struct pollfd pfd; - for (;;) { - if (cb_data->is_finished) { - break; - } + while (!cb_data->is_finished) { + pfd.fd = rpc_get_fd(rpc); pfd.events = rpc_which_events(rpc); - if (poll(&pfd, 1, -1) < 0) { rpc_set_error(rpc, "Poll failed"); cb_data->status = -EIO; @@ -70,6 +80,31 @@ static void wait_for_reply(struct rpc_context *rpc, struct sync_cb_data *cb_data cb_data->status = -EIO; break; } + if (rpc_get_fd(rpc) == -1) { + rpc_set_error(rpc, "Socket closed\n"); + break; + } + } +} + +static void wait_for_nfs_reply(struct nfs_context *nfs, struct sync_cb_data *cb_data) +{ + struct pollfd pfd; + + while (!cb_data->is_finished) { + + pfd.fd = nfs_get_fd(nfs); + pfd.events = nfs_which_events(nfs); + if (poll(&pfd, 1, -1) < 0) { + nfs_set_error(nfs, "Poll failed"); + cb_data->status = -EIO; + break; + } + if (nfs_service(nfs, pfd.revents) < 0) { + nfs_set_error(nfs, "nfs_service failed"); + cb_data->status = -EIO; + break; + } } } @@ -97,6 +132,7 @@ static void mount_cb(int status, struct nfs_context *nfs, void *data, void *priv int nfs_mount(struct nfs_context *nfs, const char *server, const char *export) { struct sync_cb_data cb_data; + struct rpc_context *rpc = nfs_get_rpc_context(nfs); cb_data.is_finished = 0; @@ -105,7 +141,10 @@ int nfs_mount(struct nfs_context *nfs, const char *server, const char *export) return -1; } - wait_for_reply(nfs_get_rpc_context(nfs), &cb_data); + wait_for_nfs_reply(nfs, &cb_data); + + /* Dont want any more callbacks even if the socket is closed */ + rpc->connect_cb = NULL; return cb_data.status; } @@ -141,7 +180,7 @@ int nfs_stat(struct nfs_context *nfs, const char *path, struct stat *st) return -1; } - wait_for_reply(nfs_get_rpc_context(nfs), &cb_data); + wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } @@ -182,7 +221,7 @@ int nfs_open(struct nfs_context *nfs, const char *path, int mode, struct nfsfh * return -1; } - wait_for_reply(nfs_get_rpc_context(nfs), &cb_data); + wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } @@ -209,7 +248,7 @@ static void pread_cb(int status, struct nfs_context *nfs, void *data, void *priv memcpy(buffer, (char *)data, status); } -int nfs_pread(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, size_t count, char *buffer) +int nfs_pread(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset, uint64_t count, char *buffer) { struct sync_cb_data cb_data; @@ -221,7 +260,7 @@ int nfs_pread(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, size_t return -1; } - wait_for_reply(nfs_get_rpc_context(nfs), &cb_data); + wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } @@ -229,7 +268,7 @@ int nfs_pread(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, size_t /* * read() */ -int nfs_read(struct nfs_context *nfs, struct nfsfh *nfsfh, size_t count, char *buffer) +int nfs_read(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t count, char *buffer) { return nfs_pread(nfs, nfsfh, nfs_get_current_offset(nfsfh), count, buffer); } @@ -260,7 +299,7 @@ int nfs_close(struct nfs_context *nfs, struct nfsfh *nfsfh) return -1; } - wait_for_reply(nfs_get_rpc_context(nfs), &cb_data); + wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } @@ -283,7 +322,7 @@ int nfs_fstat(struct nfs_context *nfs, struct nfsfh *nfsfh, struct stat *st) return -1; } - wait_for_reply(nfs_get_rpc_context(nfs), &cb_data); + wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } @@ -304,7 +343,7 @@ static void pwrite_cb(int status, struct nfs_context *nfs, void *data, void *pri } } -int nfs_pwrite(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, size_t count, char *buf) +int nfs_pwrite(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset, uint64_t count, char *buf) { struct sync_cb_data cb_data; @@ -315,7 +354,7 @@ int nfs_pwrite(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, size_ return -1; } - wait_for_reply(nfs_get_rpc_context(nfs), &cb_data); + wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } @@ -323,7 +362,7 @@ int nfs_pwrite(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, size_ /* * write() */ -int nfs_write(struct nfs_context *nfs, struct nfsfh *nfsfh, size_t count, char *buf) +int nfs_write(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t count, char *buf) { return nfs_pwrite(nfs, nfsfh, nfs_get_current_offset(nfsfh), count, buf); } @@ -355,7 +394,7 @@ int nfs_fsync(struct nfs_context *nfs, struct nfsfh *nfsfh) return -1; } - wait_for_reply(nfs_get_rpc_context(nfs), &cb_data); + wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } @@ -378,7 +417,7 @@ static void ftruncate_cb(int status, struct nfs_context *nfs, void *data, void * } } -int nfs_ftruncate(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t length) +int nfs_ftruncate(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t length) { struct sync_cb_data cb_data; @@ -389,7 +428,7 @@ int nfs_ftruncate(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t length) return -1; } - wait_for_reply(nfs_get_rpc_context(nfs), &cb_data); + wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } @@ -411,7 +450,7 @@ static void truncate_cb(int status, struct nfs_context *nfs, void *data, void *p } } -int nfs_truncate(struct nfs_context *nfs, const char *path, off_t length) +int nfs_truncate(struct nfs_context *nfs, const char *path, uint64_t length) { struct sync_cb_data cb_data; @@ -422,7 +461,7 @@ int nfs_truncate(struct nfs_context *nfs, const char *path, off_t length) return -1; } - wait_for_reply(nfs_get_rpc_context(nfs), &cb_data); + wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } @@ -457,7 +496,7 @@ int nfs_mkdir(struct nfs_context *nfs, const char *path) return -1; } - wait_for_reply(nfs_get_rpc_context(nfs), &cb_data); + wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } @@ -492,7 +531,7 @@ int nfs_rmdir(struct nfs_context *nfs, const char *path) return -1; } - wait_for_reply(nfs_get_rpc_context(nfs), &cb_data); + wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } @@ -532,12 +571,42 @@ int nfs_creat(struct nfs_context *nfs, const char *path, int mode, struct nfsfh return -1; } - wait_for_reply(nfs_get_rpc_context(nfs), &cb_data); + wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } +/* + * mknod() + */ +static void mknod_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + + cb_data->is_finished = 1; + cb_data->status = status; + + if (status < 0) { + nfs_set_error(nfs, "mknod call failed with \"%s\"", (char *)data); + return; + } +} + +int nfs_mknod(struct nfs_context *nfs, const char *path, int mode, int dev) +{ + struct sync_cb_data cb_data; + + cb_data.is_finished = 0; + if (nfs_mknod_async(nfs, path, mode, dev, mknod_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_creat_async failed"); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + + return cb_data.status; +} /* @@ -567,7 +636,7 @@ int nfs_unlink(struct nfs_context *nfs, const char *path) return -1; } - wait_for_reply(nfs_get_rpc_context(nfs), &cb_data); + wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } @@ -607,7 +676,7 @@ int nfs_opendir(struct nfs_context *nfs, const char *path, struct nfsdir **nfsdi return -1; } - wait_for_reply(nfs_get_rpc_context(nfs), &cb_data); + wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } @@ -629,11 +698,11 @@ static void lseek_cb(int status, struct nfs_context *nfs, void *data, void *priv } if (cb_data->return_data != NULL) { - memcpy(cb_data->return_data, data, sizeof(off_t)); + memcpy(cb_data->return_data, data, sizeof(uint64_t)); } } -int nfs_lseek(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, int whence, off_t *current_offset) +int nfs_lseek(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset, int whence, uint64_t *current_offset) { struct sync_cb_data cb_data; @@ -645,7 +714,7 @@ int nfs_lseek(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, int wh return -1; } - wait_for_reply(nfs_get_rpc_context(nfs), &cb_data); + wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } @@ -682,7 +751,7 @@ int nfs_statvfs(struct nfs_context *nfs, const char *path, struct statvfs *svfs) return -1; } - wait_for_reply(nfs_get_rpc_context(nfs), &cb_data); + wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } @@ -728,7 +797,7 @@ int nfs_readlink(struct nfs_context *nfs, const char *path, char *buf, int bufsi return -1; } - wait_for_reply(nfs_get_rpc_context(nfs), &cb_data); + wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } @@ -762,7 +831,7 @@ int nfs_chmod(struct nfs_context *nfs, const char *path, int mode) return -1; } - wait_for_reply(nfs_get_rpc_context(nfs), &cb_data); + wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } @@ -797,7 +866,7 @@ int nfs_fchmod(struct nfs_context *nfs, struct nfsfh *nfsfh, int mode) return -1; } - wait_for_reply(nfs_get_rpc_context(nfs), &cb_data); + wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } @@ -832,7 +901,7 @@ int nfs_chown(struct nfs_context *nfs, const char *path, int uid, int gid) return -1; } - wait_for_reply(nfs_get_rpc_context(nfs), &cb_data); + wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } @@ -864,7 +933,7 @@ int nfs_fchown(struct nfs_context *nfs, struct nfsfh *nfsfh, int uid, int gid) return -1; } - wait_for_reply(nfs_get_rpc_context(nfs), &cb_data); + wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } @@ -898,7 +967,7 @@ int nfs_utimes(struct nfs_context *nfs, const char *path, struct timeval *times) return -1; } - wait_for_reply(nfs_get_rpc_context(nfs), &cb_data); + wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } @@ -932,7 +1001,7 @@ int nfs_utime(struct nfs_context *nfs, const char *path, struct utimbuf *times) return -1; } - wait_for_reply(nfs_get_rpc_context(nfs), &cb_data); + wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } @@ -967,7 +1036,7 @@ int nfs_access(struct nfs_context *nfs, const char *path, int mode) return -1; } - wait_for_reply(nfs_get_rpc_context(nfs), &cb_data); + wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } @@ -1001,7 +1070,7 @@ int nfs_symlink(struct nfs_context *nfs, const char *oldpath, const char *newpat return -1; } - wait_for_reply(nfs_get_rpc_context(nfs), &cb_data); + wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } @@ -1035,7 +1104,7 @@ int nfs_rename(struct nfs_context *nfs, const char *oldpath, const char *newpath return -1; } - wait_for_reply(nfs_get_rpc_context(nfs), &cb_data); + wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } @@ -1069,7 +1138,7 @@ int nfs_link(struct nfs_context *nfs, const char *oldpath, const char *newpath) return -1; } - wait_for_reply(nfs_get_rpc_context(nfs), &cb_data); + wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } @@ -1136,7 +1205,6 @@ void mount_free_export_list(struct exportnode *exports) - void free_nfs_srvr_list(struct nfs_server_list *srv) { while (srv != NULL) { @@ -1184,7 +1252,7 @@ void callit_cb(struct rpc_context *rpc, int status, void *data _U_, void *privat /* check for dupes */ for (srvr = srv_data->srvrs; srvr; srvr = srvr->next) { if (!strcmp(hostdd, srvr->addr)) { - return 0; + return; } } @@ -1207,6 +1275,138 @@ void callit_cb(struct rpc_context *rpc, int status, void *data _U_, void *privat srv_data->srvrs = srvr; } +#ifdef WIN32 + +static int send_nfsd_probes(struct rpc_context *rpc, INTERFACE_INFO *InterfaceList, int numIfs, struct nfs_list_data *data) +{ + int i=0; + + for(i = 0; i < numIfs; i++) + { + SOCKADDR *pAddress; + char bcdd[16]; + unsigned long nFlags = 0; + + pAddress = (SOCKADDR *) & (InterfaceList[i].iiBroadcastAddress); + + if(pAddress->sa_family != AF_INET) + continue; + + nFlags = InterfaceList[i].iiFlags; + + if (!(nFlags & IFF_UP)) + { + continue; + } + + if (nFlags & IFF_LOOPBACK) + { + continue; + } + + if (!(nFlags & IFF_BROADCAST)) + { + continue; + } + + if (getnameinfo(pAddress, sizeof(struct sockaddr_in), &bcdd[0], sizeof(bcdd), NULL, 0, NI_NUMERICHOST) < 0) + { + continue; + } + + if (rpc_set_udp_destination(rpc, bcdd, 111, 1) < 0) + { + return -1; + } + + if (rpc_pmap_callit_async(rpc, MOUNT_PROGRAM, 2, 0, NULL, 0, callit_cb, data) < 0) + { + return -1; + } + } + return 0; +} + +struct nfs_server_list *nfs_find_local_servers(void) +{ + struct rpc_context *rpc; + struct nfs_list_data data = {0, NULL}; + struct timeval tv_start, tv_current; + int loop; + struct pollfd pfd; + INTERFACE_INFO InterfaceList[20]; + unsigned long nBytesReturned; + int nNumInterfaces = 0; + + rpc = rpc_init_udp_context(); + if (rpc == NULL) + { + return NULL; + } + + if (rpc_bind_udp(rpc, "0.0.0.0", 0) < 0) + { + rpc_destroy_context(rpc); + return NULL; + } + + if (WSAIoctl(rpc_get_fd(rpc), SIO_GET_INTERFACE_LIST, 0, 0, &InterfaceList, sizeof(InterfaceList), &nBytesReturned, 0, 0) == SOCKET_ERROR) + { + return NULL; + } + + nNumInterfaces = nBytesReturned / sizeof(INTERFACE_INFO); + + for (loop=0; loop<3; loop++) + { + if (send_nfsd_probes(rpc, InterfaceList, nNumInterfaces, &data) != 0) + { + rpc_destroy_context(rpc); + return NULL; + } + + win32_gettimeofday(&tv_start, NULL); + for(;;) + { + int mpt; + + pfd.fd = rpc_get_fd(rpc); + pfd.events = rpc_which_events(rpc); + + win32_gettimeofday(&tv_current, NULL); + mpt = 1000 + - (tv_current.tv_sec *1000 + tv_current.tv_usec / 1000) + + (tv_start.tv_sec *1000 + tv_start.tv_usec / 1000); + + if (poll(&pfd, 1, mpt) < 0) + { + free_nfs_srvr_list(data.srvrs); + rpc_destroy_context(rpc); + return NULL; + } + if (pfd.revents == 0) + { + break; + } + + if (rpc_service(rpc, pfd.revents) < 0) + { + break; + } + } + } + + rpc_destroy_context(rpc); + + if (data.status != 0) + { + free_nfs_srvr_list(data.srvrs); + return NULL; + } + return data.srvrs; +} +#else + static int send_nfsd_probes(struct rpc_context *rpc, struct ifconf *ifc, struct nfs_list_data *data) { char *ptr; @@ -1339,6 +1539,6 @@ struct nfs_server_list *nfs_find_local_servers(void) free_nfs_srvr_list(data.srvrs); return NULL; } - return data.srvrs; } +#endif//WIN32 diff --git a/lib/libnfs-win32.def b/lib/libnfs-win32.def new file mode 100644 index 0000000..4b1e6f5 --- /dev/null +++ b/lib/libnfs-win32.def @@ -0,0 +1,80 @@ +LIBRARY libnfs +EXPORTS +mount_free_export_list +mount_getexports +mount_getexports_async +nfs_find_local_servers +free_nfs_srvr_list +nfs_access +nfs_access_async +nfs_chmod +nfs_chmod_async +nfs_chown +nfs_chown_async +nfs_close +nfs_close_async +nfs_closedir +nfs_creat +nfs_creat_async +nfs_destroy_context +nfs_fchmod +nfs_fchmod_async +nfs_fchown +nfs_fchown_async +nfs_fstat +nfs_fstat_async +nfs_fsync +nfs_fsync_async +nfs_ftruncate +nfs_ftruncate_async +nfs_get_error +nfs_get_fd +nfs_get_readmax +nfs_get_writemax +nfs_init_context +nfs_link +nfs_link_async +nfs_lseek +nfs_lseek_async +nfs_mkdir +nfs_mkdir_async +nfs_mknod +nfs_mknod_async +nfs_mount +nfs_mount_async +nfs_open +nfs_open_async +nfs_opendir +nfs_opendir_async +nfs_pread +nfs_pread_async +nfs_pwrite +nfs_pwrite_async +nfs_read +nfs_read_async +nfs_readdir +nfs_readlink +nfs_readlink_async +nfs_rename +nfs_rename_async +nfs_rmdir +nfs_rmdir_async +nfs_service +nfs_set_auth +nfs_stat +nfs_stat_async +nfs_statvfs +nfs_statvfs_async +nfs_symlink +nfs_symlink_async +nfs_truncate +nfs_truncate_async +nfs_unlink +nfs_unlink_async +nfs_utime +nfs_utime_async +nfs_utimes +nfs_utimes_async +nfs_which_events +nfs_write +nfs_write_async diff --git a/lib/libnfs.c b/lib/libnfs.c index 8d27a81..6fcd48a 100644 --- a/lib/libnfs.c +++ b/lib/libnfs.c @@ -17,19 +17,25 @@ /* * High level api to nfs filesystems */ +#ifdef WIN32 +#include "win32_compat.h" +#define DllExport +#else +#include +#include +#include +#include +#endif/*WIN32*/ #define _GNU_SOURCE + #include #include #include #include -#include #include #include #include -#include -#include -#include #include #include "libnfs.h" #include "libnfs-raw.h" @@ -45,7 +51,7 @@ struct nfsdir { struct nfsfh { struct nfs_fh3 fh; int is_sync; - off_t offset; + uint64_t offset; }; struct nfs_context { @@ -53,8 +59,8 @@ struct nfs_context { char *server; char *export; struct nfs_fh3 rootfh; - size_t readmax; - size_t writemax; + uint64_t readmax; + uint64_t writemax; }; void nfs_free_nfsdir(struct nfsdir *nfsdir) @@ -92,22 +98,22 @@ struct nfs_cb_data { int error; int cancel; int num_calls; - off_t start_offset, max_offset; + uint64_t start_offset, max_offset; char *buffer; }; struct nfs_mcb_data { struct nfs_cb_data *data; - off_t offset; - size_t count; + uint64_t offset; + uint64_t count; }; static int nfs_lookup_path_async_internal(struct nfs_context *nfs, struct nfs_cb_data *data, struct nfs_fh3 *fh); -void nfs_set_auth(struct nfs_context *nfs, struct AUTH *auth) +void nfs_set_auth(struct nfs_context *nfs, AUTH *auth) { - return rpc_set_auth(nfs->rpc, auth); + rpc_set_auth(nfs->rpc, auth); } int nfs_get_fd(struct nfs_context *nfs) @@ -115,6 +121,11 @@ int nfs_get_fd(struct nfs_context *nfs) return rpc_get_fd(nfs->rpc); } +int nfs_queue_length(struct nfs_context *nfs) +{ + return rpc_queue_length(nfs->rpc); +} + int nfs_which_events(struct nfs_context *nfs) { return rpc_which_events(nfs->rpc); @@ -144,6 +155,12 @@ struct nfs_context *nfs_init_context(void) return NULL; } + nfs->server = NULL; + nfs->export = NULL; + + nfs->rootfh.data.data_len = 0; + nfs->rootfh.data.data_val = NULL; + return nfs; } @@ -275,6 +292,9 @@ static void nfs_mount_7_cb(struct rpc_context *rpc, int status, void *command_da struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; + /* Dont want any more callbacks even if the socket is closed */ + rpc->connect_cb = NULL; + if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); @@ -335,6 +355,8 @@ static void nfs_mount_6_cb(struct rpc_context *rpc, int status, void *command_da free_nfs_cb_data(data); return; } + /* NFS TCP connections we want to autoreconnect after sessions are torn down (due to inactivity or error) */ + rpc_set_autoreconnect(rpc); } @@ -366,6 +388,9 @@ static void nfs_mount_4_cb(struct rpc_context *rpc, int status, void *command_da struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; + /* Dont want any more callbacks even if the socket is closed */ + rpc->connect_cb = NULL; + if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); @@ -446,6 +471,9 @@ static void nfs_mount_1_cb(struct rpc_context *rpc, int status, void *command_da struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; + /* Dont want any more callbacks even if the socket is closed */ + rpc->connect_cb = NULL; + if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); @@ -470,15 +498,24 @@ static void nfs_mount_1_cb(struct rpc_context *rpc, int status, void *command_da int nfs_mount_async(struct nfs_context *nfs, const char *server, const char *export, nfs_cb cb, void *private_data) { struct nfs_cb_data *data; + char *new_server, *new_export; data = malloc(sizeof(struct nfs_cb_data)); if (data == NULL) { rpc_set_error(nfs->rpc, "out of memory. failed to allocate memory for nfs mount data"); return -1; } - bzero(data, sizeof(struct nfs_cb_data)); - nfs->server = strdup(server); - nfs->export = strdup(export); + memset(data, 0, sizeof(struct nfs_cb_data)); + new_server = strdup(server); + new_export = strdup(export); + if (nfs->server != NULL) { + free(nfs->server); + } + nfs->server = new_server; + if (nfs->export != NULL) { + free(nfs->export); + } + nfs->export = new_export; data->nfs = nfs; data->cb = cb; data->private_data = private_data; @@ -540,7 +577,7 @@ static int nfs_lookup_path_async_internal(struct nfs_context *nfs, struct nfs_cb } path = data->path; - str = index(path, '/'); + str = strchr(path, '/'); if (str != NULL) { *str = 0; data->path = str+1; @@ -587,7 +624,7 @@ static int nfs_lookuppath_async(struct nfs_context *nfs, const char *path, nfs_c rpc_set_error(nfs->rpc, "out of memory: failed to allocate nfs_cb_data structure"); return -1; } - bzero(data, sizeof(struct nfs_cb_data)); + memset(data, 0, sizeof(struct nfs_cb_data)); data->nfs = nfs; data->cb = cb; data->continue_cb = continue_cb; @@ -649,13 +686,18 @@ static void nfs_stat_1_cb(struct rpc_context *rpc _U_, int status, void *command if (res->GETATTR3res_u.resok.obj_attributes.type == NF3DIR) { st.st_mode |= S_IFDIR ; } + if (res->GETATTR3res_u.resok.obj_attributes.type == NF3REG) { + st.st_mode |= S_IFREG ; + } st.st_nlink = res->GETATTR3res_u.resok.obj_attributes.nlink; st.st_uid = res->GETATTR3res_u.resok.obj_attributes.uid; st.st_gid = res->GETATTR3res_u.resok.obj_attributes.gid; st.st_rdev = 0; st.st_size = res->GETATTR3res_u.resok.obj_attributes.size; +#ifndef WIN32 st.st_blksize = 4096; st.st_blocks = res->GETATTR3res_u.resok.obj_attributes.size / 4096; +#endif//WIN32 st.st_atime = res->GETATTR3res_u.resok.obj_attributes.atime.seconds; st.st_mtime = res->GETATTR3res_u.resok.obj_attributes.mtime.seconds; st.st_ctime = res->GETATTR3res_u.resok.obj_attributes.ctime.seconds; @@ -750,7 +792,7 @@ static void nfs_open_cb(struct rpc_context *rpc _U_, int status, void *command_d free_nfs_cb_data(data); return; } - bzero(nfsfh, sizeof(struct nfsfh)); + memset(nfsfh, 0, sizeof(struct nfsfh)); if (data->continue_int & O_SYNC) { nfsfh->is_sync = 1; @@ -895,7 +937,7 @@ static void nfs_pread_mcb(struct rpc_context *rpc _U_, int status, void *command free(mdata); } -int nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, size_t count, nfs_cb cb, void *private_data) +int nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset, uint64_t count, nfs_cb cb, void *private_data) { struct nfs_cb_data *data; @@ -904,7 +946,7 @@ int nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, rpc_set_error(nfs->rpc, "out of memory: failed to allocate nfs_cb_data structure"); return -1; } - bzero(data, sizeof(struct nfs_cb_data)); + memset(data, 0, sizeof(struct nfs_cb_data)); data->nfs = nfs; data->cb = cb; data->private_data = private_data; @@ -938,7 +980,7 @@ int nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, } while (count > 0) { - size_t readcount = count; + uint64_t readcount = count; struct nfs_mcb_data *mdata; if (readcount > nfs_get_readmax(nfs)) { @@ -950,7 +992,7 @@ int nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, rpc_set_error(nfs->rpc, "out of memory: failed to allocate nfs_mcb_data structure"); return -1; } - bzero(mdata, sizeof(struct nfs_mcb_data)); + memset(mdata, 0, sizeof(struct nfs_mcb_data)); mdata->data = data; mdata->offset = offset; mdata->count = readcount; @@ -972,7 +1014,7 @@ int nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, /* * Async read() */ -int nfs_read_async(struct nfs_context *nfs, struct nfsfh *nfsfh, size_t count, nfs_cb cb, void *private_data) +int nfs_read_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t count, nfs_cb cb, void *private_data) { return nfs_pread_async(nfs, nfsfh, nfsfh->offset, count, cb, private_data); } @@ -1012,7 +1054,66 @@ static void nfs_pwrite_cb(struct rpc_context *rpc _U_, int status, void *command free_nfs_cb_data(data); } -int nfs_pwrite_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, size_t count, char *buf, nfs_cb cb, void *private_data) +static void nfs_pwrite_mcb(struct rpc_context *rpc _U_, int status, void *command_data, void *private_data) +{ + struct nfs_mcb_data *mdata = private_data; + struct nfs_cb_data *data = mdata->data; + struct nfs_context *nfs = data->nfs; + WRITE3res *res; + + data->num_calls--; + + if (status == RPC_STATUS_ERROR) { + /* flag the failure but do not invoke callback until we have received all responses */ + data->error = 1; + } + if (status == RPC_STATUS_CANCEL) { + /* flag the cancellation but do not invoke callback until we have received all responses */ + data->cancel = 1; + } + + if (status == RPC_STATUS_SUCCESS) { + res = command_data; + if (res->status != NFS3_OK) { + rpc_set_error(nfs->rpc, "NFS: Write failed with %s(%d)", nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); + data->error = 1; + } else { + if (res->WRITE3res_u.resok.count > 0) { + if ((unsigned)data->max_offset < mdata->offset + res->WRITE3res_u.resok.count) { + data->max_offset = mdata->offset + res->WRITE3res_u.resok.count; + } + } + } + } + + if (data->num_calls > 0) { + /* still waiting for more replies */ + free(mdata); + return; + } + + if (data->error != 0) { + data->cb(-EFAULT, nfs, command_data, data->private_data); + free_nfs_cb_data(data); + free(mdata); + return; + } + if (data->cancel != 0) { + data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); + free_nfs_cb_data(data); + free(mdata); + return; + } + + data->nfsfh->offset = data->max_offset; + data->cb(data->max_offset - data->start_offset, nfs, NULL, data->private_data); + + free_nfs_cb_data(data); + free(mdata); +} + + +int nfs_pwrite_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset, uint64_t count, char *buf, nfs_cb cb, void *private_data) { struct nfs_cb_data *data; @@ -1021,26 +1122,68 @@ int nfs_pwrite_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, rpc_set_error(nfs->rpc, "out of memory: failed to allocate nfs_cb_data structure"); return -1; } - bzero(data, sizeof(struct nfs_cb_data)); + memset(data, 0, sizeof(struct nfs_cb_data)); data->nfs = nfs; data->cb = cb; data->private_data = private_data; data->nfsfh = nfsfh; nfsfh->offset = offset; - if (rpc_nfs_write_async(nfs->rpc, nfs_pwrite_cb, &nfsfh->fh, buf, offset, count, nfsfh->is_sync?FILE_SYNC:UNSTABLE, data) != 0) { - rpc_set_error(nfs->rpc, "RPC error: Failed to send WRITE call for %s", data->path); - data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); - free_nfs_cb_data(data); - return -1; + + if (count <= nfs_get_writemax(nfs)) { + if (rpc_nfs_write_async(nfs->rpc, nfs_pwrite_cb, &nfsfh->fh, buf, offset, count, nfsfh->is_sync?FILE_SYNC:UNSTABLE, data) != 0) { + rpc_set_error(nfs->rpc, "RPC error: Failed to send WRITE call for %s", data->path); + data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); + free_nfs_cb_data(data); + return -1; + } + return 0; } + + /* trying to write more than maximum server write size, we has to chop it up into smaller + * chunks. + * we send all writes in parallell so that performance is still good. + */ + data->max_offset = offset; + data->start_offset = offset; + + while (count > 0) { + uint64_t writecount = count; + struct nfs_mcb_data *mdata; + + if (writecount > nfs_get_writemax(nfs)) { + writecount = nfs_get_writemax(nfs); + } + + mdata = malloc(sizeof(struct nfs_mcb_data)); + if (mdata == NULL) { + rpc_set_error(nfs->rpc, "out of memory: failed to allocate nfs_mcb_data structure"); + return -1; + } + memset(mdata, 0, sizeof(struct nfs_mcb_data)); + mdata->data = data; + mdata->offset = offset; + mdata->count = writecount; + + if (rpc_nfs_write_async(nfs->rpc, nfs_pwrite_mcb, &nfsfh->fh, &buf[offset - data->start_offset], offset, writecount, nfsfh->is_sync?FILE_SYNC:UNSTABLE, mdata) != 0) { + rpc_set_error(nfs->rpc, "RPC error: Failed to send WRITE call for %s", data->path); + data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); + free(mdata); + return -1; + } + + count -= writecount; + offset += writecount; + data->num_calls++; + } + return 0; } /* * Async write() */ -int nfs_write_async(struct nfs_context *nfs, struct nfsfh *nfsfh, size_t count, char *buf, nfs_cb cb, void *private_data) +int nfs_write_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t count, char *buf, nfs_cb cb, void *private_data) { return nfs_pwrite_async(nfs, nfsfh, nfsfh->offset, count, buf, cb, private_data); } @@ -1080,7 +1223,7 @@ int nfs_fstat_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, voi rpc_set_error(nfs->rpc, "out of memory: failed to allocate nfs_cb_data structure"); return -1; } - bzero(data, sizeof(struct nfs_cb_data)); + memset(data, 0, sizeof(struct nfs_cb_data)); data->nfs = nfs; data->cb = cb; data->private_data = private_data; @@ -1137,7 +1280,7 @@ int nfs_fsync_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, voi rpc_set_error(nfs->rpc, "out of memory: failed to allocate nfs_cb_data structure"); return -1; } - bzero(data, sizeof(struct nfs_cb_data)); + memset(data, 0, sizeof(struct nfs_cb_data)); data->nfs = nfs; data->cb = cb; data->private_data = private_data; @@ -1186,7 +1329,7 @@ static void nfs_ftruncate_cb(struct rpc_context *rpc _U_, int status, void *comm free_nfs_cb_data(data); } -int nfs_ftruncate_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t length, nfs_cb cb, void *private_data) +int nfs_ftruncate_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t length, nfs_cb cb, void *private_data) { struct nfs_cb_data *data; SETATTR3args args; @@ -1196,12 +1339,12 @@ int nfs_ftruncate_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t leng rpc_set_error(nfs->rpc, "out of memory: failed to allocate nfs_cb_data structure"); return -1; } - bzero(data, sizeof(struct nfs_cb_data)); + memset(data, 0, sizeof(struct nfs_cb_data)); data->nfs = nfs; data->cb = cb; data->private_data = private_data; - bzero(&args, sizeof(SETATTR3args)); + memset(&args, 0, sizeof(SETATTR3args)); args.object.data.data_len = nfsfh->fh.data.data_len; args.object.data.data_val = nfsfh->fh.data.data_val; args.new_attributes.size.set_it = 1; @@ -1222,7 +1365,7 @@ int nfs_ftruncate_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t leng */ static int nfs_truncate_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data) { - off_t offset = data->continue_int; + uint64_t offset = data->continue_int; struct nfsfh nfsfh; nfsfh.fh.data.data_val = data->fh.data.data_val; @@ -1238,9 +1381,9 @@ static int nfs_truncate_continue_internal(struct nfs_context *nfs, struct nfs_cb return 0; } -int nfs_truncate_async(struct nfs_context *nfs, const char *path, off_t length, nfs_cb cb, void *private_data) +int nfs_truncate_async(struct nfs_context *nfs, const char *path, uint64_t length, nfs_cb cb, void *private_data) { - off_t offset; + uint64_t offset; offset = length; @@ -1316,7 +1459,7 @@ int nfs_mkdir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void * return -1; } - ptr = rindex(new_path, '/'); + ptr = strrchr(new_path, '/'); if (ptr == NULL) { rpc_set_error(nfs->rpc, "Invalid path %s", path); return -1; @@ -1397,7 +1540,7 @@ int nfs_rmdir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void * return -1; } - ptr = rindex(new_path, '/'); + ptr = strrchr(new_path, '/'); if (ptr == NULL) { rpc_set_error(nfs->rpc, "Invalid path %s", path); return -1; @@ -1454,7 +1597,7 @@ static void nfs_create_2_cb(struct rpc_context *rpc _U_, int status, void *comma free_nfs_cb_data(data); return; } - bzero(nfsfh, sizeof(struct nfsfh)); + memset(nfsfh, 0, sizeof(struct nfsfh)); /* steal the filehandle */ nfsfh->fh.data.data_len = data->fh.data.data_len; @@ -1529,7 +1672,7 @@ int nfs_creat_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb return -1; } - ptr = rindex(new_path, '/'); + ptr = strrchr(new_path, '/'); if (ptr == NULL) { rpc_set_error(nfs->rpc, "Invalid path %s", path); return -1; @@ -1609,7 +1752,7 @@ int nfs_unlink_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void return -1; } - ptr = rindex(new_path, '/'); + ptr = strrchr(new_path, '/'); if (ptr == NULL) { rpc_set_error(nfs->rpc, "Invalid path %s", path); return -1; @@ -1626,20 +1769,192 @@ int nfs_unlink_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void } +/* + * Async mknod() + */ +struct mknod_cb_data { + char *path; + int mode; + int major; + int minor; +}; + +static void free_mknod_cb_data(void *ptr) +{ + struct mknod_cb_data *data = ptr; + + free(data->path); + free(data); +} + +static void nfs_mknod_cb(struct rpc_context *rpc _U_, int status, void *command_data, void *private_data) +{ + MKNOD3res *res; + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + char *str = data->continue_data; + + str = &str[strlen(str) + 1]; + + if (status == RPC_STATUS_ERROR) { + data->cb(-EFAULT, nfs, command_data, data->private_data); + free_nfs_cb_data(data); + return; + } + if (status == RPC_STATUS_CANCEL) { + data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); + free_nfs_cb_data(data); + return; + } + + res = command_data; + if (res->status != NFS3_OK) { + rpc_set_error(nfs->rpc, "NFS: MKNOD of %s/%s failed with %s(%d)", data->saved_path, str, nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); + data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); + free_nfs_cb_data(data); + return; + } + + data->cb(0, nfs, NULL, data->private_data); + free_nfs_cb_data(data); +} + +static int nfs_mknod_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data) +{ + struct mknod_cb_data *cb_data = data->continue_data; + char *str = cb_data->path; + + str = &str[strlen(str) + 1]; + + if (rpc_nfs_mknod_async(nfs->rpc, nfs_mknod_cb, &data->fh, str, cb_data->mode, cb_data->major, cb_data->minor, data) != 0) { + data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); + free_nfs_cb_data(data); + return -1; + } + return 0; +} + +int nfs_mknod_async(struct nfs_context *nfs, const char *path, int mode, int dev, nfs_cb cb, void *private_data) +{ + char *ptr; + struct mknod_cb_data *cb_data; + + cb_data = malloc(sizeof(struct mknod_cb_data)); + if (cb_data == NULL) { + rpc_set_error(nfs->rpc, "Out of memory, failed to allocate mode buffer for cb data"); + return -1; + } + + cb_data->path = strdup(path); + if (cb_data->path == NULL) { + rpc_set_error(nfs->rpc, "Out of memory, failed to allocate mode buffer for path"); + free(cb_data); + return -1; + } + ptr = strrchr(cb_data->path, '/'); + if (ptr == NULL) { + rpc_set_error(nfs->rpc, "Invalid path %s", path); + return -1; + } + *ptr = 0; + cb_data->mode = mode; + cb_data->major = major(dev); + cb_data->minor = minor(dev); + + /* data->path now points to the parent directory, and beyond the nul terminateor is the new directory to create */ + if (nfs_lookuppath_async(nfs, cb_data->path, cb, private_data, nfs_mknod_continue_internal, cb_data, free_mknod_cb_data, 0) != 0) { + rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); + free_mknod_cb_data(cb_data); + return -1; + } + + return 0; +} /* * Async opendir() */ -static void nfs_opendir_cb(struct rpc_context *rpc _U_, int status, void *command_data, void *private_data) + +/* ReadDirPlus Emulation Callback data */ +struct rdpe_cb_data { + int getattrcount; + int status; + struct nfs_cb_data *data; +}; + +/* ReadDirPlus Emulation LOOKUP Callback data */ +struct rdpe_lookup_cb_data { + struct rdpe_cb_data *rdpe_cb_data; + struct nfsdirent *nfsdirent; +}; + +/* Workaround for servers lacking READDIRPLUS, use READDIR instead and a GETATTR-loop */ +static void nfs_opendir3_cb(struct rpc_context *rpc _U_, int status, void *command_data, void *private_data) +{ + LOOKUP3res *res = command_data; + struct rdpe_lookup_cb_data *rdpe_lookup_cb_data = private_data; + struct rdpe_cb_data *rdpe_cb_data = rdpe_lookup_cb_data->rdpe_cb_data; + struct nfs_cb_data *data = rdpe_cb_data->data; + struct nfsdir *nfsdir = data->continue_data; + struct nfs_context *nfs = data->nfs; + struct nfsdirent *nfsdirent = rdpe_lookup_cb_data->nfsdirent; + + free(rdpe_lookup_cb_data); + + rdpe_cb_data->getattrcount--; + + if (status == RPC_STATUS_ERROR) { + rdpe_cb_data->status = RPC_STATUS_ERROR; + } + if (status == RPC_STATUS_CANCEL) { + rdpe_cb_data->status = RPC_STATUS_CANCEL; + } + if (status == RPC_STATUS_SUCCESS && res->status != NFS3_OK) { + rdpe_cb_data->status = RPC_STATUS_ERROR; + } + if (status == RPC_STATUS_SUCCESS && res->status == NFS3_OK) { + if (res->LOOKUP3res_u.resok.obj_attributes.attributes_follow) { + fattr3 *attributes = &res->LOOKUP3res_u.resok.obj_attributes.post_op_attr_u.attributes; + + nfsdirent->type = attributes->type; + nfsdirent->mode = attributes->mode; + nfsdirent->size = attributes->size; + + nfsdirent->atime.tv_sec = attributes->atime.seconds; + nfsdirent->atime.tv_usec = attributes->atime.nseconds/1000; + nfsdirent->mtime.tv_sec = attributes->mtime.seconds; + nfsdirent->mtime.tv_usec = attributes->mtime.nseconds/1000; + nfsdirent->ctime.tv_sec = attributes->ctime.seconds; + nfsdirent->ctime.tv_usec = attributes->ctime.nseconds/1000; + } + } + + if (rdpe_cb_data->getattrcount == 0) { + if (rdpe_cb_data->status != RPC_STATUS_SUCCESS) { + data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); + nfs_free_nfsdir(nfsdir); + } else { + data->cb(0, nfs, nfsdir, data->private_data); + } + free(rdpe_cb_data); + + data->continue_data = NULL; + free_nfs_cb_data(data); + } +} + +static void nfs_opendir2_cb(struct rpc_context *rpc _U_, int status, void *command_data, void *private_data) { - READDIR3res *res; + READDIR3res *res = command_data; struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; - struct nfsdir *nfsdir = data->continue_data;; + struct nfsdir *nfsdir = data->continue_data; + struct nfsdirent *nfsdirent; struct entry3 *entry; uint64_t cookie; + struct rdpe_cb_data *rdpe_cb_data; if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); @@ -1648,6 +1963,7 @@ static void nfs_opendir_cb(struct rpc_context *rpc _U_, int status, void *comman free_nfs_cb_data(data); return; } + if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); nfs_free_nfsdir(nfsdir); @@ -1656,7 +1972,6 @@ static void nfs_opendir_cb(struct rpc_context *rpc _U_, int status, void *comman return; } - res = command_data; if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: READDIR of %s failed with %s(%d)", data->saved_path, nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); @@ -1668,8 +1983,6 @@ static void nfs_opendir_cb(struct rpc_context *rpc _U_, int status, void *comman entry =res->READDIR3res_u.resok.reply.entries; while (entry != NULL) { - struct nfsdirent *nfsdirent; - nfsdirent = malloc(sizeof(struct nfsdirent)); if (nfsdirent == NULL) { data->cb(-ENOMEM, nfs, "Failed to allocate dirent", data->private_data); @@ -1678,7 +1991,7 @@ static void nfs_opendir_cb(struct rpc_context *rpc _U_, int status, void *comman free_nfs_cb_data(data); return; } - bzero(nfsdirent, sizeof(struct nfsdirent)); + memset(nfsdirent, 0, sizeof(struct nfsdirent)); nfsdirent->name = strdup(entry->name); if (nfsdirent->name == NULL) { data->cb(-ENOMEM, nfs, "Failed to allocate dirent->name", data->private_data); @@ -1688,6 +2001,7 @@ static void nfs_opendir_cb(struct rpc_context *rpc _U_, int status, void *comman return; } nfsdirent->inode = entry->fileid; + nfsdirent->next = nfsdir->entries; nfsdir->entries = nfsdirent; @@ -1696,7 +2010,7 @@ static void nfs_opendir_cb(struct rpc_context *rpc _U_, int status, void *comman } if (res->READDIR3res_u.resok.reply.eof == 0) { - if (rpc_nfs_readdir_async(nfs->rpc, nfs_opendir_cb, &data->fh, cookie, res->READDIR3res_u.resok.cookieverf, 20000, data) != 0) { + if (rpc_nfs_readdir_async(nfs->rpc, nfs_opendir2_cb, &data->fh, cookie, res->READDIR3res_u.resok.cookieverf, 8192, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send READDIR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); nfs_free_nfsdir(nfsdir); @@ -1707,6 +2021,140 @@ static void nfs_opendir_cb(struct rpc_context *rpc _U_, int status, void *comman return; } + /* steal the dirhandle */ + nfsdir->current = nfsdir->entries; + + rdpe_cb_data = malloc(sizeof(struct rdpe_cb_data)); + rdpe_cb_data->getattrcount = 0; + rdpe_cb_data->status = RPC_STATUS_SUCCESS; + rdpe_cb_data->data = data; + for (nfsdirent = nfsdir->entries; nfsdirent; nfsdirent = nfsdirent->next) { + struct rdpe_lookup_cb_data *rdpe_lookup_cb_data; + + rdpe_lookup_cb_data = malloc(sizeof(struct rdpe_lookup_cb_data)); + rdpe_lookup_cb_data->rdpe_cb_data = rdpe_cb_data; + rdpe_lookup_cb_data->nfsdirent = nfsdirent; + + if (rpc_nfs_lookup_async(nfs->rpc, nfs_opendir3_cb, &data->fh, nfsdirent->name, rdpe_lookup_cb_data) != 0) { + rpc_set_error(nfs->rpc, "RPC error: Failed to send READDIR LOOKUP call"); + + /* if we have already commands in flight, we cant just stop, we have to wait for the + * commands in flight to complete + */ + if (rdpe_cb_data->getattrcount > 0) { + rdpe_cb_data->status = RPC_STATUS_ERROR; + free(rdpe_lookup_cb_data); + return; + } + + data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); + nfs_free_nfsdir(nfsdir); + data->continue_data = NULL; + free_nfs_cb_data(data); + free(rdpe_lookup_cb_data); + free(rdpe_cb_data); + return; + } + rdpe_cb_data->getattrcount++; + } +} + + +static void nfs_opendir_cb(struct rpc_context *rpc _U_, int status, void *command_data, void *private_data) +{ + READDIRPLUS3res *res = command_data; + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + struct nfsdir *nfsdir = data->continue_data; + struct entryplus3 *entry; + uint64_t cookie; + + + if (status == RPC_STATUS_ERROR || (status == RPC_STATUS_SUCCESS && res->status == NFS3ERR_NOTSUPP) ){ + cookieverf3 cv; + + if (rpc_nfs_readdir_async(nfs->rpc, nfs_opendir2_cb, &data->fh, 0, (char *)&cv, 8192, data) != 0) { + rpc_set_error(nfs->rpc, "RPC error: Failed to send READDIR call for %s", data->path); + data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); + nfs_free_nfsdir(nfsdir); + data->continue_data = NULL; + free_nfs_cb_data(data); + return; + } + return; + } + + if (status == RPC_STATUS_CANCEL) { + data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); + nfs_free_nfsdir(nfsdir); + data->continue_data = NULL; + free_nfs_cb_data(data); + return; + } + + if (res->status != NFS3_OK) { + rpc_set_error(nfs->rpc, "NFS: READDIRPLUS of %s failed with %s(%d)", data->saved_path, nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); + data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); + nfs_free_nfsdir(nfsdir); + data->continue_data = NULL; + free_nfs_cb_data(data); + return; + } + + entry =res->READDIRPLUS3res_u.resok.reply.entries; + while (entry != NULL) { + struct nfsdirent *nfsdirent; + + nfsdirent = malloc(sizeof(struct nfsdirent)); + if (nfsdirent == NULL) { + data->cb(-ENOMEM, nfs, "Failed to allocate dirent", data->private_data); + nfs_free_nfsdir(nfsdir); + data->continue_data = NULL; + free_nfs_cb_data(data); + return; + } + memset(nfsdirent, 0, sizeof(struct nfsdirent)); + nfsdirent->name = strdup(entry->name); + if (nfsdirent->name == NULL) { + data->cb(-ENOMEM, nfs, "Failed to allocate dirent->name", data->private_data); + nfs_free_nfsdir(nfsdir); + data->continue_data = NULL; + free_nfs_cb_data(data); + return; + } + nfsdirent->inode = entry->fileid; + if (entry->name_attributes.attributes_follow) { + nfsdirent->type = entry->name_attributes.post_op_attr_u.attributes.type; + nfsdirent->mode = entry->name_attributes.post_op_attr_u.attributes.mode; + nfsdirent->size = entry->name_attributes.post_op_attr_u.attributes.size; + + nfsdirent->atime.tv_sec = entry->name_attributes.post_op_attr_u.attributes.atime.seconds; + nfsdirent->atime.tv_usec = entry->name_attributes.post_op_attr_u.attributes.atime.nseconds/1000; + nfsdirent->mtime.tv_sec = entry->name_attributes.post_op_attr_u.attributes.mtime.seconds; + nfsdirent->mtime.tv_usec = entry->name_attributes.post_op_attr_u.attributes.mtime.nseconds/1000; + nfsdirent->ctime.tv_sec = entry->name_attributes.post_op_attr_u.attributes.ctime.seconds; + nfsdirent->ctime.tv_usec = entry->name_attributes.post_op_attr_u.attributes.ctime.nseconds/1000; + } + + nfsdirent->next = nfsdir->entries; + nfsdir->entries = nfsdirent; + + cookie = entry->cookie; + entry = entry->nextentry; + } + + if (res->READDIRPLUS3res_u.resok.reply.eof == 0) { + if (rpc_nfs_readdirplus_async(nfs->rpc, nfs_opendir_cb, &data->fh, cookie, res->READDIRPLUS3res_u.resok.cookieverf, 8192, data) != 0) { + rpc_set_error(nfs->rpc, "RPC error: Failed to send READDIRPLUS call for %s", data->path); + data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); + nfs_free_nfsdir(nfsdir); + data->continue_data = NULL; + free_nfs_cb_data(data); + return; + } + return; + } + /* steal the dirhandle */ data->continue_data = NULL; nfsdir->current = nfsdir->entries; @@ -1719,9 +2167,9 @@ static int nfs_opendir_continue_internal(struct nfs_context *nfs, struct nfs_cb_ { cookieverf3 cv; - bzero(cv, sizeof(cookieverf3)); - if (rpc_nfs_readdir_async(nfs->rpc, nfs_opendir_cb, &data->fh, 0, (char *)&cv, 20000, data) != 0) { - rpc_set_error(nfs->rpc, "RPC error: Failed to send READDIR call for %s", data->path); + memset(cv, 0, sizeof(cookieverf3)); + if (rpc_nfs_readdirplus_async(nfs->rpc, nfs_opendir_cb, &data->fh, 0, (char *)&cv, 8192, data) != 0) { + rpc_set_error(nfs->rpc, "RPC error: Failed to send READDIRPLUS call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; @@ -1738,7 +2186,7 @@ int nfs_opendir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void rpc_set_error(nfs->rpc, "failed to allocate buffer for nfsdir"); return -1; } - bzero(nfsdir, sizeof(struct nfsdir)); + memset(nfsdir, 0, sizeof(struct nfsdir)); if (nfs_lookuppath_async(nfs, path, cb, private_data, nfs_opendir_continue_internal, nfsdir, free, 0) != 0) { rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); @@ -1777,7 +2225,7 @@ void nfs_closedir(struct nfs_context *nfs _U_, struct nfsdir *nfsdir) struct lseek_cb_data { struct nfs_context *nfs; struct nfsfh *nfsfh; - off_t offset; + uint64_t offset; nfs_cb cb; void *private_data; }; @@ -1812,7 +2260,7 @@ static void nfs_lseek_1_cb(struct rpc_context *rpc _U_, int status, void *comman free(data); } -int nfs_lseek_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, int whence, nfs_cb cb, void *private_data) +int nfs_lseek_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset, int whence, nfs_cb cb, void *private_data) { struct lseek_cb_data *data; @@ -2012,7 +2460,7 @@ static int nfs_chmod_continue_internal(struct nfs_context *nfs, struct nfs_cb_da { SETATTR3args args; - bzero(&args, sizeof(SETATTR3args)); + memset(&args, 0, sizeof(SETATTR3args)); args.object.data.data_len = data->fh.data.data_len; args.object.data.data_val = data->fh.data.data_val; args.new_attributes.mode.set_it = 1; @@ -2050,7 +2498,7 @@ int nfs_fchmod_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int mode, nfs rpc_set_error(nfs->rpc, "out of memory. failed to allocate memory for nfs mount data"); return -1; } - bzero(data, sizeof(struct nfs_cb_data)); + memset(data, 0, sizeof(struct nfs_cb_data)); data->nfs = nfs; data->cb = cb; data->private_data = private_data; @@ -2116,7 +2564,7 @@ static int nfs_chown_continue_internal(struct nfs_context *nfs, struct nfs_cb_da SETATTR3args args; struct nfs_chown_data *chown_data = data->continue_data; - bzero(&args, sizeof(SETATTR3args)); + memset(&args, 0, sizeof(SETATTR3args)); args.object.data.data_len = data->fh.data.data_len; args.object.data.data_val = data->fh.data.data_val; if (chown_data->uid != (uid_t)-1) { @@ -2183,7 +2631,7 @@ int nfs_fchown_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int uid, int rpc_set_error(nfs->rpc, "out of memory. failed to allocate memory for fchown data"); return -1; } - bzero(data, sizeof(struct nfs_cb_data)); + memset(data, 0, sizeof(struct nfs_cb_data)); data->nfs = nfs; data->cb = cb; data->private_data = private_data; @@ -2247,7 +2695,7 @@ static int nfs_utimes_continue_internal(struct nfs_context *nfs, struct nfs_cb_d SETATTR3args args; struct timeval *utimes_data = data->continue_data; - bzero(&args, sizeof(SETATTR3args)); + memset(&args, 0, sizeof(SETATTR3args)); args.object.data.data_len = data->fh.data.data_len; args.object.data.data_val = data->fh.data.data_val; if (utimes_data != NULL) { @@ -2495,7 +2943,7 @@ int nfs_symlink_async(struct nfs_context *nfs, const char *oldpath, const char * rpc_set_error(nfs->rpc, "Out of memory, failed to allocate buffer for symlink data"); return -1; } - bzero(symlink_data, sizeof(struct nfs_symlink_data)); + memset(symlink_data, 0, sizeof(struct nfs_symlink_data)); symlink_data->oldpath = strdup(oldpath); if (symlink_data->oldpath == NULL) { @@ -2511,7 +2959,7 @@ int nfs_symlink_async(struct nfs_context *nfs, const char *oldpath, const char * return -1; } - ptr = rindex(symlink_data->newpathparent, '/'); + ptr = strrchr(symlink_data->newpathparent, '/'); if (ptr == NULL) { rpc_set_error(nfs->rpc, "Invalid path %s", oldpath); free_nfs_symlink_data(symlink_data); @@ -2649,7 +3097,7 @@ int nfs_rename_async(struct nfs_context *nfs, const char *oldpath, const char *n rpc_set_error(nfs->rpc, "Out of memory, failed to allocate buffer for rename data"); return -1; } - bzero(rename_data, sizeof(struct nfs_rename_data)); + memset(rename_data, 0, sizeof(struct nfs_rename_data)); rename_data->oldpath = strdup(oldpath); if (rename_data->oldpath == NULL) { @@ -2657,7 +3105,7 @@ int nfs_rename_async(struct nfs_context *nfs, const char *oldpath, const char *n free_nfs_rename_data(rename_data); return -1; } - ptr = rindex(rename_data->oldpath, '/'); + ptr = strrchr(rename_data->oldpath, '/'); if (ptr == NULL) { rpc_set_error(nfs->rpc, "Invalid path %s", oldpath); free_nfs_rename_data(rename_data); @@ -2674,7 +3122,7 @@ int nfs_rename_async(struct nfs_context *nfs, const char *oldpath, const char *n free_nfs_rename_data(rename_data); return -1; } - ptr = rindex(rename_data->newpath, '/'); + ptr = strrchr(rename_data->newpath, '/'); if (ptr == NULL) { rpc_set_error(nfs->rpc, "Invalid path %s", newpath); free_nfs_rename_data(rename_data); @@ -2805,7 +3253,7 @@ int nfs_link_async(struct nfs_context *nfs, const char *oldpath, const char *new rpc_set_error(nfs->rpc, "Out of memory, failed to allocate buffer for link data"); return -1; } - bzero(link_data, sizeof(struct nfs_link_data)); + memset(link_data, 0, sizeof(struct nfs_link_data)); link_data->oldpath = strdup(oldpath); if (link_data->oldpath == NULL) { @@ -2820,7 +3268,7 @@ int nfs_link_async(struct nfs_context *nfs, const char *oldpath, const char *new free_nfs_link_data(link_data); return -1; } - ptr = rindex(link_data->newpath, '/'); + ptr = strrchr(link_data->newpath, '/'); if (ptr == NULL) { rpc_set_error(nfs->rpc, "Invalid path %s", newpath); free_nfs_link_data(link_data); @@ -2841,7 +3289,7 @@ int nfs_link_async(struct nfs_context *nfs, const char *oldpath, const char *new //qqq replace later with lseek() -off_t nfs_get_current_offset(struct nfsfh *nfsfh) +uint64_t nfs_get_current_offset(struct nfsfh *nfsfh) { return nfsfh->offset; } @@ -2851,7 +3299,7 @@ off_t nfs_get_current_offset(struct nfsfh *nfsfh) /* * Get the maximum supported READ3 size by the server */ -size_t nfs_get_readmax(struct nfs_context *nfs) +uint64_t nfs_get_readmax(struct nfs_context *nfs) { return nfs->readmax; } @@ -2859,9 +3307,13 @@ size_t nfs_get_readmax(struct nfs_context *nfs) /* * Get the maximum supported WRITE3 size by the server */ -size_t nfs_get_writemax(struct nfs_context *nfs) +uint64_t nfs_get_writemax(struct nfs_context *nfs) { - return nfs->writemax; + /* Some XDR libraries can not marshall PDUs bigger than this */ + if (nfs->writemax < 32768) { + return nfs->writemax; + } + return 32768; } void nfs_set_error(struct nfs_context *nfs, char *error_string, ...) @@ -2870,12 +3322,13 @@ void nfs_set_error(struct nfs_context *nfs, char *error_string, ...) char *str = NULL; va_start(ap, error_string); - vasprintf(&str, error_string, ap); + str = malloc(1024); + vsnprintf(str, 1024, error_string, ap); if (nfs->rpc->error_string != NULL) { free(nfs->rpc->error_string); } nfs->rpc->error_string = str; - va_end(ap); + va_end(ap); } @@ -2922,6 +3375,9 @@ static void mount_export_4_cb(struct rpc_context *rpc, int status, void *command { struct mount_cb_data *data = private_data; + /* Dont want any more callbacks even if the socket is closed */ + rpc->connect_cb = NULL; + if (status == RPC_STATUS_ERROR) { data->cb(rpc, -EFAULT, command_data, data->private_data); free_mount_cb_data(data); @@ -2998,6 +3454,9 @@ static void mount_export_1_cb(struct rpc_context *rpc, int status, void *command { struct mount_cb_data *data = private_data; + /* Dont want any more callbacks even if the socket is closed */ + rpc->connect_cb = NULL; + if (status == RPC_STATUS_ERROR) { data->cb(rpc, -EFAULT, command_data, data->private_data); free_mount_cb_data(data); @@ -3024,7 +3483,7 @@ int mount_getexports_async(struct rpc_context *rpc, const char *server, rpc_cb c if (data == NULL) { return -1; } - bzero(data, sizeof(struct mount_cb_data)); + memset(data, 0, sizeof(struct mount_cb_data)); data->cb = cb; data->private_data = private_data; data->server = strdup(server); @@ -3045,3 +3504,11 @@ struct rpc_context *nfs_get_rpc_context(struct nfs_context *nfs) return nfs->rpc; } +const char *nfs_get_server(struct nfs_context *nfs) { + return nfs->server; +} + +const char *nfs_get_export(struct nfs_context *nfs) { + return nfs->export; +} + diff --git a/lib/pdu.c b/lib/pdu.c index d6e8232..276515e 100644 --- a/lib/pdu.c +++ b/lib/pdu.c @@ -14,9 +14,16 @@ You should have received a copy of the GNU Lesser General Public License along with this program; if not, see . */ +#ifdef WIN32 +#include "win32_compat.h" +#ifndef MSG_DONTWAIT +#define MSG_DONTWAIT 0 +#endif +#else +#include +#endif/*WIN32*/ #include -#include #include #include #include @@ -41,7 +48,7 @@ struct rpc_pdu *rpc_allocate_pdu(struct rpc_context *rpc, int program, int versi rpc_set_error(rpc, "Out of memory: Failed to allocate pdu structure"); return NULL; } - bzero(pdu, sizeof(struct rpc_pdu)); + memset(pdu, 0, sizeof(struct rpc_pdu)); pdu->xid = rpc->xid++; pdu->cb = cb; pdu->private_data = private_data; @@ -53,7 +60,7 @@ struct rpc_pdu *rpc_allocate_pdu(struct rpc_context *rpc, int program, int versi xdr_setpos(&pdu->xdr, 4); /* skip past the record marker */ } - bzero(&msg, sizeof(struct rpc_msg)); + memset(&msg, 0, sizeof(struct rpc_msg)); msg.rm_xid = pdu->xid; msg.rm_direction = CALL; msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; @@ -134,11 +141,6 @@ int rpc_get_pdu_size(char *buf) size = ntohl(*(uint32_t *)buf); - if ((size & 0x80000000) == 0) { - /* cant handle oncrpc fragments */ - return -1; - } - return (size & 0x7fffffff) + 4; } @@ -146,7 +148,7 @@ static int rpc_process_reply(struct rpc_context *rpc, struct rpc_pdu *pdu, XDR * { struct rpc_msg msg; - bzero(&msg, sizeof(struct rpc_msg)); + memset(&msg, 0, sizeof(struct rpc_msg)); msg.acpted_rply.ar_verf = _null_auth; if (pdu->xdr_decode_bufsize > 0) { if (pdu->xdr_decode_buf != NULL) { @@ -158,7 +160,7 @@ static int rpc_process_reply(struct rpc_context *rpc, struct rpc_pdu *pdu, XDR * pdu->cb(rpc, RPC_STATUS_ERROR, "Failed to allocate buffer for decoding of XDR reply", pdu->private_data); return 0; } - bzero(pdu->xdr_decode_buf, pdu->xdr_decode_bufsize); + memset(pdu->xdr_decode_buf, 0, pdu->xdr_decode_bufsize); } msg.acpted_rply.ar_results.where = pdu->xdr_decode_buf; msg.acpted_rply.ar_results.proc = pdu->xdr_decode_fn; @@ -207,10 +209,11 @@ int rpc_process_pdu(struct rpc_context *rpc, char *buf, int size) { struct rpc_pdu *pdu; XDR xdr; - int pos, recordmarker; + int pos, recordmarker = 0; unsigned int xid; + char *reasbuf = NULL; - bzero(&xdr, sizeof(XDR)); + memset(&xdr, 0, sizeof(XDR)); xdrmem_create(&xdr, buf, size, XDR_DECODE); if (rpc->is_udp == 0) { @@ -219,11 +222,50 @@ int rpc_process_pdu(struct rpc_context *rpc, char *buf, int size) xdr_destroy(&xdr); return -1; } + if (!(recordmarker&0x80000000)) { + xdr_destroy(&xdr); + if (rpc_add_fragment(rpc, buf+4, size-4) != 0) { + rpc_set_error(rpc, "Failed to queue fragment for reassembly."); + return -1; + } + return 0; + } } + + /* reassembly */ + if (recordmarker != 0 && rpc->fragments != NULL) { + struct rpc_fragment *fragment; + uint64_t total = size - 4; + char *ptr; + + xdr_destroy(&xdr); + for (fragment = rpc->fragments; fragment; fragment = fragment->next) { + total += fragment->size; + } + + reasbuf = malloc(total); + if (reasbuf == NULL) { + rpc_set_error(rpc, "Failed to reassemble PDU"); + rpc_free_all_fragments(rpc); + return -1; + } + ptr = reasbuf; + for (fragment = rpc->fragments; fragment; fragment = fragment->next) { + memcpy(ptr, fragment->data, fragment->size); + ptr += fragment->size; + } + memcpy(ptr, buf + 4, size - 4); + xdrmem_create(&xdr, reasbuf, total, XDR_DECODE); + rpc_free_all_fragments(rpc); + } + pos = xdr_getpos(&xdr); if (xdr_int(&xdr, (int *)&xid) == 0) { rpc_set_error(rpc, "xdr_int reading xid failed"); xdr_destroy(&xdr); + if (reasbuf != NULL) { + free(reasbuf); + } return -1; } xdr_setpos(&xdr, pos); @@ -242,10 +284,16 @@ int rpc_process_pdu(struct rpc_context *rpc, char *buf, int size) if (rpc->is_udp == 0 || rpc->is_broadcast == 0) { rpc_free_pdu(rpc, pdu); } + if (reasbuf != NULL) { + free(reasbuf); + } return 0; } rpc_set_error(rpc, "No matching pdu found for xid:%d", xid); xdr_destroy(&xdr); + if (reasbuf != NULL) { + free(reasbuf); + } return -1; } diff --git a/lib/socket.c b/lib/socket.c index e4de894..0f12697 100644 --- a/lib/socket.c +++ b/lib/socket.c @@ -14,37 +14,58 @@ You should have received a copy of the GNU Lesser General Public License along with this program; if not, see . */ +#ifdef WIN32 +#include "win32_compat.h" +#else +#include +#include +#include +#include +#include +#include +#endif/*WIN32*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include -#include #include -#include #include #include #include #include -#include #ifdef HAVE_SYS_FILIO_H #include #endif -#include +#ifdef HAVE_SYS_SOCKIO_H +#include +#endif #include -#include -#include #include "libnfs.h" #include "libnfs-raw.h" #include "libnfs-private.h" #include "slist.h" +#ifdef WIN32 +//has to be included after stdlib!! +#include "win32_errnowrapper.h" +#endif + + +static int rpc_reconnect_requeue(struct rpc_context *rpc); +static int rpc_connect_sockaddr_async(struct rpc_context *rpc, struct sockaddr_storage *s); + static void set_nonblocking(int fd) { - unsigned v; + int v = 0; +#if defined(WIN32) + long nonblocking=1; + v = ioctlsocket(fd, FIONBIO,&nonblocking); +#else v = fcntl(fd, F_GETFL, 0); fcntl(fd, F_SETFL, v | O_NONBLOCK); +#endif //FIXME } int rpc_get_fd(struct rpc_context *rpc) @@ -69,7 +90,7 @@ int rpc_which_events(struct rpc_context *rpc) static int rpc_write_to_socket(struct rpc_context *rpc) { - ssize_t count; + int64_t count; if (rpc == NULL) { return -1; @@ -80,11 +101,15 @@ static int rpc_write_to_socket(struct rpc_context *rpc) } while (rpc->outqueue != NULL) { - ssize_t total; + int64_t total; total = rpc->outqueue->outdata.size; +#if defined(WIN32) + count = send(rpc->fd, rpc->outqueue->outdata.data + rpc->outqueue->written, total - rpc->outqueue->written, 0); +#else count = write(rpc->fd, rpc->outqueue->outdata.data + rpc->outqueue->written, total - rpc->outqueue->written); +#endif if (count == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) { return 0; @@ -109,12 +134,17 @@ static int rpc_read_from_socket(struct rpc_context *rpc) int available; int size; int pdu_size; - ssize_t count; + int64_t count; +#if defined(WIN32) + if (ioctlsocket(rpc->fd, FIONREAD, &available) != 0) { +#else if (ioctl(rpc->fd, FIONREAD, &available) != 0) { +#endif rpc_set_error(rpc, "Ioctl FIONREAD returned error : %d. Closing socket.", errno); return -1; } + if (available == 0) { rpc_set_error(rpc, "Socket has been closed"); return -1; @@ -155,7 +185,11 @@ static int rpc_read_from_socket(struct rpc_context *rpc) if (rpc->inpos < 4) { size = 4 - rpc->inpos; +#if defined(WIN32) + count = recv(rpc->fd, rpc->inbuf + rpc->inpos, size, 0); +#else count = read(rpc->fd, rpc->inbuf + rpc->inpos, size); +#endif if (count == -1) { if (errno == EINTR) { return 0; @@ -191,7 +225,11 @@ static int rpc_read_from_socket(struct rpc_context *rpc) size = rpc->insize - rpc->inpos; } +#if defined(WIN32) + count = recv(rpc->fd, rpc->inbuf + rpc->inpos, size, 0); +#else count = read(rpc->fd, rpc->inbuf + rpc->inpos, size); +#endif if (count == -1) { if (errno == EINTR) { return 0; @@ -221,11 +259,15 @@ static int rpc_read_from_socket(struct rpc_context *rpc) int rpc_service(struct rpc_context *rpc, int revents) { if (revents & POLLERR) { +#ifdef WIN32 + char err = 0; +#else int err = 0; +#endif socklen_t err_size = sizeof(err); if (getsockopt(rpc->fd, SOL_SOCKET, SO_ERROR, - &err, &err_size) != 0 || err != 0) { + (char *)&err, &err_size) != 0 || err != 0) { if (err == 0) { err = errno; } @@ -236,12 +278,16 @@ int rpc_service(struct rpc_context *rpc, int revents) rpc_set_error(rpc, "rpc_service: POLLERR, " "Unknown socket error."); } - rpc->connect_cb(rpc, RPC_STATUS_ERROR, rpc->error_string, rpc->connect_data); + if (rpc->connect_cb != NULL) { + rpc->connect_cb(rpc, RPC_STATUS_ERROR, rpc->error_string, rpc->connect_data); + } return -1; } if (revents & POLLHUP) { rpc_set_error(rpc, "Socket failed with POLLHUP"); - rpc->connect_cb(rpc, RPC_STATUS_ERROR, rpc->error_string, rpc->connect_data); + if (rpc->connect_cb != NULL) { + rpc->connect_cb(rpc, RPC_STATUS_ERROR, rpc->error_string, rpc->connect_data); + } return -1; } @@ -250,23 +296,34 @@ int rpc_service(struct rpc_context *rpc, int revents) socklen_t err_size = sizeof(err); if (getsockopt(rpc->fd, SOL_SOCKET, SO_ERROR, - &err, &err_size) != 0 || err != 0) { + (char *)&err, &err_size) != 0 || err != 0) { if (err == 0) { err = errno; } rpc_set_error(rpc, "rpc_service: socket error " "%s(%d) while connecting.", strerror(err), err); - rpc->connect_cb(rpc, RPC_STATUS_ERROR, + if (rpc->connect_cb != NULL) { + rpc->connect_cb(rpc, RPC_STATUS_ERROR, NULL, rpc->connect_data); + } return -1; } rpc->is_connected = 1; - rpc->connect_cb(rpc, RPC_STATUS_SUCCESS, NULL, rpc->connect_data); + if (rpc->connect_cb != NULL) { + rpc->connect_cb(rpc, RPC_STATUS_SUCCESS, NULL, rpc->connect_data); + } return 0; } + if (revents & POLLIN) { + if (rpc_read_from_socket(rpc) != 0) { + rpc_reconnect_requeue(rpc); + return 0; + } + } + if (revents & POLLOUT && rpc->outqueue != NULL) { if (rpc_write_to_socket(rpc) != 0) { rpc_set_error(rpc, "write to socket failed"); @@ -274,22 +331,96 @@ int rpc_service(struct rpc_context *rpc, int revents) } } - if (revents & POLLIN) { - if (rpc_read_from_socket(rpc) != 0) { - rpc_disconnect(rpc, rpc_get_error(rpc)); - return -1; + return 0; +} + +void rpc_set_autoreconnect(struct rpc_context *rpc) +{ + rpc->auto_reconnect = 1; +} + +void rpc_unset_autoreconnect(struct rpc_context *rpc) +{ + rpc->auto_reconnect = 0; +} + +static int rpc_connect_sockaddr_async(struct rpc_context *rpc, struct sockaddr_storage *s) +{ + int socksize; + + switch (s->ss_family) { + case AF_INET: + socksize = sizeof(struct sockaddr_in); + rpc->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + break; + default: + rpc_set_error(rpc, "Can not handle AF_FAMILY:%d", s->ss_family); + return -1; + } + + if (rpc->fd == -1) { + rpc_set_error(rpc, "Failed to open socket"); + return -1; + } + + +#if !defined(WIN32) + /* Some systems allow you to set capabilities on an executable + * to allow the file to be executed with privilege to bind to + * privileged system ports, even if the user is not root. + * + * Opportunistically try to bind the socket to a low numbered + * system port in the hope that the user is either root or the + * executable has the CAP_NET_BIND_SERVICE. + * + * As soon as we fail the bind() with EACCES we know we will never + * be able to bind to a system port so we terminate the loop. + * + * On linux, use + * sudo setcap 'cap_net_bind_service=+ep' /path/executable + * to make the executable able to bind to a system port. + */ + if (1) { + int port; + int one = 1; + + setsockopt(rpc->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)); + + for (port = 200; port < 500; port++) { + struct sockaddr_in sin; + + memset(&sin, 0, sizeof(sin)); + sin.sin_port = htons(port); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = 0; + + if (bind(rpc->fd, (struct sockaddr *)&sin, sizeof(struct sockaddr_in)) != 0 && errno != EACCES) { + /* we didnt get EACCES, so try again */ + continue; + } + break; } } +#endif - return 0; -} + set_nonblocking(rpc->fd); +#if defined(WIN32) + if (connect(rpc->fd, (struct sockaddr *)s, socksize) == 0 && errno != EINPROGRESS ) +#else + if (connect(rpc->fd, (struct sockaddr *)s, socksize) != 0 && errno != EINPROGRESS) +#endif + { + rpc_set_error(rpc, "connect() to server failed"); + return -1; + } + + return 0; +} int rpc_connect_async(struct rpc_context *rpc, const char *server, int port, rpc_cb cb, void *private_data) { - struct sockaddr_storage s; - struct sockaddr_in *sin = (struct sockaddr_in *)&s; - int socksize; + struct sockaddr_in *sin = (struct sockaddr_in *)&rpc->s; if (rpc->fd != -1) { rpc_set_error(rpc, "Trying to connect while already connected"); @@ -301,6 +432,8 @@ int rpc_connect_async(struct rpc_context *rpc, const char *server, int port, rpc return -1; } + rpc->auto_reconnect = 0; + sin->sin_family = AF_INET; sin->sin_port = htons(port); if (inet_pton(AF_INET, server, &sin->sin_addr) != 1) { @@ -308,38 +441,35 @@ int rpc_connect_async(struct rpc_context *rpc, const char *server, int port, rpc return -1; } - switch (s.ss_family) { + + switch (rpc->s.ss_family) { case AF_INET: - socksize = sizeof(struct sockaddr_in); #ifdef HAVE_SOCKADDR_LEN - sin->sin_len = socksize; + sin->sin_len = sizeof(struct sockaddr_in); #endif - rpc->fd = socket(AF_INET, SOCK_STREAM, 0); break; } - if (rpc->fd == -1) { - rpc_set_error(rpc, "Failed to open socket"); - return -1; - } - rpc->connect_cb = cb; rpc->connect_data = private_data; - set_nonblocking(rpc->fd); - - if (connect(rpc->fd, (struct sockaddr *)&s, socksize) != 0 && errno != EINPROGRESS) { - rpc_set_error(rpc, "connect() to server failed"); + if (rpc_connect_sockaddr_async(rpc, &rpc->s) != 0) { return -1; - } + } return 0; } int rpc_disconnect(struct rpc_context *rpc, char *error) { + rpc_unset_autoreconnect(rpc); + if (rpc->fd != -1) { +#if defined(WIN32) + closesocket(rpc->fd); +#else close(rpc->fd); +#endif } rpc->fd = -1; @@ -350,6 +480,55 @@ int rpc_disconnect(struct rpc_context *rpc, char *error) return 0; } +static void reconnect_cb(struct rpc_context *rpc, int status, void *data _U_, void *private_data) +{ + if (status != RPC_STATUS_SUCCESS) { + rpc_error_all_pdus(rpc, "RPC ERROR: Failed to reconnect async"); + return; + } + + rpc->is_connected = 1; + rpc->connect_cb = NULL; +} + +/* disconnect but do not error all PDUs, just move pdus in-flight back to the outqueue and reconnect */ +static int rpc_reconnect_requeue(struct rpc_context *rpc) +{ + struct rpc_pdu *pdu; + + if (rpc->fd != -1) { +#if defined(WIN32) + closesocket(rpc->fd); +#else + close(rpc->fd); +#endif + } + rpc->fd = -1; + + rpc->is_connected = 0; + + /* socket is closed so we will not get any replies to any commands + * in flight. Move them all over from the waitpdu queue back to the out queue + */ + for (pdu=rpc->waitpdu; pdu; pdu=pdu->next) { + SLIST_REMOVE(&rpc->waitpdu, pdu); + SLIST_ADD(&rpc->outqueue, pdu); + /* we have to re-send the whole pdu again */ + pdu->written = 0; + } + + if (rpc->auto_reconnect != 0) { + rpc->connect_cb = reconnect_cb; + + if (rpc_connect_sockaddr_async(rpc, &rpc->s) != 0) { + rpc_error_all_pdus(rpc, "RPC ERROR: Failed to reconnect async"); + return -1; + } + } + + return 0; +} + int rpc_bind_udp(struct rpc_context *rpc, char *addr, int port) { @@ -361,7 +540,7 @@ int rpc_bind_udp(struct rpc_context *rpc, char *addr, int port) return -1; } - snprintf(service, 6, "%d", port); + sprintf(service, "%d", port); if (getaddrinfo(addr, service, NULL, &ai) != 0) { rpc_set_error(rpc, "Invalid address:%s. " "Can not resolv into IPv4/v6 structure."); @@ -404,7 +583,7 @@ int rpc_set_udp_destination(struct rpc_context *rpc, char *addr, int port, int i return -1; } - snprintf(service, 6, "%d", port); + sprintf(service, "%d", port); if (getaddrinfo(addr, service, NULL, &ai) != 0) { rpc_set_error(rpc, "Invalid address:%s. " "Can not resolv into IPv4/v6 structure."); @@ -424,7 +603,7 @@ int rpc_set_udp_destination(struct rpc_context *rpc, char *addr, int port, int i freeaddrinfo(ai); rpc->is_broadcast = is_broadcast; - setsockopt(rpc->fd, SOL_SOCKET, SO_BROADCAST, &is_broadcast, sizeof(is_broadcast)); + setsockopt(rpc->fd, SOL_SOCKET, SO_BROADCAST, (char *)&is_broadcast, sizeof(is_broadcast)); return 0; } @@ -433,3 +612,17 @@ struct sockaddr *rpc_get_recv_sockaddr(struct rpc_context *rpc) { return (struct sockaddr *)&rpc->udp_src; } + +int rpc_queue_length(struct rpc_context *rpc) +{ + int i=0; + struct rpc_pdu *pdu; + + for(pdu = rpc->outqueue; pdu; pdu = pdu->next) { + i++; + } + for(pdu = rpc->waitpdu; pdu; pdu = pdu->next) { + i++; + } + return i; +} diff --git a/libnfs.pc.in b/libnfs.pc.in new file mode 100644 index 0000000..e7e3a91 --- /dev/null +++ b/libnfs.pc.in @@ -0,0 +1,15 @@ +# libnfs pkg-config file + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libnfs +Description: libnfs is a client library for accessing NFS shares over a network. +Version: @VERSION@ +Requires: +Conflicts: +Libs: -L${libdir} -lnfs +Cflags: -I${includedir} +Requires.private: @LIBNFS_PC_REQ_PRIVATE@ diff --git a/ltmain.sh b/ltmain.sh old mode 100755 new mode 100644 index 6f650ae..c7d06c3 --- a/ltmain.sh +++ b/ltmain.sh @@ -1,9 +1,9 @@ -# libtool (GNU libtool) 2.4 +# libtool (GNU libtool) 2.4.2 # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, -# 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +# 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. @@ -41,6 +41,7 @@ # --quiet, --silent don't print informational messages # --no-quiet, --no-silent # print informational messages (default) +# --no-warn don't display warning messages # --tag=TAG use configuration variables from tag TAG # -v, --verbose print more informational messages than default # --no-verbose don't print the extra informational messages @@ -69,7 +70,7 @@ # compiler: $LTCC # compiler flags: $LTCFLAGS # linker: $LD (gnu? $with_gnu_ld) -# $progname: (GNU libtool) 2.4 Debian-2.4-2 +# $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1 # automake: $automake_version # autoconf: $autoconf_version # @@ -79,9 +80,9 @@ PROGRAM=libtool PACKAGE=libtool -VERSION="2.4 Debian-2.4-2" +VERSION="2.4.2 Debian-2.4.2-1" TIMESTAMP="" -package_revision=1.3293 +package_revision=1.3337 # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then @@ -136,15 +137,10 @@ progpath="$0" : ${CP="cp -f"} test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} -: ${EGREP="/bin/grep -E"} -: ${FGREP="/bin/grep -F"} -: ${GREP="/bin/grep"} -: ${LN_S="ln -s"} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} -: ${SED="/bin/sed"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} : ${Xsed="$SED -e 1s/^X//"} @@ -387,7 +383,7 @@ case $progpath in ;; *) save_IFS="$IFS" - IFS=: + IFS=${PATH_SEPARATOR-:} for progdir in $PATH; do IFS="$save_IFS" test -x "$progdir/$progname" && break @@ -771,8 +767,8 @@ func_help () s*\$LTCFLAGS*'"$LTCFLAGS"'* s*\$LD*'"$LD"'* s/\$with_gnu_ld/'"$with_gnu_ld"'/ - s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/ - s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/ + s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/ + s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/ p d } @@ -1052,6 +1048,7 @@ opt_finish=false opt_help=false opt_help_all=false opt_silent=: +opt_warning=: opt_verbose=: opt_silent=false opt_verbose=false @@ -1118,6 +1115,10 @@ esac ;; --no-silent|--no-quiet) opt_silent=false +func_append preserve_args " $opt" + ;; + --no-warning|--no-warn) + opt_warning=false func_append preserve_args " $opt" ;; --no-verbose) @@ -2059,7 +2060,7 @@ func_mode_compile () *.[cCFSifmso] | \ *.ada | *.adb | *.ads | *.asm | \ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ - *.[fF][09]? | *.for | *.java | *.obj | *.sx | *.cu | *.cup) + *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) func_xform "$libobj" libobj=$func_xform_result ;; @@ -3201,11 +3202,13 @@ func_mode_install () # Set up the ranlib parameters. oldlib="$destdir/$name" + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then - func_show_eval "$old_striplib $oldlib" 'exit $?' + func_show_eval "$old_striplib $tool_oldlib" 'exit $?' fi # Do each command in the postinstall commands. @@ -3470,7 +3473,7 @@ static const void *lt_preloaded_setup() { # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. - *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; @@ -3982,14 +3985,17 @@ func_exec_program_core () # launches target application with the remaining arguments. func_exec_program () { - for lt_wr_arg - do - case \$lt_wr_arg in - --lt-*) ;; - *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; - esac - shift - done + case \" \$* \" in + *\\ --lt-*) + for lt_wr_arg + do + case \$lt_wr_arg in + --lt-*) ;; + *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; + esac + shift + done ;; + esac func_exec_program_core \${1+\"\$@\"} } @@ -5057,9 +5063,15 @@ void lt_dump_script (FILE* f) { EOF func_emit_wrapper yes | - $SED -e 's/\([\\"]\)/\\\1/g' \ - -e 's/^/ fputs ("/' -e 's/$/\\n", f);/' - + $SED -n -e ' +s/^\(.\{79\}\)\(..*\)/\1\ +\2/ +h +s/\([\\"]\)/\\\1/g +s/$/\\n/ +s/\([^\n]*\).*/ fputs ("\1", f);/p +g +D' cat <<"EOF" } EOF @@ -5643,7 +5655,8 @@ func_mode_link () continue ;; - -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" @@ -6150,7 +6163,8 @@ func_mode_link () lib= found=no case $deplib in - -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" @@ -6834,7 +6848,7 @@ func_mode_link () test "$hardcode_direct_absolute" = no; then add="$dir/$linklib" elif test "$hardcode_minus_L" = yes; then - add_dir="-L$dir" + add_dir="-L$absdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in @@ -7319,6 +7333,7 @@ func_mode_link () # which has an extra 1 added just for fun # case $version_type in + # correct linux to gnu/linux during the next big refactor darwin|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result @@ -7438,7 +7453,7 @@ func_mode_link () versuffix="$major.$revision" ;; - linux) + linux) # correct to gnu/linux during the next big refactor func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" @@ -8026,6 +8041,11 @@ EOF # Test again, we may have decided not to build it any more if test "$build_libtool_libs" = yes; then + # Remove ${wl} instances when linking with ld. + # FIXME: should test the right _cmds variable. + case $archive_cmds in + *\$LD\ *) wl= ;; + esac if test "$hardcode_into_libs" = yes; then # Hardcode the library paths hardcode_libdirs= @@ -8056,7 +8076,7 @@ EOF elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; - *) func_apped perm_rpath " $libdir" ;; + *) func_append perm_rpath " $libdir" ;; esac fi done @@ -8064,11 +8084,7 @@ EOF if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" - if test -n "$hardcode_libdir_flag_spec_ld"; then - eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" - else - eval dep_rpath=\"$hardcode_libdir_flag_spec\" - fi + eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. @@ -9158,6 +9174,8 @@ EOF esac done fi + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result eval cmds=\"$old_archive_cmds\" func_len " $cmds" @@ -9267,7 +9285,8 @@ EOF *.la) func_basename "$deplib" name="$func_basename_result" - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + func_resolve_sysroot "$deplib" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" diff --git a/mount/Makefile.in b/mount/Makefile.in index 7ff43cc..0750ddb 100644 --- a/mount/Makefile.in +++ b/mount/Makefile.in @@ -100,6 +100,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBNFS_PC_REQ_PRIVATE = @LIBNFS_PC_REQ_PRIVATE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ @@ -124,12 +125,17 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RPCGENFLAGS = @RPCGENFLAGS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +TIRPC_CFLAGS = @TIRPC_CFLAGS@ +TIRPC_LIBS = @TIRPC_LIBS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ diff --git a/mount/mount.c b/mount/mount.c index 525c852..c530a68 100644 --- a/mount/mount.c +++ b/mount/mount.c @@ -15,6 +15,10 @@ along with this program; if not, see . */ +#ifdef WIN32 +#include "win32_compat.h" +#endif/*WIN32*/ + #include #include #include @@ -24,7 +28,6 @@ #include "libnfs-private.h" #include "libnfs-raw-mount.h" - int rpc_mount_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; diff --git a/nfs/Makefile.in b/nfs/Makefile.in index 15f90f3..8963ffc 100644 --- a/nfs/Makefile.in +++ b/nfs/Makefile.in @@ -101,6 +101,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBNFS_PC_REQ_PRIVATE = @LIBNFS_PC_REQ_PRIVATE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ @@ -125,12 +126,17 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RPCGENFLAGS = @RPCGENFLAGS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +TIRPC_CFLAGS = @TIRPC_CFLAGS@ +TIRPC_LIBS = @TIRPC_LIBS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ diff --git a/nfs/nfs.c b/nfs/nfs.c index a9775e7..48f9008 100644 --- a/nfs/nfs.c +++ b/nfs/nfs.c @@ -15,9 +15,14 @@ along with this program; if not, see . */ +#ifdef WIN32 +#include "win32_compat.h" +#else +#include +#endif/*WIN32*/ + #include #include -#include #include #include #include @@ -26,8 +31,6 @@ #include "libnfs-private.h" #include "libnfs-raw-nfs.h" - - char *nfsstat3_to_str(int error) { switch (error) { @@ -212,7 +215,7 @@ int rpc_nfs_access_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, -int rpc_nfs_read_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, off_t offset, size_t count, void *private_data) +int rpc_nfs_read_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, uint64_t offset, uint64_t count, void *private_data) { struct rpc_pdu *pdu; READ3args args; @@ -244,7 +247,7 @@ int rpc_nfs_read_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, o } -int rpc_nfs_write_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *buf, off_t offset, size_t count, int stable_how, void *private_data) +int rpc_nfs_write_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *buf, uint64_t offset, uint64_t count, int stable_how, void *private_data) { struct rpc_pdu *pdu; WRITE3args args; @@ -350,7 +353,7 @@ int rpc_nfs_mkdir_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, return -1; } - bzero(&args, sizeof(MKDIR3args)); + memset(&args, 0, sizeof(MKDIR3args)); args.where.dir.data.data_len = fh->data.data_len; args.where.dir.data.data_val = fh->data.data_val; args.where.name = dir; @@ -386,7 +389,7 @@ int rpc_nfs_rmdir_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, return -1; } - bzero(&args, sizeof(RMDIR3args)); + memset(&args, 0, sizeof(RMDIR3args)); args.object.dir.data.data_len = fh->data.data_len; args.object.dir.data.data_val = fh->data.data_val; args.object.name = dir; @@ -419,7 +422,7 @@ int rpc_nfs_create_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, return -1; } - bzero(&args, sizeof(CREATE3args)); + memset(&args, 0, sizeof(CREATE3args)); args.where.dir.data.data_len = fh->data.data_len; args.where.dir.data.data_val = fh->data.data_val; args.where.name = file; @@ -444,6 +447,66 @@ int rpc_nfs_create_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, +int rpc_nfs_mknod_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *file, int mode, int major, int minor, void *private_data) +{ + struct rpc_pdu *pdu; + MKNOD3args args; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_MKNOD, cb, private_data, (xdrproc_t)xdr_MKNOD3res, sizeof(MKNOD3res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nfs/mknod call"); + return -1; + } + + memset(&args, 0, sizeof(MKNOD3args)); + args.where.dir.data.data_len = fh->data.data_len; + args.where.dir.data.data_val = fh->data.data_val; + args.where.name = file; + switch (mode & S_IFMT) { + case S_IFCHR: + args.what.type = NF3CHR; + args.what.mknoddata3_u.chr_device.dev_attributes.mode.set_it = 1; + args.what.mknoddata3_u.chr_device.dev_attributes.mode.set_mode3_u.mode = mode & (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH); + args.what.mknoddata3_u.chr_device.spec.specdata1 = major; + args.what.mknoddata3_u.chr_device.spec.specdata2 = minor; + break; + case S_IFBLK: + args.what.type = NF3BLK; + args.what.mknoddata3_u.blk_device.dev_attributes.mode.set_it = 1; + args.what.mknoddata3_u.blk_device.dev_attributes.mode.set_mode3_u.mode = mode & (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH); + args.what.mknoddata3_u.blk_device.spec.specdata1 = major; + args.what.mknoddata3_u.blk_device.spec.specdata2 = minor; + case S_IFSOCK: + args.what.type = NF3SOCK; + args.what.mknoddata3_u.sock_attributes.mode.set_it = 1; + args.what.mknoddata3_u.sock_attributes.mode.set_mode3_u.mode = mode & (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH); + break; + case S_IFIFO: + args.what.type = NF3FIFO; + args.what.mknoddata3_u.pipe_attributes.mode.set_it = 1; + args.what.mknoddata3_u.pipe_attributes.mode.set_mode3_u.mode = mode & (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH); + break; + default: + rpc_set_error(rpc, "Invalid file type for nfs/mknod call"); + rpc_free_pdu(rpc, pdu); + return -1; + } + + if (xdr_MKNOD3args(&pdu->xdr, &args) == 0) { + rpc_set_error(rpc, "XDR error: Failed to encode MKNOD3args"); + rpc_free_pdu(rpc, pdu); + return -2; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nfs/mknod call"); + rpc_free_pdu(rpc, pdu); + return -3; + } + + return 0; +} + int rpc_nfs_remove_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *file, void *private_data) { @@ -456,7 +519,7 @@ int rpc_nfs_remove_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, return -1; } - bzero(&args, sizeof(REMOVE3args)); + memset(&args, 0, sizeof(REMOVE3args)); args.object.dir.data.data_len = fh->data.data_len; args.object.dir.data.data_val = fh->data.data_val; args.object.name = file; @@ -476,7 +539,6 @@ int rpc_nfs_remove_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, return 0; } - int rpc_nfs_readdir_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, uint64_t cookie, char *cookieverf, int count, void *private_data) { struct rpc_pdu *pdu; @@ -488,7 +550,7 @@ int rpc_nfs_readdir_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh return -1; } - bzero(&args, sizeof(READDIR3args)); + memset(&args, 0, sizeof(READDIR3args)); args.dir.data.data_len = fh->data.data_len; args.dir.data.data_val = fh->data.data_val; args.cookie = cookie; @@ -510,6 +572,40 @@ int rpc_nfs_readdir_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh return 0; } +int rpc_nfs_readdirplus_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, uint64_t cookie, char *cookieverf, int count, void *private_data) +{ + struct rpc_pdu *pdu; + READDIRPLUS3args args; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_READDIRPLUS, cb, private_data, (xdrproc_t)xdr_READDIRPLUS3res, sizeof(READDIRPLUS3res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nfs/readdirplus call"); + return -1; + } + + memset(&args, 0, sizeof(READDIRPLUS3args)); + args.dir.data.data_len = fh->data.data_len; + args.dir.data.data_val = fh->data.data_val; + args.cookie = cookie; + memcpy(&args.cookieverf, cookieverf, sizeof(cookieverf3)); + args.dircount = count; + args.maxcount = count; + + if (xdr_READDIRPLUS3args(&pdu->xdr, &args) == 0) { + rpc_set_error(rpc, "XDR error: Failed to encode READDIRPLUS3args"); + rpc_free_pdu(rpc, pdu); + return -2; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nfs/readdirplus call"); + rpc_free_pdu(rpc, pdu); + return -3; + } + + return 0; +} + int rpc_nfs_fsstat_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data) { struct rpc_pdu *pdu; @@ -609,7 +705,7 @@ int rpc_nfs_symlink_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh return -1; } - bzero(&args, sizeof(SYMLINK3args)); + memset(&args, 0, sizeof(SYMLINK3args)); args.where.dir.data.data_len = fh->data.data_len; args.where.dir.data.data_val = fh->data.data_val; args.where.name = newname; @@ -646,7 +742,7 @@ int rpc_nfs_rename_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *old return -1; } - bzero(&args, sizeof(RENAME3args)); + memset(&args, 0, sizeof(RENAME3args)); args.from.dir.data.data_len = olddir->data.data_len; args.from.dir.data.data_val = olddir->data.data_val; args.from.name = oldname; @@ -683,7 +779,7 @@ int rpc_nfs_link_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *file, return -1; } - bzero(&args, sizeof(LINK3args)); + memset(&args, 0, sizeof(LINK3args)); args.file.data.data_len = file->data.data_len; args.file.data.data_val = file->data.data_val; args.link.dir.data.data_len = newdir->data.data_len; diff --git a/nfs/nfs.x b/nfs/nfs.x index 026abe5..76b6d7e 100644 --- a/nfs/nfs.x +++ b/nfs/nfs.x @@ -333,8 +333,9 @@ typedef opaque createverf3[NFS3_CREATEVERFSIZE]; union createhow3 switch (createmode3 mode) { case UNCHECKED: - case GUARDED: sattr3 obj_attributes; + case GUARDED: + sattr3 g_obj_attributes; case EXCLUSIVE: createverf3 verf; }; @@ -556,9 +557,11 @@ struct devicedata3 { union mknoddata3 switch (ftype3 type) { case NF3CHR: + devicedata3 chr_device; case NF3BLK: - devicedata3 device; + devicedata3 blk_device; case NF3SOCK: + sattr3 sock_attributes; case NF3FIFO: sattr3 pipe_attributes; default: @@ -813,7 +816,8 @@ program NFS_PROGRAM { SYMLINK3res NFS3_SYMLINK(SYMLINK3args) = 10; -/* MKNOD3res NFSPROC3_MKNOD(MKNOD3args) = 11;*/ + MKNOD3res + NFS3_MKNOD(MKNOD3args) = 11; REMOVE3res NFS3_REMOVE(REMOVE3args) = 12; diff --git a/nfs/nfsacl.c b/nfs/nfsacl.c index 797745c..e48db02 100644 --- a/nfs/nfsacl.c +++ b/nfs/nfsacl.c @@ -14,10 +14,14 @@ You should have received a copy of the GNU Lesser General Public License along with this program; if not, see . */ +#ifdef WIN32 +#include "win32_compat.h" +#else +#include +#endif/*WIN32*/ #include #include -#include #include #include #include diff --git a/packaging/RPM/libnfs.spec.in b/packaging/RPM/libnfs.spec.in new file mode 100644 index 0000000..7fd703d --- /dev/null +++ b/packaging/RPM/libnfs.spec.in @@ -0,0 +1,107 @@ +Name: libnfs +Summary: NFS client library +Vendor: Ronnie Sahlberg +Packager: ronniesahlberg@gmail.com +Version: @VERSION@ +Release: 1 +Epoch: 0 +License: GNU LGPL version 2.1 +Group: System Environment/Libraries +URL: http://www.github.com/sahlberg/libnfs + +Source: libnfs-%{version}.tar.gz + +Provides: lib = %{version} + +Prefix: /usr +BuildRoot: %{_tmppath}/%{name}-%{version}-root + +%description +LibNFS is a NFS client library + +####################################################################### + + + +%prep +%setup -q +# setup the init script and sysconfig file +%setup -T -D -n libnfs-%{version} -q + +%build + +## check for ccache +if ccache -h >/dev/null 2>&1 ; then + CC="ccache gcc" +else + CC="gcc" +fi + +export CC + +## always run autogen.sh +aclocal +autoheader +autoconf +libtoolize -c -f -i +automake --add-missing + + +CFLAGS="$RPM_OPT_FLAGS $EXTRA -O0 -g -D_GNU_SOURCE" ./configure \ + --prefix=%{_prefix} + +%install +# Clean up in case there is trash left from a previous build +rm -rf $RPM_BUILD_ROOT + +# Create the target build directory hierarchy + +make DESTDIR=$RPM_BUILD_ROOT install + +# Remove "*.old" files +find $RPM_BUILD_ROOT -name "*.old" -exec rm -f {} \; + +%clean +rm -rf $RPM_BUILD_ROOT + + +####################################################################### +## Files section ## +####################################################################### + +%files +%defattr(-,root,root) + +%{_libdir}/libnfs.so* + +%package devel +Summary: Development libraries for LibNFS +Group: Development + +%description devel +development libraries for LibNFS + +%files devel +%defattr(-,root,root) +%{_includedir}/nfsc/libnfs.h +%{_includedir}/nfsc/libnfs-raw.h +%{_includedir}/nfsc/libnfs-raw-mount.h +%{_includedir}/nfsc/libnfs-raw-nfs.h +%{_includedir}/nfsc/libnfs-raw-portmap.h +%{_includedir}/nfsc/libnfs-raw-rquota.h +%{_libdir}/libnfs.a +%{_libdir}/libnfs.la +%{_libdir}/pkgconfig/libnfs.pc + +%changelog +* Tue Dec 6 2011 : Version 1.2 + - Add support for MKNOD + - Add support for HaneWin NFS server + - Change all [s]size_t offset_t to be 64bit clean scalars +* Sun Nov 27 2011 : Version 1.1 + - Fix definition and use of AUTH + - Only call the "connect" callback if non-NULL + - make sure the callback for connect is only invoked once for the sync api + - make file offset bits 64 bits always +* Sun Jul 31 2011 : Version 1.0 + - Initial version \ No newline at end of file diff --git a/packaging/RPM/makerpms.sh b/packaging/RPM/makerpms.sh new file mode 100755 index 0000000..c11841b --- /dev/null +++ b/packaging/RPM/makerpms.sh @@ -0,0 +1,112 @@ +#!/bin/sh +# +# makerpms.sh - build RPM packages from the git sources +# +# Copyright (C) John H Terpstra 1998-2002 +# Copyright (C) Gerald (Jerry) Carter 2003 +# Copyright (C) Jim McDonough 2007 +# Copyright (C) Andrew Tridgell 2007 +# Copyright (C) Michael Adam 2008-2009 +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 3 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# + +# +# The following allows environment variables to override the target directories +# the alternative is to have a file in your home directory calles .rpmmacros +# containing the following: +# %_topdir /home/mylogin/redhat +# +# Note: Under this directory rpm expects to find the same directories that are under the +# /usr/src/redhat directory +# + +EXTRA_OPTIONS="$1" + +DIRNAME=$(dirname $0) +TOPDIR=${DIRNAME}/../.. + +SPECDIR=`rpm --eval %_specdir` +SRCDIR=`rpm --eval %_sourcedir` + +SPECFILE="libnfs.spec" +SPECFILE_IN="libnfs.spec.in" +RPMBUILD="rpmbuild" + +# We use tags and determine the version, as follows: +# libnfs-0.9.1 (First release of 0.9). +# libnfs-0.9.23 (23rd minor release of the 112 version) +# +# If we're not directly on a tag, this is a devel release; we append +# .0...devel to the release. +TAG=`git describe` +case "$TAG" in + libnfs-*) + TAG=${TAG##libnfs-} + case "$TAG" in + *-*-g*) # 0.9-168-ge6cf0e8 + # Not exactly on tag: devel version. + VERSION=`echo "$TAG" | sed 's/\([^-]\+\)-\([0-9]\+\)-\(g[0-9a-f]\+\)/\1.0.\2.\3.devel/'` + ;; + *) + # An actual release version + VERSION=$TAG + ;; + esac + ;; + *) + echo Invalid tag "$TAG" >&2 + exit 1 + ;; +esac + +sed -e s/@VERSION@/$VERSION/g \ + < ${DIRNAME}/${SPECFILE_IN} \ + > ${DIRNAME}/${SPECFILE} + +VERSION=$(grep ^Version ${DIRNAME}/${SPECFILE} | sed -e 's/^Version:\ \+//') + +if echo | gzip -c --rsyncable - > /dev/null 2>&1 ; then + GZIP="gzip -9 --rsyncable" +else + GZIP="gzip -9" +fi + +pushd ${TOPDIR} +echo -n "Creating libnfs-${VERSION}.tar.gz ... " +git archive --prefix=libnfs-${VERSION}/ HEAD | ${GZIP} > ${SRCDIR}/libnfs-${VERSION}.tar.gz +RC=$? +popd +echo "Done." +if [ $RC -ne 0 ]; then + echo "Build failed!" + exit 1 +fi + +# At this point the SPECDIR and SRCDIR vaiables must have a value! + +## +## copy additional source files +## +cp -p ${DIRNAME}/${SPECFILE} ${SPECDIR} + +## +## Build +## +echo "$(basename $0): Getting Ready to build release package" +${RPMBUILD} -ba --clean --rmsource ${EXTRA_OPTIONS} ${SPECDIR}/${SPECFILE} || exit 1 + +echo "$(basename $0): Done." + +exit 0 diff --git a/portmap/Makefile.in b/portmap/Makefile.in index 2eeac83..957171d 100644 --- a/portmap/Makefile.in +++ b/portmap/Makefile.in @@ -100,6 +100,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBNFS_PC_REQ_PRIVATE = @LIBNFS_PC_REQ_PRIVATE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ @@ -124,12 +125,17 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RPCGENFLAGS = @RPCGENFLAGS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +TIRPC_CFLAGS = @TIRPC_CFLAGS@ +TIRPC_LIBS = @TIRPC_LIBS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ diff --git a/portmap/portmap.c b/portmap/portmap.c index 07aa912..f8c434d 100644 --- a/portmap/portmap.c +++ b/portmap/portmap.c @@ -14,6 +14,9 @@ You should have received a copy of the GNU Lesser General Public License along with this program; if not, see . */ +#ifdef WIN32 +#include "win32_compat.h" +#endif/*WIN32*/ #include #include diff --git a/rquota/Makefile.in b/rquota/Makefile.in index b9f5c47..a23ed70 100644 --- a/rquota/Makefile.in +++ b/rquota/Makefile.in @@ -100,6 +100,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBNFS_PC_REQ_PRIVATE = @LIBNFS_PC_REQ_PRIVATE@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ @@ -124,12 +125,17 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ RPCGENFLAGS = @RPCGENFLAGS@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ +TIRPC_CFLAGS = @TIRPC_CFLAGS@ +TIRPC_LIBS = @TIRPC_LIBS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ diff --git a/rquota/rquota.c b/rquota/rquota.c index 30abc67..549f2ff 100644 --- a/rquota/rquota.c +++ b/rquota/rquota.c @@ -14,6 +14,9 @@ You should have received a copy of the GNU Lesser General Public License along with this program; if not, see . */ +#ifdef WIN32 +#include "win32_compat.h" +#endif/*WIN32*/ #include #include diff --git a/win32/libnfs/libnfs.sln b/win32/libnfs/libnfs.sln new file mode 100644 index 0000000..f7b925f --- /dev/null +++ b/win32/libnfs/libnfs.sln @@ -0,0 +1,29 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual C++ Express 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libnfs", "libnfs.vcxproj", "{7CAB9B67-6AA9-497F-A900-20D9D05049F5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nfsclient-sync", "..\nfsclient-sync\nfsclient-sync.vcxproj", "{B907AC9A-50C5-4E43-97C3-27DC7241F6C5}" + ProjectSection(ProjectDependencies) = postProject + {7CAB9B67-6AA9-497F-A900-20D9D05049F5} = {7CAB9B67-6AA9-497F-A900-20D9D05049F5} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7CAB9B67-6AA9-497F-A900-20D9D05049F5}.Debug|Win32.ActiveCfg = Debug|Win32 + {7CAB9B67-6AA9-497F-A900-20D9D05049F5}.Debug|Win32.Build.0 = Debug|Win32 + {7CAB9B67-6AA9-497F-A900-20D9D05049F5}.Release|Win32.ActiveCfg = Release|Win32 + {7CAB9B67-6AA9-497F-A900-20D9D05049F5}.Release|Win32.Build.0 = Release|Win32 + {B907AC9A-50C5-4E43-97C3-27DC7241F6C5}.Debug|Win32.ActiveCfg = Debug|Win32 + {B907AC9A-50C5-4E43-97C3-27DC7241F6C5}.Debug|Win32.Build.0 = Debug|Win32 + {B907AC9A-50C5-4E43-97C3-27DC7241F6C5}.Release|Win32.ActiveCfg = Release|Win32 + {B907AC9A-50C5-4E43-97C3-27DC7241F6C5}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/win32/libnfs/libnfs.vcxproj b/win32/libnfs/libnfs.vcxproj new file mode 100644 index 0000000..e46c074 --- /dev/null +++ b/win32/libnfs/libnfs.vcxproj @@ -0,0 +1,154 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {7CAB9B67-6AA9-497F-A900-20D9D05049F5} + Win32Proj + libnfs + + + + DynamicLibrary + true + MultiByte + + + DynamicLibrary + false + true + MultiByte + + + + + + + + + + + + + true + ..\..\..\oncrpc-win32\win32\bin;$(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSdkDir)lib;$(FrameworkSDKDir)\lib + ..\..\..\oncrpc-win32\win32\bin;$(VCInstallDir)bin;$(WindowsSdkDir)bin\NETFX 4.0 Tools;$(WindowsSdkDir)bin;$(VSInstallDir)Common7\Tools\bin;$(VSInstallDir)Common7\tools;$(VSInstallDir)Common7\ide;$(ProgramFiles)\HTML Help Workshop;$(FrameworkSDKDir)\bin;$(MSBuildToolsPath32);$(VSInstallDir);$(SystemRoot)\SysWow64;$(FxCopDir);$(PATH); + + + false + ..\..\..\oncrpc-win32\win32\bin;$(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSdkDir)lib;$(FrameworkSDKDir)\lib + ..\..\..\oncrpc-win32\win32\bin;$(VCInstallDir)bin;$(WindowsSdkDir)bin\NETFX 4.0 Tools;$(WindowsSdkDir)bin;$(VSInstallDir)Common7\Tools\bin;$(VSInstallDir)Common7\tools;$(VSInstallDir)Common7\ide;$(ProgramFiles)\HTML Help Workshop;$(FrameworkSDKDir)\bin;$(MSBuildToolsPath32);$(VSInstallDir);$(SystemRoot)\SysWow64;$(FxCopDir);$(PATH); + + + + + + Level3 + Disabled + WIN32;NDEBUG;_WINDOWS;_USRDLL;_WIN32_WINNT=0x0501;_U_=;_USE_32BIT_TIME_T;__STDC_CONSTANT_MACROS;%(PreprocessorDefinitions) + ..\..\..\oncrpc-win32\win32\include;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs;..\..\lib + Default + 4996 + + + Windows + true + ..\..\lib\libnfs-win32.def + oncrpc.lib;ws2_32.lib;%(AdditionalDependencies) + MSVCRT + + + copy $(ProjectDir)..\..\nfs\nfs.x $(ProjectDir)..\..\nfs\libnfs-raw-nfs.x +rpcgen.exe -h $(ProjectDir)..\..\nfs\libnfs-raw-nfs.x > $(ProjectDir)..\..\nfs\libnfs-raw-nfs.h +rpcgen.exe -c $(ProjectDir)..\..\nfs\libnfs-raw-nfs.x > $(ProjectDir)..\..\nfs\libnfs-raw-nfs.c + +copy $(ProjectDir)..\..\rquota\rquota.x $(ProjectDir)..\..\rquota\libnfs-raw-rquota.x +rpcgen.exe -h $(ProjectDir)..\..\rquota\libnfs-raw-rquota.x > $(ProjectDir)..\..\rquota\libnfs-raw-rquota.h +rpcgen.exe -c $(ProjectDir)..\..\rquota\libnfs-raw-rquota.x > $(ProjectDir)..\..\rquota\libnfs-raw-rquota.c + +copy $(ProjectDir)..\..\portmap\portmap.x $(ProjectDir)..\..\portmap\libnfs-raw-portmap.x +rpcgen.exe -h $(ProjectDir)..\..\portmap\libnfs-raw-portmap.x > $(ProjectDir)..\..\portmap\libnfs-raw-portmap.h +rpcgen.exe -c $(ProjectDir)..\..\portmap\libnfs-raw-portmap.x > $(ProjectDir)..\..\portmap\libnfs-raw-portmap.c + +copy $(ProjectDir)..\..\mount\mount.x $(ProjectDir)..\..\mount\libnfs-raw-mount.x +rpcgen.exe -h $(ProjectDir)..\..\mount\libnfs-raw-mount.x > $(ProjectDir)..\..\mount\libnfs-raw-mount.h +rpcgen.exe -c $(ProjectDir)..\..\mount\libnfs-raw-mount.x > $(ProjectDir)..\..\mount\libnfs-raw-mount.c + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;_WIN32_WINNT=0x0501;_U_=;_USE_32BIT_TIME_T;__STDC_CONSTANT_MACROS;%(PreprocessorDefinitions) + ..\..\..\oncrpc-win32\win32\include;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs;..\..\lib + 4996 + + + Windows + true + true + true + oncrpc.lib;ws2_32.lib;%(AdditionalDependencies) + ..\..\lib\libnfs-win32.def + + + copy $(ProjectDir)..\..\nfs\nfs.x $(ProjectDir)..\..\nfs\libnfs-raw-nfs.x +rpcgen.exe -h $(ProjectDir)..\..\nfs\libnfs-raw-nfs.x > $(ProjectDir)..\..\nfs\libnfs-raw-nfs.h +rpcgen.exe -c $(ProjectDir)..\..\nfs\libnfs-raw-nfs.x > $(ProjectDir)..\..\nfs\libnfs-raw-nfs.c + +copy $(ProjectDir)..\..\rquota\rquota.x $(ProjectDir)..\..\rquota\libnfs-raw-rquota.x +rpcgen.exe -h $(ProjectDir)..\..\rquota\libnfs-raw-rquota.x > $(ProjectDir)..\..\rquota\libnfs-raw-rquota.h +rpcgen.exe -c $(ProjectDir)..\..\rquota\libnfs-raw-rquota.x > $(ProjectDir)..\..\rquota\libnfs-raw-rquota.c + +copy $(ProjectDir)..\..\portmap\portmap.x $(ProjectDir)..\..\portmap\libnfs-raw-portmap.x +rpcgen.exe -h $(ProjectDir)..\..\portmap\libnfs-raw-portmap.x > $(ProjectDir)..\..\portmap\libnfs-raw-portmap.h +rpcgen.exe -c $(ProjectDir)..\..\portmap\libnfs-raw-portmap.x > $(ProjectDir)..\..\portmap\libnfs-raw-portmap.c + +copy $(ProjectDir)..\..\mount\mount.x $(ProjectDir)..\..\mount\libnfs-raw-mount.x +rpcgen.exe -h $(ProjectDir)..\..\mount\libnfs-raw-mount.x > $(ProjectDir)..\..\mount\libnfs-raw-mount.h +rpcgen.exe -c $(ProjectDir)..\..\mount\libnfs-raw-mount.x > $(ProjectDir)..\..\mount\libnfs-raw-mount.c + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/win32/libnfs/libnfs.vcxproj.filters b/win32/libnfs/libnfs.vcxproj.filters new file mode 100644 index 0000000..24f3db0 --- /dev/null +++ b/win32/libnfs/libnfs.vcxproj.filters @@ -0,0 +1,80 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + + \ No newline at end of file diff --git a/win32/nfsclient-sync/nfsclient-sync.vcxproj b/win32/nfsclient-sync/nfsclient-sync.vcxproj new file mode 100644 index 0000000..b72672e --- /dev/null +++ b/win32/nfsclient-sync/nfsclient-sync.vcxproj @@ -0,0 +1,92 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {B907AC9A-50C5-4E43-97C3-27DC7241F6C5} + Win32Proj + nfsclientsync + + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + true + ..\libnfs\Debug;..\..\..\oncrpc-win32\win32\bin;$(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSdkDir)lib;$(FrameworkSDKDir)\lib + + + false + ..\libnfs\Release;..\..\..\oncrpc-win32\win32\bin;$(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSdkDir)lib;$(FrameworkSDKDir)\lib + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_U_=;%(PreprocessorDefinitions) + ..\..\..\oncrpc-win32\win32\include;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs + + + Console + true + libnfs.lib;oncrpc.lib;WS2_32.lib;%(AdditionalDependencies) + + + false + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_U_=;%(PreprocessorDefinitions) + ..\..\..\oncrpc-win32\win32\include;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs + + + Console + true + true + true + libnfs.lib;oncrpc.lib;WS2_32.lib;%(AdditionalDependencies) + + + + + + + + + \ No newline at end of file diff --git a/win32/nfsclient-sync/nfsclient-sync.vcxproj.filters b/win32/nfsclient-sync/nfsclient-sync.vcxproj.filters new file mode 100644 index 0000000..bfa1b9d --- /dev/null +++ b/win32/nfsclient-sync/nfsclient-sync.vcxproj.filters @@ -0,0 +1,14 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + Source Files + + + \ No newline at end of file diff --git a/win32/win32_compat.c b/win32/win32_compat.c new file mode 100644 index 0000000..fe2ca05 --- /dev/null +++ b/win32/win32_compat.c @@ -0,0 +1,201 @@ +/* +Copyright (c) 2006 by Dan Kennedy. +Copyright (c) 2006 by Juliusz Chroboczek. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifndef WIN32 + +static int dummy ATTRIBUTE((unused)); + +#else +#include "win32_compat.h" +#include +#include +#include < time.h > + +#undef poll +#undef socket +#undef connect +#undef accept +#undef shutdown +#undef getpeername +#undef sleep +#undef inet_aton +#undef gettimeofday +#undef stat +#define assert(a) + +/* Windows needs this header file for the implementation of inet_aton() */ +#include + +int win32_inet_pton(int af, const char * src, void * dst) +{ + struct sockaddr_in sa; + int len = sizeof(SOCKADDR); + int ret = -1; + int strLen = strlen(src) + 1; +#ifdef UNICODE + wchar_t *srcNonConst = (wchar_t *)malloc(strLen*sizeof(wchar_t)); + memset(srcNonConst, 0, strLen); + MultiByteToWideChar(CP_ACP, 0, src, -1, srcNonConst, strLen); +#else + char *srcNonConst = (char *)malloc(strLen); + memset(srcNonConst, 0, strLen); + strncpy(srcNonConst, src, strLen); +#endif + + if( WSAStringToAddress(srcNonConst,af,NULL,(LPSOCKADDR)&sa,&len) == 0 ) + { + ret = 1; + } + else + { + if( WSAGetLastError() == WSAEINVAL ) + { + ret = -1; + } + } + free(srcNonConst); + memcpy(dst, &sa.sin_addr, sizeof(struct in_addr)); + return ret; +} + +int win32_poll(struct pollfd *fds, unsigned int nfds, int timo) +{ + struct timeval timeout, *toptr; + fd_set ifds, ofds, efds, *ip, *op; + unsigned int i; + int rc; + + // Set up the file-descriptor sets in ifds, ofds and efds. + FD_ZERO(&ifds); + FD_ZERO(&ofds); + FD_ZERO(&efds); + for (i = 0, op = ip = 0; i < nfds; ++i) + { + fds[i].revents = 0; + if(fds[i].events & (POLLIN|POLLPRI)) + { + ip = &ifds; + FD_SET(fds[i].fd, ip); + } + if(fds[i].events & POLLOUT) + { + op = &ofds; + FD_SET(fds[i].fd, op); + } + FD_SET(fds[i].fd, &efds); + } + + // Set up the timeval structure for the timeout parameter + if(timo < 0) + { + toptr = 0; + } + else + { + toptr = &timeout; + timeout.tv_sec = timo / 1000; + timeout.tv_usec = (timo - timeout.tv_sec * 1000) * 1000; + } + +#ifdef DEBUG_POLL + printf("Entering select() sec=%ld usec=%ld ip=%lx op=%lx\n", + (long)timeout.tv_sec, (long)timeout.tv_usec, (long)ip, (long)op); +#endif + rc = select(0, ip, op, &efds, toptr); +#ifdef DEBUG_POLL + printf("Exiting select rc=%d\n", rc); +#endif + + if(rc <= 0) + return rc; + + if(rc > 0) + { + for (i = 0; i < nfds; ++i) + { + int fd = fds[i].fd; + if(fds[i].events & (POLLIN|POLLPRI) && FD_ISSET(fd, &ifds)) + fds[i].revents |= POLLIN; + if(fds[i].events & POLLOUT && FD_ISSET(fd, &ofds)) + fds[i].revents |= POLLOUT; + if(FD_ISSET(fd, &efds)) // Some error was detected ... should be some way to know. + fds[i].revents |= POLLHUP; +#ifdef DEBUG_POLL + printf("%d %d %d revent = %x\n", + FD_ISSET(fd, &ifds), FD_ISSET(fd, &ofds), FD_ISSET(fd, &efds), + fds[i].revents + ); +#endif + } + } + return rc; +} + +#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) + #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 +#else + #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL +#endif + +struct timezone +{ + int tz_minuteswest; /* minutes W of Greenwich */ + int tz_dsttime; /* type of dst correction */ +}; + +int win32_gettimeofday(struct timeval *tv, struct timezone *tz) +{ + FILETIME ft; + unsigned __int64 tmpres = 0; + static int tzflag; + + if (NULL != tv) + { + GetSystemTimeAsFileTime(&ft); + + tmpres |= ft.dwHighDateTime; + tmpres <<= 32; + tmpres |= ft.dwLowDateTime; + + /*converting file time to unix epoch*/ + tmpres -= DELTA_EPOCH_IN_MICROSECS; + tmpres /= 10; /*convert into microseconds*/ + tv->tv_sec = (long)(tmpres / 1000000UL); + tv->tv_usec = (long)(tmpres % 1000000UL); + } + + if (NULL != tz) + { + if (!tzflag) + { + _tzset(); + tzflag++; + } + tz->tz_minuteswest = _timezone / 60; + tz->tz_dsttime = _daylight; + } + + return 0; +} + +#endif diff --git a/win32/win32_compat.h b/win32/win32_compat.h new file mode 100644 index 0000000..9972e5d --- /dev/null +++ b/win32/win32_compat.h @@ -0,0 +1,83 @@ +/* +Copyright (c) 2006 by Dan Kennedy. +Copyright (c) 2006 by Juliusz Chroboczek. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ +/*Adaptions by memphiz@xbmc.org*/ + +#ifdef WIN32 +#ifndef win32_COMPAT_H_ +#define win32_COMPAT_H_ +#define NO_IPv6 1 + +#include +#include +#include +#include +#include +#include + +typedef int uid_t; +typedef int gid_t; +typedef int socklen_t; + +#define S_IRUSR 0000400 +#define S_IWUSR 0000200 +#define S_IXUSR 0000100 +#define S_IRWXG 0000070 /* RWX mask for group */ +#define S_IRGRP 0000040 +#define S_IWGRP 0000020 +#define S_IXGRP 0000010 +#define S_IRWXO 0000007 /* RWX mask for other */ +#define S_IROTH 0000004 +#define S_IWOTH 0000002 +#define S_IXOTH 0000001 + +#define F_GETFL 3 +#define F_SETFL 4 + +#define O_NONBLOCK 0x40000000 +#define O_SYNC 0 + +#define MSG_DONTWAIT 0 +#define ssize_t SSIZE_T + +#define POLLIN 0x0001 /* There is data to read */ +#define POLLPRI 0x0002 /* There is urgent data to read */ +#define POLLOUT 0x0004 /* Writing now will not block */ +#define POLLERR 0x0008 /* Error condition */ +#define POLLHUP 0x0010 /* Hung up */ +#define POLLNVAL 0x0020 /* Invalid request: fd not open */ + +struct pollfd { + SOCKET fd; /* file descriptor */ + short events; /* requested events */ + short revents; /* returned events */ +}; + +/* Wrapper macros to call misc. functions win32 is missing */ +#define poll(x, y, z) win32_poll(x, y, z) +#define inet_pton(x,y,z) win32_inet_pton(x,y,z) +int win32_inet_pton(int af, const char * src, void * dst); +int win32_poll(struct pollfd *fds, unsigned int nfsd, int timeout); +int win32_gettimeofday(struct timeval *tv, struct timezone *tz); + +#endif//win32_COMPAT_H_ +#endif//WIN32 diff --git a/win32/win32_errnowrapper.h b/win32/win32_errnowrapper.h new file mode 100644 index 0000000..4477d3f --- /dev/null +++ b/win32/win32_errnowrapper.h @@ -0,0 +1,15 @@ +#ifndef WIN32_ERRNOWRAPPER_H_ +#define WIN32_ERRNOWRAPPER_H_ + +#undef errno +#define errno WSAGetLastError() +#undef EAGAIN +#undef EWOULDBLOCK +#undef EINTR +#undef EINPROGRESS + +#define EWOULDBLOCK WSAEWOULDBLOCK +#define EAGAIN WSAEWOULDBLOCK //same on windows +#define EINTR WSAEINTR +#define EINPROGRESS WSAEINPROGRESS +#endif //WIN32_ERRNOWRAPPER_H_ diff --git a/win32/win32build.bat b/win32/win32build.bat new file mode 100644 index 0000000..55317ec --- /dev/null +++ b/win32/win32build.bat @@ -0,0 +1,97 @@ +rem build script for win32 +rem set the +rem + +rem EDIT THESE +set ONCRPC_BASE_DIR=C:\MinGW\msys\1.0\home\Administrator\src\oncrpc-win32\ +set LIBNFS_BASE_DIR=.. +rem END EDIT + +set RPCINCLUDE="%ONCRPC_BASE_DIR%\win32\include" +set RPCDLL="%ONCRPC_BASE_DIR%\win32\bin\oncrpc.dll" +set RPCLIB="%ONCRPC_BASE_DIR%\win32\bin\oncrpc.lib" +set RPCGEN="%ONCRPC_BASE_DIR%\win32\bin\rpcgen.exe" + + +cd %LIBNFS_BASE_DIR% + +rem generate NFS from .x +rem +copy nfs\nfs.x nfs\libnfs-raw-nfs.x +%RPCGEN% -h nfs\libnfs-raw-nfs.x > nfs\libnfs-raw-nfs.h +%RPCGEN% -c nfs\libnfs-raw-nfs.x > nfs\libnfs-raw-nfs.c +cl /I. /Iinclude /Iwin32 /I%RPCINCLUDE% -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0501 -MDd nfs\libnfs-raw-nfs.c -Fonfs\libnfs-raw-nfs.obj +cl /I. /Iinclude /Iwin32 /I%RPCINCLUDE% -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0501 -MDd nfs\nfs.c -Fonfs\nfs.obj +cl /I. /Iinclude /Iwin32 /I%RPCINCLUDE% -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0501 -MDd nfs\nfsacl.c -Fonfs\nfsacl.obj + + + +rem +rem generate RQUOTA from .x +rem +copy rquota\rquota.x rquota\libnfs-raw-rquota.x +%RPCGEN% -h rquota\libnfs-raw-rquota.x > rquota\libnfs-raw-rquota.h +%RPCGEN% -c rquota\libnfs-raw-rquota.x > rquota\libnfs-raw-rquota.c +cl /I. /Iinclude /Iwin32 /I%RPCINCLUDE% -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0501 -MDd rquota\libnfs-raw-rquota.c -Forquota\libnfs-raw-rquota.obj +cl /I. /Iinclude /Iwin32 /I%RPCINCLUDE% -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0501 -MDd rquota\rquota.c -Forquota\rquota.obj + + + +rem +rem generate PORTMAP from .x +rem +copy portmap\portmap.x portmap\libnfs-raw-portmap.x +%RPCGEN% -h portmap\libnfs-raw-portmap.x > portmap\libnfs-raw-portmap.h +%RPCGEN% -c portmap\libnfs-raw-portmap.x > portmap\libnfs-raw-portmap.c +cl /I. /Iinclude /Iwin32 /I%RPCINCLUDE% -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0501 -MDd portmap\libnfs-raw-portmap.c -Foportmap\libnfs-raw-portmap.obj +cl /I. /Iinclude /Iwin32 /I%RPCINCLUDE% -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0501 -MDd portmap\portmap.c -Foportmap\portmap.obj + + +rem +rem generate MOUNT from .x +rem +copy mount\mount.x mount\libnfs-raw-mount.x +%RPCGEN% -h mount\libnfs-raw-mount.x > mount\libnfs-raw-mount.h +%RPCGEN% -c mount\libnfs-raw-mount.x > mount\libnfs-raw-mount.c +cl /I. /Iinclude /Iwin32 /I%RPCINCLUDE% -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0501 -MDd mount\libnfs-raw-mount.c -Fomount\libnfs-raw-mount.obj +cl /I. /Iinclude /Iwin32 /I%RPCINCLUDE% -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0501 -MDd mount\mount.c -Fomount\mount.obj + + + +rem +rem generate core part of library +rem +cl /I. /Iinclude /Iwin32 /I%RPCINCLUDE% -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0501 -MDd lib\init.c -Folib\init.obj +cl /I. /Iinclude /Iwin32 /I%RPCINCLUDE% -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0501 -MDd -D_U_="" lib\pdu.c -Folib\pdu.obj +cl /I. /Iinclude /Iwin32 /I%RPCINCLUDE% -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0501 -MDd -D_U_="" lib\socket.c -Folib\socket.obj +cl /I. /Iinclude /Iwin32 /I%RPCINCLUDE% /Imount /Infs -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0501 -MDd -D_U_="" lib\libnfs.c -Folib\libnfs.obj +cl /I. /Iinclude /Iwin32 /I%RPCINCLUDE% /Imount /Infs -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0501 -MDd -D_U_="" lib\libnfs-sync.c -Folib\libnfs-sync.obj + +rem +rem generate win32 compat layer +rem +cl /I. -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0501 -MDd -D_U_="" win32\win32_compat.c -Fowin32\win32_compat.obj + + + +rem +rem create a linklibrary/dll +rem +lib /out:lib\libnfs.lib /def:lib\libnfs-win32.def nfs\nfs.obj nfs\nfsacl.obj nfs\libnfs-raw-nfs.obj rquota\rquota.obj rquota\libnfs-raw-rquota.obj mount\mount.obj mount\libnfs-raw-mount.obj portmap\portmap.obj portmap\libnfs-raw-portmap.obj lib\init.obj lib\pdu.obj lib\socket.obj lib\libnfs.obj lib\libnfs-sync.obj win32\win32_compat.obj + +link /DLL /out:lib\libnfs.dll /DEBUG /DEBUGTYPE:cv lib\libnfs.exp nfs\nfs.obj nfs\nfsacl.obj nfs\libnfs-raw-nfs.obj rquota\rquota.obj rquota\libnfs-raw-rquota.obj mount\mount.obj mount\libnfs-raw-mount.obj portmap\portmap.obj portmap\libnfs-raw-portmap.obj lib\init.obj lib\pdu.obj lib\socket.obj lib\libnfs.obj lib\libnfs-sync.obj win32\win32_compat.obj %RPCLIB% ws2_32.lib + + + +rem +rem build a test application +rem +cl /I. /Iinclude /Iwin32 /I%RPCINCLUDE% /Imount /Infs -Zi -Od -DWIN32 -D_WIN32_WINNT=0x0501 -MDd -D_U_="" examples\nfsclient-sync.c lib\libnfs.lib %RPCLIB% WS2_32.lib kernel32.lib mswsock.lib advapi32.lib wsock32.lib advapi32.lib + + + + + + + + diff --git a/win32build.bat b/win32build.bat new file mode 100755 index 0000000..e690fa2 --- /dev/null +++ b/win32build.bat @@ -0,0 +1,87 @@ +rem build script for win32 +rem set the +rem + +rem EDIT THESE +set RPCINCLUDE="C:\...where my rpc includes live...\include" +set RPCDLL="C:\...where my rpc DLL can be found...\rpc.dll" +set RPCLIB="C:\...where my rpc link library can be found...\rpc.lib" +set RPCGEN="C:\...where my rpcgen executable lives...\rpcgen.exe" + + + +rem generate NFS from .x +rem +copy nfs\nfs.x nfs\libnfs-raw-nfs.x +%RPCGEN% -h nfs\libnfs-raw-nfs.x > nfs\libnfs-raw-nfs.h +%RPCGEN% -c nfs\libnfs-raw-nfs.x > nfs\libnfs-raw-nfs.c +cl /I. /Iinclude /I%RPCINCLUDE% -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0600 -MDd nfs\libnfs-raw-nfs.c -Fonfs\libnfs-raw-nfs.obj +cl /I. /Iinclude /I%RPCINCLUDE% -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0600 -MDd nfs\nfs.c -Fonfs\nfs.obj +cl /I. /Iinclude /I%RPCINCLUDE% -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0600 -MDd nfs\nfsacl.c -Fonfs\nfsacl.obj + + + +rem +rem generate RQUOTA from .x +rem +copy rquota\rquota.x rquota\libnfs-raw-rquota.x +%RPCGEN% -h rquota\libnfs-raw-rquota.x > rquota\libnfs-raw-rquota.h +%RPCGEN% -c rquota\libnfs-raw-rquota.x > rquota\libnfs-raw-rquota.c +cl /I. /Iinclude /I%RPCINCLUDE% -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0600 -MDd rquota\libnfs-raw-rquota.c -Forquota\libnfs-raw-rquota.obj +cl /I. /Iinclude /I%RPCINCLUDE% -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0600 -MDd rquota\rquota.c -Forquota\rquota.obj + + + +rem +rem generate PORTMAP from .x +rem +copy portmap\portmap.x portmap\libnfs-raw-portmap.x +%RPCGEN% -h portmap\libnfs-raw-portmap.x > portmap\libnfs-raw-portmap.h +%RPCGEN% -c portmap\libnfs-raw-portmap.x > portmap\libnfs-raw-portmap.c +cl /I. /Iinclude /I%RPCINCLUDE% -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0600 -MDd portmap\libnfs-raw-portmap.c -Foportmap\libnfs-raw-portmap.obj +cl /I. /Iinclude /I%RPCINCLUDE% -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0600 -MDd portmap\portmap.c -Foportmap\portmap.obj + + +rem +rem generate MOUNT from .x +rem +copy mount\mount.x mount\libnfs-raw-mount.x +%RPCGEN% -h mount\libnfs-raw-mount.x > mount\libnfs-raw-mount.h +%RPCGEN% -c mount\libnfs-raw-mount.x > mount\libnfs-raw-mount.c +cl /I. /Iinclude /I%RPCINCLUDE% -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0600 -MDd mount\libnfs-raw-mount.c -Fomount\libnfs-raw-mount.obj +cl /I. /Iinclude /I%RPCINCLUDE% -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0600 -MDd mount\mount.c -Fomount\mount.obj + + + +rem +rem generate core part of library +rem +cl /I. /Iinclude /I%RPCINCLUDE% -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0600 -MDd lib\init.c -Folib\init.obj +cl /I. /Iinclude /I%RPCINCLUDE% -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0600 -MDd -D_U_="" lib\pdu.c -Folib\pdu.obj +cl /I. /Iinclude /I%RPCINCLUDE% -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0600 -MDd -D_U_="" lib\socket.c -Folib\socket.obj +cl /I. /Iinclude /I%RPCINCLUDE% /Imount /Infs -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0600 -MDd -D_U_="" lib\libnfs.c -Folib\libnfs.obj +cl /I. /Iinclude /I%RPCINCLUDE% /Imount /Infs -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0600 -MDd -D_U_="" lib\libnfs-sync.c -Folib\libnfs-sync.obj + + + +rem +rem create a linklibrary/dll +rem +lib /out:lib\libnfs.lib /def:lib\libnfs-win32.def nfs\nfs.obj nfs\nfsacl.obj nfs\libnfs-raw-nfs.obj rquota\rquota.obj rquota\libnfs-raw-rquota.obj mount\mount.obj mount\libnfs-raw-mount.obj portmap\portmap.obj portmap\libnfs-raw-portmap.obj lib\init.obj lib\pdu.obj lib\socket.obj lib\libnfs.obj lib\libnfs-sync.obj + +link /DLL /out:lib\libnfs.dll /DEBUG /DEBUGTYPE:cv lib\libnfs.exp nfs\nfs.obj nfs\nfsacl.obj nfs\libnfs-raw-nfs.obj rquota\rquota.obj rquota\libnfs-raw-rquota.obj mount\mount.obj mount\libnfs-raw-mount.obj portmap\portmap.obj portmap\libnfs-raw-portmap.obj lib\init.obj lib\pdu.obj lib\socket.obj lib\libnfs.obj lib\libnfs-sync.obj %RPCLIB% ws2_32.lib + + + +rem +rem build a test application +rem +cl /I. /Iinclude /I%RPCINCLUDE% /Imount /Infs -Zi -Od -DWIN32 -D_WIN32_WINNT=0x0600 -MDd -D_U_="" examples\nfsclient-sync.c lib\libnfs.lib %RPCLIB% WS2_32.lib kernel32.lib mswsock.lib advapi32.lib wsock32.lib advapi32.lib + + + + + + + +