diff --git a/Makefile b/Makefile index 89ebb389e721..329b7a9e467b 100644 --- a/Makefile +++ b/Makefile @@ -127,6 +127,26 @@ CFLAGS += $(DEF_FLAGS) CXXFLAGS += $(DEF_FLAGS) -D__STDC_CONSTANT_MACROS OBJCFLAGS := $(CFLAGS) -D__STDC_CONSTANT_MACROS +# libsmb2 and libnfs both ship include/slist.h with different macros +# (SMB2_LIST_* vs LIBNFS_LIST_*). Prepend libnfs include dirs for its +# own objects so "#include \"slist.h\"" resolves correctly when both +# clients are enabled. +# +# Vendored libnfs is not C89-clean (trailing commas, // comments). Strip +# C89_BUILD pedantic flags for libnfs TUs and the RetroArch NFS VFS shim +# that includes . +ifneq (,$(filter 1,$(HAVE_NFSCLIENT) $(HAVE_BUILTINNFSCLIENT))) +LIBNFS_CFLAGS_FILTER := -std=c89 -ansi -pedantic -Werror=pedantic -Werror=declaration-after-statement +$(OBJDIR)/deps/libnfs/%.o: CFLAGS := \ + -I$(DEPS_DIR)/libnfs/include -I$(DEPS_DIR)/libnfs/win32 -I$(DEPS_DIR)/libnfs \ + $(filter-out $(LIBNFS_CFLAGS_FILTER),$(CFLAGS)) \ + -std=gnu99 -Wno-pedantic +# LIBRETRO_COMM_DIR is "./libretro-common", so the object path keeps "./". +$(OBJDIR)/$(LIBRETRO_COMM_DIR)/vfs/vfs_implementation_nfs.o: CFLAGS := \ + $(filter-out $(LIBNFS_CFLAGS_FILTER),$(CFLAGS)) \ + -std=gnu99 -Wno-pedantic +endif + ifeq ($(HAVE_CXX), 1) ifeq ($(CXX_BUILD), 1) LINK = $(CXX) diff --git a/Makefile.common b/Makefile.common index c3f87fe6bbfc..b9a9370366a1 100644 --- a/Makefile.common +++ b/Makefile.common @@ -2932,6 +2932,95 @@ endif OBJ += $(LIBRETRO_COMM_DIR)/vfs/vfs_implementation_smb.o endif +ifneq (,$(filter 1,$(HAVE_NFSCLIENT) $(HAVE_BUILTINNFSCLIENT))) + DEFINES += -DHAVE_NFSCLIENT + + ifeq ($(HAVE_NFSCLIENT),1) + ifeq ($(shell pkg-config --exists libnfs && echo yes),yes) + CFLAGS += $(shell pkg-config --cflags libnfs) + LIBS += $(shell pkg-config --libs libnfs) + else + LIBS += -lnfs + endif + else ifeq ($(HAVE_BUILTINNFSCLIENT),1) + INCLUDE_DIRS += -I$(DEPS_DIR)/libnfs + INCLUDE_DIRS += -I$(DEPS_DIR)/libnfs/include + INCLUDE_DIRS += -I$(DEPS_DIR)/libnfs/include/nfsc + INCLUDE_DIRS += -I$(DEPS_DIR)/libnfs/mount + INCLUDE_DIRS += -I$(DEPS_DIR)/libnfs/nfs + INCLUDE_DIRS += -I$(DEPS_DIR)/libnfs/nfs4 + INCLUDE_DIRS += -I$(DEPS_DIR)/libnfs/nlm + INCLUDE_DIRS += -I$(DEPS_DIR)/libnfs/nsm + INCLUDE_DIRS += -I$(DEPS_DIR)/libnfs/portmap + INCLUDE_DIRS += -I$(DEPS_DIR)/libnfs/rquota +ifneq ($(findstring Win32,$(OS)),) + # MinGW / MXE: use libnfs win32 shims (do not force Unix feature macros). + INCLUDE_DIRS += -I$(DEPS_DIR)/libnfs/win32 + CFLAGS += '-D_U_=/**/' -DHAVE_STDINT_H -DHAVE_STDLIB_H -DHAVE_STRING_H + CFLAGS += -DSTDC_HEADERS -DHAVE_SOCKADDR_STORAGE -DHAVE_UTIME_H + OBJ += deps/libnfs/win32/win32_compat.o +else + CFLAGS += "-D_U_=__attribute__((unused))" + # Avoid -DHAVE_CONFIG_H: RetroArch's own config.h would be picked + # up by libnfs "#include \"config.h\"". Pass feature macros instead. + CFLAGS += -DHAVE_ARPA_INET_H -DHAVE_DLFCN_H -DHAVE_INTTYPES_H + CFLAGS += -DHAVE_MEMORY_H -DHAVE_NETDB_H -DHAVE_NETINET_IN_H + CFLAGS += -DHAVE_NETINET_TCP_H -DHAVE_NET_IF_H -DHAVE_POLL_H + CFLAGS += -DHAVE_PWD_H -DHAVE_SOCKADDR_STORAGE -DHAVE_STDINT_H + CFLAGS += -DHAVE_STDLIB_H -DHAVE_STDATOMIC_H -DHAVE_STRINGS_H + CFLAGS += -DHAVE_STRING_H -DHAVE_SYS_IOCTL_H -DHAVE_SYS_STATVFS_H + CFLAGS += -DHAVE_SYS_STAT_H -DHAVE_SYS_TIME_H -DHAVE_SYS_TYPES_H + CFLAGS += -DHAVE_SYS_UIO_H -DHAVE_UNISTD_H -DHAVE_UTIME_H + CFLAGS += -DHAVE_SIGNAL_H -DHAVE_SYS_UTSNAME_H -DSTDC_HEADERS +ifeq ($(findstring Darwin,$(OS)),) + CFLAGS += -DHAVE_CLOCK_GETTIME -DHAVE_STRUCT_STAT_ST_MTIM_TV_NSEC +endif +ifneq ($(findstring Darwin,$(OS)),) + CFLAGS += -DHAVE_SOCKADDR_LEN -DHAVE_SYS_FILIO_H +endif +ifneq ($(findstring Linux,$(OS)),) + CFLAGS += -DHAVE_CLOCK_GETTIME -DHAVE_STRUCT_STAT_ST_MTIM_TV_NSEC + CFLAGS += -DHAVE_SYS_VFS_H -DHAVE_SYS_SYSMACROS_H -DHAVE_SO_BINDTODEVICE +endif +ifeq ($(findstring Linux,$(OS)),) +ifeq ($(findstring Darwin,$(OS)),) + # Consoles / other non-glibc targets: mknod helpers need major()/minor(). + CFLAGS += '-Dmajor(d)=((int)(((unsigned)(d)>>8)&0xff))' + CFLAGS += '-Dminor(d)=((int)((unsigned)(d)&0xff))' +endif +endif +endif + OBJ += \ + deps/libnfs/lib/init.o \ + deps/libnfs/lib/krb5-wrapper.o \ + deps/libnfs/lib/libnfs.o \ + deps/libnfs/lib/libnfs-sync.o \ + deps/libnfs/lib/libnfs-zdr.o \ + deps/libnfs/lib/multithreading.o \ + deps/libnfs/lib/nfs_v3.o \ + deps/libnfs/lib/nfs_v4.o \ + deps/libnfs/lib/pdu.o \ + deps/libnfs/lib/socket.o \ + deps/libnfs/mount/mount.o \ + deps/libnfs/mount/libnfs-raw-mount.o \ + deps/libnfs/nfs/nfs.o \ + deps/libnfs/nfs/nfsacl.o \ + deps/libnfs/nfs/libnfs-raw-nfs.o \ + deps/libnfs/nfs4/nfs4.o \ + deps/libnfs/nfs4/libnfs-raw-nfs4.o \ + deps/libnfs/nlm/nlm.o \ + deps/libnfs/nlm/libnfs-raw-nlm.o \ + deps/libnfs/nsm/nsm.o \ + deps/libnfs/nsm/libnfs-raw-nsm.o \ + deps/libnfs/portmap/portmap.o \ + deps/libnfs/portmap/libnfs-raw-portmap.o \ + deps/libnfs/rquota/rquota.o \ + deps/libnfs/rquota/libnfs-raw-rquota.o + endif + + OBJ += $(LIBRETRO_COMM_DIR)/vfs/vfs_implementation_nfs.o +endif + ##################################### ### Android Play Feature Delivery ### ### (Play Store build core ### diff --git a/Makefile.webos b/Makefile.webos index f886fc6dace6..474f5ea25f66 100644 --- a/Makefile.webos +++ b/Makefile.webos @@ -56,6 +56,7 @@ HAVE_STATIC_AUDIO_FILTERS = 1 HAVE_FILTERS_BUILTIN = 1 HAVE_BUILTINMBEDTLS = 1 HAVE_BUILTINSMBCLIENT := 1 +HAVE_BUILTINNFSCLIENT := 1 HAVE_C99 = 1 HAVE_CC = 1 HAVE_CC_RESAMPLER = 1 @@ -336,6 +337,14 @@ endif -include $(RARCH_OBJ:.o=.d) +# libsmb2 and libnfs both ship include/slist.h with different macros +# (SMB2_LIST_* vs LIBNFS_LIST_*). Prepend libnfs include dirs for its +# own objects so "#include \"slist.h\"" resolves correctly when both +# clients are enabled. Same pattern as top-level Makefile. +ifneq (,$(filter 1,$(HAVE_NFSCLIENT) $(HAVE_BUILTINNFSCLIENT))) +$(OBJDIR)/deps/libnfs/%.o: CFLAGS := -I$(DEPS_DIR)/libnfs/include -I$(DEPS_DIR)/libnfs $(CFLAGS) +endif + SYMBOL_MAP := -Wl,-Map=output.map prebuild: diff --git a/config.def.h b/config.def.h index 7aa5edaa1011..358b8932aed7 100644 --- a/config.def.h +++ b/config.def.h @@ -772,6 +772,7 @@ #define DEFAULT_SETTINGS_SHOW_DIRECTORY true #define DEFAULT_SETTINGS_SHOW_STEAM true #define DEFAULT_SETTINGS_SHOW_SMB_CLIENT true +#define DEFAULT_SETTINGS_SHOW_NFS_CLIENT true #define DEFAULT_QUICK_MENU_SHOW_RESUME_CONTENT true #define DEFAULT_QUICK_MENU_SHOW_RESTART_CONTENT true @@ -2020,3 +2021,10 @@ #define DEFAULT_SMB_CLIENT_TIMEOUT 5 #define DEFAULT_SMB_CLIENT_MAX_TIMEOUT 20 #endif + +#ifdef HAVE_NFSCLIENT +#define DEFAULT_NFS_CLIENT_NUM_CONTEXTS 4 +#define DEFAULT_NFS_CLIENT_MAX_CONTEXTS 20 +#define DEFAULT_NFS_CLIENT_TIMEOUT 5 +#define DEFAULT_NFS_CLIENT_MAX_TIMEOUT 20 +#endif diff --git a/configuration.c b/configuration.c index 326654e2d7aa..ad7d51ca61dc 100644 --- a/configuration.c +++ b/configuration.c @@ -1657,6 +1657,12 @@ static struct config_array_setting *populate_settings_array( SETTING_ARRAY("smb_client_workgroup", settings->arrays.smb_client_workgroup, false, NULL, true); #endif +#ifdef HAVE_NFSCLIENT + SETTING_ARRAY("nfs_client_server_address", settings->arrays.nfs_client_server_address, false, NULL, true); + SETTING_ARRAY("nfs_client_export", settings->arrays.nfs_client_export, false, NULL, true); + SETTING_ARRAY("nfs_client_subdir", settings->arrays.nfs_client_subdir, false, NULL, true); +#endif + #ifdef HAVE_LAKKA SETTING_ARRAY("cpu_main_gov", settings->arrays.cpu_main_gov, false, NULL, true); SETTING_ARRAY("cpu_menu_gov", settings->arrays.cpu_menu_gov, false, NULL, true); @@ -2117,6 +2123,9 @@ static struct config_bool_setting *populate_settings_bool( #ifdef HAVE_SMBCLIENT #include "settings/settings_def_smb_client_auth.h" #endif +#ifdef HAVE_NFSCLIENT +#include "settings/settings_def_nfs_client_opts.h" +#endif #include "settings/settings_def_midi_volume.h" #ifdef HAVE_NETWORKING #include "settings/settings_def_netplay_ports.h" @@ -2190,6 +2199,9 @@ static struct config_bool_setting *populate_settings_bool( #ifdef HAVE_SMBCLIENT #include "settings/settings_def_smb_client.h" #endif +#ifdef HAVE_NFSCLIENT +#include "settings/settings_def_nfs_client.h" +#endif #ifdef HAVE_NETWORKING #ifdef HAVE_NETWORKGAMEPAD #include "settings/settings_def_netplay_stateless.h" @@ -2263,6 +2275,11 @@ static struct config_bool_setting *populate_settings_bool( #include "settings/settings_def_settings_show_smb.h" #endif #ifdef HAVE_MENU +#ifdef HAVE_NFSCLIENT +#include "settings/settings_def_settings_show_nfs.h" +#endif +#endif +#ifdef HAVE_MENU #ifdef HAVE_MIST #include "settings/settings_def_settings_show_steam.h" #endif @@ -2827,6 +2844,9 @@ static struct config_float_setting *populate_settings_float( #ifdef HAVE_SMBCLIENT #include "settings/settings_def_smb_client_auth.h" #endif +#ifdef HAVE_NFSCLIENT +#include "settings/settings_def_nfs_client_opts.h" +#endif #include "settings/settings_def_midi_volume.h" #ifdef HAVE_NETWORKING #include "settings/settings_def_netplay_ports.h" @@ -2900,6 +2920,9 @@ static struct config_float_setting *populate_settings_float( #ifdef HAVE_SMBCLIENT #include "settings/settings_def_smb_client.h" #endif +#ifdef HAVE_NFSCLIENT +#include "settings/settings_def_nfs_client.h" +#endif #ifdef HAVE_NETWORKING #ifdef HAVE_NETWORKGAMEPAD #include "settings/settings_def_netplay_stateless.h" @@ -2973,6 +2996,11 @@ static struct config_float_setting *populate_settings_float( #include "settings/settings_def_settings_show_smb.h" #endif #ifdef HAVE_MENU +#ifdef HAVE_NFSCLIENT +#include "settings/settings_def_settings_show_nfs.h" +#endif +#endif +#ifdef HAVE_MENU #ifdef HAVE_MIST #include "settings/settings_def_settings_show_steam.h" #endif @@ -3495,6 +3523,9 @@ static struct config_uint_setting *populate_settings_uint( #ifdef HAVE_SMBCLIENT #include "settings/settings_def_smb_client_auth.h" #endif +#ifdef HAVE_NFSCLIENT +#include "settings/settings_def_nfs_client_opts.h" +#endif #include "settings/settings_def_midi_volume.h" #ifdef HAVE_NETWORKING #include "settings/settings_def_netplay_ports.h" @@ -3568,6 +3599,9 @@ static struct config_uint_setting *populate_settings_uint( #ifdef HAVE_SMBCLIENT #include "settings/settings_def_smb_client.h" #endif +#ifdef HAVE_NFSCLIENT +#include "settings/settings_def_nfs_client.h" +#endif #ifdef HAVE_NETWORKING #ifdef HAVE_NETWORKGAMEPAD #include "settings/settings_def_netplay_stateless.h" @@ -3641,6 +3675,11 @@ static struct config_uint_setting *populate_settings_uint( #include "settings/settings_def_settings_show_smb.h" #endif #ifdef HAVE_MENU +#ifdef HAVE_NFSCLIENT +#include "settings/settings_def_settings_show_nfs.h" +#endif +#endif +#ifdef HAVE_MENU #ifdef HAVE_MIST #include "settings/settings_def_settings_show_steam.h" #endif @@ -4200,6 +4239,9 @@ static struct config_int_setting *populate_settings_int( #ifdef HAVE_SMBCLIENT #include "settings/settings_def_smb_client_auth.h" #endif +#ifdef HAVE_NFSCLIENT +#include "settings/settings_def_nfs_client_opts.h" +#endif #include "settings/settings_def_midi_volume.h" #ifdef HAVE_NETWORKING #include "settings/settings_def_netplay_ports.h" @@ -4273,6 +4315,9 @@ static struct config_int_setting *populate_settings_int( #ifdef HAVE_SMBCLIENT #include "settings/settings_def_smb_client.h" #endif +#ifdef HAVE_NFSCLIENT +#include "settings/settings_def_nfs_client.h" +#endif #ifdef HAVE_NETWORKING #ifdef HAVE_NETWORKGAMEPAD #include "settings/settings_def_netplay_stateless.h" @@ -4346,6 +4391,11 @@ static struct config_int_setting *populate_settings_int( #include "settings/settings_def_settings_show_smb.h" #endif #ifdef HAVE_MENU +#ifdef HAVE_NFSCLIENT +#include "settings/settings_def_settings_show_nfs.h" +#endif +#endif +#ifdef HAVE_MENU #ifdef HAVE_MIST #include "settings/settings_def_settings_show_steam.h" #endif @@ -4792,6 +4842,9 @@ static struct config_int_setting *populate_settings_int( #ifdef HAVE_SMBCLIENT #include "settings/settings_def_smb_client_auth.h" #endif +#ifdef HAVE_NFSCLIENT +#include "settings/settings_def_nfs_client_opts.h" +#endif #include "settings/settings_def_midi_volume.h" #ifdef HAVE_NETWORKING #include "settings/settings_def_netplay_ports.h" @@ -4865,6 +4918,9 @@ static struct config_int_setting *populate_settings_int( #ifdef HAVE_SMBCLIENT #include "settings/settings_def_smb_client.h" #endif +#ifdef HAVE_NFSCLIENT +#include "settings/settings_def_nfs_client.h" +#endif #ifdef HAVE_NETWORKING #ifdef HAVE_NETWORKGAMEPAD #include "settings/settings_def_netplay_stateless.h" @@ -4938,6 +4994,11 @@ static struct config_int_setting *populate_settings_int( #include "settings/settings_def_settings_show_smb.h" #endif #ifdef HAVE_MENU +#ifdef HAVE_NFSCLIENT +#include "settings/settings_def_settings_show_nfs.h" +#endif +#endif +#ifdef HAVE_MENU #ifdef HAVE_MIST #include "settings/settings_def_settings_show_steam.h" #endif diff --git a/configuration.h b/configuration.h index 3ee0720edb1e..4b26a52906ca 100644 --- a/configuration.h +++ b/configuration.h @@ -384,6 +384,10 @@ typedef struct settings unsigned smb_client_auth_mode; unsigned smb_client_num_contexts; unsigned smb_client_timeout; +#endif +#ifdef HAVE_NFSCLIENT + unsigned nfs_client_num_contexts; + unsigned nfs_client_timeout; #endif unsigned input_sensor_orientation; } uints; @@ -808,6 +812,9 @@ typedef struct settings #endif #ifdef HAVE_SMBCLIENT bool settings_show_smb_client; +#endif +#if defined(HAVE_MENU) && defined(HAVE_NFSCLIENT) + bool settings_show_nfs_client; #endif bool quick_menu_show_resume_content; bool quick_menu_show_restart_content; @@ -1072,6 +1079,9 @@ typedef struct settings #ifdef HAVE_SMBCLIENT bool smb_client_enable; +#endif +#ifdef HAVE_NFSCLIENT + bool nfs_client_enable; #endif } bools; @@ -1158,6 +1168,11 @@ typedef struct settings char smb_client_password[128]; char smb_client_workgroup[64]; #endif +#ifdef HAVE_NFSCLIENT + char nfs_client_server_address[256]; + char nfs_client_export[PATH_MAX_LENGTH]; + char nfs_client_subdir[PATH_MAX_LENGTH]; +#endif } arrays; struct diff --git a/deps/libnfs/CHANGELOG b/deps/libnfs/CHANGELOG new file mode 100644 index 000000000000..3556ba884645 --- /dev/null +++ b/deps/libnfs/CHANGELOG @@ -0,0 +1,161 @@ +Changes since 5.0.2 +drop *BSD support from github workflows +workflow: indicate that the linux workflow also runs the tests +Add workflow to build PS2 +Add workflow running make test +ps2 bonus: Remove old implementations +ps2: Fix linkage with a missing file +Fix ps2 warnings and remove read macros +update INSTALL build with cmake and debugging enable +Update waitpdu_len when a pdu times out. +ci: Build examples and run tests on Linux +Fix building examples/nfsclient-raw.c +Allow setting a limit on the number of commands in-flight. +Always close the socket. +Handle small reads for record marker field. +Reset state on reconnect. +Check return value from adjust_inbuf. +README: Document that new development has shifted to libnfs-next-gen branch +fix compiler warning +Patch to support NLM Share +rpc: re-add fragment handling when reading from socket. +change read_from_socket to use a state machine +Write multiple pdus at once. +Added NFS4.1 EXCHANGE_ID and BIND_CONN_TO_SESSION +Added poll_timeout parameter +Completed NFS 4.1 defintion of open_claim4 +NFS3: we do not need to provide an alloc-hint to write3 +Fix deprecation warnings on modern macOS +Restore Cygwin CI (official GH action from Cygwin maintainers). +Change Windows writev & readv polyfills to static inline. +Fix integer size for readdir's dircount/maxcount +Add OpenBSD back to the workflow +Add windows workflow and add missing readv/writev replacements to win32 +Remove BSD from the github workflows. +Remove CYGWIN github workflow. The cygwin action is abandonware +Modify LD_PRELOAD toy doc +Add options to set dircount/maxcount for readdir() +compile fix for mac +write3: make sure we do not add too many iovectors +Change WRITE3 to become zero-copy usinf iovectors for the data. +Switch writing PDUs to the socket use iovectors. +Add CodeQL workflow for GitHub code scanning +github: switch openbsd to 7.0 and try again +github: switch OpenBSD workflow to use 7.2 instead of 6.9 +multithreading.c: do not wake up immediately if there are no events to process +Reduced memory allocations. +Expose further configuration options +tests: disable test_8000 for now +rpm: fix building RPMs +rpc: fix use after free on init_context failure +tests: fix failure in 0201 +rpc: only scan for tiemout out RPCs every second instead of every I/O +rpc: make it possible to tweak the number of lists we hash to for waitpdu +libnfs-sync: fail all pdus before returning error from wait_for_nfs_reply +cmake: update utils to be installed +socket: remove debugging printf +Deduplicate paths in CMakeLists.txt. +Add -no-undefined linker flag for shared library +Link shared library with ws2_32 + + +Changes since 5.0.1 +Various small multithreading fixes +Add opaque pointer to service_proc to make it easier to build server apps. +BSD compile fix +OpenBSD support +fix double free in nfs3_pread_mcb() + +Changes since 5.0.0 +Fix non-pthread build + +Changes since 4.0.0 + +Multithread support for Linux and Windows +Fix NFS4 behavior of chmod/chown/utimes +Add marshalling / unmarshalling of various NFSv4.1 structures (but not 4.1 support) +PS3 support +PS2 EE support +Support escaped characters in the URL +Fix MINGW build + +Changes since 3.0.0 + +Fix the versioning in makerpms.sh +Fix some compile issues in the test programs. +NFSv3: skip commit on close if the file has not been written to. +Add nfs_umount() to NFSv3 +Add nfs_statvfs64() +Fix invalid shift of pid_t when generating rpc->xid +Compile fixes for Mac OSX +Fix for dup2() on Windows +NFSv4 fix for directory handling +Improvements to configure/bulding + +Changes since 2.0.0 + +NFSv4 support. +lockf() support (NFSv4 only). +fcntl() support for locking (NFSv4 only). +Add CMake support. +URL arguments to select NFS version. +URL argument to set nfsport. This allows NFSv4 to work for + servers without portmapper support. +URL argument to set he mount port. +NFSv4: use getpwnam to map NFSv4 (Ganesha) when passing uid/gid + as a user/group name insead of as a uid/gid. +Added nfs-fh: a simle utility to print the filehandle for a nfs file. +Win32 build fixes. +Add a new open2() function that takes a mode argument. +Add a testsuite for libnfs. + + + +Changes since 1.11.0 + +BUGS +==== +Fix NULL pointer crash in nfs_link(). + +Clamp read/write size for servers (Ganesha) that offer very large io sizes +instead of failing to connect to the export. + +Tell the server to commit all data to stable storage when we close files. + +Double free fix: don't call rpc_free_pdu() after rpc_queue_pdu() failure. + +Fix for memory leak in rpc_allocate_*(). + +Fixes to build nfs-ls and nfs-cp on win32. + +Abort the mount process correctly if MOUNT/MNT returns error or is cancelled. + +Fix memory leak in error path in nfs_create_2_cb(). + +Fix leak of rpc->inbuf if we destroy the context while we still have PDUs +in flight. + + +FEATURES +======== +Add O_NOFOLLOW support for nfs_open() + +Add a new mkdir2 command that also takes a mode argument. + +Add a new readlink2 command that avoids having to preallocate the buffer. + +Add support for RPC timeouts for both the sync and async interfaces. + +Build fixes for Mingw and Cygwin + +Update README to document two new Windows builds + +Use SOCK_CLOEXEC for the sockets + +Make rpc_set{g|u}id() public + +Performance optimization: socket: Batch pdu read in rpc_read_from_socket + +Low level support for NFSv4 and some examples + +Support for building RPC servers diff --git a/deps/libnfs/CMakeLists.txt b/deps/libnfs/CMakeLists.txt new file mode 100644 index 000000000000..52a519c434da --- /dev/null +++ b/deps/libnfs/CMakeLists.txt @@ -0,0 +1,189 @@ +cmake_minimum_required(VERSION 3.16) + +project(libnfs + LANGUAGES C + VERSION 16.2.0) + +set(SOVERSION 16.2.0 CACHE STRING "" FORCE) + +include(cmake/GNUInstallDirs.cmake) + +set(INSTALL_BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Installation directory for binaries") +set(INSTALL_LIB_DIR "${CMAKE_INSTALL_FULL_LIBDIR}" CACHE PATH "Installation directory for libraries") +set(INSTALL_INC_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "Installation directory for headers") +set(INSTALL_MAN_DIR "${CMAKE_INSTALL_PREFIX}/share/man" CACHE PATH "Installation directory for manual pages") +set(INSTALL_PKGCONFIG_DIR "${INSTALL_LIB_DIR}/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files") +set(INSTALL_CMAKE_DIR "${INSTALL_LIB_DIR}/cmake/libnfs" CACHE PATH "Installation directory for cmake (.cmake) files") + +option(BUILD_SHARED_LIBS "Build shared libraries" ON) +option(ENABLE_TESTS "Build and run test programs" OFF) +option(ENABLE_DOCUMENTATION "Build Documentation" OFF) +option(ENABLE_UTILS "Build util programs" OFF) +option(ENABLE_EXAMPLES "Build example programs" OFF) +option(ENABLE_MULTITHREADING "Enable multithreading support" OFF) + +if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + set(CMAKE_INSTALL_RPATH "${INSTALL_LIB_DIR}") + set(CMAKE_SKIP_INSTALL_RPATH FALSE) +endif() + +if(ENABLE_TESTS) + set(ENABLE_UTILS ON CACHE BOOL "Building utils required by tests" FORCE) +endif() + +if(ENABLE_MULTITHREADING) + add_definitions(-DHAVE_MULTITHREADING) +endif() + +include(cmake/Macros.cmake) + +if(IOS) + find_package(GSSAPI) + + if(GSSAPI_FOUND) + add_definitions(-DHAVE_LIBKRB5) + endif() +endif() + +include(cmake/ConfigureChecks.cmake) + +include_directories(${CMAKE_CURRENT_BINARY_DIR} + include + include/nfsc) + +# list of system libs (sockets/etc) to be linked on this system +set(SYSTEM_LIBRARIES "") +# list of core (static) libraries built in current configuration (used by lib/CMakeLists.txt) +set(CORE_LIBRARIES "" CACHE INTERNAL "") + +# make sure related functions are exported in final dll +if(WIN32 AND BUILD_SHARED_LIBS) + add_definitions(-Dlibnfs_EXPORTS) +endif() + +if(ENABLE_MULTITHREADING AND PTHREAD_LIBRARY) + list(APPEND SYSTEM_LIBRARIES pthread) +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL Linux) + add_definitions("-D_U_=__attribute__((unused))") + # + # Currently RPC-with-TLS support is only available on Linux since it depends on kTLS support + # on Linux. + # + # TODO: BSD also has kTLS support, but that will need separate validation. + # + find_package(GnuTLS "3.4.6") + if(GNUTLS_FOUND) + # + # Make sure the two most important header files are present before we enable TLS support, + # to avoid running into issues later during build. GnuTLS package found but gnutls/gnutls.h + # not found is a serious issue while if linux/tls.h is not found it would likely mean that + # user is using a kernel not supporting kTLS so we simply don't turn on TLS support. + # + check_include_file("gnutls/gnutls.h" HAVE_GNUTLS_H) + if(NOT HAVE_GNUTLS_H EQUAL "1") + message(FATAL_ERROR "GnuTLS found but gnutls/gnutls.h not found, GNUTLS_INCLUDE_DIR is ${GNUTLS_INCLUDE_DIR}") + endif() + + check_include_file("linux/tls.h" HAVE_LINUX_TLS_H) + if(NOT HAVE_LINUX_TLS_H EQUAL "1") + message(STATUS "GnuTLS found but linux/tls.h not found, likely a kernel w/o kTLS support, can't enable TLS support") + else() + message(STATUS "Using ${GNUTLS_LIBRARIES}") + add_definitions(-DHAVE_TLS) + list(APPEND SYSTEM_LIBRARIES ${GNUTLS_LIBRARIES}) + add_subdirectory(tls) + endif() + endif() +elseif(CMAKE_SYSTEM_NAME STREQUAL Windows OR CMAKE_SYSTEM_NAME STREQUAL WindowsStore) + add_definitions("-D_U_=" -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE) + list(APPEND SYSTEM_LIBRARIES ws2_32) + add_subdirectory(win32) +elseif(CMAKE_SYSTEM_NAME STREQUAL Solaris) + add_definitions("-D_U_=__attribute__((unused))") + find_library(SOCKET_LIBRARY socket) + find_library(NSL_LIBRARY nsl) + list(APPEND SYSTEM_LIBRARIES ${SOCKET_LIBRARY} ${NSL_LIBRARY}) +elseif(CMAKE_SYSTEM_NAME STREQUAL aros) + add_definitions("-D_U_=__attribute__((unused))") + add_definitions(-DAROS) + add_subdirectory(aros) +else() + add_definitions("-D_U_=__attribute__((unused))") +endif() + +add_subdirectory(mount) +add_subdirectory(nfs) +add_subdirectory(nfs4) +add_subdirectory(nlm) +add_subdirectory(nsm) +add_subdirectory(portmap) +add_subdirectory(rquota) +add_subdirectory(lib) # this has to be last (it links all static libs mentioned in CORE_LIBRARIES) + +if(ENABLE_DOCUMENTATION) + add_subdirectory(doc) +endif() + +if(ENABLE_EXAMPLES) + add_subdirectory(examples) +endif() + +if(ENABLE_TESTS) + enable_testing() + add_subdirectory(tests) +endif() + +if(ENABLE_UTILS) + add_subdirectory(utils) +endif() + +# this will create build-tree-specific config file (so downstream client can use this specific build without having to install package) +export(EXPORT libnfs + NAMESPACE libnfs:: + FILE "${CMAKE_CURRENT_BINARY_DIR}/libnfs-config.cmake") + +# this will create relocatable config file in installation directory +install(EXPORT libnfs + DESTINATION "${INSTALL_CMAKE_DIR}" + NAMESPACE libnfs:: + FILE libnfs-config.cmake) + +# handle version file +include(CMakePackageConfigHelpers) +write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/libnfs-config-version.cmake + VERSION ${PROJECT_VERSION} + COMPATIBILITY AnyNewerVersion) + +install(FILES cmake/FindNFS.cmake + ${CMAKE_CURRENT_BINARY_DIR}/libnfs-config-version.cmake + DESTINATION ${INSTALL_CMAKE_DIR}) + +# handle pc-config files +set(PKG_LIBLIST "") +foreach(LIB ${SYSTEM_LIBRARIES}) + if(IS_ABSOLUTE ${LIB} AND EXISTS ${LIB}) + list(APPEND PKG_LIBLIST "${LIB}") + else() + list(APPEND PKG_LIBLIST "-l${LIB}") + endif() +endforeach() +configure_file(cmake/libnfs.pc.cmake + ${CMAKE_CURRENT_BINARY_DIR}/libnfs.pc @ONLY) + +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libnfs.pc + DESTINATION ${INSTALL_PKGCONFIG_DIR}) + +# handle headers installation +install(DIRECTORY include/nfsc + DESTINATION ${INSTALL_INC_DIR}) + +install(FILES mount/libnfs-raw-mount.h + nfs/libnfs-raw-nfs.h + nfs4/libnfs-raw-nfs4.h + nlm/libnfs-raw-nlm.h + nsm/libnfs-raw-nsm.h + portmap/libnfs-raw-portmap.h + rquota/libnfs-raw-rquota.h + DESTINATION ${INSTALL_INC_DIR}/nfsc) diff --git a/deps/libnfs/COPYING b/deps/libnfs/COPYING new file mode 100644 index 000000000000..8d02122bf0e8 --- /dev/null +++ b/deps/libnfs/COPYING @@ -0,0 +1,39 @@ +Libnfs components fall under two separate licences + + +The library sources and include directories +=========================================== +The nfs client library itself, i.e. the lib and include directories, +is licenced under GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +The protocol definition, .x, files +================================== +These are based on old RFCs and studying how wireshark dissects various packets. +These are distributed under the simplified BSD licence. + +The files generated from the .x files +===================================== +The files that are generated from the .x sources, +i.e. */libnfs-raw-.[ch] +can be considered to be distributed under the simplified BSD licence. + +These files are only provided as a convenience, so that you do not need to +install and run rpcgen on the *.x files locally. +If you disagree with the simplified BSD licence I provide them under +then just delete them and then generate identical copies of these files yourself +using "make compile_rpc" in each protocol subdirectory. + +Then you can pick whatever licence you want on those files. + +The examples directory +================================ +The utility and example applications using this library, i.e. the +examples directory, are licenced under 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. + + +To avoid any confusion, every source file contains a licence boilerplate. + diff --git a/deps/libnfs/INSTALL b/deps/libnfs/INSTALL new file mode 100644 index 000000000000..46e1677d4453 --- /dev/null +++ b/deps/libnfs/INSTALL @@ -0,0 +1,19 @@ +To install + +- mkdir build && cd build +- cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr .. +- make && sudo make install + +To build with support debugging that enable example and test cases. + +- mkdir build && cd build +- cmake -DENABLE_UTILS=yes \ + -DENABLE_EXAMPLES=yes \ + -DENABLE_TESTS=yes \ + -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_VERBOSE_MAKEFILE=yes .. + +To build with multithreading support add -DENABLE_MULTITHREADING=yes + +- make +- make test diff --git a/deps/libnfs/LICENCE-BSD.txt b/deps/libnfs/LICENCE-BSD.txt new file mode 100644 index 000000000000..f645551f99e4 --- /dev/null +++ b/deps/libnfs/LICENCE-BSD.txt @@ -0,0 +1,23 @@ +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. diff --git a/deps/libnfs/LICENCE-GPL-3.txt b/deps/libnfs/LICENCE-GPL-3.txt new file mode 100644 index 000000000000..94a9ed024d38 --- /dev/null +++ b/deps/libnfs/LICENCE-GPL-3.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/deps/libnfs/LICENCE-LGPL-2.1.txt b/deps/libnfs/LICENCE-LGPL-2.1.txt new file mode 100644 index 000000000000..4362b49151d7 --- /dev/null +++ b/deps/libnfs/LICENCE-LGPL-2.1.txt @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/deps/libnfs/Makefile.am b/deps/libnfs/Makefile.am new file mode 100644 index 000000000000..dee215dde35a --- /dev/null +++ b/deps/libnfs/Makefile.am @@ -0,0 +1,22 @@ +SUBDIRS = doc mount nfs nfs4 nlm nsm portmap rquota +ACLOCAL_AMFLAGS = -I m4 + +if HAVE_TLS +SUBDIRS += tls +endif +SUBDIRS += lib include $(MAYBE_UTILS) . $(MAYBE_EXAMPLES) $(MAYBE_SERVERS) + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = libnfs.pc + +EXTRA_DIST = \ + README \ + COPYING \ + LICENCE-BSD.txt \ + LICENCE-GPL-3.txt \ + LICENCE-LGPL-2.1.txt \ + examples \ + libnfs.pc.in + +test: $(SUBDIRS) + cd tests; make test diff --git a/deps/libnfs/README b/deps/libnfs/README new file mode 100644 index 000000000000..6d1d6fb5429e --- /dev/null +++ b/deps/libnfs/README @@ -0,0 +1,283 @@ +--- Read this first +This version 2 of the libnfs API. It is not compatible with the earlier API. +All rpc___async() functions have been changed to +rpc___task(). +The _task() functions return a struct rpc_pdu * which can later be used +to cancel an inflight command. + +nfs_[]read and nfs_[p]write functions have new signatures. +Pay attention to any compiler warnings when compiling against this new API. + +The symbol LIBNFS_API_V2 can be used to identify that the library uses the new +API. + +This version of the library supports zero-copy read and write for NFS v3/4 +--- + + +LIBNFS is a client library for accessing NFS shares over a network. + +LIBNFS offers three different APIs, for different use : +1, RAW : A fully async low level RPC library for NFS protocols +This API is described in include/libnfs-raw.h +it offers a fully async interface to raw XDR encoded blobs. +This API provides very flexible and precise control of the RPC issued. + +examples/nfsclient-raw.c provides examples on how to use the raw API + +2, NFS ASYNC : A fully asynchronous library for high level vfs functions +This API is described by the *_async() functions in include/libnfs.h. +This API provides a fully async access to posix vfs like functions such as +stat(), read(), ... + +examples/nfsclient-async.c provides examples on how to use this API + + +3, NFS SYNC : A synchronous library for high level vfs functions +This API is described by the *_sync() functions in include/libnfs.h. +This API provides access to posix vfs like functions such as +stat(), read(), ... + +examples/nfsclient-sync.c provides examples on how to use this API + +NFSv4: +====== +NFSv3 is the default but NFSv4 can be selected either by using the URL argument +version=4 or programatically calling nfs_set_version(nfs, NFS_V4) before +connecting to the server/share. + +SERVER SUPPORT: +=============== +Libnfs supports building RPC servers. +Examples/portmapper-server.c is a small "portmapper" example written using +libnfs. + +URL-FORMAT: +=========== +Libnfs uses RFC2224 style URLs extended with some minor libnfs extensions. +The basic syntax of these URLs is : + +nfs://[@][:]/path[?arg=val[&arg=val]*] + +Special characters in 'path' are escaped using %-hex-hex syntax. + +For example '?' must be escaped if it occurs in a path as '?' is also used to +separate the path from the optional list of url arguments. + +Example: +nfs://127.0.0.1/my?path/?version=4 +must be escaped as +nfs://127.0.0.1/my%3Fpath/?version=4 + +Arguments supported by libnfs are : + tcp-syncnt= : Number of SYNs to send during the session establish + before failing setting up the tcp connection to the + server. + uid= : UID value to use when talking to the server. + default it 65534 on Windows and getuid() on unixen. + gid= : GID value to use when talking to the server. + default it 65534 on Windows and getgid() on unixen. + debug= : Debug level used by libnfs. Default is 0 which is quiet. + Higher values increase verbosity. + timeo= : The time in deciseconds (tenths of a second) libnfs client + will wait for a response before it retries an RPC request. + Default value of 'timeo' is 600, i.e., 60 seconds. + Values less than 100, i.e., 10 seconds, are not allowed. + retrans= : After 'retrans' failed retries libnfs will generate a + "server not responding" message and then attempt further + recovery action. If no successful RPC response has been + received over the connection for the last 'timeo' period, + then the connection would be terminated and all queued RPCs + will be retried over the new connection. If other RPC + responses are being received then it means connection is + fine and this is likely a problem with this specific RPC, + in that case it'll simply keep retrying the RPC for ever at + 'timeo' interval. This mimics the 'hard' mount behaviour of + NFS clients. + If 'retrans' is 0, then RPC is not retried on timeout but + instead failed with RPC_STATUS_TIMEOUT. This will roughly + mimic the 'soft' mount behaviour of NFS clients. + Default value of 'retrans' is 2. + sec= + : Specify the security mode. + xprtsec= + : Specify the transport security mode. + none : No TLS security. This is the default. + tls : TLS with server authentication only. + mtls : Mutual TLS, both server and client authentication. + + See CERTIFICATES for details about specifying certificates/keys + that libnfs must use when using "tls" or "mtls" security. + auto-traverse-mounts=<0|1> + : Should libnfs try to traverse across nested mounts + automatically or not. Default is 1 == enabled. + dircache=<0|1> : Disable/enable directory caching. Enabled by default. + readonly : Set the mount to readonly. + autoreconnect=<-1|0|>=1> + : Control the auto-reconnect behaviour to the NFS session. + -1 : Try to reconnect forever on session failures. + Just like normal NFS clients do. + 0 : Disable auto-reconnect completely and immediately + return a failure to the application. + >=1 : Retry to connect back to the server this many + times before failing and returing an error back + to the application. + if= : Interface name (e.g., eth1) to bind; requires `root` + version=<3|4> : NFS Version. Default is 3. + nfsport= : Use this port for NFS instead of using the portmapper. + mountport= : Use this port for the MOUNT protocol instead of + using portmapper. This argument is ignored for NFSv4 + as it does not use the MOUNT protocol. + rsize= : This is the maximum number of bytes libnfs client will + ask in a single READ request. The actual value is the + minimum of this and the 'rtmax' value shared by the + server in the FSINFO response. The largest rsize value + supported is 4,194,304 bytes, i.e., 4MiB. The smallest + rsize value supported is 8192 bytes, i.e., 8KiB. The + provided value must be a multiple of 4096, else it's + rounded down to the nearest 4096 bytes. + Default value used when rsize option is not specified, + is 1,048,576 bytes, i.e., 1MiB. + wsize= : This is the maximum number of bytes libnfs client will + send in a single WRITE request. The actual value is the + minimum of this and the 'wtmax' value shared by the + server in the FSINFO response. The largest wsize value + supported is 4,194,304 bytes, i.e., 4MiB. The smallest + wsize value supported is 8192 bytes, i.e., 8KiB. The + provided value must be a multiple of 4096, else it's + rounded down to the nearest 4096 bytes. + Default value used when wsize option is not specified, + is 1,048,576 bytes, i.e., 1MiB. + readdir-buffer= | readdir-buffer=, + : Set the buffer size for READDIRPLUS, where dircount is + the maximum amount of bytes the server should use to + retrieve the entry names and maxcount is the maximum + size of the response buffer (including attributes). + If only one is given it will be used for both. + The provided value(s) must be multiple of 4096, else + they are rounded down to the nearest 4096 bytes. + The actual value is the minimum of this and the 'dtpref' + value shared by the server in the FSINFO response. + Default is 8192 for both. + +Auto_traverse_mounts +==================== +Normally in NFSv3 if a server has nested exports, for example if it would +export both /data and /data/tmp then a client would need to mount +both these exports as well. +The reason is because the NFSv3 protocol does not allow a client request +to return data for an object in a different filesystem/mount. +(legacy, but it is what it is. One reason for this restriction is to +guarantee that inodes are unique across the mounted system.) + +This option, when enabled, will make libnfs perform all these mounts +internally for you. This means that one libnfs mount may now have files +with duplicate inode values so if you cache files based on inode +make sure you cache files based on BOTH st.st_ino and st.st_dev. + + +ROOT vs NON-ROOT +================ +When running as root, libnfs tries to allocate a system port for its connection +to the NFS server. When running as non-root it will use a normal +ephemeral port. +Many NFS servers default to a mode where they do not allow non-system +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. + +On Linux we can get around this restriction by setting the NET_BIND_SERVICE +capability for the application binary. + +This is set up by running + sudo setcap 'cap_net_bind_service=+ep' /path/to/executable +This capability allows the binary to use systems ports like this even when +not running as root. Thus if you set this capability for your application +you no longer need to edit the export on the NFS server to set "insecure". + + +I do not know what equivalent "capability" support is available on other +platforms. Please drop me an email if your os of choice has something similar +and I can add it to the README. + + +CERTIFICATES +============ +libnfs reads CA certs from the following places, so make sure your server's CA +cert is present in at least one of these: + +- default system trust store (/etc/ssl/certs/ca-certificates.crt on most systems). +- all PEM format certs in the directory specified by env variable LIBNFS_TLS_TRUSTED_CA_DIR. +- cert(s) present in the PEM file specified by env variable LIBNFS_TLS_TRUSTED_CA_PEM. + +If you want to use mutual TLS (xprtsec=mtls) then you will need a client certificate +too. You need to provide the client's public certificate and the private key using +the following environment variables. + +- LIBNFS_TLS_CLIENT_CERT_PEM - this is the public certificate. +- LIBNFS_TLS_CLIENT_KEY_PEM - this is the private key. + + +DOCUMENTATION +============= +libnfs sources ship with prebuilt manpage(s) in the doc directory. +If you change the manpage sources you need to manually regenerate the new +manpages by running + cd doc + make doc + + +PLATFORM support +================= +This is a truly multiplatform library. + +Linux: - tested with Ubuntu 10.04 - should work with others as well +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 +Solaris +Windows:- tested on Windows 7 64 and Windows XP 32 using Visual Studio 10 + - tested on Windows 7 64 using MingW on Linux to cross-compile (Debian and Ubuntu tested) +Android:- tested with NDK r10e - running on Android 4.4 (should work starting from 2.3.3) +AROS: - Build with 'make -f aros/Makefile.AROS' +Playstation 2: - Build and install with 'cd ps2_ee; make -f Makefile.PS2_EE install' +PlayStation 3: - Build and install the library with 'make -f ps3_ppu/Makefile.PS3_PPU install' + + +LD_PRELOAD +========== +examples/ld_nfs.c contains a LD_PRELOADable module that can be used to make +several standard utilities nfs aware. +It is still very incomplete but can be used for basic things such as cat and cp. +Patches to add more coverage is welcome. + +Compile with : +gcc -fPIC -shared -o ld_nfs.so examples/ld_nfs.c -ldl -lnfs + +Then try things like +LD_NFS_DEBUG=9 LD_PRELOAD=./ld_nfs.so cat nfs://127.0.0.1//data/tmp/foo123 + +LD_NFS_DEBUG=9 LD_PRELOAD=./ld_nfs.so cp nfs://127.0.0.1//data/tmp/foo123 nfs://127.0.0.1//data/tmp/foo123.copy + +LD_NFS_UID and LD_NFS_GID can be used to fake the uid and the gid in the nfs context. +This can be useful on "insecure" enabled NFS share to make the server trust you as a root. +You can try to run as a normal user things like : +LD_NFS_DEBUG=9 LD_NFS_UID=0 LD_NFS_GID=0 LD_PRELOAD=./ld_nfs.so chown root:root nfs://127.0.0.1//data/tmp/foo123 + +This is just a toy preload module. Don't open bugs if it does not work. Send +patches to make it better instead. + + +RELEASE TARBALLS +================ +Release tarballs are available at +https://sites.google.com/site/libnfstarballs/li + + + +MAILING LIST +============ +A libnfs mailing list is available at http://groups.google.com/group/libnfs +Announcements of new versions of libnfs will be posted to this list. + diff --git a/deps/libnfs/README.multithreading b/deps/libnfs/README.multithreading new file mode 100644 index 000000000000..3cb98383487c --- /dev/null +++ b/deps/libnfs/README.multithreading @@ -0,0 +1,95 @@ +Multithreading +============== +Libnfs supports multithreading using the pthread API on linux/unix and using +the native API for Windows. +By default libnfs is beuilt without pthread support to avoid the overhead +for locking, but pthread support, and thus support for multithreading, can be +configured using --enable-pthread + +$ ./configure --prefix=/usr --enable-examples --enable-pthread + +or, for cmake + +$ cmake -DENABLE_MULTITHREADING=yes .. + +The process to use multithreading from your application is: +1, nfs_init_context() to create an NFS context. This context defaults to + not (yet) be multithreading aware. +2, nfs_mount(...) to mount the NFS share. + +IF the share mounted successfully we can now turn on multithreading for all I/O +to the share: +3, nfs_mt_service_thread_start(nfs) + this starts a dedicated thread to manage all socket + I/O and queue management and also flags the context + to be multithreading ready. + If this returns successfully you can now start using + this context from separate threads in your + application. But remember, only the SYNC API + is supported from this point. +... use the nfs context from all your threads ... + +Once the application is finished and ready to terminate, first close all other +threads, or make sure that they will NOT perform any further I/O to the nfs +context. Wait until all in-flight I/O has stopped. + +Then call nfs_mt_service_thread_stop(nfs) to terminate the service thread and +disable the multithreading support. + + +See examples/nfs-pthreads-*.c for examples on how to use multithreading. + +Porting +------- +The multithreading support is abstracted out into two separate files to make +it easier to add other threading APIs instead of pthreads. +include/libnfs-multithreading.h and lib/multithreading.c + +Multithreading requires two separate defines to be present. +The global one is HAVE_MULTITHREADING which will activate general +multithreading support in the library and the second one that enables a specific +implementation of threading. +HAVE_PTHREAD is defined when you want to use libpthread. +For other threading APIs you will need a new define HAVE_OTHER_API +to select it. + +include/libnfs-multithreading.h +------------------------------- +This file consists of two parts. +The first part is creating typedefs for a tread, a mutex and a semaphore. +When porting to a different threads API, add a new section that adds suitable +typedefs for thread/mutex/semaphore. + +The second part is the wrapper API for the libnfs threading abstractions and +should not need to be changed. + +lib/multithreading.c +-------------------- +This file contains the actual abstraction used for multithreading. +When porting to a different threads API you will need to create replacement +functions for : + +nfs_mt_service_thread() : This is the service thread that is responsible + for performing all socket I/O. +nfs_mt_service_thread_start() +nfs_mt_service_thread_stop() + : Functions to start/stop the service thread. + +nfs_mt_mutex_init() +nfs_mt_mutex_destroy() +nfs_mt_mutex_lock() +nfs_mt_mutex_unlock() : Wrappers that implement the 4 basic mutex calls. + +nfs_mt_sem_init() +nfs_mt_sem_destroy() +nfs_mt_sem_post() +nfs_mt_sem_wait() : Wrappers that implement the 4 basic semaphore calls. + +nfs_mt_get_tid() : Get an identifier for the current thread. + + +TODO +---- +* Optimization: have the service thread just read the PDU from the socket and +add it to a new queue. Then have a pool of threads to read from this queue and +unmarshall the pdu's in concurrently. diff --git a/deps/libnfs/README.security-scan b/deps/libnfs/README.security-scan new file mode 100644 index 000000000000..0e1001c62c03 --- /dev/null +++ b/deps/libnfs/README.security-scan @@ -0,0 +1,91 @@ +# Security Analysis (security-scan) + +This file records an independent, third-party security analysis of libnfs, contributed at +the maintainer's invitation. It documents the methodology, the findings, how they were +scored, and their remediation status. All issues described here were fixed in `master` +in May–June 2026. + +- **Analyst:** Michalis Vasileiadis — independent security researcher (GitHub: [@vmihalis](https://github.com/vmihalis)) +- **Reviewed:** libnfs `master` @ `589e23304a30ffe9624f24a8a8955240a66ec98e` (May 2026) +- **Disclosure:** reported privately to the maintainer on 2026-05-20; fixes landed in `master` + on 2026-05-30/31, each commit carrying a `Reported-by:` credit. + +## Methodology + +A static-analysis security review of the XDR/RPC decoding paths and the TLS handshake, +focused on attacker-reachable input handling — an untrusted NFS server in client context, +or an untrusted NFS client in server context (`rpc_init_server_context`). + +The review combined AI-assisted static analysis (using my security-analysis system, +"Hacker Bob") with manual verification and triage: each candidate was traced to a concrete +`file:line`, validated against the surrounding code paths, and scored by reachability and +impact. The initial pass was static-only — no live server or sanitizer build — so findings +cite source evidence (`file:line`/symbol) rather than crash dumps. Sanitizer and fuzzing +reproductions (libFuzzer / AFL++ with AddressSanitizer) were offered as a follow-up for +regression testing. + +## Severity scoring + +Severities reflect a network threat model: these decoders run on data controlled by the +remote peer, with no application-level interaction required. **HIGH** = memory-corruption +(out-of-bounds access or NULL dereference) reachable during decoding; **MEDIUM** = +denial-of-service or a security-control weakness (silent downgrade). All values are the +analyst's own assessment. + +## Findings + +### F-1 — Signed cast bypasses bounds check in `libnfs_zdr_bytes` (HIGH, CWE-125) +- **Location:** `lib/libnfs-zdr.c:200` +- The bounds guard cast a `uint32_t` size to `(int)`; a value with the high bit set becomes + negative and defeats the `zdrs->pos + (int)*size > zdrs->size` check, while the subsequent + `memcpy` uses the raw `uint32_t`. Reachable via AUTH opaque credential/verifier decode → + out-of-bounds read/write. +- **Fixed:** ZDR object sizes clamped to 1 GB — commit [`3c23b77d82e9`](https://github.com/sahlberg/libnfs/commit/3c23b77d82e9). + +### F-2 — Negative length in NFSv4 attribute parsing (HIGH, CWE-125) +- **Location:** `lib/nfs_v4.c:547,559` +- `int slen` stored a network `uint32_t` length in `nfs_parse_attributes`; a negative `slen` + bypassed `CHECK_GETATTR_BUF_SPACE` and drove an infinite loop + out-of-bounds read in + `nfs_get_ugid`'s `while (slen) { ...; slen--; }` (owner and group fields). +- **Fixed:** attribute size sanity-checked — commit [`0a628210dc88`](https://github.com/sahlberg/libnfs/commit/0a628210dc88). + +### F-3 — Integer overflow + unchecked allocation in `zdr_malloc` (HIGH, CWE-476) +- **Location:** `lib/libnfs-zdr.c:114-119` +- `int mem_size = offsetof(...) + size` overflowed for large server-controlled sizes; the + `malloc` result was not checked, leading to an unconditional NULL dereference at line 119. + Reachable from any server-controlled string, pointer, or array length. +- **Fixed:** `zdr_malloc` allocation clamped to 1 GB — commit [`627e37d36bfd`](https://github.com/sahlberg/libnfs/commit/627e37d36bfd). + +### F-4 — Unbounded recursion in READDIR/READDIRPLUS decoders (MEDIUM, CWE-674) +- **Location:** `nfs/libnfs-raw-nfs.c:1571,1579` (via `lib/libnfs-zdr.c:273`) +- `zdr_entry3` / `zdr_entryplus3` recursed through `libnfs_zdr_pointer` with no depth limit; + a single ~8 MB PDU packed with minimal entry records yields hundreds of thousands of linked + entries, exceeding the thread stack → stack overflow / SIGSEGV. +- **Fixed:** directory entries decoded iteratively rather than recursively — commit [`0e6398550c8d`](https://github.com/sahlberg/libnfs/commit/0e6398550c8d). + +### F-5 — Silent mTLS downgrade when client credentials are absent (MEDIUM, CWE-297) +- **Location:** `tls/handshake.c:258-264` +- When `xprtsec=mtls` was requested but `LIBNFS_TLS_CLIENT_CERT_PEM` / + `LIBNFS_TLS_CLIENT_KEY_PEM` were unset, `tls_global_init()` returned success with only a + debug-level log; `wanted_xprtsec` was never read, so the layer could not distinguish `tls` + from `mtls` → silent downgrade to one-way TLS, defeating the documented mutual-auth + guarantee. This also lowers the precondition for F-1–F-4 (a man-in-the-middle on a believed + mutually-authenticated channel could inject crafted PDUs). +- **Fixed:** `mtls` now fails closed when credentials are unavailable — commit [`f0b109df8fd8`](https://github.com/sahlberg/libnfs/commit/f0b109df8fd8). + +## Threat model + +F-1 through F-4 are reachable from an untrusted NFS server (client context) or an untrusted +NFS client (server context, via `rpc_init_server_context`), with no application-level +interaction — they trigger during XDR decoding. F-5 silently weakens the mutual-authentication +precondition for the rest. + +## Remediation status + +All five issues were fixed in `master` on 2026-05-30/31, each commit carrying a `Reported-by:` +credit, and are included in the subsequent release. CVE identifiers were requested +independently (the maintainer opted not to file advisories); they will be listed here once +assigned. + +--- +*Contributed by Michalis Vasileiadis ([@vmihalis](https://github.com/vmihalis)). Follow-up via GitHub.* diff --git a/deps/libnfs/bootstrap b/deps/libnfs/bootstrap new file mode 100755 index 000000000000..17615844e1e2 --- /dev/null +++ b/deps/libnfs/bootstrap @@ -0,0 +1,2 @@ +#!/bin/sh -e +exec autoreconf -vif diff --git a/deps/libnfs/configure.ac b/deps/libnfs/configure.ac new file mode 100644 index 000000000000..ffe8afd5c15d --- /dev/null +++ b/deps/libnfs/configure.ac @@ -0,0 +1,346 @@ +AC_PREREQ([2.69]) +AC_INIT([libnfs],[16.2.0],[ronniesahlberg@gmail.com]) +AC_CONFIG_HEADERS([config.h]) +AM_INIT_AUTOMAKE([-Wall foreign subdir-objects]) +AC_CANONICAL_HOST +AC_CONFIG_MACRO_DIR([m4]) +m4_pattern_allow([AM_PROG_AR]) +AM_PROG_AR + +# Work around stupid autoconf default cflags. pt 1 +SAVE_CFLAGS="x${CFLAGS}" + +AC_PROG_CC +LT_INIT + +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 +AC_SYS_LARGEFILE + +#option: utils +MAYBE_UTILS="utils" +AC_ARG_ENABLE([utils], + [AS_HELP_STRING([--enable-utils],[Build util programs])], + [if test $enableval = no ; then + MAYBE_UTILS="" + fi]) +AC_SUBST(MAYBE_UTILS) + +#option: examples +AC_ARG_ENABLE([examples], + [AS_HELP_STRING([--enable-examples],[Build example programs])], + [ENABLE_EXAMPLES=$enableval], + [ENABLE_EXAMPLES="no"]) + +#option: servers +MAYBE_SERVERS="" +AC_ARG_ENABLE([servers], + [AS_HELP_STRING([--enable-servers],[Build example servers])], + [if test $enableval = yes ; then + MAYBE_SERVERS="servers" + fi]) +AC_SUBST(MAYBE_SERVERS) + +AC_ARG_WITH([libkrb5], + [AS_HELP_STRING([--without-libkrb5], + [Do not link with libkrb5 even if available.])]) +AS_IF([test "x$with_libkrb5" != "xno"], [ + MAYBE_LIBKRB5="-lgssapi_krb5" + AC_DEFINE([HAVE_LIBKRB5], [1], [Whether we use gssapi_krb5 or not]) + AC_MSG_NOTICE([Build with gssapi_krb5 support]) + dnl Check for gssapi/gssapi.h + AC_CHECK_HEADERS([gssapi/gssapi.h], [], [ + AC_MSG_ERROR([You need gssapi development files to compile libnfs with kerberos support.]) + ]) +], [ + MAYBE_LIBKRB5="" + AC_MSG_NOTICE([Build WITHOUT gssapi_krb5 support]) +]) + +# We need popt to compile the examples +if test x$ENABLE_EXAMPLES = xyes; then +AC_MSG_CHECKING(whether libpopt is available) +ac_save_LIBS="$LIBS" +LIBS="$LIBS -lpopt" +AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ +/* + * Just see if we can compile/link with popt + */ + int _argc; + const char **_argv; + struct poptOption popt_options[] = { + POPT_TABLEEND + }; + poptGetContext(_argv[0], _argc, _argv, popt_options, POPT_CONTEXT_KEEP_FIRST); +]])],[ac_cv_have_popt=yes],[ac_cv_have_popt=no]) +LIBS="$ac_save_LIBS" +if test "$ac_cv_have_popt" = yes ; then + AC_MSG_RESULT(yes) + MAYBE_EXAMPLES="examples" +else + AC_MSG_RESULT(no) + AC_MSG_NOTICE(You need libpopt to compile the sample libnfs clients.) + AC_MSG_NOTICE(Only the library will be compiled and installed.) +fi +fi + +AC_SUBST(MAYBE_EXAMPLES) + +#option: examples +AC_ARG_ENABLE([pthread], + [AS_HELP_STRING([--enable-pthread],[Build with pthread multithreading support])], + [ENABLE_PTHREAD=$enableval], + [ENABLE_PTHREAD="no"]) +if test x$ENABLE_PTHREAD = xyes; then +# check for lpthread +AC_CACHE_CHECK([for pthread support],libnfs_cv_HAVE_PTHREAD,[ +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include ]], [[pthread_t thread1, thread2;]])],[libnfs_cv_HAVE_PTHREAD=yes],[libnfs_cv_HAVE_PTHREAD=no])]) +if test x"$libnfs_cv_HAVE_PTHREAD" = x"yes"; then + AC_DEFINE(HAVE_PTHREAD,1,[Whether we have pthread support]) + AC_DEFINE(HAVE_MULTITHREADING,1,[Whether we have multithreading support]) +fi +fi +AM_CONDITIONAL([HAVE_PTHREAD], [test x$libnfs_cv_HAVE_PTHREAD = xyes]) + +# check for libpthread +if test "$libnfs_cv_HAVE_PTHREAD" = yes; then + ac_save_LIBS=$LIBS + AC_CHECK_LIB([pthread], [pthread_spin_lock], []) + LIBS="$ac_save_LIBS" + if test "$ac_cv_lib_pthread_pthread_spin_lock" = yes; then + LIBS_PRIVATE="-lpthread" + LIBPTHREAD="-lpthread" + fi +fi +AC_SUBST(LIBS_PRIVATE) +AC_SUBST([LIBPTHREAD]) + +AC_MSG_CHECKING(whether SO_BINDTODEVICE is available) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ + int i = SO_BINDTODEVICE; +]])],[ac_cv_have_so_bindtodevice=yes],[ac_cv_have_so_bindtodevice=no]) +if test "$ac_cv_have_so_bindtodevice" = yes ; then + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_SO_BINDTODEVICE, 1, [Whether our sockets support SO_BINDTODEVICE]) +else + AC_MSG_RESULT(no) + AC_MSG_NOTICE(SO_BINDTODEVICE support for if= support is missing.) + AC_MSG_NOTICE(Compiling without if= support.) +fi + +AC_MSG_CHECKING(whether getpwnam() is available) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include + #include +]], [[ + struct passwd *pwd = getpwnam("nobody"); +]])],[ac_cv_have_getpwnam=yes],[ac_cv_have_getpwnam=no]) +if test "$ac_cv_have_getpwnam" = yes ; then + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_GETPWNAM, 1, [Whether we have getpwnam()]) +else + AC_MSG_RESULT(no) + AC_MSG_NOTICE(getpwnam() support is missing.) + AC_MSG_NOTICE(Compiling without getpwnam() support.) +fi + +AC_SUBST([MAYBE_LIBKRB5]) + +AC_ARG_ENABLE([werror], [AS_HELP_STRING([--disable-werror], + [Disables building with -Werror by default])]) + +if test "$ac_cv_c_compiler_gnu" = yes; then + WARN_CFLAGS="-Wall -Wshadow -Wno-write-strings -Wstrict-prototypes -Wpointer-arith -Wcast-align -Wno-strict-aliasing" + if test "x$enable_werror" != "xno"; then + WARN_CFLAGS="$WARN_CFLAGS -Werror" + fi +fi +AC_SUBST(WARN_CFLAGS) + +LIBSOCKET= +SYS= + +case $host in + *solaris*) + AC_CHECK_HEADERS([sys/filio.h]) + AC_CHECK_HEADERS([sys/sockio.h]) + 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])]) + ;; + *mingw32* | *wince* | *mingwce*) + LIBSOCKET='-lws2_32' + SYS=mingw32 + ;; + *) + ;; +esac +AM_CONDITIONAL(HAVE_WIN32, test "${SYS}" = "mingw32") +AC_SUBST([LIBSOCKET]) + +# check for sys/sysmacros.h +dnl Check for sys/sysmacros.h +AC_CHECK_HEADERS([sys/sysmacros.h]) + +# check for poll.h +dnl Check for poll.h +AC_CHECK_HEADERS([poll.h]) + +# check for stdatomic.h +dnl Check for stdatomic.h +AC_CHECK_HEADERS([stdatomic.h]) + +# check for unistd.h +dnl Check for unistd.h +AC_CHECK_HEADERS([unistd.h]) + +# check for netdb.h +dnl Check for netdb.h +AC_CHECK_HEADERS([netdb.h]) + +# check for utime.h +dnl Check for utime.h +AC_CHECK_HEADERS([utime.h]) + +# check for net/if.h +dnl Check for net/if.h +AC_CHECK_HEADERS([net/if.h]) + +# check for sys/time.h +dnl Check for sys/time.h +AC_CHECK_HEADERS([sys/time.h]) + +# check for sys/ioctl.h +dnl Check for sys/ioctl.h +AC_CHECK_HEADERS([sys/ioctl.h]) + +# check for sys/vfs.h +dnl Check for sys/vfs.h +AC_CHECK_HEADERS([sys/vfs.h]) + +# check for sys/statvfs.h +dnl Check for sys/statvfs.h +AC_CHECK_HEADERS([sys/statvfs.h]) + +# check for fuse.h +dnl Check for fuse.h +AC_CHECK_HEADERS([fuse.h]) + +# check for sys/socket.h +dnl Check for sys/socket.h +AC_CHECK_HEADERS([sys/socket.h]) + +# check for netinet/tcp.h +dnl Check for netinet/tcp.h +AC_CHECK_HEADERS([netinet/tcp.h]) + +# check for netinet/in.h +dnl Check for netinet/in.h +AC_CHECK_HEADERS([netinet/in.h]) + +# check for arpa/inet.h +dnl Check for arpa/inet.h +AC_CHECK_HEADERS([arpa/inet.h]) + +# check for sys/uio.h +dnl Check for sys/uio.h +AC_CHECK_HEADERS([sys/uio.h]) + +# check for SA_LEN +dnl Check if sockaddr data structure includes a "sa_len" +AC_CHECK_MEMBER([struct sockaddr.sa_len], + [ AC_DEFINE(HAVE_SOCKADDR_LEN,1,[Whether sockaddr struct has sa_len]) ], + [], + [ +#include +#include +]) + +# check for sockaddr_storage +dnl Check if sockaddr structure includes a "ss_family" +AC_CHECK_MEMBER([struct sockaddr_storage.ss_family], + [ AC_DEFINE(HAVE_SOCKADDR_STORAGE,1,[Whether we have sockaddr_Storage]) ], + [], + [ +#include +#include +]) + +# check for clock_gettime(CLOCK_MONOTONIC_COARSE) +AC_MSG_CHECKING(if clock_gettime(CLOCK_MONOTONIC_COARSE) is available) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ + int i = clock_gettime(CLOCK_MONOTONIC_COARSE, NULL); +]])],[ac_cv_have_clock_gettime=yes],[ac_cv_have_clock_gettime=no]) +if test "$ac_cv_have_clock_gettime" = yes ; then + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_CLOCK_GETTIME, 1, [Whether we have clock_gettime]) +else + AC_MSG_RESULT(no) + AC_MSG_NOTICE(clock_gettime(CLOCK_MONOTONIC_COARSE) support is missing.) + AC_MSG_NOTICE(Compiling without clock_gettime support..) +fi + +# check for tevent + talloc +AC_CACHE_CHECK([for talloc and tevent support],libnfs_cv_HAVE_TALLOC_TEVENT,[ +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include ]], [[struct tevent_context *ctx = tevent_context_init(NULL); + int major = talloc_version_major();]])],[libnfs_cv_HAVE_TALLOC_TEVENT=yes],[libnfs_cv_HAVE_TALLOC_TEVENT=no])]) +if test x"$libnfs_cv_HAVE_TALLOC_TEVENT" = x"yes"; then + AC_DEFINE(HAVE_TALLOC_TEVENT,1,[Whether we have talloc nad tevent support]) +fi +AM_CONDITIONAL([HAVE_TALLOC_TEVENT], [test $libnfs_cv_HAVE_TALLOC_TEVENT = yes]) + +# check for linux tls +AC_CACHE_CHECK([for linux tls support],libnfs_cv_HAVE_TLS,[ +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include ]], +[[const char *v = GNUTLS_VERSION;]])],[libnfs_cv_HAVE_TLS=yes],[libnfs_cv_HAVE_TLS=no])]) +if test x"$libnfs_cv_HAVE_TLS" = x"yes"; then + AC_DEFINE(HAVE_TLS,1,[Whether we have linux tls support]) + # tell pkg-config that gnutls needs to be linked also + AC_SUBST(tls_library,"-lgnutls") +fi +AM_CONDITIONAL([HAVE_TLS], [test $libnfs_cv_HAVE_TLS = yes]) + +AC_CHECK_MEMBERS([struct stat.st_mtim.tv_nsec]) + +AC_CHECK_HEADERS(dispatch/dispatch.h) + +AC_CHECK_FUNCS(pthread_threadid_np) + +# check where makedev is defined +AC_HEADER_MAJOR + +#output +AC_CONFIG_FILES([Makefile] + [doc/Makefile] + [examples/Makefile] + [servers/Makefile] + [servers/rpcbind/Makefile] + [servers/statd/Makefile] + [servers/nfsd/Makefile] + [include/Makefile] + [lib/Makefile] + [mount/Makefile] + [nfs/Makefile] + [nfs4/Makefile] + [nlm/Makefile] + [nsm/Makefile] + [portmap/Makefile] + [rquota/Makefile] + [tests/Makefile] + [utils/Makefile] + [tls/Makefile] + ) + +AC_CONFIG_FILES([libnfs.pc]) +AC_OUTPUT diff --git a/deps/libnfs/include/Makefile.am b/deps/libnfs/include/Makefile.am new file mode 100644 index 000000000000..c3673886067f --- /dev/null +++ b/deps/libnfs/include/Makefile.am @@ -0,0 +1,17 @@ +nfscdir = $(includedir)/nfsc +dist_nfsc_HEADERS = \ + nfsc/libnfs.h \ + nfsc/libnfs-raw.h \ + nfsc/libnfs-zdr.h \ + ../mount/libnfs-raw-mount.h \ + ../portmap/libnfs-raw-portmap.h \ + ../nfs/libnfs-raw-nfs.h \ + ../nfs4/libnfs-raw-nfs4.h \ + ../nlm/libnfs-raw-nlm.h \ + ../nsm/libnfs-raw-nsm.h \ + ../rquota/libnfs-raw-rquota.h + +dist_noinst_HEADERS = \ + win32/win32_compat.h \ + libnfs-private.h \ + slist.h diff --git a/deps/libnfs/include/libnfs-multithreading.h b/deps/libnfs/include/libnfs-multithreading.h new file mode 100644 index 000000000000..305ad9500a1a --- /dev/null +++ b/deps/libnfs/include/libnfs-multithreading.h @@ -0,0 +1,73 @@ +/* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */ +/* + Copyright (C) 2021 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 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ + +#ifndef _LIBNFS_MULTITHREADING_H_ +#define _LIBNFS_MULTITHREADING_H_ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAVE_MULTITHREADING + +#ifdef WIN32 +typedef HANDLE libnfs_thread_t; +typedef HANDLE libnfs_mutex_t; +typedef HANDLE libnfs_sem_t; +typedef DWORD nfs_tid_t; +#elif defined(HAVE_PTHREAD) +#include +typedef pthread_t libnfs_thread_t; +typedef pthread_mutex_t libnfs_mutex_t; + +#if defined(__APPLE__) && defined(HAVE_DISPATCH_DISPATCH_H) +#include +typedef dispatch_semaphore_t libnfs_sem_t; +#else +#include +typedef sem_t libnfs_sem_t; +#endif +#ifdef HAVE_PTHREAD_THREADID_NP +typedef uint64_t nfs_tid_t; +#else +typedef pid_t nfs_tid_t; +#endif +#endif /* HAVE_PTHREAD */ + +nfs_tid_t nfs_mt_get_tid(void); +int nfs_mt_mutex_init(libnfs_mutex_t *mutex); +int nfs_mt_mutex_destroy(libnfs_mutex_t *mutex); +int nfs_mt_mutex_lock(libnfs_mutex_t *mutex); +int nfs_mt_mutex_unlock(libnfs_mutex_t *mutex); + +int nfs_mt_sem_init(libnfs_sem_t *sem, int value); +int nfs_mt_sem_destroy(libnfs_sem_t *sem); +int nfs_mt_sem_post(libnfs_sem_t *sem); +int nfs_mt_sem_wait(libnfs_sem_t *sem); + +#endif /* HAVE_MULTITHREADING */ + +#ifdef __cplusplus +} +#endif + +#endif /* !_LIBNFS_MULTITHREADING_H_ */ diff --git a/deps/libnfs/include/libnfs-private.h b/deps/libnfs/include/libnfs-private.h new file mode 100644 index 000000000000..e741dfe40c50 --- /dev/null +++ b/deps/libnfs/include/libnfs-private.h @@ -0,0 +1,1037 @@ +/* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */ +/* + 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 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ + +#ifndef _LIBNFS_PRIVATE_H_ +#define _LIBNFS_PRIVATE_H_ + +#ifdef HAVE_CONFIG_H +#include "config.h" /* HAVE_SOCKADDR_STORAGE ? */ +#endif + +#if !defined(WIN32) && !defined(PS2_EE) +#include /* struct sockaddr_storage */ +#endif + +#ifdef HAVE_NET_IF_H +#include +#endif + +#ifdef HAVE_LIBKRB5 +#include "lib/krb5-wrapper.h" +#endif + +#ifdef HAVE_TLS +#include +#endif + +#if defined(WIN32) && !defined(IFNAMSIZ) +#define IFNAMSIZ 255 +#endif + +#if defined(PS3_PPU) && !defined(IFNAMSIZ) +#define IFNAMSIZ 16 +#endif + +#if defined(PS2_EE) && !defined(IFNAMSIZ) +#define IFNAMSIZ 16 +#endif + +#ifdef HAVE_MULTITHREADING +#ifdef HAVE_STDATOMIC_H +#include +#define ATOMIC_INC(rpc, x) \ + atomic_fetch_add_explicit(&x, 1, memory_order_relaxed) +#define ATOMIC_DEC(rpc, x) \ + atomic_fetch_sub_explicit(&x, 1, memory_order_relaxed) +#else /* HAVE_STDATOMIC_H */ +#define ATOMIC_INC(rpc, x) \ + if (rpc->multithreading_enabled) { \ + nfs_mt_mutex_lock(&rpc->atomic_int_mutex); \ + } \ + x++; \ + if (rpc->multithreading_enabled) { \ + nfs_mt_mutex_unlock(&rpc->atomic_int_mutex); \ + } +#define ATOMIC_DEC(rpc, x) \ + if (rpc->multithreading_enabled) { \ + nfs_mt_mutex_lock(&rpc->atomic_int_mutex); \ + } \ + x--; \ + if (rpc->multithreading_enabled) { \ + nfs_mt_mutex_unlock(&rpc->atomic_int_mutex); \ + } +#endif /* HAVE_STDATOMIC_H */ +#else /* HAVE_MULTITHREADING */ +/* no multithreading support, no need to protect the increment */ +#define ATOMIC_INC(rpc, x) x++ +#define ATOMIC_DEC(rpc, x) x-- +#endif /* HAVE_MULTITHREADING */ + +#include "libnfs-multithreading.h" +#include "libnfs-zdr.h" +#include "../nfs/libnfs-raw-nfs.h" +#include "../nfs4/libnfs-raw-nfs4.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)((char *)__mptr - offsetof(type,member));}) + +#ifndef MIN +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif +#ifndef MAX +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif + +#if !defined(HAVE_SOCKADDR_STORAGE) && !defined(WIN32) && !defined(PS2_EE) +/* + * RFC 2553: protocol-independent placeholder for socket addresses + */ +#define _SS_MAXSIZE 128 +#define _SS_ALIGNSIZE (sizeof(double)) +#define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(unsigned char) * 2) +#define _SS_PAD2SIZE (_SS_MAXSIZE - sizeof(unsigned char) * 2 - \ + _SS_PAD1SIZE - _SS_ALIGNSIZE) + +struct sockaddr_storage { +#ifdef HAVE_SOCKADDR_LEN + unsigned char ss_len; /* address length */ + unsigned char ss_family; /* address family */ +#else + unsigned short ss_family; +#endif + char __ss_pad1[_SS_PAD1SIZE]; + double __ss_align; /* force desired structure storage alignment */ + char __ss_pad2[_SS_PAD2SIZE]; +}; +#endif + + +struct rpc_fragment { + struct rpc_fragment *next; + uint32_t size; + char *data; +}; + +#define RPC_CONTEXT_MAGIC 0xc6e46435 +#define RPC_PARAM_UNDEFINED -1 + +/* + * Queue is singly-linked but we hold on to the tail + */ +struct rpc_queue { + struct rpc_pdu *head, *tail; +}; + +#define DEFAULT_HASHES 4 +#define NFS_RA_TIMEOUT 5 +#define NFS_MIN_XFER_SIZE NFSMAXDATA2 +#define NFS_MAX_XFER_SIZE (4 * 1024 * 1024) +#define NFS_DEF_XFER_SIZE (1 * 1024 * 1024) +#define ZDR_ENCODE_OVERHEAD 1024 +#define ZDR_ENCODEBUF_MINSIZE 4096 + +struct rpc_endpoint { + struct rpc_endpoint *next; + int program; + int version; + struct service_proc *procs; + int num_procs; +}; + +#define RPC_FAST_VECTORS 8 /* Same as UIO_FASTIOV used by the Linux kernel */ + +/* + * Maximum io vectors supported by rpc_io_vectors. + * This must not be greater than the POSIX UIO_MAXIOV value as we use writev() + * to write the io vectors over the socket. + */ +#define RPC_MAX_VECTORS 1024 + +struct rpc_iovec { + char *buf; + size_t len; + void (*free)(void *); +}; + +/** + * Vectored buffer for holding zero-copy user data to be sent over the socket. + */ +struct rpc_io_vectors { + /* How many bytes from iov[] already written out over the network */ + size_t num_done; + /* Cumulative size of all rpc_iovecs in iov[] */ + size_t total_size; + /* iov[] has space for these many rpc_iovecs */ + int iov_capacity; + /* These many are currently filled */ + int niov; + /* + * For small vectors this will point to fast_iov, else it'll be + * allocated dynamically and must be freed using free(). + */ + struct rpc_iovec *iov; + /* Inline vector, for saving allocation in the common case */ + struct rpc_iovec fast_iov[RPC_FAST_VECTORS]; +}; + +/** + * Vectored buffer for holding zero-copy user data to be read over the socket. + */ +struct rpc_iovec_cursor { + /* + * Fixed base of the allocated iovec array. + * Once allocated this doesn't change, and should be used for freeing + * the iovec array. + */ + struct iovec *base; + + /* + * Current iovec we should be reading into, updated as we finish + * reading whole iovecs. iovcnt holds the count of iovecs remaining + * to be read into and is decremented as we read whole iovecs or if + * the cursor is shrinked. We also update the iov_base and iov_len as + * we read data into iov[], so at any point iov and iovcnt can be + * passed to readv() to read remaining data. + */ + struct iovec *iov; + int iovcnt; + + /* + * Total to-be-read bytes. This is initialized to the total size of + * all the individual buffers and later updated as we read data or if + * the cursor length is reduced due to short read. + * At any point these many new bytes need to be read into this cursor. + */ + size_t remaining_size; + + /* + * Following ref are used to reset iov[] in case we need to resend + * this request, (possibly) after a reconnect. + */ + struct iovec *iov_ref; + int iovcnt_ref; +}; + +enum input_state { + READ_RM = 0, + READ_PAYLOAD = 1, + READ_FRAGMENT = 2, + READ_IOVEC = 3, + READ_PADDING = 4, + READ_UNKNOWN = 5, +}; + +#ifdef HAVE_TLS +struct tls_cb_data { + rpc_cb cb; + void *private_data; +}; + +typedef enum tls_handshake_state { + TLS_HANDSHAKE_UNDEFINED = 0, + TLS_HANDSHAKE_WAITING_FOR_STARTTLS, + TLS_HANDSHAKE_IN_PROGRESS, + TLS_HANDSHAKE_COMPLETED, + TLS_HANDSHAKE_FAILED, +} tls_handshake_state_t; + +/* + * TLS handshake context information. + */ +struct tls_context { + /* Current TLS handshake state */ + enum tls_handshake_state state; + + /* Callback to be called on handshake completion (or failure) */ + struct tls_cb_data data; + + /* gnutls session used for the handshake */ + gnutls_session_t session; +}; +#endif /* HAVE_TLS */ + +#define INC_STATS(rpc, stat) ++((rpc)->stats.stat) + +struct gss_ctx_id_struct; +struct rpc_context { + uint32_t magic; + int fd; + int socket_disabled; /* Do not allow read/write to the socket */ + int old_fd; + int is_connected; + int is_nonblocking; + + char *error_string; + + uint32_t program; + uint32_t version; + + rpc_cb connect_cb; + void *connect_data; + + struct AUTH *auth; + uint32_t xid; + + /* + * Queue of to-be-transmitted PDUs. + * Note: The PDU at the head of this queue will be the next one to be + * written to the socket. This can be a half-sent PDU for which + * (out.num_done < out.total_size). This implies that it's never + * safe to add anything to the head of this queue as that might + * cause the next rpc_write_to_socket() to incorrectly pick data + * from this new PDU while the previous one is half written. + * Only rpc_reconnect_requeue() can safely add to the head of + * this queue as it resets the connection and also the read and + * write cursors. Always use rpc_return_to_outqueue() to safely + * return a pdu to outqueue for retransmit. + */ + struct rpc_queue outqueue; + struct sockaddr_storage udp_src; +#ifdef __linux__ + struct sockaddr_storage udp_dst; /* Which ip we received a UDP packet on */ +#endif + uint32_t num_hashes; + /* + * Queue of transmitted-and-awaiting-response PDUs. + */ + struct rpc_queue *waitpdu; + uint32_t waitpdu_len; + uint32_t max_waitpdu_len; + +#ifdef HAVE_MULTITHREADING + int multithreading_enabled; + libnfs_mutex_t rpc_mutex; +#ifndef HAVE_STDATOMIC_H + libnfs_mutex_t atomic_int_mutex; +#endif /* HAVE_STDATOMIC_H */ +#endif /* HAVE_MULTITHREADING */ + + uint32_t inpos; + uint32_t inbuf_size; + char *inbuf; + enum input_state state; + uint32_t rm_xid[2]; /* array holding the record marker and the next 4 bytes */ + uint32_t pdu_size; /* used in rpc_read_from_socket() */ + char *buf; /* used in rpc_read_from_socket() */ + struct rpc_pdu *pdu; + + /* special fields for UDP, which can sometimes be BROADCASTed */ + int is_udp; + struct sockaddr_storage 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; + int num_retries; + + /* + * NFS server name or IP address. It has the following uses: + * - Used for certificate verification, in case of xprtsec=[tls,mtls] + * mount option. + * Note: In this case it must be a DNS name and not an IP address. + * - For logging along with the "server not responding" message. + * + * Since at RPC layer we don't have access to struct nfs_context, we instead + * save a copy here from nfs_get_server(). + */ + char *server; + + int mountport; + + /* fragment reassembly */ + struct rpc_fragment *fragments; + + /* parameters passable via URL */ + int tcp_syncnt; + int uid; + int gid; + int debug; + uint64_t last_timeout_scan; + + /* + * Absolute time in milliseconds when the last successful RPC response + * was received over this RPC transport/connection. We use it to see if + * some RPC transport could be stuck and if yes we terminate and reconnect + * as recovery action. + * Note that this is to check activity at the RPC level and not at the + * TCP level, latter is checked by using TCP keepalives. + */ + uint64_t last_successful_rpc_response; + + /* + * RPC timeout in milliseconds. This is set from the timeo= mount + * option. This is also called the "minor timeout", in contrast to the + * "major timeout" that happens after retrans*timeout milliseconds. + * It cannot have a value less than 10000, i.e., 10 seconds. + */ + int timeout; + + /* + * Number of times an RPC request is retried before taking further + * recovery action. This is set from the retrans= mount option. + * If 'retrans' is 0 then RPC requests are not retried and they fail + * (with RPC_STATUS_TIMEOUT) after 'timeout' milliseconds. This roughly + * mimics the "soft" mount option of NFS clients. Note that it's almost + * never a good idea for NFS clients to let RPC requests fail, so 'retrans' + * must not be set to 0. + * If 'retrans' is non-zero then that's the number of times an RPC + * request is retried before declaring a "major timeout", which prompts + * more stricter recovery actions, f.e., reconnection. + * + * Note: This is set to non-zero only after successful mount as we want + * a resilient RPC transport only after mount. + * Ref rpc_set_resiliency(). + */ + int retrans; + + char ifname[IFNAMSIZ]; + int poll_timeout; + +#ifdef HAVE_TLS + /* + * Transport level security as selected by the xprtsec=[none,tls,mtls] + * mount option. + */ + enum rpc_xprtsec wanted_xprtsec; + + /* + * Do we need to send AUTH_TLS NULL RPC on connect/reconnect? + * Note that we need this even with wanted_xprtsec as we use TLS only + * for connections to NFS program and not for MOUNT or PORTMAP programs. + * Once set, this remains set for the life of the rpc_context as we need + * it for reconnect also. Note that this is fine for NFSv4 clients as they + * only ever make RPC calls to NFS_PROGRAM. This is fine for NFSv3 clients + * as we turn it on after we are done talking to the PORTMAP and MOUNT + * programs and after that we only talk to NFS_PROGRAM using this rpc_context. + * + * Note: If the rpc_context is again used for talking to PORTMAP/MOUNT + * programs, use_tls must be cleared. + */ + bool_t use_tls; + + /* NFS version to use when sending the AUTH_TLS NULL RPC */ + int nfs_version; + + /* Context used for performing TLS handshake with the server */ + struct tls_context tls_context; +#endif /* HAVE_TLS */ + +#ifdef HAVE_LIBKRB5 + const char *username; + enum rpc_sec wanted_sec; + enum rpc_sec sec; + uint32_t gss_seqno; + int context_len; + char *context; + + void *auth_data; /* for krb5 */ + struct gss_ctx_id_struct *gss_context; +#endif /* HAVE_LIBKRB5 */ + + /* Is a server context ? */ + int is_server_context; + struct rpc_endpoint *endpoints; + + /* Per-transport RPC stats */ + struct rpc_stats stats; + + /* Stats callback */ + rpc_stats_cb stats_cb; + void *stats_private_data; + + /* Logging callback */ + rpc_log_cb log_cb; + void *log_private_data; +}; + +struct rpc_pdu { + struct rpc_pdu *next; + + uint32_t xid; + + ZDR zdr; + ZDR zdr_in; + int free_zdr; + int free_pdu; + + struct rpc_data outdata; + + /* For sending/receiving + * out contains at least three vectors: + * [0] 4 bytes for the stream protocol length + * [1] Varying size for the rpc header (including cred & verf) + * [2+] command and and extra parameters + */ + struct rpc_io_vectors out; + + /* + * vector for zero-copy READ3 receive. + * This is updated as data is read from the socket into the user's + * zero-copy buffers directly. + */ + struct rpc_iovec_cursor in; + + /* + * How much more data remains to be read into 'in'. It's initialized + * with the returned count in READ response and is reduced as we + * read data from the socket into the user's zero-copy buffers. + */ + uint32_t read_count; + uint32_t requested_read_count; /* The amount requested by the + * application. + * Used to clamp long reads. + */ + + rpc_cb cb; + void *private_data; + + /* function to decode the zdr reply data and buffer to decode into */ + zdrproc_t zdr_decode_fn; + void *zdr_decode_buf; + uint32_t zdr_decode_bufsize; + + uint32_t discard_after_sending:1; + uint32_t zero_copy_iov:1; + + /* + * If TRUE, this RPC would not be retried. If no response is received + * it'll fail with RPC_STATUS_TIMEOUT after 'timeout' msecs. + * 'major_timeout' and 'snr_logged' fields are ignored for an RPC which + * has do_not_retry set. + * Non-NFS RPCs are not retried as they are mostly sent before or during + * the mount process and it's desirable to fail them so that the mount + * program can fail with appropriate error to the user who is waiting for + * the mount to complete. + * + * Note that there are two ways to ensure that RPCs are not retried: + * 1. Set rpc->retrans to 0. + * 2. Set pd->do_not_retry to TRUE. + * + * Since we set rpc->retrans to non-zero value only after successful + * mount completion all RPCs sent during the mount process are not + * retried. For any other PDU if we don't want it to be retried we need + * to set pdu->do_not_retry to TRUE. One such example is the AUTH_TLS + * NULL RPC sent on reconnect which needs to be sent inline and hence + * cannot be safely retried. + */ + bool_t do_not_retry; + + /* + * Absolute (minor) timeout in milliseconds for this RPC request. + * This is set to current time in milliseconds (when the RPC is + * queued) plus rpc->timeout. + * If we do not get a response for an RPC request till timeout + * milliseconds we retry the RPC request and reset pdu->timeout to + * the next rpc->timeout milliseconds. + */ + uint64_t timeout; + + /* + * Absolute major timeout in milliseconds for this RPC request. + * A major timeout happens after every rpc->retrans retries, i.e., + * after rpc->retrans*rpc->timeout milliseconds. + * If we do not get a response for an RPC request till 'major_timeout' + * milliseconds we log the "server not responding" message and take + * further recovery action like reconnecting to the server and retrying + * the RPC over the new connection. 'major_timeout' is also reset to + * the next rpc->retrans*rpc->timeout milliseconds. + */ + uint64_t major_timeout; + + /* + * Have we logged the "server not responding" message for this RPC. + * Note that for any RPC the "server not responding" message is logged + * just once, when the first major_timeout occurs. After a major timeout + * if we get the response to the RPC request we log the "server OK" + * message. + */ + bool_t snr_logged; + +#ifdef HAVE_LIBKRB5 + uint32_t gss_seqno; + char creds[64]; + int start_of_payload; + gss_buffer_desc output_buffer; +#endif + +#ifdef HAVE_TLS + /* Set by rpc_allocate_pdu2() when we use AUTH_TLS for a NULL RPC request */ + bool_t expect_starttls; +#endif + /* ONC-RPC header for outgoing PDUs */ + struct rpc_msg msg; + struct rpc_pdu_stats pdu_stats; +}; + +void rpc_reset_queue(struct rpc_queue *q); +void rpc_enqueue(struct rpc_queue *q, struct rpc_pdu *pdu); +void rpc_return_to_outqueue(struct rpc_context *rpc, struct rpc_pdu *pdu); +int rpc_remove_pdu_from_queue(struct rpc_queue *q, struct rpc_pdu *remove_pdu); +unsigned int rpc_hash_xid(struct rpc_context *rpc, uint32_t xid); +struct rpc_pdu *rpc_allocate_pdu(struct rpc_context *rpc, int program, int version, int procedure, rpc_cb cb, void *private_data, zdrproc_t zdr_decode_fn, int zdr_bufsize); +struct rpc_pdu *rpc_allocate_pdu2(struct rpc_context *rpc, int program, int version, int procedure, rpc_cb cb, void *private_data, zdrproc_t zdr_decode_fn, int zdr_bufsize, size_t alloc_hint, int iovcnt_hint); +void pdu_set_timeout(struct rpc_context *rpc, struct rpc_pdu *pdu, uint64_t now_msecs); + +void rpc_free_pdu(struct rpc_context *rpc, struct rpc_pdu *pdu); +int rpc_queue_pdu(struct rpc_context *rpc, struct rpc_pdu *pdu); +int rpc_process_pdu(struct rpc_context *rpc, char *buf, int size); +struct rpc_pdu *rpc_find_pdu(struct rpc_context *rpc, uint32_t xid); +void rpc_error_all_pdus(struct rpc_context *rpc, const char *error); + +/* + * XXX This holds rpc->rpc_mutex, so if the caller is already holding + * rpc->rpc_mutex, use the nolock version below. + */ +void rpc_set_error(struct rpc_context *rpc, const char *error_string, ...) +#ifdef __GNUC__ + __attribute__((format(printf, 2, 3))) +#endif +; + +/* + * rpc_set_error() is a common error path function which is called from many + * functions that hold rpc->rpc_mutex. The following nolock version must be + * used by callers who hold the rpc->rpc_mutex. + */ +void rpc_set_error_locked(struct rpc_context *rpc, const char *error_string, ...) +#ifdef __GNUC__ + __attribute__((format(printf, 2, 3))) +#endif +; + +void nfs_set_error(struct nfs_context *nfs, char *error_string, ...) +#ifdef __GNUC__ + __attribute__((format(printf, 2, 3))) +#endif +; + +void nfs_set_error_locked(struct nfs_context *nfs, char *error_string, ...) +#ifdef __GNUC__ + __attribute__((format(printf, 2, 3))) +#endif +; + +#if defined(PS2_EE) +#define RPC_LOG(rpc, level, format, ...) ; +#else +#define RPC_LOG(rpc, level, format, ...) \ + do { \ + if (rpc->log_cb && level <= rpc->debug) { \ + char xxlogbuf[256]; \ + snprintf(xxlogbuf, 255, "libnfs:%d rpc %p " format, level, rpc, ## __VA_ARGS__); \ + rpc->log_cb(rpc, level, xxlogbuf, rpc->log_private_data); \ + } \ + } while (0) +#endif + +const char *nfs_get_server(struct nfs_context *nfs); +const char *nfs_get_export(struct nfs_context *nfs); + +void rpc_set_interface(struct rpc_context *rpc, const char *ifname); + +void rpc_set_tcp_syncnt(struct rpc_context *rpc, int v); +void rpc_set_mountport(struct rpc_context *rpc, int port); +int rpc_get_mountport(struct rpc_context *rpc); +void rpc_set_poll_timeout(struct rpc_context *rpc, int poll_timeout); +int rpc_get_poll_timeout(struct rpc_context *rpc); +int rpc_add_fragment(struct rpc_context *rpc, char *data, uint32_t size); +void rpc_free_all_fragments(struct rpc_context *rpc); +uint64_t rpc_current_time(void); +uint64_t rpc_current_time_us(void); + +void *zdr_malloc(ZDR *zdrs, uint32_t size); + + +struct nfs_cb_data; +void free_nfs_cb_data(struct nfs_cb_data *data); + +struct nfs_specdata { + uint32_t specdata1; + uint32_t specdata2; +}; +struct nfs_time { + uint32_t seconds; + uint32_t nseconds; +}; +struct nfs_attr { + uint32_t type; + uint32_t mode; + uint32_t uid; + uint32_t gid; + uint32_t nlink; + uint64_t size; + uint64_t used; + uint64_t fsid; + struct nfs_specdata rdev; + struct nfs_time atime; + struct nfs_time mtime; + struct nfs_time ctime; +}; + +struct nfs_fh { + int len; + char *val; +}; + +struct nfs_context_internal { + char *server; + char *export; + char *cwd; + struct nfs_fh rootfh; + size_t readmax; + size_t writemax; + + /* + * Resilency parameters, taken from mount parameters and saved here. + * Later these are pushed to the RPC layer by rpc_set_resiliency(). + */ + int auto_reconnect; + int timeout; + int retrans; + + int dircache_enabled; + struct nfsdir *dircache; + uint16_t mask; + int auto_traverse_mounts; + struct nested_mounts *nested_mounts; + int default_version; /* if 0 it means no default version and only use the + * selected version. + */ + int version; + int nfsport; + int mountport; + uint32_t readdir_dircount; + uint32_t readdir_maxcount; + + /* NFSv4 specific fields */ + verifier4 verifier; + char *client_name; + uint64_t clientid; + verifier4 setclientid_confirm; + uint32_t open_counter; + int has_lock_owner; +#ifdef HAVE_MULTITHREADING + libnfs_thread_t service_thread; + libnfs_mutex_t nfs_mutex; + libnfs_mutex_t nfs4_open_counter_mutex; + libnfs_mutex_t nfs4_open_call_mutex; + struct nfs_thread_context *thread_ctx; +#endif /* HAVE_MULTITHREADING */ + int readonly; +}; + +struct nfs_context { + struct rpc_context *rpc; + struct nfs_context_internal *nfsi; + char *error_string; + +#ifdef HAVE_MULTITHREADING + struct nfs_context *master_ctx; +#endif /* HAVE_MULTITHREADING */ +}; + +#ifdef HAVE_MULTITHREADING +struct nfs_thread_context { + struct nfs_thread_context *next; + nfs_tid_t tid; + struct nfs_context nfs; +}; +#endif /* HAVE_MULTITHREADING */ + +typedef int (*continue_func)(struct nfs_context *nfs, struct nfs_attr *attr, + struct nfs_cb_data *data); + +struct nfs_cb_data { + struct nfs_context *nfs; + struct nfsfh *nfsfh; + char *saved_path, *path; + int link_count, no_follow; + + nfs_cb cb; + void *private_data; + + continue_func continue_cb; + void *continue_data; + void (*free_continue_data)(void *); + uint64_t continue_int; + + struct nfs_fh fh; + + /* for multi-read/write calls. */ + int error; + int cancel; + int oom; +#if defined(HAVE_MULTITHREADING) && defined(HAVE_STDATOMIC_H) + atomic_int num_calls; +#else + int num_calls; +#endif + size_t count, org_count; + uint64_t offset, max_offset, org_offset; + char *buffer; + int not_my_buffer; + const char *usrbuf; + int update_pos; +}; + +struct nested_mounts { + struct nested_mounts *next; + char *path; + struct nfs_fh fh; + struct nfs_attr attr; +}; + +#define MAX_DIR_CACHE 128 +#define MAX_LINK_COUNT 40 + +struct nfsdir { + struct nfs_fh fh; + struct nfs_attr attr; + struct nfsdir *next; + + struct nfsdirent *entries; + struct nfsdirent *current; +}; + +struct stateid { + uint32_t seqid; + char other[12]; +}; + +struct nfsfh { + struct nfs_fh fh; + int is_sync; + int is_append; + int is_readonly; + int is_dirty; + uint64_t offset; + + /* NFSv4 */ + struct stateid stateid; + uint32_t open_owner; + /* locking */ + uint32_t open_seqid; + uint32_t lock_seqid; + struct stateid lock_stateid; +}; + +void rpc_free_iovector(struct rpc_context *rpc, struct rpc_io_vectors *v); +int rpc_add_iovector(struct rpc_context *rpc, struct rpc_io_vectors *v, + char *buf, int len, void (*free)(void *)); +void rpc_advance_cursor(struct rpc_context *rpc, struct rpc_iovec_cursor *v, + size_t len); +void rpc_shrink_cursor(struct rpc_context *rpc, struct rpc_iovec_cursor *v, + size_t new_len); +void rpc_memcpy_cursor(struct rpc_context *rpc, struct rpc_iovec_cursor *v, + const void *src, size_t len); +void rpc_free_cursor(struct rpc_context *rpc, struct rpc_iovec_cursor *v); +void rpc_reset_cursor(struct rpc_context *rpc, struct rpc_iovec_cursor *v); +const struct nfs_fh *nfs_get_rootfh(struct nfs_context *nfs); + +int nfs_normalize_path(struct nfs_context *nfs, char *path); +void nfs_free_nfsdir(struct nfsdir *nfsdir); +void nfs_free_nfsfh(struct nfsfh *nfsfh); + +void nfs_dircache_add(struct nfs_context *nfs, struct nfsdir *nfsdir); +struct nfsdir *nfs_dircache_find(struct nfs_context *nfs, struct nfs_fh *fh); +void nfs_dircache_drop(struct nfs_context *nfs, struct nfs_fh *fh); + +int nfs3_access_async(struct nfs_context *nfs, const char *path, int mode, + nfs_cb cb, void *private_data); +int nfs3_access2_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data); +int nfs3_chdir_async(struct nfs_context *nfs, const char *path, + nfs_cb cb, void *private_data); +int nfs3_chmod_async_internal(struct nfs_context *nfs, const char *path, + int no_follow, int mode, nfs_cb cb, + void *private_data); +int nfs3_chown_async_internal(struct nfs_context *nfs, const char *path, + int no_follow, int uid, int gid, + nfs_cb cb, void *private_data); +int nfs3_close_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, + void *private_data); +int nfs3_creat_async(struct nfs_context *nfs, const char *path, + int mode, nfs_cb cb, void *private_data); +int nfs3_fchmod_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int mode, + nfs_cb cb, void *private_data); +int nfs3_fchown_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int uid, + int gid, nfs_cb cb, void *private_data); +int nfs3_fstat_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, + void *private_data); +int nfs3_fstat64_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, + void *private_data); +int nfs3_fsync_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, + void *private_data); +int nfs3_ftruncate_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + uint64_t length, nfs_cb cb, void *private_data); +int nfs3_link_async(struct nfs_context *nfs, const char *oldpath, + const char *newpath, nfs_cb cb, void *private_data); +int nfs3_lseek_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + int64_t offset, int whence, nfs_cb cb, void *private_data); +int nfs3_mkdir2_async(struct nfs_context *nfs, const char *path, int mode, + nfs_cb cb, void *private_data); +int nfs3_mknod_async(struct nfs_context *nfs, const char *path, int mode, + int dev, nfs_cb cb, void *private_data); +int nfs3_mount_async(struct nfs_context *nfs, const char *server, + const char *export, nfs_cb cb, void *private_data); +int nfs3_open_async(struct nfs_context *nfs, const char *path, int flags, + int mode, nfs_cb cb, void *private_data); +int nfs3_opendir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data); +int nfs3_pread_async_internal(struct nfs_context *nfs, struct nfsfh *nfsfh, + void *buf, size_t count, uint64_t offset, + nfs_cb cb, void *private_data, int update_pos); +int nfs3_preadv_async_internal(struct nfs_context *nfs, struct nfsfh *nfsfh, + const struct iovec *iov, int iovcnt, uint64_t offset, + nfs_cb cb, void *private_data, int update_pos); +int nfs3_pwrite_async_internal(struct nfs_context *nfs, struct nfsfh *nfsfh, + const char *buf, size_t count, uint64_t offset, + nfs_cb cb, void *private_data, int update_pos); +int nfs3_readlink_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data); +int nfs3_rename_async(struct nfs_context *nfs, const char *oldpath, + const char *newpath, nfs_cb cb, void *private_data); +int nfs3_rmdir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data); +int nfs3_stat_async(struct nfs_context *nfs, const char *path, + nfs_cb cb, void *private_data); +int nfs3_stat64_async(struct nfs_context *nfs, const char *path, + int no_follow, nfs_cb cb, void *private_data); +int nfs3_statvfs_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data); +int nfs3_statvfs64_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data); +int nfs3_symlink_async(struct nfs_context *nfs, const char *oldpath, + const char *newpath, nfs_cb cb, void *private_data); +int nfs3_truncate_async(struct nfs_context *nfs, const char *path, + uint64_t length, nfs_cb cb, void *private_data); +int nfs3_umount_async(struct nfs_context *nfs, nfs_cb cb, void *private_data); +int nfs3_unlink_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data); +int nfs3_utime_async(struct nfs_context *nfs, const char *path, + struct utimbuf *times, nfs_cb cb, void *private_data); +int nfs3_utimes_async_internal(struct nfs_context *nfs, const char *path, + int no_follow, struct timeval *times, + nfs_cb cb, void *private_data); +int nfs3_write_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + const void *buf, size_t count, nfs_cb cb, + void *private_data); + +int nfs4_access_async(struct nfs_context *nfs, const char *path, int mode, + nfs_cb cb, void *private_data); +int nfs4_access2_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data); +int nfs4_chdir_async(struct nfs_context *nfs, const char *path, + nfs_cb cb, void *private_data); +int nfs4_chmod_async_internal(struct nfs_context *nfs, const char *path, + int no_follow, int mode, nfs_cb cb, + void *private_data); +int nfs4_chown_async_internal(struct nfs_context *nfs, const char *path, + int no_follow, int uid, int gid, + nfs_cb cb, void *private_data); +int nfs4_close_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, + void *private_data); +int nfs4_creat_async(struct nfs_context *nfs, const char *path, + int mode, nfs_cb cb, void *private_data); +int nfs4_fchmod_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int mode, + nfs_cb cb, void *private_data); +int nfs4_fchown_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int uid, + int gid, nfs_cb cb, void *private_data); +int nfs4_fcntl_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + enum nfs4_fcntl_op cmd, void *arg, + nfs_cb cb, void *private_data); +int nfs4_fstat64_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, + void *private_data); +int nfs4_fsync_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, + void *private_data); +int nfs4_ftruncate_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + uint64_t length, nfs_cb cb, void *private_data); +int nfs4_link_async(struct nfs_context *nfs, const char *oldpath, + const char *newpath, nfs_cb cb, void *private_data); +int nfs4_lseek_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + int64_t offset, int whence, nfs_cb cb, void *private_data); +int nfs4_lockf_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + enum nfs4_lock_op op, uint64_t count, + nfs_cb cb, void *private_data); +int nfs4_mkdir2_async(struct nfs_context *nfs, const char *path, int mode, + nfs_cb cb, void *private_data); +int nfs4_mknod_async(struct nfs_context *nfs, const char *path, int mode, + int dev, nfs_cb cb, void *private_data); +int nfs4_mount_async(struct nfs_context *nfs, const char *server, + const char *export, nfs_cb cb, void *private_data); +int nfs4_open_async(struct nfs_context *nfs, const char *path, int flags, + int mode, nfs_cb cb, void *private_data); +int nfs4_opendir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data); +int nfs4_pread_async_internal(struct nfs_context *nfs, struct nfsfh *nfsfh, + void *buf, size_t count, uint64_t offset, + nfs_cb cb, void *private_data, int update_pos); +int nfs4_preadv_async_internal(struct nfs_context *nfs, struct nfsfh *nfsfh, + const struct iovec *iov, int iovcnt, uint64_t offset, + nfs_cb cb, void *private_data, int update_pos); +int nfs4_pwrite_async_internal(struct nfs_context *nfs, struct nfsfh *nfsfh, + const void *buf, size_t count, uint64_t offset, + nfs_cb cb, void *private_data, int update_pos); +int nfs4_readlink_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data); +int nfs4_rename_async(struct nfs_context *nfs, const char *oldpath, + const char *newpath, nfs_cb cb, void *private_data); +int nfs4_rmdir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data); +int nfs4_stat64_async(struct nfs_context *nfs, const char *path, + int no_follow, nfs_cb cb, void *private_data); +int nfs4_statvfs_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data); +int nfs4_statvfs64_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data); +int nfs4_symlink_async(struct nfs_context *nfs, const char *oldpath, + const char *newpath, nfs_cb cb, void *private_data); +int nfs4_truncate_async(struct nfs_context *nfs, const char *path, + uint64_t length, nfs_cb cb, void *private_data); +int nfs4_unlink_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data); +int nfs4_utime_async(struct nfs_context *nfs, const char *path, + struct utimbuf *times, nfs_cb cb, void *private_data); +int nfs4_utimes_async_internal(struct nfs_context *nfs, const char *path, + int no_follow, struct timeval *times, + nfs_cb cb, void *private_data); +int nfs4_write_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + uint64_t count, const void *buf, nfs_cb cb, + void *private_data); + +int rpc_write_to_socket(struct rpc_context *rpc); +int _nfs_mount_async(struct nfs_context *nfs, const char *server, + const char *exportname, nfs_cb cb, + void *private_data); + +#ifdef HAVE_TLS +int tls_global_init(struct rpc_context *rpc); +enum tls_handshake_state do_tls_handshake(struct rpc_context *rpc); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* !_LIBNFS_PRIVATE_H_ */ diff --git a/deps/libnfs/include/nfsc/libnfs-raw.h b/deps/libnfs/include/nfsc/libnfs-raw.h new file mode 100644 index 000000000000..96e368fa61fa --- /dev/null +++ b/deps/libnfs/include/nfsc/libnfs-raw.h @@ -0,0 +1,3034 @@ +/* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */ +/* + 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 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ +/* + * This is the lowlevel interface to access NFS resources. + * Through this interface you have access to the full gamut of nfs and nfs + * related protocol as well as the XDR encoded/decoded structures. + */ +#ifndef _LIBNFS_RAW_H_ +#define _LIBNFS_RAW_H_ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef AROS +#include "aros_compat.h" +#endif + +#ifdef PS2_EE +#include "ps2_compat.h" +#endif + +#ifdef PS3_PPU +#include "ps3_compat.h" +#endif + +#include + +#if defined(HAVE_SYS_UIO_H) || (defined(__APPLE__) && defined(__MACH__)) +#include +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct rpc_data { + int size; + char *data; +}; + +/* + * Stats maintained per RPC transport. + * User can query these using get_rpc_stats(). + * + * Note: If you add more counters, make sure they are updated atomically. + * + * TODO: These are currently updated only for the client. + */ +struct rpc_stats { + /* + * RPC requests sent out. + * Retransmitted requests are counted multiple times in this. + */ + uint64_t num_req_sent; + + /* + * RPC responses received. + * (num_req_sent - num_resp_rcvd) could be one of the following: + * - requests in flight, whose responses are awaited. + * - requests timed out, whose responses were never received. + * If retransmits are enabled, we would have retransmited these. + */ + uint64_t num_resp_rcvd; + + /* + * RPC requests which didn't get a response for timeo period. + * See mount option 'timeo'. + * These indicate some issue with the server and/or connection. + */ + uint64_t num_timedout; + + /* + * RPC requests that timed out while sitting in outqueue. + * Unlike num_timedout, these are requests which were not sent to + * server. If this number is high it indicates a slow or unresponsive + * server and/or slow connection. Application should slow down issuing + * new RPC requests. + */ + uint64_t num_timedout_in_outqueue; + + /* + * RPC requests which didn't get a response even after retrans + * retries. These are counted in num_timedout as well. + * See mount option 'retrans'. + */ + uint64_t num_major_timedout; + + /* + * RPC requests retransmited due to reconnect or timeout. + */ + uint64_t num_retransmitted; + + /* + * Number of times we had to reconnect, for one of the following + * reasons: + * - Peer closed connection. + * - Major timeout was observed. + */ + uint64_t num_reconnects; +}; + +struct rpc_context; +EXTERN struct rpc_context *rpc_init_context(void); +EXTERN void rpc_destroy_context(struct rpc_context *rpc); + +/* + * Stats callback for all ASYNC rpc functions. + * When the stats callback is provided it will geterate a callback + * every time a PDU is queued for sending as well as when it has received + * on the socket. + */ +struct rpc_pdu; +struct rpc_pdu_stats { + uint32_t size; + uint32_t xid; + uint32_t direction; + uint32_t status; /* only valid in replies */ + uint32_t prog; + uint32_t vers; + uint32_t proc; + uint64_t enqueue_timestamp; /* us, when the pdu was enqueued */ + uint64_t send_timestamp; /* us, when the pdu was sent */ + uint64_t response_time; /* us, only valid in replies */ +}; +typedef void (*rpc_stats_cb)(struct rpc_context *rpc, + struct rpc_pdu_stats *data, + void *private_data); +/* + * Function to query the pdu stats for the current PDU. + * Only valid if called from an RPC callback function. + */ +struct rpc_pdu_stats *rpc_get_pdu_stats(struct rpc_context *rpc); + +/* + * The callback executes in the context of the event-loop so it is vital + * that the callback will never block and will return as fast as possible. + */ +EXTERN void rpc_set_stats_cb(struct rpc_context *rpc, rpc_stats_cb cb, + void *private_data); + +/* + * Set debug level for logging. + */ +void rpc_set_debug(struct rpc_context *rpc, int level); +/* + * Logging is done via a callback. + * Log level is set via rpc_set_debug()/nfs_set_debug() + */ +typedef void (*rpc_log_cb)(struct rpc_context *rpc, + int level, char *msg, void *private_data); +/* + * The callback executes in the context of the event-loop so it is vital + * that the callback will never block and will return as fast as possible. + */ +EXTERN void rpc_set_log_cb(struct rpc_context *rpc, rpc_log_cb cb, + void *private_data); + + +/* + * Commands that are in flight are kept on linked lists and keyed by + * XID so that responses received can be matched with a request. + * For performance reasons, this would not scale well for applications + * that use many concurrent async requests concurrently. + * The default setting is to hash the requests into a small number of + * lists which should work well for single threaded syncrhonous and + * async applications with a moderate number of concurrent requests in flight + * at any one time. + * If you application uses a significant number of concurrent requests + * as in thousands or more, then the default might not be sufficient. + * In that case you can change the number of lists that requests will + * be hashed into with this function. + * NOTE: you can only call this function and modify the number of hashes + * before you connect to the remote service. + */ +EXTERN int rpc_set_hash_size(struct rpc_context *rpc, int hashes); + +EXTERN void rpc_set_auth(struct rpc_context *rpc, struct AUTH *auth); + +/* + * Used for interfacing the api into an external eventsystem. + * + * rpc_get_fd() returns the file descriptor to poll. + * + * rpc_which_events() returns which events that we need to poll for. + * This is a combination of the POLLIN and POLLOUT flags. + * + * rpc_service() is called everytime there are events that needs to be + * processed. + * revents is a combination of POLLIN/POLLOUT/POLLHUP/POLLERR + * + * This function returns 0 on success or -1 on error. If it returns -1 it + * means that the socket is in an unrecoverable error state (disconnected?) + * and that no further commands can be used. + * When this happens the application should destroy the now errored context + * re-create a new context and reconnect. + * + * + * rpc_service() will both process the events indicated by revents and also + * check for and terminate any RPCs that have timed out. + * Thus, if using rpc timeouts, you will need to ensure that rpc_service() + * is invoked on a regular basis so that the timeout processing can take place. + * The easiest way to do this is to call rpc_service() once every 100ms from + * your event system and passing revents as 0. + * + * rpc_disable_socket() will disable libnfs reading/writing to the socket. + * Useful if you want to manage the socket from an external event loop and + * want to ensure that libnfs will never do i/o to the socket. + */ +EXTERN int rpc_get_fd(struct rpc_context *rpc); +EXTERN int rpc_which_events(struct rpc_context *rpc); +EXTERN int rpc_service(struct rpc_context *rpc, int revents); +EXTERN void rpc_disable_socket(struct rpc_context *rpc, int val); + + +/* + * Returns the number of commands in-flight. Can be used by the application + * to check if there are any more responses we are awaiting from the server + * or if the connection is completely idle. + * The number returned includes the commands on the output queue and the + * commands waiting from a response from the server. + */ +EXTERN int rpc_queue_length(struct rpc_context *rpc); + +/* + * Returns the number of commands awaiting from the server. + * Can be used by the application to check if there are any + * more responses we are awaiting from the server + * or if the connection is completely idle. + */ +EXTERN int rpc_get_num_awaiting(struct rpc_context *rpc); + +/* + * Used to limit the total number of commands awaiting from the server. + * By default there is no limit, all commands will be sent as soon as possible. + * If a limit is set and it is reached then new commands will be kept on + * the output queue until the total number of commands in-flight goes below + * the limit again. + */ +EXTERN void rpc_set_awaiting_limit(struct rpc_context *rpc, int limit); + +/* + * Set which UID/GIDs to use in the authenticator. + * By default libnfs will use getuid()/getgid() where available + * and 65534/65534 where not, with no auxiliary GIDs. + */ +EXTERN void rpc_set_uid(struct rpc_context *rpc, int uid); +EXTERN void rpc_set_gid(struct rpc_context *rpc, int gid); +EXTERN void rpc_set_auxiliary_gids(struct rpc_context *rpc, uint32_t len, uint32_t* gids); + +/* + * Used in GSSAPI mode + */ +EXTERN int rpc_set_username(struct rpc_context *rpc, const char *username); + + +/* + * sync rpc_set_timeout() + * This function sets the timeout used for this rpc context. + * + * Function returns nothing. + * + * int milliseconds : timeout to be applied in milliseconds (-1 no timeout) + * timeouts must currently be set in whole seconds, + * i.e. units of 1000 + */ +EXTERN void rpc_set_timeout(struct rpc_context *rpc, int timeout); +/* + * sync rpc_get_timeout() + * This function gets the timeout used for rpc context. + * + * Function returns + * -1 : No timeout applied + * > 0 : Timeout in milliseconds + */ +EXTERN int rpc_get_timeout(struct rpc_context *rpc); + +/* + * Create a server context. + */ +EXTERN struct rpc_context *rpc_init_server_context(int s); + +/* This is the callback functions for server contexts. + * These are invoked from the library when a CALL has been received and a + * service procedure has been found that matches the rpc + * program/version/procedure. + * + * The rpc arguments are stored in call->body.cbody.args; + * Example: + * static int pmap2_getport_proc(struct rpc_context *rpc, struct rpc_msg *call) + * { + * pmap2_mapping *args = call->body.cbody.args; + * ... + * + * struct service_proc pmap2_pt[] = { + * {PMAP2_GETPORT, pmap2_getport_proc, + * (zdrproc_t)zdr_pmap2_mapping, sizeof(pmap2_mapping)}, + * ... + * + * + * The call argument is only valid for the duration of the callback. + * If your application needs to call rpc_send_reply() not from the callback + * but from a different context at a later time you will need to make a temporary + * copy of the call structure using rpc_copy_deferred_call()/rpc_free_deferred_call(). + * See for example examples/rpcbind.c where during the callit processing + * we create a copy so that we can send the reply at a later point in time + * when the rpc created in callit has completed. + * + * The return value is: + * 0: Procedure was completed normally. + * !0: An abnormal error has occured. It is unrecoverable and the only + * meaningful action is to tear down the connection to the server. + */ +typedef int (*service_fn)(struct rpc_context *rpc, struct rpc_msg *call, void *opaque); + +struct service_proc { + int proc; + service_fn func; + zdrproc_t decode_fn; + int decode_buf_size; + void *opaque; +}; + +/* + * Register a service callback table for program/version. + * Can only be used with contexts created with rpc_init_server_context() + */ +EXTERN int rpc_register_service(struct rpc_context *rpc, int program, + int version, struct service_proc *procs, + int num_procs); + +EXTERN int rpc_send_reply(struct rpc_context *rpc, struct rpc_msg *call, + void *reply, zdrproc_t encode_fn, + int alloc_hint); + +EXTERN struct rpc_msg *rpc_copy_deferred_call(struct rpc_context *rpc, + struct rpc_msg *call); + +EXTERN void rpc_free_deferred_call(struct rpc_context *rpc, + struct rpc_msg *call); + +/* + * When an operation failed, this function can extract a detailed error string. + */ +EXTERN char *rpc_get_error(struct rpc_context *rpc); + +/* + * Return the current snapshot of stats for this transport. + */ +EXTERN void rpc_get_stats(struct rpc_context *rpc, struct rpc_stats *stats); + +/* Utility function to get an RPC context from a NFS context. Useful for doing + * low level NFSACL calls on a NFS context. + */ +EXTERN struct rpc_context *nfs_get_rpc_context(struct nfs_context *nfs); + +/* This function returns the nfs_fh structure from a nfsfh structure. + This allows to use a file opened with nfs_open() together with low-level + rpc functions that thake a nfs filehandle +*/ +EXTERN struct nfs_fh *nfs_get_fh(struct nfsfh *nfsfh); + +/* Control what the next XID value to be used on the context will be. + This can be used when multiple contexts are used to the same server + to avoid that the two contexts have xid collissions. + */ +EXTERN void rpc_set_next_xid(struct rpc_context *rpc, uint32_t xid); + +/* This function can be used to set the file descriptor used for + * the RPC context. It is primarily useful when emulating dup2() + * and similar or where you want full control of the filedescriptor numbers + * used by the rpc socket. + * + * ... + * oldfd = rpc_get_fd(rpc); + * dup2(oldfd, newfd); + * rpc_set_fd(rpc, newfd); + * close(oldfd); + * ... + */ +EXTERN void rpc_set_fd(struct rpc_context *rpc, int fd); + +#define RPC_STATUS_SUCCESS 0 +#define RPC_STATUS_ERROR 1 +#define RPC_STATUS_CANCEL 2 +#define RPC_STATUS_TIMEOUT 3 + +/* + * Async connection to the tcp port at server:port. + * Function returns + * 0 : The connection was initiated. The callback will be invoked once the + * connection establish finishes. + * <0 : An error occured when trying to set up the connection. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * RPC_STATUS_SUCCESS : The tcp connection was successfully established. + * data is NULL. + * RPC_STATUS_ERROR : The connection failed to establish. + * data is the error string. + * RPC_STATUS_CANCEL : The connection attempt was aborted before it could + * complete. + * : data is NULL. + */ +EXTERN int rpc_connect_async(struct rpc_context *rpc, const char *server, + int port, rpc_cb cb, void *private_data); + +/* + * Async function to connect to a specific RPC program/version + * Function returns + * 0 : The connection was initiated. The callback will be invoked once the + * connection establish finishes. + * <0 : An error occured when trying to set up the connection. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * RPC_STATUS_SUCCESS : The tcp connection was successfully established. + * data is NULL. + * RPC_STATUS_ERROR : The connection failed to establish. + * data is the error string. + * RPC_STATUS_CANCEL : The connection attempt was aborted before it could + * complete. + * : data is NULL. + */ +EXTERN int rpc_connect_program_async(struct rpc_context *rpc, + const char *server, + int program, int version, + rpc_cb cb, void *private_data); + +/* + * Async function to connect to a specific RPC program/version. + * This connects directly to the specified port without using portmapper. + * + * Function returns + * 0 : The connection was initiated. The callback will be invoked once the + * connection establish finishes. + * <0 : An error occured when trying to set up the connection. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * RPC_STATUS_SUCCESS : The tcp connection was successfully established. + * data is NULL. + * RPC_STATUS_ERROR : The connection failed to establish. + * data is the error string. + * RPC_STATUS_CANCEL : The connection attempt was aborted before it could + * complete. + * : data is NULL. + */ +EXTERN int rpc_connect_port_async(struct rpc_context *rpc, const char *server, + int port, + int program, int version, + rpc_cb cb, void *private_data); + +/* + * When disconnecting a connection all commands in flight will be + * called with a callback status RPC_STATUS_ERROR. Data will be the + * error string for the disconnection. + */ +EXTERN int rpc_disconnect(struct rpc_context *rpc, const char *error); + + +/* + * All rpc__ functions return a struct rpc_pdu * + * This is to allow to cancel a pdu in flight. Beware, the pdu pointer + * is only valid until the callback function has completed. + * After the callback function has finished the pdu structure will no longer + * be valid. + * It is the responsibility of the application to make sure + * that the pdu pointer is not used after the callback has returned. + * + * A PDU can not be cancelled once we has started to receive it on the + * socket. + */ +/* + * rpc_cancel_pdu() + * + * Function returns + * 0 : PDU was successfully cancelled. + * <0 : PDU could not be cancelled. + * This can happen for example if we have started to receive this + * pdu on the socket but have not yet completed the callback + * function. + */ +struct rpc_pdu; +int rpc_cancel_pdu(struct rpc_context *rpc, struct rpc_pdu *pdu); + +/* + * PORTMAP v2 FUNCTIONS + */ + +/* + * Call PORTMAPPER2/NULL + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is NULL. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_pmap2_null_task(struct rpc_context *rpc, + rpc_cb cb, void *private_data); + +/* + * Call PORTMAPPER2/GETPORT. + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is a (uint32_t *), containing the port returned. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_pmap2_getport_task(struct rpc_context *rpc, int program, + int version, int protocol, + rpc_cb cb, void *private_data); + +/* + * Call PORTMAPPER2/SET + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is a (uint32_t *), containing status + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_pmap2_set_task(struct rpc_context *rpc, int program, + int version, int protocol, int port, + rpc_cb cb, void *private_data); + +/* + * Call PORTMAPPER2/UNSET + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is a (uint32_t *), containing status + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_pmap2_unset_task(struct rpc_context *rpc, int program, + int version, int protocol, int port, + rpc_cb cb, void *private_data); + +/* + * Call PORTMAPPER2/DUMP. + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is struct pmap2_dump_result. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_pmap2_dump_task(struct rpc_context *rpc, rpc_cb cb, + void *private_data); + +/* + * Call PORTMAPPER2/CALLIT. + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is a 'pmap2_call_result' pointer. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_pmap2_callit_task(struct rpc_context *rpc, int program, + int version, int procedure, + char *data, int datalen, + rpc_cb cb, void *private_data); + +/* + * PORTMAP v3 FUNCTIONS + */ + +/* + * Call PORTMAPPER3/NULL + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is NULL. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_pmap3_null_task(struct rpc_context *rpc, + rpc_cb cb, void *private_data); + +/* + * Call PORTMAPPER3/SET. + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is uint32_t * containing status. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct pmap3_mapping; +EXTERN struct rpc_pdu * +rpc_pmap3_set_task(struct rpc_context *rpc, + struct pmap3_mapping *map, + rpc_cb cb, void *private_data); + +/* + * Call PORTMAPPER3/UNSET. + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is uint32_t * containing status. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_pmap3_unset_task(struct rpc_context *rpc, + struct pmap3_mapping *map, + rpc_cb cb, void *private_data); + +/* + * Call PORTMAPPER3/GETADDR. + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is struct pmap3_string_result. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_pmap3_getaddr_task(struct rpc_context *rpc, + struct pmap3_mapping *map, + rpc_cb cb, void *private_data); + +/* + * Call PORTMAPPER3/DUMP. + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is struct pmap3_dump_result. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_pmap3_dump_task(struct rpc_context *rpc, + rpc_cb cb, void *private_data); + +/* + * Call PORTMAPPER3/CALLIT. + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is a 'pmap3_call_result' pointer. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_pmap3_callit_task(struct rpc_context *rpc, int program, + int version, int procedure, + char *data, int datalen, + rpc_cb cb, void *private_data); + +/* + * Call PORTMAPPER3/GETTIME. + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is a uint32_t * containing status. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_pmap3_gettime_task(struct rpc_context *rpc, + rpc_cb cb, void *private_data); + +/* + * Call PORTMAPPER3/UADDR2TADDR. + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is a struct pmap3_netbuf *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_pmap3_uaddr2taddr_task(struct rpc_context *rpc, char *uaddr, + rpc_cb cb, void *private_data); + +/* + * Call PORTMAPPER3/TADDR2UADDR. + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is a struct pmap3_string_result *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct pmap3_netbuf; +EXTERN struct rpc_pdu * +rpc_pmap3_taddr2uaddr_task(struct rpc_context *rpc, + struct pmap3_netbuf *netbuf, + rpc_cb cb, void *private_data); + +/* + * PORTMAP v4 FUNCTIONS + */ + +/* + * Call PORTMAPPER4/NULL + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is NULL. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_pmap4_null_task(struct rpc_context *rpc, + rpc_cb cb, void *private_data); + +/* + * Call PORTMAPPER4/SET. + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is uint32_t * containing status. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct pmap4_mapping; +EXTERN struct rpc_pdu * +rpc_pmap4_set_task(struct rpc_context *rpc, + struct pmap4_mapping *map, + rpc_cb cb, void *private_data); + +/* + * Call PORTMAPPER4/UNSET. + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is uint32_t * containing status. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_pmap4_unset_task(struct rpc_context *rpc, + struct pmap4_mapping *map, + rpc_cb cb, void *private_data); + +/* + * Call PORTMAPPER4/GETADDR. + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is struct pmap4_string_result. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_pmap4_getaddr_task(struct rpc_context *rpc, + struct pmap4_mapping *map, + rpc_cb cb, void *private_data); + +/* + * Call PORTMAPPER4/DUMP. + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is struct pmap4_dump_result. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_pmap4_dump_task(struct rpc_context *rpc, + rpc_cb cb, void *private_data); + +/* + * Call PORTMAPPER4/BCAST. + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is a 'pmap4_bcast_result' pointer. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_pmap4_bcast_task(struct rpc_context *rpc, int program, + int version, int procedure, + char *data, int datalen, + rpc_cb cb, void *private_data); + +/* + * Call PORTMAPPER4/GETTIME. + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is a uint32_t * containing status. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_pmap4_gettime_task(struct rpc_context *rpc, + rpc_cb cb, void *private_data); + +/* + * Call PORTMAPPER4/UADDR2TADDR. + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is a struct pmap4_netbuf *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_pmap4_uaddr2taddr_task(struct rpc_context *rpc, char *uaddr, + rpc_cb cb, void *private_data); + +/* + * Call PORTMAPPER4/TADDR2UADDR. + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is a struct pmap4_string_result *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct pmap4_netbuf; +EXTERN struct rpc_pdu * +rpc_pmap4_taddr2uaddr_task(struct rpc_context *rpc, + struct pmap4_netbuf *netbuf, + rpc_cb cb, void *private_data); + +/* + * Call PORTMAPPER4/GETVERSADDR. + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is a struct pmap4_string_result *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_pmap4_getversaddr_task(struct rpc_context *rpc, struct pmap4_mapping *map, rpc_cb cb, void *private_data); + +/* + * Call PORTMAPPER4/INDIRECT. + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is a 'pmap4_indirect_result' pointer. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_pmap4_indirect_task(struct rpc_context *rpc, int program, + int version, int procedure, + char *data, int datalen, + rpc_cb cb, void *private_data); + +/* + * Call PORTMAPPER4/GETADDRLIST. + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is a 'pmap4_entry_list_ptr' pointer. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_pmap4_getaddrlist_task(struct rpc_context *rpc, struct pmap4_mapping *map, rpc_cb cb, void *private_data); + +/* + * Call PORTMAPPER4/GETSTAT. + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is a 'pmap4_stat_byvers' pointer. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_pmap4_getstat_task(struct rpc_context *rpc, rpc_cb cb, void *private_data); + + + +/* + * MOUNT v3 FUNCTIONS + */ +EXTERN char *mountstat3_to_str(int stat); +EXTERN int mountstat3_to_errno(int error); + +/* + * Call MOUNT3/NULL + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is NULL. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_mount3_null_task(struct rpc_context *rpc, + rpc_cb cb, void *private_data); + +/* + * Call MOUNT3/MNT + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is union mountres3. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_mount3_mnt_task(struct rpc_context *rpc, rpc_cb cb, + char *exportname, void *private_data); + +/* + * Call MOUNT3/DUMP + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is a mountlist. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_mount3_dump_task(struct rpc_context *rpc, + rpc_cb cb, void *private_data); + +/* + * Call MOUNT3/UMNT + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data NULL. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_mount3_umnt_task(struct rpc_context *rpc, rpc_cb cb, + char *exportname, + void *private_data); + +/* + * Call MOUNT3/UMNTALL + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data NULL. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_mount3_umntall_task(struct rpc_context *rpc, + rpc_cb cb, void *private_data); + +/* + * Call MOUNT3/EXPORT + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is exports *: + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_mount3_export_task(struct rpc_context *rpc, + rpc_cb cb, void *private_data); + +/* + * MOUNT v1 FUNCTIONS (Used with NFSv2) + */ +/* + * Call MOUNT1/NULL + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is NULL. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_mount1_null_task(struct rpc_context *rpc, + rpc_cb cb, void *private_data); + +/* + * Call MOUNT1/MNT + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is union mountres1. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_mount1_mnt_task(struct rpc_context *rpc, rpc_cb cb, + char *exportname, + void *private_data); + +/* + * Call MOUNT1/DUMP + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is a mountlist. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_mount1_dump_task(struct rpc_context *rpc, + rpc_cb cb, void *private_data); + +/* + * Call MOUNT1/UMNT + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data NULL. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_mount1_umnt_task(struct rpc_context *rpc, rpc_cb cb, + char *exportname, + void *private_data); + +/* + * Call MOUNT1/UMNTALL + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data NULL. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_mount1_umntall_task(struct rpc_context *rpc, + rpc_cb cb, void *private_data); + +/* + * Call MOUNT1/EXPORT + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is exports *: + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_mount1_export_task(struct rpc_context *rpc, + rpc_cb cb, void *private_data); + + +/* + * NFS v3 FUNCTIONS + */ +struct nfs_fh3; +EXTERN char *nfsstat3_to_str(int error); +EXTERN int nfsstat3_to_errno(int error); + +/* + * Call NFS3/NULL + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is NULL. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_nfs3_null_task(struct rpc_context *rpc, + rpc_cb cb, void *private_data); + +/* + * Call NFS3/GETATTR + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is GETATTR3res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct GETATTR3args; +EXTERN struct rpc_pdu * +rpc_nfs3_getattr_task(struct rpc_context *rpc, rpc_cb cb, + struct GETATTR3args *args, + void *private_data); + +/* + * Call NFS3/PATHCONF + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is PATHCONF3res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct PATHCONF3args; +EXTERN struct rpc_pdu * +rpc_nfs3_pathconf_task(struct rpc_context *rpc, rpc_cb cb, + struct PATHCONF3args *args, + void *private_data); + +/* + * Call NFS3/LOOKUP + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is LOOKUP3res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct LOOKUP3args; +EXTERN struct rpc_pdu * +rpc_nfs3_lookup_task(struct rpc_context *rpc, rpc_cb cb, + struct LOOKUP3args *args, + void *private_data); + +/* + * Call NFS3/ACCESS + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is ACCESS3res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct ACCESS3args; +EXTERN struct rpc_pdu * +rpc_nfs3_access_task(struct rpc_context *rpc, rpc_cb cb, + struct ACCESS3args *args, + void *private_data); + +/* + * Call NFS3/READ + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is READ3res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct READ3args; +EXTERN struct rpc_pdu * +rpc_nfs3_read_task(struct rpc_context *rpc, rpc_cb cb, + void *buf, size_t count, + struct READ3args *args, + void *private_data); + +/* + * Same as rpc_nfs3_read_task() but can be used to receive READ data into + * an iovec. Useful for callers who do not have a single contiguous read + * buffer but instead want the READ data to be gathered into multiple + * non-contiguous buffers. + */ +EXTERN struct rpc_pdu * +rpc_nfs3_readv_task(struct rpc_context *rpc, rpc_cb cb, + const struct iovec *iov, int iovcnt, + struct READ3args *args, + void *private_data); + +/* + * Call NFS3/WRITE + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is WRITE3res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct WRITE3args; +EXTERN struct rpc_pdu * +rpc_nfs3_write_task(struct rpc_context *rpc, rpc_cb cb, + struct WRITE3args *args, + void *private_data); + +/* + * Same as rpc_nfs3_write_task() but can be used to send WRITE data from + * an iovec. Useful for callers who do not have the WRITE data in a single + * contiguous buffer but instead the WRITE data needs to be gathered from + * multiple non-contiguous buffers. + */ +EXTERN struct rpc_pdu * +rpc_nfs3_writev_task(struct rpc_context *rpc, rpc_cb cb, + struct WRITE3args *args, + const struct iovec *iov, int iovcnt, + void *private_data); + +/* + * Call NFS3/COMMIT + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is COMMIT3res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct COMMIT3args; +EXTERN struct rpc_pdu * +rpc_nfs3_commit_task(struct rpc_context *rpc, rpc_cb cb, + struct COMMIT3args *args, + void *private_data); + +/* + * Call NFS3/SETATTR + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is SETATTR3res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct SETATTR3args; +EXTERN struct rpc_pdu * +rpc_nfs3_setattr_task(struct rpc_context *rpc, rpc_cb cb, + struct SETATTR3args *args, + void *private_data); + +/* + * Call NFS3/MKDIR + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is MKDIR3res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct MKDIR3args; +EXTERN struct rpc_pdu * +rpc_nfs3_mkdir_task(struct rpc_context *rpc, rpc_cb cb, + struct MKDIR3args *args, + void *private_data); + +/* + * Call NFS3/RMDIR + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is RMDIR3res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct RMDIR3args; +EXTERN struct rpc_pdu * +rpc_nfs3_rmdir_task(struct rpc_context *rpc, rpc_cb cb, + struct RMDIR3args *args, + void *private_data); + +/* + * Call NFS3/CREATE + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is CREATE3res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct CREATE3args; +EXTERN struct rpc_pdu * +rpc_nfs3_create_task(struct rpc_context *rpc, rpc_cb cb, + struct CREATE3args *args, + void *private_data); + +/* + * Call NFS3/MKNOD + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is MKNOD3res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct MKNOD3args; +EXTERN struct rpc_pdu * +rpc_nfs3_mknod_task(struct rpc_context *rpc, rpc_cb cb, + struct MKNOD3args *args, + void *private_data); + +/* + * Call NFS3/REMOVE + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is REMOVE3res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct REMOVE3args; +EXTERN struct rpc_pdu * +rpc_nfs3_remove_task(struct rpc_context *rpc, rpc_cb cb, + struct REMOVE3args *args, + void *private_data); + +/* + * Call NFS3/READDIR + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is READDIR3res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct READDIR3args; +EXTERN struct rpc_pdu * +rpc_nfs3_readdir_task(struct rpc_context *rpc, rpc_cb cb, + struct READDIR3args *args, + void *private_data); + +/* + * Call NFS3/READDIRPLUS + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is READDIRPLUS3res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct READDIRPLUS3args; +EXTERN struct rpc_pdu * +rpc_nfs3_readdirplus_task(struct rpc_context *rpc, rpc_cb cb, + struct READDIRPLUS3args *args, + void *private_data); + +/* + * Call NFS3/FSSTAT + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is FSSTAT3res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct FSSTAT3args; +EXTERN struct rpc_pdu * +rpc_nfs3_fsstat_task(struct rpc_context *rpc, rpc_cb cb, + struct FSSTAT3args *args, + void *private_data); + +/* + * Call NFS3/FSINFO + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is FSINFO3res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct FSINFO3args; +EXTERN struct rpc_pdu * +rpc_nfs3_fsinfo_task(struct rpc_context *rpc, rpc_cb cb, + struct FSINFO3args *args, + void *private_data); + +/* + * Call NFS3/READLINK + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is READLINK3res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct READLINK3args; +EXTERN struct rpc_pdu * +rpc_nfs3_readlink_task(struct rpc_context *rpc, rpc_cb cb, + struct READLINK3args *args, + void *private_data); + +/* + * Call NFS3/SYMLINK + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is SYMLINK3res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct SYMLINK3args; +EXTERN struct rpc_pdu * +rpc_nfs3_symlink_task(struct rpc_context *rpc, rpc_cb cb, + struct SYMLINK3args *args, + void *private_data); + +/* + * Call NFS3/RENAME + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is RENAME3res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct RENAME3args; +EXTERN struct rpc_pdu * +rpc_nfs3_rename_task(struct rpc_context *rpc, rpc_cb cb, + struct RENAME3args *args, + void *private_data); + +/* + * Call NFS3/LINK + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is LINK3res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct LINK3args; +EXTERN struct rpc_pdu * +rpc_nfs3_link_task(struct rpc_context *rpc, rpc_cb cb, + struct LINK3args *args, + void *private_data); + +/* + * NFS v2 FUNCTIONS + */ + +/* + * Call NFS2/NULL + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is NULL. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_nfs2_null_task(struct rpc_context *rpc, + rpc_cb cb, void *private_data); + +/* + * Call NFS2/GETATTR + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is GETATTR2res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct GETATTR2args; +EXTERN struct rpc_pdu * +rpc_nfs2_getattr_task(struct rpc_context *rpc, rpc_cb cb, + struct GETATTR2args *args, + void *private_data); + +/* + * Call NFS2/SETATTR + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is SETATTR2res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct SETATTR2args; +EXTERN struct rpc_pdu * +rpc_nfs2_setattr_task(struct rpc_context *rpc, rpc_cb cb, + struct SETATTR2args *args, + void *private_data); + +/* + * Call NFS2/LOOKUP + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is LOOKUP2res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct LOOKUP2args; +EXTERN struct rpc_pdu * +rpc_nfs2_lookup_task(struct rpc_context *rpc, rpc_cb cb, + struct LOOKUP2args *args, + void *private_data); + +/* + * Call NFS2/READLINK + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is READLINK2res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct READLINK2args; +EXTERN struct rpc_pdu * +rpc_nfs2_readlink_task(struct rpc_context *rpc, rpc_cb cb, + struct READLINK2args *args, + void *private_data); + +/* + * Call NFS2/READ + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is READ2res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct READ2args; +EXTERN struct rpc_pdu * +rpc_nfs2_read_task(struct rpc_context *rpc, rpc_cb cb, + struct READ2args *args, + void *private_data); + +/* + * Call NFS2/WRITE + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is WRITE2res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct WRITE2args; +EXTERN struct rpc_pdu * +rpc_nfs2_write_task(struct rpc_context *rpc, rpc_cb cb, + struct WRITE2args *args, + void *private_data); + +/* + * Call NFS2/CREATE + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is CREATE2res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct CREATE2args; +EXTERN struct rpc_pdu * +rpc_nfs2_create_task(struct rpc_context *rpc, rpc_cb cb, + struct CREATE2args *args, + void *private_data); + +/* + * Call NFS2/REMOVE + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is REMOVE2res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct REMOVE2args; +EXTERN struct rpc_pdu * +rpc_nfs2_remove_task(struct rpc_context *rpc, rpc_cb cb, + struct REMOVE2args *args, + void *private_data); + +/* + * Call NFS2/RENAME + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is RENAME2res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct RENAME2args; +EXTERN struct rpc_pdu * +rpc_nfs2_rename_task(struct rpc_context *rpc, rpc_cb cb, + struct RENAME2args *args, + void *private_data); + +/* + * Call NFS2/LINK + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is LINK2res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct LINK2args; +EXTERN struct rpc_pdu * +rpc_nfs2_link_task(struct rpc_context *rpc, rpc_cb cb, + struct LINK2args *args, + void *private_data); + +/* + * Call NFS2/SYMLINK + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is SYMLINK2res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct SYMLINK2args; +EXTERN struct rpc_pdu * +rpc_nfs2_symlink_task(struct rpc_context *rpc, rpc_cb cb, + struct SYMLINK2args *args, + void *private_data); + +/* + * Call NFS2/MKDIR + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is MKDIR2res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct MKDIR2args; +EXTERN struct rpc_pdu * +rpc_nfs2_mkdir_task(struct rpc_context *rpc, rpc_cb cb, + struct MKDIR2args *args, + void *private_data); + +/* + * Call NFS2/RMDIR + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is RMDIR2res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct RMDIR2args; +EXTERN struct rpc_pdu * +rpc_nfs2_rmdir_task(struct rpc_context *rpc, rpc_cb cb, + struct RMDIR2args *args, + void *private_data); + +/* + * Call NFS2/READDIR + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is READDIR2res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct READDIR2args; +EXTERN struct rpc_pdu * +rpc_nfs2_readdir_task(struct rpc_context *rpc, rpc_cb cb, + struct READDIR2args *args, + void *private_data); + +/* + * Call NFS2/STATFS + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is STATFS2res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct STATFS2args; +EXTERN struct rpc_pdu * +rpc_nfs2_statfs_task(struct rpc_context *rpc, rpc_cb cb, + struct STATFS2args *args, + void *private_data); + +/* + * RQUOTA FUNCTIONS + */ +EXTERN char *rquotastat_to_str(int error); +EXTERN int rquotastat_to_errno(int error); + +/* + * Call RQUOTA1/NULL + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is NULL. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_rquota1_null_task(struct rpc_context *rpc, + rpc_cb cb, void *private_data); + +/* + * Call RQUOTA1/GETQUOTA + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is GETQUOTA1res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_rquota1_getquota_task(struct rpc_context *rpc, rpc_cb cb, + char *exportname, int uid, + void *private_data); + +/* + * Call RQUOTA1/GETACTIVEQUOTA + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is GETQUOTA1res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_rquota1_getactivequota_task(struct rpc_context *rpc, rpc_cb cb, + char *exportname, int uid, + void *private_data); + + +/* + * Call RQUOTA2/NULL + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is NULL. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_rquota2_null_task(struct rpc_context *rpc, + rpc_cb cb, void *private_data); + +/* + * Call RQUOTA2/GETQUOTA + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is GETQUOTA1res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_rquota2_getquota_task(struct rpc_context *rpc, rpc_cb cb, + char *exportname, int type, int uid, + void *private_data); + +/* + * Call RQUOTA2/GETACTIVEQUOTA + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is GETQUOTA1res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_rquota2_getactivequota_task(struct rpc_context *rpc, rpc_cb cb, + char *exportname, int type, int uid, + void *private_data); + + +/* + * NFSACL functions + */ + +/* + * Call NFSACL3/NULL + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is NULL. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_nfsacl3_null_task(struct rpc_context *rpc, rpc_cb cb, + void *private_data); + +/* + * Call NFSACL3/GETACL + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is GETACL3res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct GETACL3args; +EXTERN struct rpc_pdu * +rpc_nfsacl3_getacl_task(struct rpc_context *rpc, rpc_cb cb, + struct GETACL3args *args, + void *private_data); + +/* + * Call NFSACL3/SETACL + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is SETACL3res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct SETACL3args; +EXTERN struct rpc_pdu * +rpc_nfsacl3_setacl_task(struct rpc_context *rpc, rpc_cb cb, + struct SETACL3args *args, + void *private_data); + + + + +/* + * NLM functions + */ +EXTERN char *nlmstat4_to_str(int stat); + +/* + * Call NLM/NULL + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is NULL. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_nlm4_null_task(struct rpc_context *rpc, rpc_cb cb, + void *private_data); + +/* + * Call NLM/TEST + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is NLM4_TESTres *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct NLM4_TESTargs; +EXTERN struct rpc_pdu * +rpc_nlm4_test_task(struct rpc_context *rpc, rpc_cb cb, + struct NLM4_TESTargs *args, + void *private_data); + +/* + * Call NLM/LOCK + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is NLM4_LOCKres *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct NLM4_LOCKargs; +EXTERN struct rpc_pdu * +rpc_nlm4_lock_task(struct rpc_context *rpc, rpc_cb cb, + struct NLM4_LOCKargs *args, + void *private_data); + +/* + * Call NLM/CANCEL + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is NLM4_CANCres *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct NLM4_CANCargs; +EXTERN struct rpc_pdu * +rpc_nlm4_cancel_task(struct rpc_context *rpc, rpc_cb cb, + struct NLM4_CANCargs *args, + void *private_data); + +/* + * Call NLM/UNLOCK + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is NLM4_UNLOCKres *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct NLM4_UNLOCKargs; +EXTERN struct rpc_pdu * +rpc_nlm4_unlock_task(struct rpc_context *rpc, rpc_cb cb, + struct NLM4_UNLOCKargs *args, + void *private_data); + +/* + * Call NLM/SHARE + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is NLM4_LOCKres *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct NLM4_SHAREargs; +EXTERN struct rpc_pdu * +rpc_nlm4_share_task(struct rpc_context *rpc, rpc_cb cb, + struct NLM4_SHAREargs *args, + void *private_data); + +/* + * Call NLM/UNSHARE + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is NLM4_UNLOCKres *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_nlm4_unshare_task(struct rpc_context *rpc, rpc_cb cb, + struct NLM4_SHAREargs *args, + void *private_data); + +/* + * NSM functions + */ +EXTERN char *nsmstat1_to_str(int stat); + +/* + * Call NSM/NULL + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is NULL + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_nsm1_null_task(struct rpc_context *rpc, rpc_cb cb, + void *private_data); + +/* + * Call NSM/STAT + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is NSM1_STATres *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct NSM1_STATargs; +EXTERN struct rpc_pdu * +rpc_nsm1_stat_task(struct rpc_context *rpc, rpc_cb cb, + struct NSM1_STATargs *args, + void *private_data); + +/* + * Call NSM/MON + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is NSM1_MONres *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct NSM1_MONargs; +EXTERN struct rpc_pdu * +rpc_nsm1_mon_task(struct rpc_context *rpc, rpc_cb cb, + struct NSM1_MONargs *args, + void *private_data); + +/* + * Call NSM/UNMON + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is NSM1_UNMONres *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct NSM1_UNMONargs; +EXTERN struct rpc_pdu * +rpc_nsm1_unmon_task(struct rpc_context *rpc, rpc_cb cb, + struct NSM1_UNMONargs *args, + void *private_data); + +/* + * Call NSM/UNMONALL + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is NSM1_UNMONALLres *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct NSM1_UNMONALLargs; +EXTERN struct rpc_pdu * +rpc_nsm1_unmonall_task(struct rpc_context *rpc, rpc_cb cb, + struct NSM1_UNMONALLargs *args, + void *private_data); + +/* + * Call NSM/SIMUCRASH + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is NULL. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_nsm1_simucrash_task(struct rpc_context *rpc, rpc_cb cb, + void *private_data); + +/* + * Call NSM/NOTIFY + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is NULL. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +struct NSM1_NOTIFYargs; +EXTERN struct rpc_pdu * +rpc_nsm1_notify_task(struct rpc_context *rpc, rpc_cb cb, + struct NSM1_NOTIFYargs *args, + void *private_data); + +/* + * NFS v4 FUNCTIONS + */ +EXTERN char *nfsstat4_to_str(int error); +EXTERN int nfsstat4_to_errno(int error); + +/* + * Call NFS4/NULL + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is NULL. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_nfs4_null_task(struct rpc_context *rpc, rpc_cb cb, + void *private_data); + +/* + * Call NFS4/COMPOUND + * + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is COMPOUND4res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + * This function can NOT be used for compounds that contain OP_READ or OP_WRITE. + */ +struct COMPOUND4args; +EXTERN struct rpc_pdu * +rpc_nfs4_compound_task(struct rpc_context *rpc, rpc_cb cb, + struct COMPOUND4args *args, + void *private_data); +/* + * Call NFS4/COMPOUND with extra allocation. + + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * 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 server. + * data is COMPOUND4res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + * This function can NOT be used for compounds that contain OP_READ or OP_WRITE. + */ +struct COMPOUND4args; +EXTERN struct rpc_pdu * +rpc_nfs4_compound_task2(struct rpc_context *rpc, rpc_cb cb, + struct COMPOUND4args *args, + void *private_data, + size_t alloc_hint); + +/* + * Call NFS4/COMPOUND for read operations + + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * 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 server. + * data is COMPOUND4res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + * If the compound contains OP_READ you must use this function and not + * rpc_nfs4_compound_task() + * The OP_READ must be the last operation in the compound. + */ +EXTERN struct rpc_pdu * +rpc_nfs4_read_task(struct rpc_context *rpc, rpc_cb cb, + void *buf, size_t count, + struct COMPOUND4args *args, + void *private_data); + +/* + * Same as rpc_nfs4_read_task() but can be used to receive READ data into + * an iovec. Useful for callers who do not have a single contiguous read + * buffer but instead want the READ data to be gathered into multiple + * non-contiguous buffers. + */ +EXTERN struct rpc_pdu * +rpc_nfs4_readv_task(struct rpc_context *rpc, rpc_cb cb, + const struct iovec *iov, int iovcnt, + struct COMPOUND4args *args, + void *private_data); + +/* + * Call NFS4/COMPOUND for write operations + * + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * 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 server. + * data is COMPOUND4res *. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + * If the compound contains OP_WRITE you must use this function and not + * rpc_nfs4_compound_async() + * The OP_WRITE must be the last operation in the compound. + */ +EXTERN struct rpc_pdu * +rpc_nfs4_write_task(struct rpc_context *rpc, rpc_cb cb, + const void *buf, size_t count, + struct COMPOUND4args *args, + void *private_data); + +/* + * Same as rpc_nfs3_write_task() but can be used to send WRITE data from + * an iovec. Useful for callers who do not have the WRITE data in a single + * contiguous buffer but instead the WRITE data needs to be gathered from + * multiple non-contiguous buffers. + */ +EXTERN struct rpc_pdu * +rpc_nfs4_writev_task(struct rpc_context *rpc, rpc_cb cb, + const struct iovec *iov, int iovcnt, + struct COMPOUND4args *args, + void *private_data); + +/* + * Call /NULL + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * 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 server. + * data is NULL. + * RPC_STATUS_ERROR : The command failed with an error. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_null_task(struct rpc_context *rpc, int program, int version, + rpc_cb cb, void *private_data); + +#ifdef HAVE_TLS +/* + * Call /NULL RPC with AUTH_TLS in order to probe RPC-with-TLS + * support from the server, and if server supports RPC-with-TLS, initiate a TLS + * handshake. Callback will be called after TLS handshake completes (success or + * failure) and not just after we get a response for this NULL RPC. + * Function returns + * pdu : The command was queued successfully. The callback will be invoked once + * the command completes. + * NULL : An error occured when trying to queue the command. + * 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 server. + * data is NULL. + * RPC_STATUS_ERROR : The command failed with an error, either server doesn't + * support TLS or the TLS handshake failed. + * data is the error string. + * RPC_STATUS_CANCEL : The command was cancelled. + * data is NULL. + */ +EXTERN struct rpc_pdu * +rpc_null_task_authtls(struct rpc_context *rpc, int nfs_version, rpc_cb cb, + void *private_data); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/deps/libnfs/include/nfsc/libnfs-zdr.h b/deps/libnfs/include/nfsc/libnfs-zdr.h new file mode 100644 index 000000000000..eb159c5137ac --- /dev/null +++ b/deps/libnfs/include/nfsc/libnfs-zdr.h @@ -0,0 +1,329 @@ +/* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */ +/* + Copyright (C) 2012 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 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ +/* + * This file contains definitions for the built in ZDR implementation. + * This is a very limited ZDR subset that can only marshal to/from a momory buffer, + * i.e. zdrmem_create() buffers. + * It aims to be compatible with normal rpcgen generated functions. + */ + +/************************************************************ + * Definitions copied from RFC 5531 + * and slightly modified. + ************************************************************/ + +#ifndef _LIBNFS_ZDR_H_ +#define _LIBNFS_ZDR_H_ + +#ifdef WIN32 +#ifndef CADDR_T_DEFINED +#define CADDR_T_DEFINED +typedef char *caddr_t; +#endif +#include +#endif + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define _RPC_RPC_H 1 +#define _RPC_ZDR_H 1 +#define _RPC_AUTH_H 1 + +/* we dont need these */ +typedef void CLIENT; +struct svc_req { + int _dummy_; +}; +typedef void SVCXPRT; + + + + + +#define ZDR_INLINE(...) NULL +#define IZDR_PUT_U_LONG(...) assert(0) +#define IZDR_GET_U_LONG(...) (assert(0), 0) +#define IZDR_PUT_LONG(...) assert(0) +#define IZDR_GET_LONG(...) (assert(0), 0) +#define IZDR_PUT_BOOL(...) assert(0) +#define IZDR_GET_BOOL(...) (assert(0), 0) + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +enum zdr_op { + ZDR_ENCODE = 0, + ZDR_DECODE = 1 +}; + +struct zdr_mem; + +struct ZDR { + enum zdr_op x_op; + caddr_t buf; + int size; + int pos; + struct zdr_mem *mem; +}; +typedef struct ZDR ZDR; + + +#ifdef __MINGW32__ +typedef uint32_t u_int; +#endif +typedef uint32_t enum_t; +typedef uint32_t bool_t; + +typedef uint32_t (*zdrproc_t) (ZDR *, void *,...); + +#define AUTH_NONE 0 +#define AUTH_NULL 0 +#define AUTH_SYS 1 +#define AUTH_UNIX 1 +#define AUTH_GSS 6 + +#ifdef HAVE_TLS +#define AUTH_TLS 7 +#endif + +struct opaque_cred { + uint32_t oa_flavor; + caddr_t oa_base; + uint32_t oa_length; +}; + +struct gss_ctx_id_struct; +struct opaque_verf { + uint32_t oa_flavor; + caddr_t oa_base; + uint32_t oa_length; + + /* GSS */ + struct gss_ctx_id_struct *gss_context; +}; +extern struct opaque_verf _null_auth; + +struct AUTH { + struct opaque_cred ah_cred; + struct opaque_verf ah_verf; + caddr_t ah_private; +}; + +#define RPC_MSG_VERSION 2 + +enum msg_type { + CALL = 0, + REPLY = 1 +}; + +enum reply_stat { + MSG_ACCEPTED=0, + MSG_DENIED=1 +}; + +enum accept_stat { + SUCCESS = 0, + PROG_UNAVAIL = 1, + PROG_MISMATCH = 2, + PROC_UNAVAIL = 3, + GARBAGE_ARGS = 4, + SYSTEM_ERR = 5 +}; + +enum reject_stat { + RPC_MISMATCH = 0, + AUTH_ERROR = 1 +}; + +enum auth_stat { + AUTH_OK=0, + /* + * failed at remote end + */ + AUTH_BADCRED = 1, /* bogus credentials (seal broken) */ + AUTH_REJECTEDCRED = 2, /* client should begin new session */ + AUTH_BADVERF = 3, /* bogus verifier (seal broken) */ + AUTH_REJECTEDVERF = 4, /* verifier expired or was replayed */ + AUTH_TOOWEAK = 5, /* rejected due to security reasons */ + /* + * failed locally + */ + AUTH_INVALIDRESP = 6, /* bogus response verifier */ + AUTH_FAILED = 7 /* some unknown reason */ +}; + +struct call_body { + uint32_t rpcvers; + uint32_t prog; + uint32_t vers; + uint32_t proc; + struct opaque_cred cred; + struct opaque_verf verf; + void *args; +}; + +struct accepted_reply { + struct opaque_verf verf; + uint32_t stat; + union { + struct { + caddr_t where; + zdrproc_t proc; + + /* GSS */ + uint32_t krb5i; + uint32_t krb5p; + void *output_buffer; + } results; + struct { + uint32_t low; + uint32_t high; + } mismatch_info; + } reply_data; +}; + +struct rejected_reply { + enum reject_stat stat; + union { + struct { + uint32_t low; + uint32_t high; + } mismatch_info; + enum auth_stat stat; + } reject_data; +}; + +struct reply_body { + uint32_t stat; + union { + struct accepted_reply areply; + struct rejected_reply rreply; + } reply; +}; + +struct rpc_msg { + uint32_t xid; + + uint32_t direction; + union { + struct call_body cbody; + struct reply_body rbody; + } body; +}; + +#define zdrmem_create libnfs_zdrmem_create +void libnfs_zdrmem_create(ZDR *zdrs, const caddr_t addr, uint32_t size, enum zdr_op xop); + +#define zdr_destroy libnfs_zdr_destroy +void libnfs_zdr_destroy(ZDR *zdrs); + +#define zdr_bytes libnfs_zdr_bytes +bool_t libnfs_zdr_bytes(ZDR *zdrs, char **bufp, uint32_t *size, uint32_t maxsize); + +#define zdr_u_int libnfs_zdr_u_int +#define zdr_uint32_t libnfs_zdr_u_int +bool_t libnfs_zdr_u_int(ZDR *zdrs, uint32_t *u); + +#define zdr_int libnfs_zdr_int +#define zdr_int32_t libnfs_zdr_int +bool_t libnfs_zdr_int(ZDR *zdrs, int32_t *i); + +#define zdr_uint64_t libnfs_zdr_uint64_t +bool_t libnfs_zdr_uint64_t(ZDR *zdrs, uint64_t *u); + +#define zdr_int64_t libnfs_zdr_int64_t +bool_t libnfs_zdr_int64_t(ZDR *zdrs, int64_t *i); + +#define zdr_enum libnfs_zdr_enum +bool_t libnfs_zdr_enum(ZDR *zdrs, enum_t *e); + +#define zdr_bool libnfs_zdr_bool +bool_t libnfs_zdr_bool(ZDR *zdrs, bool_t *b); + +#define zdr_void libnfs_zdr_void +bool_t libnfs_zdr_void(ZDR *zdrs, void *); + +#define zdr_pointer libnfs_zdr_pointer +bool_t libnfs_zdr_pointer(ZDR *zdrs, char **objp, uint32_t size, zdrproc_t proc); + +#define zdr_opaque libnfs_zdr_opaque +bool_t libnfs_zdr_opaque(ZDR *zdrs, char *objp, uint32_t size); + +#define zdr_string libnfs_zdr_string +bool_t libnfs_zdr_string(ZDR *zdrs, char **strp, uint32_t maxsize); + +#define zdr_array libnfs_zdr_array +bool_t libnfs_zdr_array(ZDR *zdrs, char **arrp, uint32_t *size, uint32_t maxsize, uint32_t elsize, zdrproc_t proc); + +#define zdr_vector libnfs_zdr_vector +bool_t libnfs_zdr_vector(ZDR *zdrs, char *arrp, uint32_t size, uint32_t elsize, zdrproc_t proc); + +#define zdr_setpos libnfs_zdr_setpos +bool_t libnfs_zdr_setpos(ZDR *zdrs, uint32_t pos); + +#define zdr_getpos libnfs_zdr_getpos +uint32_t libnfs_zdr_getpos(ZDR *zdrs); + +#define zdr_getsize libnfs_zdr_getsize +uint32_t libnfs_zdr_getsize(ZDR *zdrs); + +#define zdr_getptr libnfs_zdr_getptr +char *libnfs_zdr_getptr(ZDR *zdrs); + +#define zdr_free libnfs_zdr_free +void libnfs_zdr_free(zdrproc_t proc, char *objp); + +struct rpc_context; + +#define zdr_callmsg libnfs_zdr_callmsg +bool_t libnfs_zdr_callmsg(struct rpc_context *rpc, ZDR *zdrs, struct rpc_msg *msg); + +#define zdr_replymsg libnfs_zdr_replymsg +bool_t libnfs_zdr_replymsg(struct rpc_context *rpc, ZDR *zdrs, struct rpc_msg *msg); + +#define authnone_create libnfs_authnone_create +struct AUTH *libnfs_authnone_create(void); + +#define authunix_create libnfs_authunix_create +struct AUTH *libnfs_authunix_create(const char *host, uint32_t uid, uint32_t gid, uint32_t len, uint32_t *groups); + +#define authunix_create_default libnfs_authunix_create_default +struct AUTH *libnfs_authunix_create_default(void); + +int libnfs_authgss_init(struct rpc_context *rpc); +int libnfs_authgss_gen_creds(struct rpc_context *rpc, ZDR *zdr, int level); + +#define auth_destroy libnfs_auth_destroy +void libnfs_auth_destroy(struct AUTH *auth); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/deps/libnfs/include/nfsc/libnfs.h b/deps/libnfs/include/nfsc/libnfs.h new file mode 100755 index 000000000000..21a0c69ef7b4 --- /dev/null +++ b/deps/libnfs/include/nfsc/libnfs.h @@ -0,0 +1,2150 @@ +/* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */ +/* + 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 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ +/* + * This is the high-level interface to access NFS resources using posix-like + * functions. + */ + +#ifndef _LIBNFS_H_ +#define _LIBNFS_H_ + +#ifdef PS2_EE +#include "ps2_compat.h" +#endif + +#include +#include +#if !defined(_WIN32) +#include +#else +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define LIBNFS_API_V2 +#define LIBNFS_FEATURE_DEBUG +#define LIBNFS_FEATURE_UMOUNT +#define LIBNFS_FEATURE_MULTITHREADING + +#define NFS_BLKSIZE 4096 + +struct nfs_context; +struct rpc_context; + +struct nfs_url { + char *server; + int port; + char *path; + char *file; +}; + +#if defined(WIN32) && defined(libnfs_EXPORTS) +#define EXTERN __declspec( dllexport ) +#else +#ifndef EXTERN +#define EXTERN +#endif +#endif + +#ifdef WIN32 +#include +#ifdef HAVE_FUSE_H +#include +#else +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; +}; +#endif +#if !defined(__MINGW32__) +struct utimbuf { + time_t actime; + time_t modtime; +}; +#endif +#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. + * + * nfs_get_fd() returns the file descriptor for the context we need to + * listen for events from. + * + * nfs_which_events() returns which events that we need to poll for. + * This is a combination of the POLLIN and POLLOUT flags. + * + * nfs_service() This function should be called once there are events triggered + * for the filedescriptor. This function takes POLLIN/POLLOUT/POLLHUP/POLLERR + * as arguments. + * This function returns 0 on success or -1 on error. If it returns -1 it + * means that the socket is in an unrecoverable error state (disconnected?) + * and that no further commands can be used. + * When this happens the application should destroy the now errored context + * re-create a new context and reconnect. + * + * + * If using the async interface and nfs timeouts, i.e. nfs_set_timeout(), + * you will need to ensure to call nfs_service() on a regular basis as + * the timeout handling is done as part of that function. + * For example calling nfs_service() with revents == 0 once every 100ms + * or so from your event loop. + * You only need this for the async interface. The sync interface already + * do this in their built-in event loops. + */ +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); + +/* + * Returns the number of commands in-flight. Can be used by the application + * to check if there are any more responses we are awaiting for the server + * or if the connection is completely idle. + */ +EXTERN int nfs_queue_length(struct nfs_context *nfs); + +/* + * Used if you need different credentials than the default for the current user. + */ +struct AUTH; +EXTERN void nfs_set_auth(struct nfs_context *nfs, struct AUTH *auth); + +/* + * Used to set which security to use. + */ +enum rpc_sec { + RPC_SEC_UNDEFINED = 0, + RPC_SEC_KRB5, + RPC_SEC_KRB5I, + RPC_SEC_KRB5P, +}; +EXTERN void nfs_set_security(struct nfs_context *nfs, enum rpc_sec sec); + +/* + * Set readonly parameter of the mount. + */ +EXTERN void nfs_set_readonly(struct nfs_context *nfs, int readonly); + +#ifdef HAVE_TLS +/* + * Various transport level security values that map to the mount option + * xprtsec=[none,tls,mtls]. + */ +enum rpc_xprtsec { + RPC_XPRTSEC_UNDEFINED = 0, + RPC_XPRTSEC_NONE, /* No transport security */ + RPC_XPRTSEC_TLS, /* TLS, with server authentication */ + RPC_XPRTSEC_MTLS, /* Mutual TLS, with both server and client authentication */ +}; + +EXTERN void nfs_set_xprtsecurity(struct nfs_context *nfs, enum rpc_xprtsec xprtsec); +#endif /* HAVE_TLS */ + +/* + * Used if you need to bind to a specific interface. + * Only available on platforms that support SO_BINDTODEVICE. + */ +EXTERN void nfs_set_interface(struct nfs_context *nfs, const char *ifname); + +/* + * When an operation failed, this function can extract a detailed error string. + */ +EXTERN char *nfs_get_error(struct nfs_context *nfs); + + +/* + * Callback for all ASYNC nfs functions + */ +typedef void (*nfs_cb)(int err, struct nfs_context *nfs, void *data, + void *private_data); + +/* + * Callback for all ASYNC rpc functions + */ +typedef void (*rpc_cb)(struct rpc_context *rpc, int status, void *data, + void *private_data); + + +/* + * NFS CONTEXT. + */ +/* + * Create an NFS context. + * Function returns + * NULL : Failed to create a context. + * *nfs : A pointer to an nfs context. + */ +EXTERN struct nfs_context *nfs_init_context(void); +/* + * Destroy an nfs context. + */ +EXTERN void nfs_destroy_context(struct nfs_context *nfs); + +/* + * Commands that are in flight are kept on linked lists and keyed by + * XID so that responses received can be matched with a request. + * For performance reasons, this would not scale well for applications + * that use many concurrent async requests concurrently. + * The default setting is to hash the requests into a small number of + * lists which should work well for single threaded syncrhonous and + * async applications with a moderate number of concurrent requests in flight + * at any one time. + * If you application uses a significant number of concurrent requests + * as in thousands or more, then the default might not be sufficient. + * In that case you can change the number of lists that requests will + * be hashed into with this function. + * NOTE: you can only call this function and modify the number of hashes + * before you mount the share. + */ +EXTERN int nfs_set_hash_size(struct nfs_context *nfs, int hashes); + + +/* + * URL parsing functions. + * These functions all parse a URL of the form + * nfs://server/path/file?argv=val[&arg=val]* + * and returns a nfs_url. + * + * Apart from parsing the URL the functions will also update + * the nfs context to reflect settings controlled via url arguments. + * + * Current URL arguments are : + * tcp-syncnt= : Number of SYNs to send during the session establish + * before failing setting up the TCP connection to the + * server. + * uid= : UID value to use when talking to the server. + * default is 65534 on Windows and getuid() on unixen. + * gid= : GID value to use when talking to the server. + * default is 65534 on Windows and getgid() on unixen. + * sec= + * : Specify the security mode. + * xprtsec= + * : Specify the transport security mode. + * none : No TLS security. + * tls : TLS with server authentication only. + * mtls : Mutual TLS, both server and client authentication. + * auto-traverse-mounts=<0|1> + * : Should libnfs try to traverse across nested mounts + * automatically or not. Default is 1 == enabled. + * readonly : Set the mount to readonly. + * dircache=<0|1> : Disable/enable directory caching. Enabled by default. + * autoreconnect=<-1|0|>=1> + * : Control the auto-reconnect behaviour to the NFS session. + * -1 : Try to reconnect forever on session failures. + * Just like normal NFS clients do. + * 0 : Disable auto-reconnect completely and immediately + * return a failure to the application. + * >=1 : Retry to connect back to the server this many + * times before failing and returing an error back + * to the application. + * version=<3|4> : NFS version. Default is 3. + * nfsport= : Use this port for NFS instead of using the portmapper. + * mountport= : Use this port for the MOUNT protocol instead of + * using portmapper. This argument is ignored for NFSv4 + * as it does not use the MOUNT protocol. + * readdir-buffer= | readdir-buffer=, + * : Set the buffer size for READDIRPLUS, where dircount is + * the maximum amount of bytes the server should use to + * retrieve the entry names and maxcount is the maximum + * size of the response buffer (including attributes). + * If only one is given it will be used for both. + * Default is 8192 for both. + */ +/* + * Parse a complete NFS URL including, server, path and + * filename. Fail if any component is missing. + */ +EXTERN struct nfs_url *nfs_parse_url_full(struct nfs_context *nfs, + const char *url); + +/* + * Parse an NFS URL, but do not split path and file. File + * in the resulting struct remains NULL. + */ +EXTERN struct nfs_url *nfs_parse_url_dir(struct nfs_context *nfs, + const char *url); + +/* + * Parse an NFS URL, but do not fail if file, path or even server is missing. + * Check elements of the resulting struct for NULL. + */ +EXTERN struct nfs_url *nfs_parse_url_incomplete(struct nfs_context *nfs, + const char *url); + + +/* + * Free the URL struct returned by the nfs_parse_url_* functions. + */ +EXTERN void nfs_destroy_url(struct nfs_url *url); + + +struct nfsfh; + +/* + * Get the NFS server address we are currently connected to. + */ +EXTERN const struct sockaddr_storage *nfs_get_server_address(struct nfs_context *nfs); + +/* + * Get the maximum supported READ size by the server + */ +EXTERN size_t nfs_get_readmax(struct nfs_context *nfs); + +/* + * Get the maximum supported WRITE size by the server + */ +EXTERN size_t nfs_get_writemax(struct nfs_context *nfs); + +/* + * Set the maximum supported READ size by the server + */ +EXTERN void nfs_set_readmax(struct nfs_context *nfs, size_t readmax); + +/* + * Set the maximum supported WRITE size by the server + */ +EXTERN void nfs_set_writemax(struct nfs_context *nfs, size_t writemax); + +/* + * MODIFY CONNECT PARAMETERS + */ + +EXTERN void nfs_set_tcp_syncnt(struct nfs_context *nfs, int v); +EXTERN void nfs_set_uid(struct nfs_context *nfs, int uid); +EXTERN void nfs_set_gid(struct nfs_context *nfs, int gid); +EXTERN void nfs_set_auxiliary_gids(struct nfs_context *nfs, uint32_t len, uint32_t* gids); +EXTERN void nfs_set_debug(struct nfs_context *nfs, int level); +EXTERN void nfs_set_auto_traverse_mounts(struct nfs_context *nfs, int enabled); +EXTERN void nfs_set_dircache(struct nfs_context *nfs, int enabled); +EXTERN void nfs_set_autoreconnect(struct nfs_context *nfs, int num_retries); +EXTERN void nfs_set_retrans(struct nfs_context *nfs, int retrans); +EXTERN void nfs_set_nfsport(struct nfs_context *nfs, int port); +EXTERN void nfs_set_mountport(struct nfs_context *nfs, int port); +EXTERN size_t nfs_get_readdir_maxcount(struct nfs_context *nfs); +EXTERN void nfs_set_readdir_max_buffer_size(struct nfs_context *nfs, uint32_t dircount, uint32_t maxcount); + +/* + * Set NFS version. Supported versions are + * NFS_V3 (default) + * NFS_V4 + */ +EXTERN int nfs_set_version(struct nfs_context *nfs, int version); +/* + * Get NFS version of a connected share. Supported versions are + * NFS_V3 + * NFS_V4 + */ +EXTERN int nfs_get_version(struct nfs_context *nfs); + +/* + * MOUNT THE EXPORT + */ +/* + * Async nfs mount. + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is NULL + * -errno : An error occured. + * data is the error string. + */ +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 successful. + * -errno : The command failed. + */ +EXTERN int nfs_mount(struct nfs_context *nfs, const char *server, + const char *exportname); + + +/* + * UNMOUNT THE EXPORT + */ +/* + * Async nfs umount. + * For NFSv4 this is a NO-OP. + * For NFSv3 this function returns unregisters the mount from the MOUNT Daemon. + * + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is NULL + * -errno : An error occured. + * data is the error string. + */ +EXTERN int nfs_umount_async(struct nfs_context *nfs, nfs_cb cb, + void *private_data); +/* + * Sync nfs umount. + * For NFSv4 this is a NO-OP. + * For NFSv3 this function returns unregisters the mount from the MOUNT Daemon. + * + * Function returns + * 0 : The operation was successful. + * -errno : The command failed. + */ +EXTERN int nfs_umount(struct nfs_context *nfs); + + + + +/* + * STAT() + */ +/* + * Async stat() + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is struct stat * + * -errno : An error occured. + * data is the error string. + */ +/* This function is deprecated. Use nfs_stat64_async() instead */ +struct stat; +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 successful. + * -errno : The command failed. + */ +/* This function is deprecated. Use nfs_stat64() instead */ +#ifdef WIN32 +EXTERN int nfs_stat(struct nfs_context *nfs, const char *path, + struct __stat64 *st); +#else +EXTERN int nfs_stat(struct nfs_context *nfs, const char *path, struct stat *st); +#endif + + +/* nfs_stat64 + * 64 bit version if stat. All fields are always 64bit. + * Use these functions instead of nfs_stat[_async](), especially if you + * have weird stat structures. + */ +/* + * STAT() + */ +struct nfs_stat_64 { + uint64_t nfs_dev; + uint64_t nfs_ino; + uint64_t nfs_mode; + uint64_t nfs_nlink; + uint64_t nfs_uid; + uint64_t nfs_gid; + uint64_t nfs_rdev; + uint64_t nfs_size; + uint64_t nfs_blksize; + uint64_t nfs_blocks; + uint64_t nfs_atime; + uint64_t nfs_mtime; + uint64_t nfs_ctime; + uint64_t nfs_atime_nsec; + uint64_t nfs_mtime_nsec; + uint64_t nfs_ctime_nsec; + uint64_t nfs_used; +}; + +/* + * Async stat64filename>) + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is struct nfs_stat_64 * + * -errno : An error occured. + * data is the error string. + */ +EXTERN int nfs_stat64_async(struct nfs_context *nfs, const char *path, + nfs_cb cb, void *private_data); +/* + * Sync stat64filename>) + * Function returns + * 0 : The operation was successful. + * -errno : The command failed. + */ +EXTERN int nfs_stat64(struct nfs_context *nfs, const char *path, + struct nfs_stat_64 *st); + +/* + * Async stat() + * + * Like stat except if the destination is a symbolic link, it acts on the + * symbolic link itself. + * + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is struct nfs_stat_64 * + * -errno : An error occured. + * data is the error string. + */ +EXTERN int nfs_lstat64_async(struct nfs_context *nfs, const char *path, + nfs_cb cb, void *private_data); +/* + * Sync stat() + * + * Like stat except if the destination is a symbolic link, it acts on the + * symbolic link itself. + * + * Function returns + * 0 : The operation was successful. + * -errno : The command failed. + */ +EXTERN int nfs_lstat64(struct nfs_context *nfs, const char *path, + struct nfs_stat_64 *st); + +/* + * FSTAT() + */ +/* + * Async fstat(nfsfh *) + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is struct stat * + * -errno : An error occured. + * data is the error string. + */ +/* This function is deprecated. Use nfs_fstat64_async() instead */ +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 successful. + * -errno : The command failed. + */ +#ifdef WIN32 +EXTERN int nfs_fstat(struct nfs_context *nfs, struct nfsfh *nfsfh, + struct __stat64 *st); +#else +EXTERN int nfs_fstat(struct nfs_context *nfs, struct nfsfh *nfsfh, + struct stat *st); +#endif + +/* nfs_fstat64 + * 64 bit version of fstat. All fields are always 64bit. + * Use these functions instead of nfs_fstat[_async](), especially if you + * have weird stat structures. + */ +/* + * FSTAT() + */ +/* + * Async fstat(nfsfh *) + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is struct stat * + * -errno : An error occured. + * data is the error string. + */ +EXTERN int nfs_fstat64_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + nfs_cb cb, void *private_data); +/* + * Sync fstat(nfsfh *) + * Function returns + * 0 : The operation was successful. + * -errno : The command failed. + */ +EXTERN int nfs_fstat64(struct nfs_context *nfs, struct nfsfh *nfsfh, + struct nfs_stat_64 *st); + +/* + * UMASK() never blocks, so no special aync/async versions are available + */ +/* + * Sync umask() + * Function returns the old mask. + */ +EXTERN uint16_t nfs_umask(struct nfs_context *nfs, uint16_t mask); + +/* + * OPEN() + */ +/* + * Async open() + * + * mode is a combination of the flags : + * O_RDONLY, O_WRONLY, O_RDWR , O_SYNC, O_APPEND, O_TRUNC, O_NOFOLLOW, + * O_CREAT + * + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * Supported flags are + * O_NOFOLLOW + * O_APPEND + * O_CREAT + * O_RDONLY + * O_WRONLY + * O_RDWR + * O_SYNC + * O_TRUNC (Only valid with O_RDWR or O_WRONLY. Ignored otherwise.) + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is a struct *nfsfh; + * The nfsfh is close using nfs_close(). + * -errno : An error occured. + * data is the error string. + */ +EXTERN int nfs_open_async(struct nfs_context *nfs, const char *path, int flags, + nfs_cb cb, void *private_data); +EXTERN int nfs_open2_async(struct nfs_context *nfs, const char *path, int flags, + int mode, nfs_cb cb, void *private_data); +/* + * Sync open() + * Function returns + * 0 : The operation was successful. *nfsfh is filled in. + * -errno : The command failed. + */ +EXTERN int nfs_open(struct nfs_context *nfs, const char *path, int flags, + struct nfsfh **nfsfh); +EXTERN int nfs_open2(struct nfs_context *nfs, const char *path, int flags, + int mode, struct nfsfh **nfsfh); + + + + +/* + * CLOSE + */ +/* + * Async close(nfsfh) + * + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is NULL. + * -errno : An error occured. + * data is the error string. + */ +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 successful. + * -errno : The command failed. + */ +EXTERN int nfs_close(struct nfs_context *nfs, struct nfsfh *nfsfh); + + +struct iovec; +/* + * PREAD() + */ +/* + * Async pread() + * + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * >=0 : Success. + * status is numer of bytes read. + * -errno : An error occured. + * data is the error string. + */ +EXTERN int nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + void *buf, size_t count, uint64_t offset, + nfs_cb cb, void *private_data); +/* + * Sync pread() + * Function returns + * >=0 : numer of bytes read. + * -errno : An error occured. + */ +EXTERN int nfs_pread(struct nfs_context *nfs, struct nfsfh *nfsfh, + void *buf, size_t count, uint64_t offset); + +/* + * PREADV() + */ +/* + * Async preadv() + * + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * >=0 : Success. + * status is numer of bytes read. + * -errno : An error occured. + * data is the error string. + */ +EXTERN int nfs_preadv_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + const struct iovec *iov, int iovcnt, uint64_t offset, + nfs_cb cb, void *private_data); +/* + * Sync preadv() + * Function returns + * >=0 : numer of bytes read. + * -errno : An error occured. + */ +EXTERN int nfs_preadv(struct nfs_context *nfs, struct nfsfh *nfsfh, + const struct iovec *iov, int iovcnt, uint64_t offset); + + + +/* + * READ() + */ +/* + * Async read() + * + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * >=0 : Success. + * status is numer of bytes read. + * -errno : An error occured. + * data is the error string. + */ +EXTERN int nfs_read_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + void *buf, size_t count, + nfs_cb cb, void *private_data); +/* + * Sync read() + * Function returns + * >=0 : numer of bytes read. + * -errno : An error occured. + */ +EXTERN int nfs_read(struct nfs_context *nfs, struct nfsfh *nfsfh, + void *buf, size_t count); + +/* + * READV() + */ +/* + * Async readv() + * + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * >=0 : Success. + * status is numer of bytes read. + * -errno : An error occured. + * data is the error string. + */ +EXTERN int nfs_readv_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + const struct iovec *iov, int iovcnt, + nfs_cb cb, void *private_data); +/* + * Sync readv() + * Function returns + * >=0 : numer of bytes read. + * -errno : An error occured. + */ +EXTERN int nfs_readv(struct nfs_context *nfs, struct nfsfh *nfsfh, + const struct iovec *iov, int iovcnt); + +/* + * PWRITE() + */ +/* + * Async pwrite() + * + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * >=0 : Success. + * status is numer of bytes written. + * -errno : An error occured. + * data is the error string. + */ +EXTERN int nfs_pwrite_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + const void *buf, size_t count, uint64_t offset, + nfs_cb cb, void *private_data); +/* + * Sync pwrite() + * Function returns + * >=0 : numer of bytes written. + * -errno : An error occured. + */ +EXTERN int nfs_pwrite(struct nfs_context *nfs, struct nfsfh *nfsfh, + const void *buf, size_t count, uint64_t offset); + + +/* + * WRITE() + */ +/* + * Async write() + * + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * >=0 : Success. + * status is numer of bytes written. + * -errno : An error occured. + * data is the error string. + */ +EXTERN int nfs_write_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + const void *buf, size_t count, + nfs_cb cb, void *private_data); +/* + * Sync write() + * Function returns + * >=0 : numer of bytes written. + * -errno : An error occured. + */ +EXTERN int nfs_write(struct nfs_context *nfs, struct nfsfh *nfsfh, + const void *buf, uint64_t count); + + +/* + * LSEEK() + */ +/* + * Async lseek() + * + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * >=0 : Success. + * data is uint64_t * for the current position. + * -errno : An error occured. + * data is the error string. + */ +EXTERN int nfs_lseek_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + int64_t offset, int whence, nfs_cb cb, + void *private_data); +/* + * Sync lseek() + * Function returns + * >=0 : Success + * -errno : An error occured. + */ +EXTERN int nfs_lseek(struct nfs_context *nfs, struct nfsfh *nfsfh, + int64_t offset, int whence, uint64_t *current_offset); + + +/* + * LOCKF() + */ +/* + * Async lockf() + * + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * 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. + */ +enum nfs4_lock_op { + NFS4_F_LOCK = 0, + NFS4_F_TLOCK = 1, + NFS4_F_ULOCK = 2, + NFS4_F_TEST = 3, +}; +EXTERN int nfs_lockf_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + enum nfs4_lock_op op, uint64_t count, + nfs_cb cb, void *private_data); +/* + * Sync lockf() + * Function returns + * 0 : Success. + * -errno : An error occured. + */ +EXTERN int nfs_lockf(struct nfs_context *nfs, struct nfsfh *nfsfh, + enum nfs4_lock_op op, uint64_t count); + +/* + * FCNTL() + */ +/* + * Async fcntl() + * Supported commands are : + * NFS4_F_SETLK + * NFS4_F_SETLKW + * + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * 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. + */ +enum nfs4_fcntl_op { + NFS4_F_SETLK = 0, + NFS4_F_SETLKW, +}; +struct nfs4_flock { + int l_type; /* F_RDLCK, F_WRLCK or F_UNLCK */ + int l_whence; /* SEEK_SET, SEEK_CUR or SEEK_END */ + uint32_t l_pid; + uint64_t l_start; + uint64_t l_len; +}; + +EXTERN int nfs_fcntl_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + enum nfs4_fcntl_op cmd, void *arg, + nfs_cb cb, void *private_data); +/* + * Sync lockf() + * Function returns + * 0 : Success. + * -errno : An error occured. + */ +EXTERN int nfs_fcntl(struct nfs_context *nfs, struct nfsfh *nfsfh, + enum nfs4_fcntl_op cmd, void *arg); + +/* + * FSYNC() + */ +/* + * Async fsync() + * + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * 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_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. + */ +EXTERN int nfs_fsync(struct nfs_context *nfs, struct nfsfh *nfsfh); + + + +/* + * TRUNCATE() + */ +/* + * Async truncate() + * + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * 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_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. + */ +EXTERN int nfs_truncate(struct nfs_context *nfs, const char *path, + uint64_t length); + + + +/* + * FTRUNCATE() + */ +/* + * Async ftruncate() + * + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * 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_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. + */ +EXTERN int nfs_ftruncate(struct nfs_context *nfs, struct nfsfh *nfsfh, + uint64_t length); + + + + + + +/* + * MKDIR() + */ +/* + * Async mkdir() + * + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * 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_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. + */ +EXTERN int nfs_mkdir(struct nfs_context *nfs, const char *path); + +/* + * Async mkdir2() + * + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * 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_mkdir2_async(struct nfs_context *nfs, const char *path, + int mode, nfs_cb cb, void *private_data); +/* + * Sync mkdir2() + * Function returns + * 0 : Success + * -errno : An error occured. + */ +EXTERN int nfs_mkdir2(struct nfs_context *nfs, const char *path, int mode); + + + +/* + * RMDIR() + */ +/* + * Async rmdir() + * + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * 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_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. + */ +EXTERN int nfs_rmdir(struct nfs_context *nfs, const char *path); + + + + +/* + * CREAT() + */ +/* + * Async creat() + * + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is a struct *nfsfh; + * -errno : An error occured. + * data is the error string. + */ +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. + */ +EXTERN int nfs_creat(struct nfs_context *nfs, const char *path, int mode, + struct nfsfh **nfsfh); + + +/* + * MKNOD() + */ +/* + * Async mknod() + * + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * 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); + + + +/* + * UNLINK() + */ +/* + * Async unlink() + * + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is NULL + * -errno : An error occured. + * data is the error string. + */ +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. + */ +EXTERN int nfs_unlink(struct nfs_context *nfs, const char *path); + + + + +/* + * OPENDIR() + */ +struct nfsdir; +/* + * Async opendir() + * + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When struct nfsdir * is returned, this resource is closed/freed by calling nfs_closedir() + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is struct nfsdir * + * -errno : An error occured. + * data is the error string. + */ +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. + */ +EXTERN int nfs_opendir(struct nfs_context *nfs, const char *path, + struct nfsdir **nfsdir); + + + +/* + * READDIR() + */ +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 type/mode constants */ + uint32_t type; /* NF3REG, NF3DIR, NF3BLK, ... */ + uint32_t mode; + uint64_t size; + struct timeval atime; + struct timeval mtime; + struct timeval ctime; + uint32_t uid; + uint32_t gid; + uint32_t nlink; + uint64_t dev; + uint64_t rdev; + uint64_t blksize; + uint64_t blocks; + uint64_t used; + uint32_t atime_nsec; + uint32_t mtime_nsec; + uint32_t ctime_nsec; +}; +/* + * nfs_readdir() never blocks, so no special sync/async versions are available + */ +EXTERN struct nfsdirent *nfs_readdir(struct nfs_context *nfs, + struct nfsdir *nfsdir); + + +/* + * SEEKDIR() + */ +/* + * This function will never block so there is no need for an async version. + */ +EXTERN void nfs_seekdir(struct nfs_context *nfs, struct nfsdir *nfsdir, + long loc); + +/* + * TELLDIR() + */ +/* + * On success, nfs_telldir() will return a location as a value >= 0. + * On failure, nfs_telldir() will return -1. + * + * This function will never block so there is no need for an async version. + */ +EXTERN long nfs_telldir(struct nfs_context *nfs, struct nfsdir *nfsdir); + + +/* + * REWINDDIR() + */ +/* + * nfs_rewinddir() cancel all previous nfs_readdir() side effects. + * This function will never block so there is no need for an async version. + */ +EXTERN void nfs_rewinddir(struct nfs_context *nfs, struct nfsdir *nfsdir); + + +/* + * CLOSEDIR() + */ +/* + * nfs_closedir() never blocks, so no special sync/async versions are available + */ +EXTERN void nfs_closedir(struct nfs_context *nfs, struct nfsdir *nfsdir); + + +/* + * CHDIR() + */ +/* + * Async chdir() + * + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is NULL; + * -errno : An error occured. + * data is the error string. + */ +EXTERN int nfs_chdir_async(struct nfs_context *nfs, const char *path, + nfs_cb cb, void *private_data); +/* + * Sync chdir() + * Function returns + * 0 : The operation was successful. + * -errno : The command failed. + */ +EXTERN int nfs_chdir(struct nfs_context *nfs, const char *path); + +/* + * GETCWD() + */ +/* + * nfs_getcwd() never blocks, so no special sync/async versions are available + */ +/* + * Sync getcwd() + * This function returns a pointer to the current working directory. + * This pointer is only stable until the next [f]chdir or when the + * context is destroyed. + * + * Function returns + * 0 : The operation was successful and *cwd is filled in. + * -errno : The command failed. + */ +EXTERN void nfs_getcwd(struct nfs_context *nfs, const char **cwd); + + +/* + * STATVFS() + */ +struct nfs_statvfs_64 { + uint64_t f_bsize; + uint64_t f_frsize; + uint64_t f_blocks; + uint64_t f_bfree; + uint64_t f_bavail; + uint64_t f_files; + uint64_t f_ffree; + uint64_t f_favail; + uint64_t f_fsid; + uint64_t f_flag; + uint64_t f_namemax; +}; +/* + * Async statvfs() + * This function is deprecated. Use nfs_statvfs64_async() instead. + * + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is struct statvfs * + * -errno : An error occured. + * data is the error string. + */ +struct statvfs; +EXTERN int nfs_statvfs_async(struct nfs_context *nfs, const char *path, + nfs_cb cb, void *private_data); +/* + * Sync statvfs() + * This function is deprecated. Use nfs_statvfs64() instead. + * + * Function returns + * 0 : The operation was successful. + * -errno : The command failed. + */ +EXTERN int nfs_statvfs(struct nfs_context *nfs, const char *path, + struct statvfs *svfs); +/* + * Async statvfs64() + * + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is struct nfs_statvfs_64 * + * -errno : An error occured. + * data is the error string. + */ +EXTERN int nfs_statvfs64_async(struct nfs_context *nfs, const char *path, + nfs_cb cb, void *private_data); +/* + * Sync statvfs64() + * + * Function returns + * 0 : The operation was successful. + * -errno : The command failed. + */ +EXTERN int nfs_statvfs64(struct nfs_context *nfs, const char *path, + struct nfs_statvfs_64 *svfs); + +/* + * READLINK() + */ +/* + * Async readlink() + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is a char * + * data is only valid during the callback and is automatically freed + * when the callback returns. + * -errno : An error occured. + * data is the error string. + */ +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 successful. + * -errno : The command failed. + */ +EXTERN int nfs_readlink(struct nfs_context *nfs, const char *path, char *buf, + int bufsize); + +/* + * Sync readlink2() + * Function returns + * 0 : The operation was successful. + * -errno : The command failed. + * *bufptr : NULL if the command failed, otherwise the contents of the symlink. + * The caller must free the buffer. + */ +EXTERN int nfs_readlink2(struct nfs_context *nfs, const char *path, + char **bufptr); + + + +/* + * CHMOD() + */ +/* + * Async chmod() + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is NULL + * -errno : An error occured. + * data is the error string. + */ +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 successful. + * -errno : The command failed. + */ +EXTERN int nfs_chmod(struct nfs_context *nfs, const char *path, int mode); +/* + * Async chmod() + * + * Like chmod except if the destination is a symbolic link, it acts on the + * symbolic link itself. + * + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is NULL + * -errno : An error occured. + * data is the error string. + */ +EXTERN int nfs_lchmod_async(struct nfs_context *nfs, const char *path, + int mode, nfs_cb cb, void *private_data); +/* + * Sync chmod() + * + * Like chmod except if the destination is a symbolic link, it acts on the + * symbolic link itself. + * + * Function returns + * 0 : The operation was successful. + * -errno : The command failed. + */ +EXTERN int nfs_lchmod(struct nfs_context *nfs, const char *path, int mode); + + + +/* + * FCHMOD() + */ +/* + * Async fchmod() + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is NULL + * -errno : An error occured. + * data is the error string. + */ +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 successful. + * -errno : The command failed. + */ +EXTERN int nfs_fchmod(struct nfs_context *nfs, struct nfsfh *nfsfh, int mode); + + + +/* + * CHOWN() + */ +/* + * Async chown() + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is NULL + * -errno : An error occured. + * data is the error string. + */ +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 successful. + * -errno : The command failed. + */ +EXTERN int nfs_chown(struct nfs_context *nfs, const char *path, int uid, + int gid); +/* + * Async chown() + * + * Like chown except if the destination is a symbolic link, it acts on the + * symbolic link itself. + * + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is NULL + * -errno : An error occured. + * data is the error string. + */ +EXTERN int nfs_lchown_async(struct nfs_context *nfs, const char *path, int uid, + int gid, nfs_cb cb, void *private_data); +/* + * Sync chown() + * + * Like chown except if the destination is a symbolic link, it acts on the + * symbolic link itself. + * + * Function returns + * 0 : The operation was successful. + * -errno : The command failed. + */ +EXTERN int nfs_lchown(struct nfs_context *nfs, const char *path, int uid, + int gid); + + + +/* + * FCHOWN() + */ +/* + * Async fchown() + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is NULL + * -errno : An error occured. + * data is the error string. + */ +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 successful. + * -errno : The command failed. + */ +EXTERN int nfs_fchown(struct nfs_context *nfs, struct nfsfh *nfsfh, int uid, + int gid); + + + + +/* + * UTIMES() + */ +/* + * Async utimes() + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is NULL + * -errno : An error occured. + * data is the error string. + */ +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 successful. + * -errno : The command failed. + */ +EXTERN int nfs_utimes(struct nfs_context *nfs, const char *path, + struct timeval *times); +/* + * Async utimes() + * + * Like utimes except if the destination is a symbolic link, it acts on the + * symbolic link itself. + * + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is NULL + * -errno : An error occured. + * data is the error string. + */ +EXTERN int nfs_lutimes_async(struct nfs_context *nfs, const char *path, + struct timeval *times, nfs_cb cb, + void *private_data); +/* + * Sync utimes() + * + * Like utimes except if the destination is a symbolic link, it acts on the + * symbolic link itself. + * + * Function returns + * 0 : The operation was successful. + * -errno : The command failed. + */ +EXTERN int nfs_lutimes(struct nfs_context *nfs, const char *path, + struct timeval *times); + + +/* + * UTIME() + */ +/* + * Async utime() + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is NULL + * -errno : An error occured. + * data is the error string. + */ +struct utimbuf; +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 successful. + * -errno : The command failed. + */ +EXTERN int nfs_utime(struct nfs_context *nfs, const char *path, + struct utimbuf *times); + + + + +/* + * ACCESS() + */ +/* + * Async access() + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is NULL + * -errno : An error occured. + * data is the error string. + */ +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 successful. + * -errno : The command failed. + */ +EXTERN int nfs_access(struct nfs_context *nfs, const char *path, int mode); + + + + + +/* + * ACCESS2() + */ +/* + * Async access2() + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * >= 0 : A mask of R_OK, W_OK and X_OK indicating which permissions are + * available. + * data is NULL + * -errno : An error occured. + * data is the error string. + */ +EXTERN int nfs_access2_async(struct nfs_context *nfs, const char *path, + nfs_cb cb, void *private_data); +/* + * Sync access() + * Function returns + * >= 0 : A mask of R_OK, W_OK and X_OK indicating which permissions are + * available. + * -errno : The command failed. + */ +EXTERN int nfs_access2(struct nfs_context *nfs, const char *path); + + + + +/* + * SYMLINK() + */ +/* + * Async symlink() + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is NULL + * -errno : An error occured. + * data is the error string. + */ +EXTERN int nfs_symlink_async(struct nfs_context *nfs, const char *target, + const char *linkname, nfs_cb cb, + void *private_data); +/* + * Sync symlink() + * Function returns + * 0 : The operation was successful. + * -errno : The command failed. + */ +EXTERN int nfs_symlink(struct nfs_context *nfs, const char *target, + const char *linkname); + + +/* + * RENAME() + */ +/* + * Async rename(, ) + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is NULL + * -errno : An error occured. + * data is the error string. + */ +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 successful. + * -errno : The command failed. + */ +EXTERN int nfs_rename(struct nfs_context *nfs, const char *oldpath, + const char *newpath); + + + +/* + * LINK() + */ +/* + * Async link(, ) + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is NULL + * -errno : An error occured. + * data is the error string. + */ +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 successful. + * -errno : The command failed. + */ +EXTERN int nfs_link(struct nfs_context *nfs, const char *oldpath, + const char *newpath); + + +/* + * GETEXPORTS() + */ +/* + * Async getexports() + * NOTE: You must include 'libnfs-raw-mount.h' to get the definitions of the + * returned structures. + * + * This function will return the list of exports from an NFS server. + * + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is a pointer to an exports pointer: + * exports export = *(exports *)data; + * -errno : An error occured. + * data is the error string. + */ +EXTERN int mount_getexports_async(struct rpc_context *rpc, const char *server, + rpc_cb cb, void *private_data); +/* + * Sync getexports() + * Function returns + * NULL : something failed + * exports export : a linked list of exported directories + * + * returned data must be freed by calling mount_free_export_list(exportnode); + */ +EXTERN struct exportnode *mount_getexports(const char *server); + +/* + * Sync getexports_mountport(, ) + * Function returns + * NULL : something failed + * exports export : a linked list of exported directories + * + * returned data must be freed by calling mount_free_export_list(exportnode); + */ +EXTERN struct exportnode *mount_getexports_mountport(const char *server, int mountport); +/* + * Sync getexports_timeout(, ) + * Function returns + * NULL : something failed + * exports export : a linked list of exported directories + * + * returned data must be freed by calling mount_free_export_list(exportnode); + */ +EXTERN struct exportnode *mount_getexports_timeout(const char *server, int timeout); + +EXTERN void mount_free_export_list(struct exportnode *exports); + + +struct nfs_server_list { + struct nfs_server_list *next; + char *addr; +}; + +/* + * Sync find_local_servers() + * This function will probe all local networks for NFS server. + * This function will block for one second while awaiting for all nfs servers + * to respond. + * + * Function returns + * NULL : something failed + * + * struct nfs_server_list : a linked list of all discovered servers + * + * returned data must be freed by nfs_free_srvr_list(srv); + */ +struct nfs_server_list *nfs_find_local_servers(void); +void free_nfs_srvr_list(struct nfs_server_list *srv); + +/* + * nfs_set_poll_timeout() + * This function sets the polling timeout used for nfs rpc calls. + * + * Function returns nothing. + * + * int milliseconds : timeout that is passed to poll(2) + * to be applied in milliseconds (-1 no timeout) + */ +EXTERN void nfs_set_poll_timeout(struct nfs_context *nfs, int milliseconds); + +/* + * nfs_get_poll_timeout() + * This function gets the polling timeout used for nfs rpc calls. + * + * Function returns: + * int milliseconds : timeout that is passed to poll(2) + * to be applied in milliseconds (-1 no timeout) + */ +EXTERN int nfs_get_poll_timeout(struct nfs_context *nfs); + +/* + * sync nfs_set_timeout() + * This function sets the timeout used for nfs rpc calls. + * + * Function returns nothing. + * + * int milliseconds : timeout to be applied in milliseconds (-1 no timeout) + * timeouts must currently be set in whole seconds, + * i.e. units of 1000 + * + * Note: Prefer the mount option timeo= to set the timeout over directly + * calling nfs_set_timeout(). + */ +EXTERN void nfs_set_timeout(struct nfs_context *nfs, int milliseconds); + +/* + * sync nfs_get_timeout() + * This function gets the timeout used for nfs rpc calls. + * + * Function returns + * -1 : No timeout applied + * > 0 : Timeout in milliseconds + */ +EXTERN int nfs_get_timeout(struct nfs_context *nfs); + +/* + * Set the client name for NFSv4. + */ +EXTERN void nfs4_set_client_name(struct nfs_context *nfs, const char *id); + +/* + * Set the client verifier for NFSv4. + * This an 8 byte array of random data. + */ +EXTERN void nfs4_set_verifier(struct nfs_context *nfs, const char *verifier); + +/* + * MULTITHREADING + */ +/* + * This function starts a separate service thread for multithreading support. + * When multithreading is enabled the eventdriven async API is no longer + * supported and you can only use the synchronous API. + */ +EXTERN int nfs_mt_service_thread_start(struct nfs_context *nfs); +/* + * Shutdown multithreading support. + */ +EXTERN void nfs_mt_service_thread_stop(struct nfs_context *nfs); + +#ifdef __cplusplus +} +#endif + + +/* + * UDP contexts for UDP servers + */ +EXTERN int rpc_bind_udp(struct rpc_context *rpc, char *addr, int port); +EXTERN int rpc_set_udp_destination(struct rpc_context *rpc, char *addr, int port, int is_broadcast); +EXTERN struct rpc_context *rpc_init_udp_context(void); +EXTERN int rpc_is_udp_socket(struct rpc_context *rpc); + +/* UDP server sockets */ +/* The ip address of the udp client */ +EXTERN struct sockaddr *rpc_get_udp_src_sockaddr(struct rpc_context *rpc); +#ifdef __linux__ +/* The ip address where we received the udp packet from the client */ +EXTERN struct sockaddr *rpc_get_udp_dst_sockaddr(struct rpc_context *rpc); +#endif + +void rpc_set_resiliency(struct rpc_context *rpc, + int num_tcp_reconnect, + int timeout, + int retrans); + + +#endif /* !_LIBNFS_H_ */ diff --git a/deps/libnfs/include/slist.h b/deps/libnfs/include/slist.h new file mode 100644 index 000000000000..5755ca14e3b6 --- /dev/null +++ b/deps/libnfs/include/slist.h @@ -0,0 +1,52 @@ +/* + 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 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ + +#ifndef _LIBNFS_SLIST_H_ +#define _LIBNFS_SLIST_H_ + +#define LIBNFS_LIST_ADD(list, item) \ + do { \ + (item)->next = (*list); \ + (*list) = (item); \ + } while (0); + +#define LIBNFS_LIST_ADD_END(list, item) \ + if ((*list) == NULL) { \ + LIBNFS_LIST_ADD((list), (item)); \ + } else { \ + void *head = (*list); \ + while ((*list)->next) \ + (*list) = (*list)->next; \ + (*list)->next = (item); \ + (item)->next = NULL; \ + (*list) = head; \ + } + +#define LIBNFS_LIST_REMOVE(list, item) \ + if ((*list) == (item)) { \ + (*list) = (item)->next; \ + } else { \ + void *head = (*list); \ + while ((*list)->next && (*list)->next != (item)) \ + (*list) = (*list)->next; \ + if ((*list)->next != NULL) { \ + (*list)->next = (*list)->next->next; \ + } \ + (*list) = head; \ + } + +#endif /* !_LIBNFS_SLIST_H_ */ diff --git a/deps/libnfs/include/win32/win32_compat.h b/deps/libnfs/include/win32/win32_compat.h new file mode 100755 index 000000000000..09f8eb11a715 --- /dev/null +++ b/deps/libnfs/include/win32/win32_compat.h @@ -0,0 +1,202 @@ +/* +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*/ + +#ifndef win32_COMPAT_H_ +#define win32_COMPAT_H_ +#define NO_IPv6 1 + +#include +#include +#include +#include +#include +#include +#include +#include // For size_t type + +/* We always have multithreading for windows */ +#ifndef HAVE_MULTITHREADING +#define HAVE_MULTITHREADING 1 +#endif + +typedef unsigned long fsblkcnt_t; +typedef unsigned long fsfilcnt_t; +typedef unsigned int uid_t; +typedef unsigned int gid_t; +typedef int socklen_t; + +#ifndef S_IRUSR +#define S_IRUSR 0000400 +#define S_IWUSR 0000200 +#define S_IXUSR 0000100 +#endif +#ifndef S_IRWXG +#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 +#endif + +#ifndef MSG_NOSIGNAL +#define MSG_NOSIGNAL 0 +#endif + +#define F_GETFL 3 +#define F_SETFL 4 + +#ifndef S_IFLNK +#define S_IFLNK 0xA000 /* Link */ +#endif + +#ifndef F_RDLCK +#define F_RDLCK 0 +#define F_WRLCK 1 +#define F_UNLCK 2 +#endif + +#ifndef S_IFIFO +#define S_IFIFO 0x1000 /* FIFO */ +#endif + +#ifndef S_IFBLK +#define S_IFBLK 0x3000 /* Block: Is this ever set under w32? */ +#endif + +#ifndef S_IFSOCK +#define S_IFSOCK 0x0 /* not defined in mingw either */ +#endif + +#ifndef major +#define major(a) 0 +#endif + +#ifndef minor +#define minor(a) 0 +#endif + +#ifndef O_NONBLOCK +#define O_NONBLOCK 0x40000000 +#endif + +#ifndef O_SYNC +#define O_SYNC 0 +#endif + +#ifndef O_NOFOLLOW +#define O_NOFOLLOW 00400000 +#endif + +#define MSG_DONTWAIT 0 +#define ssize_t SSIZE_T + +#if(_WIN32_WINNT < 0x0600) + +#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 */ +}; +#endif + +#define close closesocket +#define ioctl ioctlsocket + +#ifndef ESTALE +#define ESTALE 116 +#endif + +/* Wrapper macros to call misc. functions win32 is missing */ +#define poll(x, y, z) win32_poll(x, y, z) +//#define snprintf sprintf_s +#define inet_pton(x,y,z) win32_inet_pton(x,y,z) +#define open(x, y, z) _open(x, y, z) +#ifndef lseek +#define lseek(x, y, z) _lseek(x, y, z) +#endif +#define read(x, y, z) _read(x, y, z) +#define write(x, y, z) _write(x, y, z) +int getpid(void); +int win32_inet_pton(int af, const char * src, void * dst); +int win32_poll(struct pollfd *fds, unsigned int nfsd, int timeout); +#ifdef __MINGW32__ +# define win32_gettimeofday mingw_gettimeofday +#else +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); +#endif + +#define DllExport + +#if defined(__MINGW32__) || defined(_MSC_VER) +char* libnfs_strndup(const char *s, size_t n); +#define strndup libnfs_strndup +#endif + +struct iovec +{ + unsigned long iov_len; // from WSABUF + void *iov_base; +}; + +static inline int writev(SOCKET sock, struct iovec *iov, int nvecs) +{ + DWORD ret; + + int res = WSASend(sock, (LPWSABUF)iov, nvecs, &ret, 0, NULL, NULL); + + if (res == 0) { + return (int)ret; + } + return -1; +} + +static inline int readv(SOCKET sock, struct iovec *iov, int nvecs) +{ + DWORD ret; + DWORD flags = 0; + + int res = WSARecv(sock, (LPWSABUF)iov, nvecs, &ret, &flags, NULL, NULL); + + if (res == 0) { + return (int)ret; + } + return -1; +} + +#endif//win32_COMPAT_H_ diff --git a/deps/libnfs/lib/CMakeLists.txt b/deps/libnfs/lib/CMakeLists.txt new file mode 100644 index 000000000000..e3f2a396072f --- /dev/null +++ b/deps/libnfs/lib/CMakeLists.txt @@ -0,0 +1,38 @@ +set(SOURCES init.c + krb5-wrapper.c + libnfs.c + libnfs-sync.c + libnfs-zdr.c + multithreading.c + nfs_v3.c + nfs_v4.c + pdu.c + socket.c +) + +# deal with version info in "dll" case +if(WIN32 AND BUILD_SHARED_LIBS) + configure_file(../win32/version.rc.template version.rc @ONLY) + list(APPEND SOURCES ${CMAKE_CURRENT_BINARY_DIR}/version.rc libnfs-win32.def) +endif() + +add_library(nfs ${SOURCES}) +target_link_libraries(nfs PRIVATE ${CORE_LIBRARIES} PUBLIC ${SYSTEM_LIBRARIES}) + +# Set version properties for the library +set_target_properties(nfs PROPERTIES + VERSION ${PROJECT_VERSION} + SOVERSION ${SOVERSION} +) + +# Set the output filename to "libnfs" consistently across platforms +set_target_properties(nfs PROPERTIES + OUTPUT_NAME "libnfs" # Ensures consistent output name (e.g., libnfs.dll on Windows, libnfs.so on Unix) + PREFIX "" # Removes the "lib" prefix on Unix-like systems to avoid "liblibnfs.so" +) + + +install(TARGETS nfs EXPORT libnfs + RUNTIME DESTINATION bin + ARCHIVE DESTINATION lib + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/deps/libnfs/lib/Makefile.am b/deps/libnfs/lib/Makefile.am new file mode 100644 index 000000000000..6ba49aa934aa --- /dev/null +++ b/deps/libnfs/lib/Makefile.am @@ -0,0 +1,53 @@ +AM_CFLAGS=$(WARN_CFLAGS) + +lib_LTLIBRARIES = libnfs.la + +libnfs_la_CPPFLAGS = -I$(abs_top_srcdir)/include \ + -I$(abs_top_srcdir)/include/nfsc \ + -I$(abs_top_srcdir)/mount \ + -I$(abs_top_srcdir)/nfs \ + -I$(abs_top_srcdir)/nfs4 \ + -I$(abs_top_srcdir)/nlm \ + -I$(abs_top_srcdir)/nsm \ + -I$(abs_top_srcdir)/portmap \ + -I$(abs_top_srcdir)/rquota \ + -I$(abs_top_srcdir)/win32 \ + "-D_U_=__attribute__((unused))" + +libnfs_la_SOURCES = \ + init.c \ + krb5-wrapper.c \ + libnfs.c \ + libnfs-sync.c \ + libnfs-zdr.c \ + multithreading.c \ + nfs_v3.c \ + nfs_v4.c \ + pdu.c \ + socket.c \ + ../win32/win32_compat.c + +SOCURRENT=16 +SOREVISION=2 +SOAGE=0 +libnfs_la_LDFLAGS = -version-info $(SOCURRENT):$(SOREVISION):$(SOAGE) \ + $(MAYBE_LIBKRB5) +if HAVE_WIN32 +libnfs_la_LDFLAGS += -no-undefined +endif + +libnfs_la_LIBADD = \ + ../mount/libmount.la \ + ../nfs/libnfs.la \ + ../nfs4/libnfs4.la \ + ../nlm/libnlm.la \ + ../nsm/libnsm.la \ + ../portmap/libportmap.la \ + ../rquota/librquota.la \ + $(LIBSOCKET) \ + $(LIBPTHREAD) + +if HAVE_TLS +libnfs_la_CPPFLAGS += -I$(abs_top_srcdir)/tls +libnfs_la_LIBADD += ../tls/libtls.la -lgnutls +endif diff --git a/deps/libnfs/lib/init.c b/deps/libnfs/lib/init.c new file mode 100644 index 000000000000..4cf8419ab98e --- /dev/null +++ b/deps/libnfs/lib/init.c @@ -0,0 +1,815 @@ +/* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */ +/* + 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 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef AROS +#include "aros_compat.h" +#endif + +#ifdef PS2_EE +#include "ps2_compat.h" +#endif + +#ifdef PS3_PPU +#include "ps3_compat.h" +#endif + +#ifdef WIN32 +#include +#endif + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_STRINGS_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include "slist.h" +#include "libnfs-zdr.h" +#include "libnfs.h" +#include "libnfs-raw.h" +#include "libnfs-private.h" + +#ifdef HAVE_LIBKRB5 +#include "krb5-wrapper.h" +#endif + +#ifndef discard_const +#define discard_const(ptr) ((void *)((intptr_t)(ptr))) +#endif + +static const char *oom = "out of memory"; + +uint64_t rpc_current_time(void) +{ +#ifdef HAVE_CLOCK_GETTIME + struct timespec tp; + + clock_gettime(CLOCK_MONOTONIC_COARSE, &tp); + return (uint64_t)tp.tv_sec * 1000 + tp.tv_nsec / 1000000; +#else + return (uint64_t)time(NULL) * 1000; +#endif +} + +uint64_t rpc_current_time_us(void) +{ +#ifdef HAVE_CLOCK_GETTIME + struct timespec tp; + + clock_gettime(CLOCK_MONOTONIC_COARSE, &tp); + return (uint64_t)tp.tv_sec * 1000000 + tp.tv_nsec / 1000; +#else + return (uint64_t)time(NULL) * 1000000; +#endif +} + +int rpc_set_hash_size(struct rpc_context *rpc, int hashes) +{ + uint32_t i; + +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_lock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ + rpc->num_hashes = hashes; + free(rpc->waitpdu); + rpc->waitpdu = malloc(sizeof(struct rpc_queue) * rpc->num_hashes); + if (rpc->waitpdu == NULL) { + return -1; + } + for (i = 0; i < rpc->num_hashes; i++) + rpc_reset_queue(&rpc->waitpdu[i]); +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_unlock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ + return 0; +} + +int nfs_set_hash_size(struct nfs_context *nfs, int hashes) +{ + return rpc_set_hash_size(nfs->rpc, hashes); +} + +struct rpc_context *rpc_init_context(void) +{ + struct rpc_context *rpc; + static uint32_t salt = 0; + + rpc = calloc(1, sizeof(struct rpc_context)); + if (rpc == NULL) { + return NULL; + } + + if (rpc_set_hash_size(rpc, DEFAULT_HASHES)) { + free(rpc); + return NULL; + } + + rpc->magic = RPC_CONTEXT_MAGIC; + rpc->inpos = 0; + rpc->state = READ_RM; + +#ifdef HAVE_MULTITHREADING + nfs_mt_mutex_init(&rpc->rpc_mutex); +#ifndef HAVE_STDATOMIC_H + nfs_mt_mutex_init(&rpc->atomic_int_mutex); +#endif +#endif /* HAVE_MULTITHREADING */ + + rpc->auth = authunix_create_default(); + if (rpc->auth == NULL) { + free(rpc->waitpdu); + free(rpc); + return NULL; + } + // Add PID to rpc->xid for easier debugging, making sure to cast + // pid to 32-bit type to avoid invalid left-shifts. + rpc->xid = salt + (uint32_t)rpc_current_time() + ((uint32_t)getpid() << 16); + salt += 0x01000000; + rpc->fd = -1; + rpc->tcp_syncnt = RPC_PARAM_UNDEFINED; +#if defined(WIN32) || defined(ANDROID) || defined(PS3_PPU) || defined(WEBOS) + /* Sandboxed app UIDs rarely match NFS export owners; use nobody. */ + rpc->uid = 65534; + rpc->gid = 65534; +#else + rpc->uid = getuid(); + rpc->gid = getgid(); +#endif + rpc_reset_queue(&rpc->outqueue); + /* Default is no limit */ + rpc->max_waitpdu_len = 0; + + /* + * Default RPC timeout is 60 secs, but it will later be updated if user + * has passed the timeo= mount option. Another way to set the RPC + * timeout is by calling the nfs_set_timeout()/rpc_set_timeout() + * function but the mount option should be prefered by new users. + */ + rpc->timeout = 60 * 1000; + + /* + * Default value of retrans starts as 0, i.e., no retries. + * Only after mount completes successfully and the rpc_context is used + * for NFS requests, do we set rpc->retrans to the value set by retrans= + * mount parameter. See rpc_set_resiliency(). + */ + rpc->retrans = 0; + + /* Default is to timeout after 100ms of poll(2) */ + rpc->poll_timeout = 100; + + return rpc; +} + +static int +is_nonblocking(int s) +{ +#if defined(WIN32) + return 0; +#else + int v; + v = fcntl(s, F_GETFL, 0); + return (v & O_NONBLOCK) != 0; +#endif +} + +struct rpc_context *rpc_init_server_context(int s) +{ + struct rpc_context *rpc; + + rpc = calloc(1, sizeof(struct rpc_context)); + if (rpc == NULL) { + return NULL; + } + + rpc->magic = RPC_CONTEXT_MAGIC; + + rpc->is_server_context = 1; + rpc->fd = s; + rpc->is_connected = 1; + + rpc->is_nonblocking = is_nonblocking(s); + + rpc->is_udp = rpc_is_udp_socket(rpc); + rpc_reset_queue(&rpc->outqueue); + +#ifdef HAVE_MULTITHREADING + nfs_mt_mutex_init(&rpc->rpc_mutex); +#ifndef HAVE_STDATOMIC_H + nfs_mt_mutex_init(&rpc->atomic_int_mutex); +#endif +#endif /* HAVE_MULTITHREADING */ + return rpc; +} + +#ifdef HAVE_SO_BINDTODEVICE +void rpc_set_interface(struct rpc_context *rpc, const char *ifname) +{ + /* + * This only copies the interface information into the RPC + * structure. It doesn't stop whatever interface is being used. The + * connection needs to be restarted for that happen. In other words, + * set this before you connect. + */ + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (ifname) { + /* + * Allow at one-less character just-in-case IFNAMSIZ for + * the defined platform does not include the NUL-terminator. + */ + strncpy(rpc->ifname, ifname, sizeof(rpc->ifname) - 1); + } +} +#endif + +void rpc_set_debug(struct rpc_context *rpc, int level) +{ + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + rpc->debug = level; +} + +struct rpc_context *rpc_init_udp_context(void) +{ + struct rpc_context *rpc; + + rpc = rpc_init_context(); + if (rpc != NULL) { + rpc->is_udp = 1; + } + + return rpc; +} + +int rpc_set_username(struct rpc_context *rpc, const char *username) +{ +#ifdef HAVE_LIBKRB5 + free(discard_const(rpc->username)); + rpc->username = NULL; + + if (username == NULL) { + return 0; + } + rpc->username = strdup(username); + if (rpc->username == NULL) { + rpc_set_error(rpc, + "Out of memory: Failed to allocate username"); + return -1; + } +#endif + return 0; +} + +void rpc_set_auth(struct rpc_context *rpc, struct AUTH *auth) +{ + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (rpc->auth != NULL) { + auth_destroy(rpc->auth); + } + rpc->auth = auth; +} + +static void rpc_set_uid_gid(struct rpc_context *rpc, int uid, int gid) { + if (uid != rpc->uid || gid != rpc->gid) { + struct AUTH *auth = libnfs_authunix_create("libnfs", uid, gid, 0, NULL); + if (auth != NULL) { + rpc_set_auth(rpc, auth); + rpc->uid = uid; + rpc->gid = gid; + } + } +} + +void rpc_set_uid(struct rpc_context *rpc, int uid) { + rpc_set_uid_gid(rpc, uid, rpc->gid); +} + +void rpc_set_gid(struct rpc_context *rpc, int gid) { + rpc_set_uid_gid(rpc, rpc->uid, gid); +} + +void rpc_set_auxiliary_gids(struct rpc_context *rpc, uint32_t len, uint32_t* gids) { + struct AUTH *auth = libnfs_authunix_create("libnfs", rpc->uid, rpc->gid, len, gids); + if (auth != NULL) { + rpc_set_auth(rpc, auth); + } +} + +void rpc_set_error(struct rpc_context *rpc, const char *error_string, ...) +{ + va_list ap; + char *old_error_string = NULL; + +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_lock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ + old_error_string = rpc->error_string; + va_start(ap, error_string); + rpc->error_string = malloc(1024); + if (rpc->error_string == NULL) { + rpc->error_string = discard_const(oom); + goto finished; + } + vsnprintf(rpc->error_string, 1024, error_string, ap); + va_end(ap); + + RPC_LOG(rpc, 1, "error: %s", rpc->error_string); + + finished: + if (old_error_string && old_error_string != oom) { + free(old_error_string); + } +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_unlock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ +} + +void rpc_set_error_locked(struct rpc_context *rpc, const char *error_string, ...) +{ + va_list ap; + char *old_error_string = rpc->error_string; + + va_start(ap, error_string); + rpc->error_string = malloc(1024); + if (rpc->error_string == NULL) { + free(old_error_string); + rpc->error_string = discard_const(oom); + return; + } + vsnprintf(rpc->error_string, 1024, error_string, ap); + va_end(ap); + + RPC_LOG(rpc, 1, "error: %s", rpc->error_string); + + if (old_error_string && old_error_string != oom) { + free(old_error_string); + } +} + +char *rpc_get_error(struct rpc_context *rpc) +{ + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + return rpc->error_string ? rpc->error_string : ""; +} + +void rpc_get_stats(struct rpc_context *rpc, struct rpc_stats *stats) +{ + assert(rpc->magic == RPC_CONTEXT_MAGIC); + +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_lock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ + + *stats = rpc->stats; + +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_unlock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ + + return; +} + +static void rpc_purge_all_pdus(struct rpc_context *rpc, int status, const char *error) +{ + struct rpc_queue outqueue; + struct rpc_pdu *pdu; + int i; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + /* Remove all entries from each queue before cancellation to prevent + * the callbacks manipulating entries that are about to be removed. + * + * This code assumes that the callbacks will not enqueue any new + * pdus when called. + */ + +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_lock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ + outqueue = rpc->outqueue; + + rpc_reset_queue(&rpc->outqueue); + while ((pdu = outqueue.head) != NULL) { + outqueue.head = pdu->next; + pdu->next = NULL; + if (pdu->cb) { + pdu->cb(rpc, status, (void *) error, pdu->private_data); + } + rpc_free_pdu(rpc, pdu); + } +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_unlock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ + + for (i = 0; i < rpc->num_hashes; i++) { + struct rpc_queue waitqueue; + +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_lock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ + waitqueue = rpc->waitpdu[i]; + rpc_reset_queue(&rpc->waitpdu[i]); +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_unlock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ + while((pdu = waitqueue.head) != NULL) { + waitqueue.head = pdu->next; + pdu->next = NULL; + if (pdu->cb) { + pdu->cb(rpc, status, (void *) error, pdu->private_data); + } + rpc_free_pdu(rpc, pdu); + } + } + + assert(!rpc->outqueue.head); +} + +void rpc_error_all_pdus(struct rpc_context *rpc, const char *error) +{ + rpc_purge_all_pdus(rpc, RPC_STATUS_ERROR, 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) +{ + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + while (rpc->fragments != NULL) { + struct rpc_fragment *fragment = rpc->fragments; + + rpc->fragments = fragment->next; + rpc_free_fragment(fragment); + } +} + +int rpc_add_fragment(struct rpc_context *rpc, char *data, uint32_t size) +{ + struct rpc_fragment *fragment; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + 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); + LIBNFS_LIST_ADD_END(&rpc->fragments, fragment); + return 0; +} + +void rpc_destroy_context(struct rpc_context *rpc) +{ + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + rpc_purge_all_pdus(rpc, RPC_STATUS_CANCEL, NULL); + + rpc_free_all_fragments(rpc); + + if (rpc->auth) { + auth_destroy(rpc->auth); + rpc->auth =NULL; + } + + if (rpc->fd != -1) { + close(rpc->fd); + } + + if (rpc->error_string && rpc->error_string != oom) { + free(rpc->error_string); + rpc->error_string = NULL; + } + + free(rpc->waitpdu); + rpc->waitpdu = NULL; + free(rpc->inbuf); + rpc->inbuf = NULL; + + rpc->magic = 0; +#ifdef HAVE_MULTITHREADING + nfs_mt_mutex_destroy(&rpc->rpc_mutex); +#ifndef HAVE_STDATOMIC_H + nfs_mt_mutex_destroy(&rpc->atomic_int_mutex); +#endif +#endif /* HAVE_MULTITHREADING */ +#ifdef HAVE_LIBKRB5 + if (rpc->auth_data) { + krb5_free_auth_data(rpc->auth_data); + } + free(discard_const(rpc->username)); + free(rpc->context); +#endif /* HAVE_LIBKRB5 */ + free(rpc->server); + free(rpc); +} + +void rpc_set_mountport(struct rpc_context *rpc, int port) +{ + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + rpc->mountport = port; +} + +int rpc_get_mountport(struct rpc_context *rpc) +{ + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + return rpc->mountport; +} + +void rpc_set_poll_timeout(struct rpc_context *rpc, int poll_timeout) +{ + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + rpc->poll_timeout = poll_timeout; +} + +int rpc_get_poll_timeout(struct rpc_context *rpc) +{ + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + return rpc->poll_timeout; +} + +void rpc_set_timeout(struct rpc_context *rpc, int timeout_msecs) +{ + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + rpc->timeout = timeout_msecs; +} + +int rpc_get_timeout(struct rpc_context *rpc) +{ + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + return rpc->timeout; +} + +int rpc_register_service(struct rpc_context *rpc, int program, int version, + struct service_proc *procs, int num_procs) +{ + struct rpc_endpoint *endpoint; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (!rpc->is_server_context) { + rpc_set_error(rpc, "Not a server context."); + return -1; + } + + endpoint = malloc(sizeof(*endpoint)); + if (endpoint == NULL) { + rpc_set_error(rpc, "Out of memory: Failed to allocate endpoint " + "structure"); + return -1; + } + + endpoint->program = program; + endpoint->version = version; + endpoint->procs = procs; + endpoint->num_procs = num_procs; + endpoint->next = rpc->endpoints; + rpc->endpoints = endpoint; + + return 0; +} + +void rpc_free_iovector(struct rpc_context *rpc, struct rpc_io_vectors *v) +{ + int i; + + assert(v->niov <= v->iov_capacity); + + for (i = 0; i < v->niov; i++) { + if (v->iov[i].free) { + v->iov[i].free(v->iov[i].buf); + } + } + v->niov = 0; + + if (v->iov != v->fast_iov) { + assert(v->iov_capacity > RPC_FAST_VECTORS && + v->iov_capacity <= RPC_MAX_VECTORS); + free(v->iov); + } else { + assert(v->iov_capacity == RPC_FAST_VECTORS); + } +} + +int rpc_add_iovector(struct rpc_context *rpc, struct rpc_io_vectors *v, + char *buf, int len, void (*free)(void *)) +{ + if (v->niov >= v->iov_capacity) { + rpc_set_error(rpc, "Too many io vectors"); + return -1; + } + + v->iov[v->niov].buf = buf; + v->iov[v->niov].len = len; + v->iov[v->niov].free = free; + v->niov++; + + return 0; +} + +/* + * Advance the cursor by len bytes. + * This must be called after reading len bytes into the cursor, so that the + * subsequent data can be correctly read into iov[]. + */ +void rpc_advance_cursor(struct rpc_context *rpc, struct rpc_iovec_cursor *v, + size_t len) +{ + while (len) { + assert(v->iovcnt > 0); + assert(v->remaining_size >= v->iov[0].iov_len); + + if (v->iov[0].iov_len > len) { + v->iov[0].iov_base = ((uint8_t*) v->iov[0].iov_base) + len; + v->iov[0].iov_len -= len; + v->remaining_size -= len; + break; + } else { + len -= v->iov[0].iov_len; + v->remaining_size -= v->iov[0].iov_len; + /* Exhausted this iovec completely */ + v->iov++; + v->iovcnt--; + } + } + + /* remaining_size can only be 0 when iovcnt is 0 and v.v. */ + assert((v->iovcnt == 0) == (v->remaining_size == 0)); + assert(v->iovcnt <= v->iovcnt_ref); + assert(v->iov >= v->base); + assert(v->iov <= v->iov_ref); + assert(v->iov_ref == (v->base + v->iovcnt_ref)); +} + +/* + * Reduce the size of rpc_iovec_cursor to match new_len if the current size is + * greater than new_len. If remaining_size <= new_len, then this is a no-op. + */ +void rpc_shrink_cursor(struct rpc_context *rpc, struct rpc_iovec_cursor *v, + size_t new_len) +{ + int i; + size_t num_done = 0; + + if (v->remaining_size <= new_len) { + return; + } + + for (i = 0; i < v->iovcnt && num_done < new_len; i++) { + if (v->iov[i].iov_len <= (new_len - num_done)) { + num_done += v->iov[i].iov_len; + continue; + } + + v->iov[i].iov_len = (new_len - num_done); + num_done = new_len; + } + + v->iovcnt = i; + v->remaining_size = new_len; + + /* remaining_size can only be 0 when iovcnt is 0 and v.v. */ + assert((v->iovcnt == 0) == (v->remaining_size == 0)); + assert(v->iovcnt <= v->iovcnt_ref); + assert(v->iov >= v->base); + assert(v->iov <= v->iov_ref); + assert(v->iov_ref == (v->base + v->iovcnt_ref)); +} + +/* + * memcpy data into the cursor at the current position and advance the cursor + * to be ready for subsequent data. + */ +void rpc_memcpy_cursor(struct rpc_context *rpc, struct rpc_iovec_cursor *v, + const void *src, size_t len) +{ + while (len) { + assert(v->iovcnt > 0); + + if (v->iov[0].iov_len > len) { + memcpy(v->iov[0].iov_base, src, len); + v->iov[0].iov_base = ((uint8_t*) v->iov[0].iov_base) + len; + v->iov[0].iov_len -= len; + v->remaining_size -= len; + break; + } else { + memcpy(v->iov[0].iov_base, src, v->iov[0].iov_len); + len -= v->iov[0].iov_len; + src = ((uint8_t *) src) + v->iov[0].iov_len; + v->remaining_size -= v->iov[0].iov_len; + /* Exhausted this iovec completely */ + v->iov++; + v->iovcnt--; + } + } + + /* remaining_size can only be 0 when iovcnt is 0 and v.v. */ + assert((v->iovcnt == 0) == (v->remaining_size == 0)); + assert(v->iovcnt <= v->iovcnt_ref); + assert(v->iov >= v->base); + assert(v->iov <= v->iov_ref); + assert(v->iov_ref == (v->base + v->iovcnt_ref)); +} + +void rpc_reset_cursor(struct rpc_context *rpc, struct rpc_iovec_cursor *v) +{ + int i; + + if (!v->base) { + return; + } + + assert(v->iovcnt <= v->iovcnt_ref); + assert(v->iov >= v->base); + assert(v->iov <= v->iov_ref); + assert(v->iov_ref == (v->base + v->iovcnt_ref)); + + v->iovcnt = v->iovcnt_ref; + v->iov = v->base; + + v->remaining_size = 0; + for (i = 0; i < v->iovcnt_ref; i++) { + v->iov[i] = v->iov_ref[i]; + v->remaining_size += v->iov[i].iov_len; + } +} + +void rpc_free_cursor(struct rpc_context *rpc, struct rpc_iovec_cursor *v) +{ + free(v->base); +} diff --git a/deps/libnfs/lib/krb5-wrapper.c b/deps/libnfs/lib/krb5-wrapper.c new file mode 100644 index 000000000000..cbaf241fe170 --- /dev/null +++ b/deps/libnfs/lib/krb5-wrapper.c @@ -0,0 +1,343 @@ +/* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */ +/* + Copyright (C) 2024 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 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_LIBKRB5 + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#ifdef HAVE_STDINT_H +#include +#endif + +#ifdef HAVE_STDLIB_H +#include +#endif + +#ifdef HAVE_STRING_H +#include +#endif + +#ifdef STDC_HEADERS +#include +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#endif + +#ifdef HAVE_SYS_STAT_H +#include +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_SYS_UNISTD_H +#include +#endif + +#include +#if __APPLE__ +#include +#else +#include +#include +#endif +#include + +#include "slist.h" +#include "libnfs.h" +#include "libnfs-raw.h" +#include "libnfs-raw-mount.h" +#include "libnfs-raw-portmap.h" +#include "libnfs-private.h" + +#include "krb5-wrapper.h" + +#ifndef discard_const +#define discard_const(ptr) ((void *)((intptr_t)(ptr))) +#endif + +void +krb5_free_auth_data(struct private_auth_data *auth) +{ + uint32_t maj, min; + + /* Delete context */ + if (auth->context) { + maj = gss_delete_sec_context(&min, &auth->context, + &auth->output_token); + if (maj != GSS_S_COMPLETE) { + /* No logging, yet. Do we care? */ + } + } + + gss_release_cred(&min, &auth->cred); + gss_release_buffer(&min, &auth->output_token); + + if (auth->target_name) { + gss_release_name(&min, &auth->target_name); + } + + if (auth->user_name) { + gss_release_name(&min, &auth->user_name); + } + + free(auth->g_server); + free(auth); +} + +static char * +display_status(int type, uint32_t err) +{ + gss_buffer_desc text; + uint32_t msg_ctx; + char *msg, *tmp; + uint32_t maj, min; + + msg = NULL; + msg_ctx = 0; + do { + maj = gss_display_status(&min, err, type, + GSS_C_NO_OID, &msg_ctx, &text); + if (maj != GSS_S_COMPLETE) { + return msg; + } + + tmp = NULL; + if (msg) { + tmp = msg; + min = asprintf(&msg, "%s, %*s", msg, + (int)text.length, (char *)text.value); + } else { + min = asprintf(&msg, "%*s", (int)text.length, + (char *)text.value); + } + if (min == -1) return tmp; + free(tmp); + gss_release_buffer(&min, &text); + } while (msg_ctx != 0); + + return msg; +} + +//qqq add back use_cached_credentials +struct private_auth_data * +krb5_auth_init(struct rpc_context *rpc, + const char *server, + const char *user_name, + int wanted_sec) +{ + struct private_auth_data *auth_data; + gss_buffer_desc target = GSS_C_EMPTY_BUFFER; + uint32_t maj, min; + gss_buffer_desc user; + //char user_principal[2048]; + char *nc_password = NULL; + //gss_buffer_desc passwd; + gss_OID_set_desc mechOidSet; + gss_OID_set_desc wantMech; + + auth_data = calloc(1, sizeof(struct private_auth_data)); + if (auth_data == NULL) { + rpc_set_error(rpc, "Failed to allocate private_auth_data"); + return NULL; + } + auth_data->context = GSS_C_NO_CONTEXT; + auth_data->wanted_sec = wanted_sec; + + if (asprintf(&auth_data->g_server, "nfs@%s", server) < 0) { + krb5_free_auth_data(auth_data); + rpc_set_error(rpc, "Failed to allocate server string"); + return NULL; + } + + target.value = auth_data->g_server; + target.length = strlen(auth_data->g_server); + + maj = gss_import_name(&min, &target, GSS_C_NT_HOSTBASED_SERVICE, + &auth_data->target_name); + + if (maj != GSS_S_COMPLETE) { + krb5_free_auth_data(auth_data); + krb5_set_gss_error(rpc, "gss_import_name", maj, min); + return NULL; + } + + user.value = discard_const(user_name); + user.length = strlen(user_name); + + /* create a name for the user */ + maj = gss_import_name(&min, &user, GSS_C_NT_USER_NAME, + &auth_data->user_name); + + if (maj != GSS_S_COMPLETE) { + krb5_free_auth_data(auth_data); + krb5_set_gss_error(rpc, "gss_import_name", maj, min); + return NULL; + } + + /* TODO: the proper mechanism (SPNEGO vs NTLM vs KRB5) should be + * selected based on the SMB negotiation flags */ + #ifdef __APPLE__ + auth_data->mech_type = GSS_SPNEGO_MECHANISM; + #else + auth_data->mech_type = &spnego_mech_krb5; + #endif + auth_data->cred = GSS_C_NO_CREDENTIAL; + + /* Create creds for the user */ + mechOidSet.count = 1; + #ifdef __APPLE__ + mechOidSet.elements = discard_const(GSS_SPNEGO_MECHANISM); + #else + mechOidSet.elements = discard_const(&gss_mech_spnego); + #endif + + maj = gss_acquire_cred(&min, auth_data->user_name, 0, + &mechOidSet, GSS_C_INITIATE, + &auth_data->cred, NULL, NULL); + + if (maj != GSS_S_COMPLETE) { + krb5_free_auth_data(auth_data); + krb5_set_gss_error(rpc, "gss_acquire_cred", maj, min); + return NULL; + } + + #ifndef __APPLE__ /* gss_set_neg_mechs is not defined on macOS/iOS. */ + if (rpc->sec != RPC_SEC_UNDEFINED) { + wantMech.count = 1; + + switch (rpc->sec) { + case RPC_SEC_KRB5: + case RPC_SEC_KRB5I: + case RPC_SEC_KRB5P: + wantMech.elements = discard_const(&spnego_mech_krb5); + break; + case RPC_SEC_UNDEFINED: + ; + } + + maj = gss_set_neg_mechs(&min, auth_data->cred, &wantMech); + if (GSS_ERROR(maj)) { + krb5_free_auth_data(auth_data); + krb5_set_gss_error(rpc, "gss_set_neg_mechs", maj, min); + return NULL; + } + } + #endif + + if (nc_password) { + free(nc_password); + nc_password = NULL; + } + return auth_data; +} + +void +krb5_set_gss_error(struct rpc_context *rpc, char *func, + uint32_t maj, uint32_t min) +{ + char *err_maj = display_status(GSS_C_GSS_CODE, maj); + char *err_min = display_status(GSS_C_MECH_CODE, min); + rpc_set_error(rpc, "%s: (%s, %s)", func, err_maj, err_min); + free(err_min); + free(err_maj); +} + +int +krb5_auth_request(struct rpc_context *rpc, + struct private_auth_data *auth_data, + unsigned char *buf, int len) +{ + uint32_t maj, min; + gss_buffer_desc *input_token = NULL; + gss_buffer_desc token = GSS_C_EMPTY_BUFFER; + + if (buf) { + /* release the previous token */ + gss_release_buffer(&min, &auth_data->output_token); + auth_data->output_token.length = 0; + auth_data->output_token.value = NULL; + + token.value = buf; + token.length = len; + input_token = &token; + } + + /* TODO return -errno instead of just -1 */ + /* NOTE: this call is not async, a helper thread should be used if that + * is an issue */ + auth_data->req_flags = GSS_C_MUTUAL_FLAG; + if (auth_data->wanted_sec == RPC_SEC_KRB5I) { + auth_data->req_flags |= GSS_C_INTEG_FLAG; + } + if (auth_data->wanted_sec == RPC_SEC_KRB5P) { + auth_data->req_flags |= GSS_C_CONF_FLAG; + } + if (auth_data->cred == GSS_C_NO_CREDENTIAL) { + input_token=GSS_C_NO_BUFFER; + } + maj = gss_init_sec_context(&min, auth_data->cred, + &auth_data->context, + auth_data->target_name, + discard_const(auth_data->mech_type), + auth_data->req_flags, + GSS_C_INDEFINITE, + GSS_C_NO_CHANNEL_BINDINGS, + input_token, + NULL, + &auth_data->output_token, + NULL, + NULL); + rpc->gss_context = auth_data->context; + + /* GSS_C_MUTUAL_FLAG expects the acceptor to send a token so + * a second call to gss_init_sec_context is required to complete the session. + * A second call is required even if the first call returns GSS_S_COMPLETE + */ + if (maj & GSS_S_CONTINUE_NEEDED) { + return 0; + } + if (GSS_ERROR(maj)) { + krb5_set_gss_error(rpc, "gss_init_sec_context", maj, min); + return -1; + } + + return 0; +} + +int +krb5_get_output_token_length(struct private_auth_data *auth_data) +{ + return auth_data->output_token.length; +} + +unsigned char * +krb5_get_output_token_buffer(struct private_auth_data *auth_data) +{ + return auth_data->output_token.value; +} + +#endif /* HAVE_LIBKRB5 */ diff --git a/deps/libnfs/lib/krb5-wrapper.h b/deps/libnfs/lib/krb5-wrapper.h new file mode 100644 index 000000000000..da2c270e5fdc --- /dev/null +++ b/deps/libnfs/lib/krb5-wrapper.h @@ -0,0 +1,91 @@ +/* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */ +#ifndef _KRB5_WRAPPER_H_ +#define _KRB5_WRAPPER_H_ + +/* + Copyright (C) 2024 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 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_LIBKRB5 + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if __APPLE__ +#import +#else +#include + +static const gss_OID_desc gss_mech_spnego = { + 6, "\x2b\x06\x01\x05\x05\x02" +}; +#endif + +static const gss_OID_desc spnego_mech_krb5 = { + 9, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" +}; + +struct private_auth_data { + gss_ctx_id_t context; + gss_cred_id_t cred; + gss_name_t user_name; + gss_name_t target_name; + gss_const_OID mech_type; + uint32_t req_flags; + gss_buffer_desc output_token; + char *g_server; + int wanted_sec; +}; + +void +krb5_free_auth_data(struct private_auth_data *auth); + +struct private_auth_data * +krb5_auth_init(struct rpc_context *rpc, + const char *server, + const char *user_name, + int wanted_sec); + +void +krb5_set_gss_error(struct rpc_context *rpc, char *func, + uint32_t maj, uint32_t min); + +int +krb5_auth_request(struct rpc_context *rpc, + struct private_auth_data *auth_data, + unsigned char *buf, int len); + +unsigned char * +krb5_get_output_token_buffer(struct private_auth_data *auth_data); + +int +krb5_get_output_token_length(struct private_auth_data *auth_data); + +#ifdef __cplusplus +} +#endif + +#endif /* HAVE_LIBKRB5 */ + +#endif /* _KRB5_WRAPPER_H_ */ diff --git a/deps/libnfs/lib/libnfs-sync.c b/deps/libnfs/lib/libnfs-sync.c new file mode 100644 index 000000000000..d25566d9c3f6 --- /dev/null +++ b/deps/libnfs/lib/libnfs-sync.c @@ -0,0 +1,2832 @@ +/* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */ +/* + 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 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ +/* + * High level api to nfs filesystems + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef AROS +#include "aros_compat.h" +#endif + +#ifdef PS2_EE +#include "ps2_compat.h" +#endif + +#ifdef PS3_PPU +#include "ps3_compat.h" +#endif + +#ifdef WIN32 +#include +#endif + +#ifdef HAVE_SYS_SOCKET_H +#include +#endif + +#ifdef HAVE_NET_IF_H +#include +#endif + +#ifdef HAVE_SYS_VFS_H +#include +#endif + +#ifdef HAVE_SYS_STATVFS_H +#include +#endif + +#if defined(__ANDROID__) && !defined(HAVE_SYS_STATVFS_H) +#define statvfs statfs +#endif + +#ifdef HAVE_SYS_IOCTL_H +#include +#endif + +#ifdef HAVE_POLL_H +#include +#endif + +#ifdef HAVE_NETDB_H +#include +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_NETINET_IN_H +#include +#endif + +#ifdef HAVE_STRINGS_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_SYS_SOCKIO_H +#include +#endif + +#if defined(__sun) +#include +#endif + +#ifdef HAVE_SYS_TIME_H +#include +#endif + +#include "libnfs-zdr.h" +#include "libnfs.h" +#include "libnfs-raw.h" +#include "libnfs-raw-mount.h" +#include "libnfs-raw-nfs.h" +#include "libnfs-raw-nfs4.h" +#include "libnfs-private.h" + +struct sync_cb_data { + int is_finished; + int status; + uint64_t offset; + void *return_data; + int return_int; + const char *call; +#ifdef HAVE_MULTITHREADING + int has_sem; + libnfs_sem_t wait_sem; +#endif /* HAVE_MULTITHREADING */ +}; + +static inline int +nfs_init_cb_data(struct nfs_context **nfs, struct sync_cb_data *cb_data) +{ + cb_data->is_finished = 0; +#ifdef HAVE_MULTITHREADING + if (nfs && (*nfs)->rpc->multithreading_enabled && (*nfs)->master_ctx == NULL) { + struct nfs_thread_context *ntc; + + for(ntc = (*nfs)->nfsi->thread_ctx; ntc; ntc = ntc->next) { + if (nfs_mt_get_tid() == ntc->tid) { + break; + } + } + if (ntc) { + *nfs = &ntc->nfs; + } else { + ntc = calloc(1, sizeof(struct nfs_thread_context)); + if (ntc == NULL) { + return -1; + } + nfs_mt_mutex_lock(&(*nfs)->rpc->rpc_mutex); + ntc->next = (*nfs)->nfsi->thread_ctx; + ntc->tid = nfs_mt_get_tid(); + (*nfs)->nfsi->thread_ctx = ntc; + nfs_mt_mutex_unlock(&(*nfs)->rpc->rpc_mutex); + memcpy(&ntc->nfs, *nfs, sizeof(struct nfs_context)); + ntc->nfs.error_string = NULL; + ntc->nfs.master_ctx = *nfs; + + *nfs = &ntc->nfs; + } + } + + /* + * Create a semaphore and initialize it to zero. So that we + * can wait for it and immetiately block until the service thread + * has received the reply. + */ + if (nfs_mt_sem_init(&cb_data->wait_sem, 0)) { + if (nfs && *nfs) { + nfs_set_error(*nfs, "Failed to initialize semaphore"); + } + return -1; + } + cb_data->has_sem = 1; +#endif /* HAVE_MULTITHREADING */ + return 0; +} + +static inline void +nfs_destroy_cb_sem(struct sync_cb_data *cb_data) +{ +#ifdef HAVE_MULTITHREADING + if (cb_data->has_sem) { + nfs_mt_sem_destroy(&cb_data->wait_sem); + } + cb_data->has_sem = 0; +#endif +} + +static inline void +cb_data_is_finished(struct sync_cb_data *cb_data, int status) +{ + cb_data->is_finished = 1; + cb_data->status = status; +#ifdef HAVE_MULTITHREADING + if (cb_data->has_sem) { + nfs_mt_sem_post(&cb_data->wait_sem); + } +#endif +} + +static void +wait_for_reply(struct rpc_context *rpc, struct sync_cb_data *cb_data) +{ + struct pollfd pfd; + int revents; + int ret; + uint64_t timeout; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (rpc->timeout > 0) { + timeout = rpc_current_time() + rpc->timeout; +#ifndef HAVE_CLOCK_GETTIME + /* If we do not have GETTIME we fallback to time() which + * has 1s granularity for its timestamps. + * We thus need to bump the timeout by 1000ms + * so that we break if timeout is within 1.0 - 2.0 seconds. + * Otherwise setting a 1s timeout would trigger within + * 0.001 - 1.0s. + */ + timeout += 1000; +#endif + } + else { + timeout = 0; + } + + while (!cb_data->is_finished) { + + pfd.fd = rpc_get_fd(rpc); + pfd.events = rpc_which_events(rpc); + pfd.revents = 0; + + ret = poll(&pfd, 1, rpc->poll_timeout); + if (ret < 0) { + rpc_set_error(rpc, "Poll failed"); + revents = -1; + } else { + revents = pfd.revents; + } + + if (rpc_service(rpc, revents) < 0) { + if (revents != -1) + rpc_set_error(rpc, "rpc_service failed"); + cb_data->status = -EIO; + break; + } + + if (rpc_get_fd(rpc) == -1) { + rpc_set_error(rpc, "Socket closed"); + break; + } + + if (timeout > 0 && rpc_current_time() > timeout) { + rpc_set_error(rpc, "Timeout reached"); + break; + } + } +} + +static void +wait_for_nfs_reply(struct nfs_context *nfs, struct sync_cb_data *cb_data) +{ + struct pollfd pfd; + int revents; + int ret; + +#ifdef HAVE_MULTITHREADING + if(nfs->rpc->multithreading_enabled) { + nfs_mt_sem_wait(&cb_data->wait_sem); + return; + } +#endif + while (!cb_data->is_finished) { + + pfd.fd = nfs_get_fd(nfs); + pfd.events = nfs_which_events(nfs); + pfd.revents = 0; + + ret = poll(&pfd, 1, nfs->rpc->poll_timeout); + if (ret < 0) { + nfs_set_error(nfs, "Poll failed"); + revents = -1; + } else { + revents = pfd.revents; + } + + if (nfs_service(nfs, revents) < 0) { + if (revents != -1) + nfs_set_error(nfs, "nfs_service failed"); + cb_data->status = -EIO; + rpc_error_all_pdus(nfs->rpc, "RPC ERROR: Failed to reconnect async"); + break; + } + } +} + + + +/* + * connect to the server and mount the export + */ +static void +mount_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + + if (status < 0) { + nfs_set_error(nfs, "%s: %s", + __FUNCTION__, rpc_get_error(nfs->rpc)); + goto finished; + } + + finished: + cb_data_is_finished(cb_data, status); +} + +static 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); + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_mount_async(nfs, server, export, mount_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_mount_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + /* Dont want any more callbacks even if the socket is closed */ + rpc->connect_cb = NULL; + + /* Ensure that no RPCs are pending. In error case (e.g. timeout in + * wait_for_nfs_reply()) we can disconnect; in success case all RPCs + * are completed by definition. + */ + if (cb_data.status) { + rpc_disconnect(rpc, "failed mount"); + } + + return cb_data.status; +} + +int +nfs_mount(struct nfs_context *nfs, const char *server, const char *export) +{ + int ret; + ret = _nfs_mount(nfs, server, export); + + /* + * Mount using default v3 failed, try v4 instead + */ + if (ret && nfs->nfsi->default_version) { + free(nfs->nfsi->rootfh.val); + nfs->nfsi->rootfh.val = NULL; + nfs->nfsi->rootfh.len = 0; + nfs->nfsi->version = NFS_V4; + rpc_disconnect(nfs->rpc, "disconnect to try different dialect"); + ret = _nfs_mount(nfs, server, export); + } + nfs_set_error(nfs, "%s", rpc_get_error(nfs->rpc)); + + return ret; +} + +/* + * unregister the mount + */ +static void +umount_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + + if (status < 0) { + nfs_set_error(nfs, "%s: %s", + __FUNCTION__, nfs_get_error(nfs)); + goto finished; + } + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs_umount(struct nfs_context *nfs) +{ + struct sync_cb_data cb_data; + struct rpc_context *rpc = nfs_get_rpc_context(nfs); + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_umount_async(nfs, umount_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_umount_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + if (cb_data.status == -EIO) { + /* We have already disconnected the session in nfs3_umount_2_cb so + * -EIO is epxected at this point + */ + cb_data.status = 0; + } + nfs_destroy_cb_sem(&cb_data); + + /* Dont want any more callbacks even if the socket is closed */ + rpc->connect_cb = NULL; + + /* Ensure that no RPCs are pending. In error case (e.g. timeout in + * wait_for_nfs_reply()) we can disconnect; in success case all RPCs + * are completed by definition. + */ + if (cb_data.status) { + rpc_disconnect(rpc, "failed mount"); + } + + return cb_data.status; +} + + +/* + * stat() + */ +static void +stat_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + + if (status < 0) { + nfs_set_error(nfs, "stat call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } +#ifdef WIN32 + memcpy(cb_data->return_data, data, sizeof(struct __stat64)); +#else + memcpy(cb_data->return_data, data, sizeof(struct stat)); +#endif + + finished: + cb_data_is_finished(cb_data, status); +} + +int +#ifdef WIN32 +nfs_stat(struct nfs_context *nfs, const char *path, struct __stat64 *st) +#else +nfs_stat(struct nfs_context *nfs, const char *path, struct stat *st) +#endif +{ + struct sync_cb_data cb_data; + + cb_data.return_data = st; + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_stat_async(nfs, path, stat_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_stat_async failed"); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + +static void +stat64_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + + if (status < 0) { + nfs_set_error(nfs, "stat call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + memcpy(cb_data->return_data, data, sizeof(struct nfs_stat_64)); + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs_stat64(struct nfs_context *nfs, const char *path, struct nfs_stat_64 *st) +{ + struct sync_cb_data cb_data; + + cb_data.return_data = st; + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_stat64_async(nfs, path, stat64_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_stat64_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + +int +nfs_lstat64(struct nfs_context *nfs, const char *path, struct nfs_stat_64 *st) +{ + struct sync_cb_data cb_data; + + cb_data.return_data = st; + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_lstat64_async(nfs, path, stat64_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_lstat64_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + +/* + * open() + */ +static void +open_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + struct nfsfh *fh, **nfsfh; + + if (status < 0) { + nfs_set_error(nfs, "open call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + + fh = data; + nfsfh = cb_data->return_data; + *nfsfh = fh; + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs_open(struct nfs_context *nfs, const char *path, int flags, + struct nfsfh **nfsfh) +{ + struct sync_cb_data cb_data; + int retry = 0; + struct nfs_context *onfs = nfs; + + try_again: + nfs = onfs; + cb_data.return_data = nfsfh; + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_open_async(nfs, path, flags, open_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_open_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + if (cb_data.status == -EIO && retry < 10) { + retry++; + goto try_again; + } + return cb_data.status; +} + +int +nfs_open2(struct nfs_context *nfs, const char *path, int flags, + int mode, struct nfsfh **nfsfh) +{ + struct sync_cb_data cb_data; + + cb_data.return_data = nfsfh; + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_open2_async(nfs, path, flags, mode, open_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_open2_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + +/* + * chdir() + */ +static void +chdir_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + + if (status < 0) { + nfs_set_error(nfs, "chdir call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs_chdir(struct nfs_context *nfs, const char *path) +{ + struct sync_cb_data cb_data; + + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_chdir_async(nfs, path, chdir_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_chdir_async failed with %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + + +/* + * pread() + */ +static void +pread_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + + if (status < 0) { + nfs_set_error(nfs, "%s call failed with \"%s\"", cb_data->call, + nfs_get_error(nfs)); + goto finished; + } + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs_pread(struct nfs_context *nfs, struct nfsfh *nfsfh, + void *buf, size_t count, uint64_t offset) +{ + struct sync_cb_data cb_data; + + cb_data.call = "pread"; + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_pread_async(nfs, nfsfh, buf, count, offset, + pread_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_pread_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + +/* + * preadv() + */ +int +nfs_preadv(struct nfs_context *nfs, struct nfsfh *nfsfh, + const struct iovec *iov, int iovcnt, uint64_t offset) +{ + struct sync_cb_data cb_data; + + cb_data.call = "preadv"; + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_preadv_async(nfs, nfsfh, iov, iovcnt, offset, + pread_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_preadv_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + +/* + * read() + */ +int +nfs_read(struct nfs_context *nfs, struct nfsfh *nfsfh, + void *buf, size_t count) +{ + struct sync_cb_data cb_data; + + cb_data.call = "read"; + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_read_async(nfs, nfsfh, buf, count, pread_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_read_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + +/* + * readv() + */ +int +nfs_readv(struct nfs_context *nfs, struct nfsfh *nfsfh, + const struct iovec *iov, int iovcnt) +{ + struct sync_cb_data cb_data; + + cb_data.call = "readv"; + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_readv_async(nfs, nfsfh, iov, iovcnt, + pread_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_readv_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + +/* + * close() + */ +static void +close_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + + if (status < 0) { + nfs_set_error(nfs, "close call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs_close(struct nfs_context *nfs, struct nfsfh *nfsfh) +{ + struct sync_cb_data cb_data; + + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_close_async(nfs, nfsfh, close_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_close_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + + +/* + * fstat() + */ +int +#ifdef WIN32 +nfs_fstat(struct nfs_context *nfs, struct nfsfh *nfsfh, struct __stat64 *st) +#else +nfs_fstat(struct nfs_context *nfs, struct nfsfh *nfsfh, struct stat *st) +#endif +{ + struct sync_cb_data cb_data; + + cb_data.return_data = st; + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_fstat_async(nfs, nfsfh, stat_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_fstat_async failed"); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + +/* + * fstat64() + */ +int +nfs_fstat64(struct nfs_context *nfs, struct nfsfh *nfsfh, + struct nfs_stat_64 *st) +{ + struct sync_cb_data cb_data; + + cb_data.return_data = st; + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_fstat64_async(nfs, nfsfh, stat64_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_fstat64_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + + +/* + * pwrite() + */ +static void +pwrite_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + + if (status < 0) { + nfs_set_error(nfs, "%s call failed with \"%s\"", + cb_data->call, nfs_get_error(nfs)); + goto finished; + } + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs_pwrite(struct nfs_context *nfs, struct nfsfh *nfsfh, + const void *buf, size_t count, uint64_t offset) +{ + struct sync_cb_data cb_data; + + cb_data.call = "pwrite"; + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_pwrite_async(nfs, nfsfh, buf, count, offset, pwrite_cb, + &cb_data) != 0) { + nfs_set_error(nfs, "nfs_pwrite_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + +/* + * write() + */ +int +nfs_write(struct nfs_context *nfs, struct nfsfh *nfsfh, + const void *buf, uint64_t count) +{ + struct sync_cb_data cb_data; + + cb_data.call = "write"; + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_write_async(nfs, nfsfh, buf, count, pwrite_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_write_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + + +/* + * fsync() + */ +static void +fsync_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + + if (status < 0) { + nfs_set_error(nfs, "fsync call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs_fsync(struct nfs_context *nfs, struct nfsfh *nfsfh) +{ + struct sync_cb_data cb_data; + + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_fsync_async(nfs, nfsfh, fsync_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_fsync_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + + +/* + * ftruncate() + */ +static void +ftruncate_cb(int status, struct nfs_context *nfs, void *data, + void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + + if (status < 0) { + nfs_set_error(nfs, "ftruncate call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs_ftruncate(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t length) +{ + struct sync_cb_data cb_data; + + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_ftruncate_async(nfs, nfsfh, length, ftruncate_cb, + &cb_data) != 0) { + nfs_set_error(nfs, "nfs_ftruncate_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + + + +/* + * truncate() + */ +static void +truncate_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + + if (status < 0) { + nfs_set_error(nfs, "truncate call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + + finished: + cb_data_is_finished(cb_data, status); +} + +int nfs_truncate(struct nfs_context *nfs, const char *path, uint64_t length) +{ + struct sync_cb_data cb_data; + + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_truncate_async(nfs, path, length, truncate_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_ftruncate_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + + +/* + * mkdir() + */ +static void +mkdir_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + + if (status < 0) { + nfs_set_error(nfs, "mkdir call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs_mkdir(struct nfs_context *nfs, const char *path) +{ + struct sync_cb_data cb_data; + + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_mkdir_async(nfs, path, mkdir_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_mkdir_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + +int +nfs_mkdir2(struct nfs_context *nfs, const char *path, int mode) +{ + struct sync_cb_data cb_data; + + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_mkdir2_async(nfs, path, mode, mkdir_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_mkdir2_async failed"); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + + + + +/* + * rmdir() + */ +static void +rmdir_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + + if (status < 0) { + nfs_set_error(nfs, "rmdir call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + + finished: + cb_data_is_finished(cb_data, status); +} + +int nfs_rmdir(struct nfs_context *nfs, const char *path) +{ + struct sync_cb_data cb_data; + + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_rmdir_async(nfs, path, rmdir_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_rmdir_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + + + +/* + * creat() + */ +static void +creat_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + struct nfsfh *fh, **nfsfh; + + if (status < 0) { + nfs_set_error(nfs, "creat call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + + fh = data; + nfsfh = cb_data->return_data; + *nfsfh = fh; + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs_creat(struct nfs_context *nfs, const char *path, int mode, + struct nfsfh **nfsfh) +{ + struct sync_cb_data cb_data; + + cb_data.return_data = nfsfh; + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_creat_async(nfs, path, mode, creat_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_create_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&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; + + if (status < 0) { + nfs_set_error(nfs, "mknod call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs_mknod(struct nfs_context *nfs, const char *path, int mode, int dev) +{ + struct sync_cb_data cb_data; + + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_mknod_async(nfs, path, mode, dev, mknod_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_creat_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + + +/* + * unlink() + */ +static void +unlink_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + + if (status < 0) { + nfs_set_error(nfs, "unlink call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs_unlink(struct nfs_context *nfs, const char *path) +{ + struct sync_cb_data cb_data; + + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_unlink_async(nfs, path, unlink_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_unlink_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + + + +/* + * opendir() + */ +static void +opendir_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + struct nfsdir *dir, **nfsdir; + + if (status < 0) { + nfs_set_error(nfs, "opendir call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + + dir = data; + nfsdir = cb_data->return_data; + *nfsdir = dir; + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs_opendir(struct nfs_context *nfs, const char *path, struct nfsdir **nfsdir) +{ + struct sync_cb_data cb_data; + + cb_data.return_data = nfsdir; + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_opendir_async(nfs, path, opendir_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_opendir_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + + +/* + * lseek() + */ +static void +lseek_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + + if (status < 0) { + nfs_set_error(nfs, "lseek call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + + if (cb_data->return_data != NULL) { + memcpy(cb_data->return_data, data, sizeof(uint64_t)); + } + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs_lseek(struct nfs_context *nfs, struct nfsfh *nfsfh, int64_t offset, int whence, uint64_t *current_offset) +{ + struct sync_cb_data cb_data; + + cb_data.return_data = current_offset; + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_lseek_async(nfs, nfsfh, offset, whence, lseek_cb, + &cb_data) != 0) { + nfs_set_error(nfs, "nfs_lseek_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + + +/* + * lockf() + */ +static void +lockf_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + + if (status < 0) { + nfs_set_error(nfs, "lockf call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs_lockf(struct nfs_context *nfs, struct nfsfh *nfsfh, + enum nfs4_lock_op cmd, uint64_t count) +{ + struct sync_cb_data cb_data; + + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_lockf_async(nfs, nfsfh, cmd, count, + lockf_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_lockf_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + +/* + * fcntl() + */ +static void +fcntl_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + + if (status < 0) { + nfs_set_error(nfs, "fcntl call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs_fcntl(struct nfs_context *nfs, struct nfsfh *nfsfh, + enum nfs4_fcntl_op cmd, void *arg) +{ + struct sync_cb_data cb_data; + + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_fcntl_async(nfs, nfsfh, cmd, arg, + fcntl_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_fcntl_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + +/* + * statvfs() + */ +static void +statvfs_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + + if (status < 0) { + nfs_set_error(nfs, "statvfs call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + + memcpy(cb_data->return_data, data, sizeof(struct statvfs)); + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs_statvfs(struct nfs_context *nfs, const char *path, struct statvfs *svfs) +{ + struct sync_cb_data cb_data; + + cb_data.return_data = svfs; + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_statvfs_async(nfs, path, statvfs_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_statvfs_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + +/* + * statvfs64() + */ +static void +statvfs64_cb(int status, struct nfs_context *nfs, void *data, + void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + + if (status < 0) { + nfs_set_error(nfs, "statvfs64 call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + + memcpy(cb_data->return_data, data, sizeof(struct nfs_statvfs_64)); + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs_statvfs64(struct nfs_context *nfs, const char *path, + struct nfs_statvfs_64 *svfs) +{ + struct sync_cb_data cb_data; + + cb_data.return_data = svfs; + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_statvfs64_async(nfs, path, statvfs64_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_statvfs64_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + +/* + * readlink() + */ +static void +readlink_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + + if (status < 0) { + nfs_set_error(nfs, "readlink call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + + if (strlen(data) > (size_t)cb_data->return_int) { + nfs_set_error(nfs, "Too small buffer for readlink"); + cb_data->status = -ENAMETOOLONG; + goto finished; + } + + memcpy(cb_data->return_data, data, strlen(data)+1); + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs_readlink(struct nfs_context *nfs, const char *path, char *buf, int bufsize) +{ + struct sync_cb_data cb_data; + + cb_data.return_data = buf; + cb_data.return_int = bufsize; + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_readlink_async(nfs, path, readlink_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_readlink_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + +static void +readlink2_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + char **bufptr; + char *buf; + + if (status < 0) { + nfs_set_error(nfs, "readlink call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + + buf = strdup(data); + if (buf == NULL) { + cb_data->status = errno ? -errno : -ENOMEM; + goto finished; + } + + bufptr = cb_data->return_data; + if (bufptr) + *bufptr = buf; + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs_readlink2(struct nfs_context *nfs, const char *path, char **bufptr) +{ + struct sync_cb_data cb_data; + + *bufptr = NULL; + cb_data.return_data = bufptr; + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_readlink_async(nfs, path, readlink2_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_readlink_async failed"); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + + + +/* + * chmod() + */ +static void +chmod_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + + if (status < 0) { + nfs_set_error(nfs, "chmod call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs_chmod(struct nfs_context *nfs, const char *path, int mode) +{ + struct sync_cb_data cb_data; + + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_chmod_async(nfs, path, mode, chmod_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_chmod_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + +int +nfs_lchmod(struct nfs_context *nfs, const char *path, int mode) +{ + struct sync_cb_data cb_data; + + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_lchmod_async(nfs, path, mode, chmod_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_lchmod_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + + + + +/* + * fchmod() + */ +static void +fchmod_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + + if (status < 0) { + nfs_set_error(nfs, "fchmod call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs_fchmod(struct nfs_context *nfs, struct nfsfh *nfsfh, int mode) +{ + struct sync_cb_data cb_data; + + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_fchmod_async(nfs, nfsfh, mode, fchmod_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_fchmod_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + + + + +/* + * chown() + */ +static void +chown_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + + if (status < 0) { + nfs_set_error(nfs, "chown call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs_chown(struct nfs_context *nfs, const char *path, int uid, int gid) +{ + struct sync_cb_data cb_data; + + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_chown_async(nfs, path, uid, gid, chown_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_chown_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + +/* + * lchown() + */ +int +nfs_lchown(struct nfs_context *nfs, const char *path, int uid, int gid) +{ + struct sync_cb_data cb_data; + + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_lchown_async(nfs, path, uid, gid, chown_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_lchown_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + +/* + * fchown() + */ +static void +fchown_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + + if (status < 0) { + nfs_set_error(nfs, "fchown call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs_fchown(struct nfs_context *nfs, struct nfsfh *nfsfh, int uid, int gid) +{ + struct sync_cb_data cb_data; + + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_fchown_async(nfs, nfsfh, uid, gid, fchown_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_fchown_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + + + +/* + * utimes() + */ +static void +utimes_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + + if (status < 0) { + nfs_set_error(nfs, "utimes call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs_utimes(struct nfs_context *nfs, const char *path, struct timeval *times) +{ + struct sync_cb_data cb_data; + + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_utimes_async(nfs, path, times, utimes_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_utimes_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + +int +nfs_lutimes(struct nfs_context *nfs, const char *path, struct timeval *times) +{ + struct sync_cb_data cb_data; + + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_lutimes_async(nfs, path, times, utimes_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_lutimes_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + + + +/* + * utime() + */ +static void +utime_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + + if (status < 0) { + nfs_set_error(nfs, "utime call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs_utime(struct nfs_context *nfs, const char *path, struct utimbuf *times) +{ + struct sync_cb_data cb_data; + + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_utime_async(nfs, path, times, utime_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_utimes_async failed"); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + + +/* + * access() + */ +static void +access_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + + if (status < 0) { + nfs_set_error(nfs, "access call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs_access(struct nfs_context *nfs, const char *path, int mode) +{ + struct sync_cb_data cb_data; + + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_access_async(nfs, path, mode, access_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_access_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + + + +/* + * access2() + */ +static void +access2_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + + if (status < 0) { + nfs_set_error(nfs, "access2 call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs_access2(struct nfs_context *nfs, const char *path) +{ + struct sync_cb_data cb_data; + + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_access2_async(nfs, path, access2_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_access2_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + + + +/* + * symlink() + */ +static void +symlink_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + + if (status < 0) { + nfs_set_error(nfs, "symlink call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs_symlink(struct nfs_context *nfs, const char *target, const char *linkname) +{ + struct sync_cb_data cb_data; + + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_symlink_async(nfs, target, linkname, symlink_cb, + &cb_data) != 0) { + nfs_set_error(nfs, "nfs_symlink_async failed: %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + + +/* + * rename() + */ +static void +rename_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + + if (status < 0) { + nfs_set_error(nfs, "rename call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs_rename(struct nfs_context *nfs, const char *oldpath, const char *newpath) +{ + struct sync_cb_data cb_data; + + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_rename_async(nfs, oldpath, newpath, rename_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_rename_async failed: %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + + + +/* + * link() + */ +static void +link_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + + if (status < 0) { + nfs_set_error(nfs, "link call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs_link(struct nfs_context *nfs, const char *oldpath, const char *newpath) +{ + struct sync_cb_data cb_data; + + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs_link_async(nfs, oldpath, newpath, link_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_link_async failed: %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + + +/* + * nfs3_getacl() + */ +void nfs3_acl_free(fattr3_acl *nfs3acl) +{ + if (nfs3acl == NULL) { + return; + } + if (nfs3acl->ace) { + free(nfs3acl->ace); + } + if (nfs3acl->default_ace) { + free(nfs3acl->default_ace); + } +} + +static void +nfs3_getacl_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + fattr3_acl *src = data; + fattr3_acl *dst = cb_data->return_data; + + if (status < 0) { + nfs_set_error(nfs, "getacl call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + memcpy(dst, src, sizeof(fattr3_acl)); + src->ace = NULL; /* steal the pointer to ACEs */ + src->default_ace = NULL; /* steal the pointer to Default ACEs */ + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs3_getacl(struct nfs_context *nfs, struct nfsfh *nfsfh, + fattr3_acl *acl) +{ + struct sync_cb_data cb_data; + + cb_data.return_data = acl; + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs3_getacl_async(nfs, nfsfh, nfs3_getacl_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_getacl_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + + +/* + * nfs4_getacl() + */ +void nfs4_acl_free(fattr4_acl *acl) +{ + int i; + + for (i = 0; i < acl->fattr4_acl_len; i++) { + free(acl->fattr4_acl_val[i].who.utf8string_val); + } + free(acl->fattr4_acl_val); +} + +static void +nfs4_getacl_cb(int status, struct nfs_context *nfs, void *data, void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + fattr4_acl *src = data; + fattr4_acl *dst = cb_data->return_data; + int i; + + if (status < 0) { + nfs_set_error(nfs, "getacl call failed with \"%s\"", + nfs_get_error(nfs)); + goto finished; + } + dst->fattr4_acl_len = src->fattr4_acl_len; + dst->fattr4_acl_val = calloc(dst->fattr4_acl_len, sizeof(nfsace4)); + if (dst->fattr4_acl_val == NULL) { + cb_data->status = -ENOMEM; + nfs_set_error(nfs, "Failed to allocate fattr4_acl_val"); + goto finished; + } + for (i = 0; i < dst->fattr4_acl_len; i++) { + dst->fattr4_acl_val[i].type = src->fattr4_acl_val[i].type; + dst->fattr4_acl_val[i].flag = src->fattr4_acl_val[i].flag; + dst->fattr4_acl_val[i].access_mask = src->fattr4_acl_val[i].access_mask; + dst->fattr4_acl_val[i].who.utf8string_len = src->fattr4_acl_val[i].who.utf8string_len; + dst->fattr4_acl_val[i].who.utf8string_val = calloc(dst->fattr4_acl_val[i].who.utf8string_len + 1, 1); + if (dst->fattr4_acl_val[i].who.utf8string_val == NULL) { + cb_data->status = -ENOMEM; + nfs4_acl_free(dst); + nfs_set_error(nfs, "Failed to allocate acl name"); + goto finished; + } + memcpy(dst->fattr4_acl_val[i].who.utf8string_val, + src->fattr4_acl_val[i].who.utf8string_val, + dst->fattr4_acl_val[i].who.utf8string_len); + } + + finished: + cb_data_is_finished(cb_data, status); +} + +int +nfs4_getacl(struct nfs_context *nfs, struct nfsfh *nfsfh, + fattr4_acl *acl) +{ + struct sync_cb_data cb_data; + + cb_data.return_data = acl; + if (nfs_init_cb_data(&nfs, &cb_data)) { + return -1; + } + + if (nfs4_getacl_async(nfs, nfsfh, nfs4_getacl_cb, &cb_data) != 0) { + nfs_set_error(nfs, "nfs_getacl_async failed. %s", + nfs_get_error(nfs)); + nfs_destroy_cb_sem(&cb_data); + return -1; + } + + wait_for_nfs_reply(nfs, &cb_data); + nfs_destroy_cb_sem(&cb_data); + + return cb_data.status; +} + +void +mount_getexports_cb(struct rpc_context *mount_context, int status, void *data, + void *private_data) +{ + struct sync_cb_data *cb_data = private_data; + exports export; + + assert(mount_context->magic == RPC_CONTEXT_MAGIC); + + cb_data->return_data = NULL; + + if (status != 0) { + rpc_set_error(mount_context, "mount/export call failed with " + "\"%s\"", rpc_get_error(mount_context)); + goto finished; + } + + export = *(exports *)data; + while (export != NULL) { + exports new_export; + + new_export = calloc(1, sizeof(*new_export)); + new_export->ex_dir = strdup(export->ex_dir); + new_export->ex_next = cb_data->return_data; + + cb_data->return_data = new_export; + + export = export->ex_next; + } + + finished: + cb_data_is_finished(cb_data, status); +} + +struct exportnode * +mount_getexports_mountport(const char *server, int mountport) +{ + struct sync_cb_data cb_data; + struct rpc_context *rpc; + + + cb_data.return_data = NULL; + if (nfs_init_cb_data(NULL, &cb_data)) { + return NULL; + } + + rpc = rpc_init_context(); + rpc_set_mountport(rpc, mountport); + if (mount_getexports_async(rpc, server, mount_getexports_cb, + &cb_data) != 0) { + rpc_destroy_context(rpc); + nfs_destroy_cb_sem(&cb_data); + return NULL; + } + + wait_for_reply(rpc, &cb_data); + nfs_destroy_cb_sem(&cb_data); + rpc_destroy_context(rpc); + + return cb_data.return_data; +} + +struct exportnode * +mount_getexports_timeout(const char *server, int timeout) +{ + struct sync_cb_data cb_data; + struct rpc_context *rpc; + + + cb_data.return_data = NULL; + if (nfs_init_cb_data(NULL, &cb_data)) { + return NULL; + } + + rpc = rpc_init_context(); + rpc_set_timeout(rpc, timeout); + if (mount_getexports_async(rpc, server, mount_getexports_cb, + &cb_data) != 0) { + rpc_destroy_context(rpc); + nfs_destroy_cb_sem(&cb_data); + return NULL; + } + + wait_for_reply(rpc, &cb_data); + nfs_destroy_cb_sem(&cb_data); + rpc_destroy_context(rpc); + + return cb_data.return_data; +} + +struct exportnode * +mount_getexports(const char *server) +{ + return mount_getexports_timeout(server, -1); +} + +void +mount_free_export_list(struct exportnode *exp) +{ + struct exportnode *tmp; + + while ((tmp = exp)) { + exp = exp->ex_next; + free(tmp->ex_dir); + free(tmp); + } +} + +#if !defined(NO_SRV_AUTOSCAN) + +void +free_nfs_srvr_list(struct nfs_server_list *srv) +{ + while (srv != NULL) { + struct nfs_server_list *next = srv->next; + + free(srv->addr); + free(srv); + srv = next; + } +} + +struct nfs_list_data { + int status; + struct nfs_server_list *srvrs; +}; + +void +callit_cb(struct rpc_context *rpc, int status, void *data _U_, + void *private_data) +{ + struct nfs_list_data *srv_data = private_data; + struct sockaddr *sin; + char hostdd[16]; + struct nfs_server_list *srvr; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (status == RPC_STATUS_CANCEL) { + return; + } + if (status != 0) { + srv_data->status = -1; + return; + } + + sin = rpc_get_udp_src_sockaddr(rpc); + if (sin == NULL) { + rpc_set_error(rpc, "failed to get sockaddr in CALLIT callback"); + srv_data->status = -1; + return; + } + + if (getnameinfo(sin, sizeof(struct sockaddr_in), &hostdd[0], + sizeof(hostdd), NULL, 0, NI_NUMERICHOST) < 0) { + rpc_set_error(rpc, "getnameinfo failed in CALLIT callback"); + srv_data->status = -1; + return; + } + + /* check for dupes */ + for (srvr = srv_data->srvrs; srvr; srvr = srvr->next) { + if (!strcmp(hostdd, srvr->addr)) { + return; + } + } + + srvr = malloc(sizeof(struct nfs_server_list)); + if (srvr == NULL) { + rpc_set_error(rpc, "Malloc failed when allocating server " + "structure"); + srv_data->status = -1; + return; + } + + srvr->addr = strdup(hostdd); + if (srvr->addr == NULL) { + rpc_set_error(rpc, "Strdup failed when allocating server " + "structure"); + free(srvr); + srv_data->status = -1; + return; + } + + srvr->next = srv_data->srvrs; + 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; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + 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_pmap2_callit_task(rpc, MOUNT_PROGRAM, 2, 0, NULL, 0, callit_cb, data) == NULL) + { + 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; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + for (ptr =(char *)(ifc->ifc_buf); + ptr < (char *)(ifc->ifc_buf) + ifc->ifc_len; + ) { + struct ifreq ifr; + char bcdd[16]; + + memcpy(&ifr, ptr, sizeof(struct ifreq)); +#ifdef HAVE_SOCKADDR_LEN + if (ifr.ifr_addr.sa_len > sizeof(struct sockaddr)) { + ptr += sizeof(ifr.ifr_name) + ifr.ifr_addr.sa_len; + } else { + ptr += sizeof(ifr.ifr_name) + sizeof(struct sockaddr); + } +#else + ptr += sizeof(struct ifreq); +#endif + + if (ifr.ifr_addr.sa_family != AF_INET) { + continue; + } +#ifndef PS3_PPU + if (ioctl(rpc_get_fd(rpc), SIOCGIFFLAGS, &ifr) < 0) { + return -1; + } +#endif + if (!(ifr.ifr_flags & IFF_UP)) { + continue; + } + if (ifr.ifr_flags & IFF_LOOPBACK) { + continue; + } + if (!(ifr.ifr_flags & IFF_BROADCAST)) { + continue; + } +#ifndef PS3_PPU + if (ioctl(rpc_get_fd(rpc), SIOCGIFBRDADDR, &ifr) < 0) { + continue; + } +#endif + if (getnameinfo(&ifr.ifr_broadaddr, 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_pmap2_callit_task(rpc, MOUNT_PROGRAM, 2, 0, NULL, 0, + callit_cb, data) == NULL) { + 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; + struct ifconf ifc; + int size, loop; + struct pollfd pfd; + + 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; + } + + + /* get list of all interfaces */ + size = sizeof(struct ifreq); + ifc.ifc_buf = NULL; + ifc.ifc_len = size; + + while(ifc.ifc_len > (size - sizeof(struct ifreq))) { + size *= 2; + + free(ifc.ifc_buf); + ifc.ifc_len = size; + ifc.ifc_buf = calloc(1, size); +#ifndef PS3_PPU + if (ioctl(rpc_get_fd(rpc), SIOCGIFCONF, (caddr_t)&ifc) < 0) { + rpc_destroy_context(rpc); + free(ifc.ifc_buf); + return NULL; + } +#endif + } + + for (loop=0; loop<3; loop++) { + if (send_nfsd_probes(rpc, &ifc, &data) != 0) { + rpc_destroy_context(rpc); + free(ifc.ifc_buf); + return NULL; + } + + gettimeofday(&tv_start, NULL); + for(;;) { + int mpt; + + pfd.fd = rpc_get_fd(rpc); + pfd.events = rpc_which_events(rpc); + + 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; + } + } + } + + free(ifc.ifc_buf); + rpc_destroy_context(rpc); + + if (data.status != 0) { + free_nfs_srvr_list(data.srvrs); + return NULL; + } + return data.srvrs; +} +#endif /* WIN32 */ + +#endif /* !defined(NO_SRV_AUTOSCAN) */ diff --git a/deps/libnfs/lib/libnfs-win32.def b/deps/libnfs/lib/libnfs-win32.def new file mode 100644 index 000000000000..14bbe9014e22 --- /dev/null +++ b/deps/libnfs/lib/libnfs-win32.def @@ -0,0 +1,261 @@ +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_chdir +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_fcntl +nfs_fcntl_async +nfs_fstat +nfs_fstat_async +nfs_fstat64 +nfs_fstat64_async +nfs_fsync +nfs_fsync_async +nfs_ftruncate +nfs_ftruncate_async +nfs_get_error +nfs_get_fd +nfs_get_readmax +nfs_get_writemax +nfs_getcwd +nfs_get_version +nfs_get_timeout +nfs_init_context +nfs_link +nfs_link_async +nfs_lockf +nfs_lockf_async +nfs_lseek +nfs_lseek_async +nfs_mkdir +nfs_mkdir_async +nfs_mkdir2 +nfs_mkdir2_async +nfs_mknod +nfs_mknod_async +nfs_mount +nfs_mount_async +nfs_mt_service_thread_start +nfs_mt_service_thread_stop +nfs_open +nfs_open_async +nfs_open2 +nfs_open2_async +nfs_opendir +nfs_opendir_async +nfs_parse_url_full +nfs_parse_url_dir +nfs_parse_url_incomplete +nfs_destroy_url +nfs_pread +nfs_pread_async +nfs_pwrite +nfs_pwrite_async +nfs_read +nfs_read_async +nfs_readdir +nfs_readlink +nfs_readlink_async +nfs_readlink2 +nfs_rename +nfs_rename_async +nfs_rmdir +nfs_rmdir_async +nfs_service +nfs_set_auth +nfs_set_autoreconnect +rpc_set_auxiliary_gids +nfs_set_debug +nfs_set_auto_traverse_mounts +nfs_set_dircache +nfs_set_gid +nfs_set_hash_size +nfs_set_mountport +nfs_set_nfsport +nfs_set_readdir_max_buffer_size +nfs_set_readmax +nfs_set_readonly +nfs_set_security +nfs_set_tcp_syncnt +nfs_set_timeout +nfs_set_uid +rpc_set_username +nfs_set_version +nfs_set_writemax +nfs_stat +nfs_stat_async +nfs_stat64 +nfs_stat64_async +nfs_statvfs +nfs_statvfs_async +nfs_statvfs64 +nfs_statvfs64_async +nfs_symlink +nfs_symlink_async +nfs_truncate +nfs_truncate_async +nfs_umount +nfs_umount_async +nfs_unlink +nfs_unlink_async +nfs_utime +nfs_utime_async +nfs_utimes +nfs_utimes_async +nfs_which_events +nfs_write +nfs_write_async +nfsstat3_to_errno +nfsstat3_to_str +nfsstat4_to_errno +nfsstat4_to_str +nfs3_getacl +nfs3_getacl_async +nfs4_set_client_name +nfs4_set_verifier +nfs4_acl_free +nfs4_getacl +nfs4_getacl_async +win32_poll +rpc_cancel_pdu +rpc_connect_async +rpc_connect_port_async +rpc_connect_program_async +rpc_destroy_context +rpc_disconnect +rpc_get_error +rpc_get_fd +rpc_get_timeout +rpc_init_context +rpc_init_server_context +rpc_pmap2_null_task +rpc_pmap2_getport_task +rpc_pmap2_set_task +rpc_pmap2_unset_task +rpc_pmap2_dump_task +rpc_pmap2_callit_task +rpc_pmap3_null_task +rpc_pmap3_set_task +rpc_pmap3_unset_task +rpc_pmap3_getaddr_task +rpc_pmap3_dump_task +rpc_pmap3_callit_task +rpc_pmap3_gettime_task +rpc_pmap3_uaddr2taddr_task +rpc_pmap3_taddr2uaddr_task +rpc_pmap4_null_task +rpc_pmap4_set_task +rpc_pmap4_unset_task +rpc_pmap4_getaddr_task +rpc_pmap4_dump_task +rpc_pmap4_bcast_task +rpc_pmap4_gettime_task +rpc_pmap4_uaddr2taddr_task +rpc_pmap4_taddr2uaddr_task +rpc_pmap4_getversaddr_task +rpc_pmap4_indirect_task +rpc_pmap4_getstat_task +rpc_pmap4_getaddrlist_task +rpc_mount1_null_task +rpc_mount1_mnt_task +rpc_mount1_dump_task +rpc_mount1_umnt_task +rpc_mount1_umntall_task +rpc_mount1_export_task +rpc_mount3_null_task +rpc_mount3_mnt_task +rpc_mount3_dump_task +rpc_mount3_umnt_task +rpc_mount3_umntall_task +rpc_mount3_export_task +rpc_nfsacl3_null_task +rpc_nfsacl3_getacl_task +rpc_nfsacl3_setacl_task +rpc_nfs2_null_task +rpc_nfs2_getattr_task +rpc_nfs2_setattr_task +rpc_nfs2_lookup_task +rpc_nfs2_readlink_task +rpc_nfs2_read_task +rpc_nfs2_write_task +rpc_nfs2_create_task +rpc_nfs2_remove_task +rpc_nfs2_rename_task +rpc_nfs2_link_task +rpc_nfs2_symlink_task +rpc_nfs2_mkdir_task +rpc_nfs2_rmdir_task +rpc_nfs2_readdir_task +rpc_nfs2_statfs_task +rpc_nfs3_null_task +rpc_nfs3_getattr_task +rpc_nfs3_pathconf_task +rpc_nfs3_lookup_task +rpc_nfs3_access_task +rpc_nfs3_read_task +rpc_nfs3_write_task +rpc_nfs3_commit_task +rpc_nfs3_setattr_task +rpc_nfs3_mkdir_task +rpc_nfs3_rmdir_task +rpc_nfs3_create_task +rpc_nfs3_mknod_task +rpc_nfs3_remove_task +rpc_nfs3_readdir_task +rpc_nfs3_readdirplus_task +rpc_nfs3_fsstat_task +rpc_nfs3_fsinfo_task +rpc_nfs3_readlink_task +rpc_nfs3_symlink_task +rpc_nfs3_rename_task +rpc_nfs3_link_task +rpc_nfs4_compound_task +rpc_nfs4_compound_task2 +rpc_nfs4_null_task +rpc_nlm4_null_task +rpc_nlm4_test_task +rpc_nlm4_lock_task +rpc_nlm4_cancel_task +rpc_nlm4_unlock_task +rpc_nsm1_null_task +rpc_nsm1_stat_task +rpc_nsm1_mon_task +rpc_nsm1_unmon_task +rpc_nsm1_unmonall_task +rpc_nsm1_simucrash_task +rpc_nsm1_notify_task +rpc_null_task +rpc_register_service +rpc_rquota1_null_task +rpc_rquota1_getquota_task +rpc_rquota1_getactivequota_task +rpc_rquota2_null_task +rpc_rquota2_getquota_task +rpc_rquota2_getactivequota_task +rpc_send_reply +rpc_service +rpc_set_fd +rpc_set_gid +rpc_set_hash_size +rpc_set_timeout +rpc_set_uid +rpc_which_events diff --git a/deps/libnfs/lib/libnfs-zdr.c b/deps/libnfs/lib/libnfs-zdr.c new file mode 100644 index 000000000000..357b27465740 --- /dev/null +++ b/deps/libnfs/lib/libnfs-zdr.c @@ -0,0 +1,794 @@ +/* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */ +/* + Copyright (C) 2012 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 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ +/* + * This file contains definitions for the built in ZDR implementation. + * This is a very limited ZDR subset that can only marshal to/from a momory buffer, + * i.e. zdrmem_create() buffers. + * It aims to be compatible with normal rpcgen generated functions. + */ + +/* + RFC2203: 5.2.3.1 struct rpc_gss_init_res is what the NULL reply contains + Credentials type, len + struct rpc_gss_cred_vers_1_t +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef WIN32 +#include +#endif + +#ifdef AROS +#include "aros_compat.h" +#endif + +#ifdef PS2_EE +#include "ps2_compat.h" +#endif + +#ifdef PS3_PPU +#include "ps3_compat.h" +#endif + +#ifdef HAVE_ARPA_INET_H +#include +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include +#include +#include +#include +#include "libnfs-zdr.h" +#include "libnfs.h" +#include "libnfs-raw.h" +#include "libnfs-private.h" +#include "libnfs-raw-nfs4.h" + +#ifdef HAVE_LIBKRB5 +#include "krb5-wrapper.h" +#endif + +struct zdr_mem { + struct zdr_mem *next; + uint32_t size; + char buf[1]; +}; + +struct opaque_verf _null_auth; + +bool_t libnfs_zdr_setpos(ZDR *zdrs, uint32_t pos) +{ + zdrs->pos = pos; + + return TRUE; +} + +uint32_t libnfs_zdr_getpos(ZDR *zdrs) +{ + return zdrs->pos; +} + +uint32_t libnfs_zdr_getsize(ZDR *zdrs) +{ + return zdrs->size; +} + +char *libnfs_zdr_getptr(ZDR *zdrs) +{ + return zdrs->buf; +} + +void libnfs_zdrmem_create(ZDR *zdrs, const caddr_t addr, uint32_t size, enum zdr_op xop) +{ + zdrs->x_op = xop; + zdrs->buf = addr; + zdrs->size = size; + zdrs->pos = 0; + zdrs->mem = NULL; +} + +void *zdr_malloc(ZDR *zdrs, uint32_t size) +{ + struct zdr_mem *mem; + int mem_size; + + /* Clamp max size we handle to 1GB */ + if (size > 1024 * 1024 * 1024) { + return NULL; + } + + mem_size = offsetof(struct zdr_mem, buf) + size; + mem = malloc(mem_size); + if (mem == NULL) { + return NULL; + } + + mem->next = zdrs->mem; + mem->size = size; + + zdrs->mem = mem; + + return &mem->buf[0]; +} + +void libnfs_zdr_destroy(ZDR *zdrs) +{ + while (zdrs->mem != NULL) { + struct zdr_mem *mem = zdrs->mem->next; + free(zdrs->mem); + zdrs->mem = mem; + } +} + +bool_t libnfs_zdr_u_int(ZDR *zdrs, uint32_t *u) +{ + if (zdrs->pos + 4 > zdrs->size) { + return FALSE; + } + + switch (zdrs->x_op) { + case ZDR_ENCODE: + *(uint32_t *)(void *)&zdrs->buf[zdrs->pos] = htonl(*u); + zdrs->pos += 4; + return TRUE; + case ZDR_DECODE: + *u = ntohl(*(uint32_t *)(void *)&zdrs->buf[zdrs->pos]); + zdrs->pos += 4; + return TRUE; + } + + return FALSE; +} + +bool_t libnfs_zdr_int(ZDR *zdrs, int32_t *i) +{ + return libnfs_zdr_u_int(zdrs, (uint32_t *)i); +} + +bool_t libnfs_zdr_uint64_t(ZDR *zdrs, uint64_t *u) +{ + if (zdrs->pos + 8 > zdrs->size) { + return FALSE; + } + + switch (zdrs->x_op) { + case ZDR_ENCODE: + *(uint32_t *)(void *)&zdrs->buf[zdrs->pos] = htonl((*u >> 32)); + zdrs->pos += 4; + *(uint32_t *)(void *)&zdrs->buf[zdrs->pos] = htonl((*u & 0xffffffff)); + zdrs->pos += 4; + return TRUE; + case ZDR_DECODE: + *u = ntohl(*(uint32_t *)(void *)&zdrs->buf[zdrs->pos]); + zdrs->pos += 4; + *u <<= 32; + *u |= (uint32_t)ntohl(*(uint32_t *)(void *)&zdrs->buf[zdrs->pos]); + zdrs->pos += 4; + return TRUE; + } + + return FALSE; +} + +bool_t libnfs_zdr_int64_t(ZDR *zdrs, int64_t *i) +{ + return libnfs_zdr_uint64_t(zdrs, (uint64_t *)i); +} + +bool_t libnfs_zdr_bytes(ZDR *zdrs, char **bufp, uint32_t *size, uint32_t maxsize) +{ + uint32_t zero = 0; + int pad; + + if (!libnfs_zdr_u_int(zdrs, size)) { + return FALSE; + } + + /* Clamp max size we handle to 1GB */ + if (*size > 1024 * 1024 * 1024) { + return FALSE; + } + + if (zdrs->pos + (int)*size > zdrs->size) { + return FALSE; + } + + switch (zdrs->x_op) { + case ZDR_ENCODE: + memcpy(&zdrs->buf[zdrs->pos], *bufp, *size); + zdrs->pos += *size; + + pad = (4 - (zdrs->pos & 0x03)) & 0x03; + if (pad) { + /* Make valgrind happy again */ + memcpy(&zdrs->buf[zdrs->pos], &zero, pad); + zdrs->pos += pad; + } + return TRUE; + case ZDR_DECODE: + if (*bufp != NULL) { + memcpy(*bufp, &zdrs->buf[zdrs->pos], *size); + } else { + *bufp = &zdrs->buf[zdrs->pos]; + } + zdrs->pos += *size; + zdrs->pos = (zdrs->pos + 3) & ~3; + return TRUE; + } + + return FALSE; +} + + +bool_t libnfs_zdr_enum(ZDR *zdrs, enum_t *e) +{ + bool_t ret; + int32_t i = *e; + + ret = libnfs_zdr_u_int(zdrs, (uint32_t *)&i); + *e = i; + + return ret; +} + +bool_t libnfs_zdr_bool(ZDR *zdrs, bool_t *b) +{ + return libnfs_zdr_u_int(zdrs, (uint32_t *)b); +} + +bool_t libnfs_zdr_void(ZDR *zdrs, void *v) +{ + return TRUE; +} + +bool_t libnfs_zdr_pointer(ZDR *zdrs, char **objp, uint32_t size, zdrproc_t proc) +{ + bool_t more_data; + + more_data = (*objp != NULL); + + if (!libnfs_zdr_bool(zdrs, &more_data)) { + return FALSE; + } + if (more_data == 0) { + *objp = NULL; + return TRUE; + } + + if (zdrs->x_op == ZDR_DECODE) { + *objp = zdr_malloc(zdrs, size); + if (*objp == NULL) { + return FALSE; + } + memset(*objp, 0, size); + } + return proc(zdrs, *objp); +} + +bool_t libnfs_zdr_opaque(ZDR *zdrs, char *objp, uint32_t size) +{ + switch (zdrs->x_op) { + case ZDR_ENCODE: + memcpy(&zdrs->buf[zdrs->pos], objp, size); + zdrs->pos += size; + if (zdrs->pos & 3) { + memset(&zdrs->buf[zdrs->pos], 0x00, 4 - (zdrs->pos & 3)); + } + zdrs->pos = (zdrs->pos + 3) & ~3; + return TRUE; + case ZDR_DECODE: + memcpy(objp, &zdrs->buf[zdrs->pos], size); + zdrs->pos += size; + zdrs->pos = (zdrs->pos + 3) & ~3; + return TRUE; + } + + return FALSE; +} + +bool_t libnfs_zdr_string(ZDR *zdrs, char **strp, uint32_t maxsize) +{ + uint32_t size; + + if (zdrs->x_op == ZDR_ENCODE) { + size = strlen(*strp); + } + + if (!libnfs_zdr_u_int(zdrs, &size)) { + return FALSE; + } + if (size > zdrs->size) { + return FALSE; + } + if (zdrs->pos + (int)size > zdrs->size) { + return FALSE; + } + + switch (zdrs->x_op) { + case ZDR_ENCODE: + return libnfs_zdr_opaque(zdrs, *strp, size); + case ZDR_DECODE: + /* If the we string is null terminated we can just return it + * in place. + */ + if (zdrs->size > zdrs->pos + (int)size && zdrs->buf[zdrs->pos + size] == 0) { + *strp = &zdrs->buf[zdrs->pos]; + (*strp)[size] = 0; + zdrs->pos += size; + zdrs->pos = (zdrs->pos + 3) & ~3; + return TRUE; + } + + /* Crap. The string is not null terminated in the rx buffer. + * we have to allocate a buffer so we can add the null byte. + */ + *strp = zdr_malloc(zdrs, size + 1); + if (*strp == NULL) { + return FALSE; + } + (*strp)[size] = 0; + return libnfs_zdr_opaque(zdrs, *strp, size); + } + + return FALSE; +} + +bool_t libnfs_zdr_array(ZDR *zdrs, char **arrp, uint32_t *size, uint32_t maxsize, uint32_t elsize, zdrproc_t proc) +{ + int i; + uint32_t s; + + if (!libnfs_zdr_u_int(zdrs, size)) { + return FALSE; + } + + if (*size > UINT32_MAX/elsize) { + return FALSE; + } + s = *size * elsize; + + if (zdrs->x_op == ZDR_DECODE) { + *arrp = zdr_malloc(zdrs, s); + if (*arrp == NULL) { + return FALSE; + } + memset(*arrp, 0, s); + } + + for (i = 0; i < (int)*size; i++) { + if (!proc(zdrs, *arrp + i * elsize)) { + return FALSE; + } + } + return TRUE; +} + +bool_t libnfs_zdr_vector(ZDR *zdrs, char *arrp, uint32_t size, uint32_t elsize, zdrproc_t proc) +{ + int i; + + for (i = 0; i < size; i++) { + if (!proc(zdrs, arrp + i * elsize)) { + return FALSE; + } + } + return TRUE; +} + +void libnfs_zdr_free(zdrproc_t proc, char *objp) +{ +} + +static bool_t libnfs_opaque_cred(ZDR *zdrs, struct opaque_cred *cred) +{ + if (!libnfs_zdr_u_int(zdrs, &cred->oa_flavor)) { + return FALSE; + } + + if (!libnfs_zdr_bytes(zdrs, &cred->oa_base, &cred->oa_length, cred->oa_length)) { + return FALSE; + } + + return TRUE; +} + +static bool_t libnfs_opaque_verf(ZDR *zdrs, struct opaque_verf *verf) +{ +#ifdef HAVE_LIBKRB5 + uint32_t maj, min; + gss_buffer_desc message_buffer, output_token; + char *buf; + uint32_t len; +#endif + switch (verf->oa_flavor) { +#ifdef HAVE_LIBKRB5 + case AUTH_GSS: + if (zdrs->x_op ==ZDR_ENCODE && verf->gss_context) { + message_buffer.length = zdr_getpos(zdrs); + message_buffer.value = zdr_getptr(zdrs); + maj = gss_get_mic(&min, verf->gss_context, + GSS_C_QOP_DEFAULT, + &message_buffer, + &output_token); + if (maj != GSS_S_COMPLETE) { + return FALSE; + } + buf = output_token.value; + len = output_token.length; + if (!libnfs_zdr_u_int(zdrs, &verf->oa_flavor)) { + gss_release_buffer(&min, &output_token); + return FALSE; + } + if (!libnfs_zdr_bytes(zdrs, &buf, &len, len)) { + gss_release_buffer(&min, &output_token); + return FALSE; + } + gss_release_buffer(&min, &output_token); + break; + } + // fallthrough +#endif + default: + if (!libnfs_zdr_u_int(zdrs, &verf->oa_flavor)) { + return FALSE; + } + if (!libnfs_zdr_bytes(zdrs, &verf->oa_base, &verf->oa_length, verf->oa_length)) { + return FALSE; + } + } + + return TRUE; +} + +static bool_t libnfs_rpc_call_body(struct rpc_context *rpc, ZDR *zdrs, struct call_body *cmb) +{ + if (!libnfs_zdr_u_int(zdrs, &cmb->rpcvers)) { + rpc_set_error(rpc, "libnfs_rpc_call_body failed to encode " + "RPCVERS"); + return FALSE; + } + + if (!libnfs_zdr_u_int(zdrs, &cmb->prog)) { + rpc_set_error(rpc, "libnfs_rpc_call_body failed to encode " + "PROG"); + return FALSE; + } + + if (!libnfs_zdr_u_int(zdrs, &cmb->vers)) { + rpc_set_error(rpc, "libnfs_rpc_call_body failed to encode " + "VERS"); + return FALSE; + } + + if (!libnfs_zdr_u_int(zdrs, &cmb->proc)) { + rpc_set_error(rpc, "libnfs_rpc_call_body failed to encode " + "PROC"); + return FALSE; + } + + if (!libnfs_opaque_cred(zdrs, &cmb->cred)) { + rpc_set_error(rpc, "libnfs_rpc_call_body failed to encode " + "CRED"); + return FALSE; + } + + if (!libnfs_opaque_verf(zdrs, &cmb->verf)) { + rpc_set_error(rpc, "libnfs_rpc_call_body failed to encode " + "VERF"); + return FALSE; + } + + return TRUE; +} + +static bool_t libnfs_accepted_reply(ZDR *zdrs, struct accepted_reply *ar) +{ +#ifdef HAVE_LIBKRB5 + uint32_t maj, min, len, tmp; + gss_buffer_desc message_buffer, *output_buffer; +#endif + + if (!libnfs_opaque_verf(zdrs, &ar->verf)) { + return FALSE; + } + + if (!libnfs_zdr_u_int(zdrs, &ar->stat)) { + return FALSE; + } + + switch (ar->stat) { + case SUCCESS: +#ifdef HAVE_LIBKRB5 + if (zdrs->x_op ==ZDR_DECODE && ar->reply_data.results.krb5p) { + if (!libnfs_zdr_u_int(zdrs, &len)) { + return FALSE; + } + + message_buffer.length = len; + message_buffer.value = zdr_getptr(zdrs) + zdr_getpos(zdrs); + output_buffer = ar->reply_data.results.output_buffer; + maj = gss_unwrap (&min, ar->verf.gss_context, + &message_buffer, + output_buffer, + NULL, + NULL); + if (maj) { + return FALSE; + } + zdrs->buf = (char *)output_buffer->value + 4; + zdrs->pos = 0; + zdrs->size = output_buffer->length - 4; + } + if (zdrs->x_op ==ZDR_DECODE && ar->reply_data.results.krb5i) { + /* TODO should check the signature */ + libnfs_zdr_u_int(zdrs, &tmp); + libnfs_zdr_u_int(zdrs, &tmp); + } +#endif /* HAVE_LIBKRB5 */ + if (!ar->reply_data.results.proc(zdrs, ar->reply_data.results.where)) { + return FALSE; + } + return TRUE; + case PROG_MISMATCH: + if (!libnfs_zdr_u_int(zdrs, &ar->reply_data.mismatch_info.low)) { + return FALSE; + } + if (!libnfs_zdr_u_int(zdrs, &ar->reply_data.mismatch_info.high)) { + return FALSE; + } + return TRUE; + default: + return TRUE; + } + + return FALSE; +} + +static bool_t libnfs_rejected_reply(ZDR *zdrs, struct rejected_reply *rr) +{ + if (!libnfs_zdr_u_int(zdrs, (uint32_t *)&rr->stat)) { + return FALSE; + } + + switch (rr->stat) { + case RPC_MISMATCH: + if (!libnfs_zdr_u_int(zdrs, &rr->reject_data.mismatch_info.low)) { + return FALSE; + } + if (!libnfs_zdr_u_int(zdrs, &rr->reject_data.mismatch_info.high)) { + return FALSE; + } + return TRUE; + case AUTH_ERROR: + if (!libnfs_zdr_u_int(zdrs, (uint32_t *)&rr->reject_data.stat)) { + return FALSE; + } + return TRUE; + default: + return TRUE; + } + + return FALSE; +} + +static bool_t libnfs_rpc_reply_body(struct rpc_context *rpc, ZDR *zdrs, struct reply_body *rmb) +{ + if (!libnfs_zdr_u_int(zdrs, &rmb->stat)) { + rpc_set_error(rpc, "libnfs_rpc_reply_body failed to decode " + "STAT"); + return FALSE; + } + + switch (rmb->stat) { + case MSG_ACCEPTED: + if (!libnfs_accepted_reply(zdrs, &rmb->reply.areply)) { + rpc_set_error(rpc, "libnfs_rpc_reply_body failed to " + "decode ACCEPTED"); + return FALSE; + } + return TRUE; + case MSG_DENIED: + if (!libnfs_rejected_reply(zdrs, &rmb->reply.rreply)) { + rpc_set_error(rpc, "libnfs_rpc_reply_body failed to " + "decode DENIED"); + return FALSE; + } + return TRUE; + } + + rpc_set_error(rpc, "libnfs_rpc_reply_body failed to " + "decode. Neither ACCEPTED nor DENIED"); + return FALSE; +} + +static bool_t libnfs_rpc_msg(struct rpc_context *rpc, ZDR *zdrs, struct rpc_msg *msg) +{ + int ret; + + if (!libnfs_zdr_u_int(zdrs, &msg->xid)) { + rpc_set_error(rpc, "libnfs_rpc_msg failed to decode XID"); + return FALSE; + } + + if (!libnfs_zdr_u_int(zdrs, &msg->direction)) { + rpc_set_error(rpc, "libnfs_rpc_msg failed to decode DIRECTION"); + return FALSE; + } + + switch (msg->direction) { + case CALL: + ret = libnfs_rpc_call_body(rpc, zdrs, &msg->body.cbody); + if (!ret) { + rpc_set_error(rpc, "libnfs_rpc_msg failed to encode " + "CALL, ret=%d: %s", ret, rpc_get_error(rpc)); + } + return ret; + case REPLY: + ret = libnfs_rpc_reply_body(rpc, zdrs, &msg->body.rbody); + if (!ret) { + rpc_set_error(rpc, "libnfs_rpc_msg failed to decode " + "REPLY, ret=%d: %s", ret, rpc_get_error(rpc)); + } + return ret; + default: + rpc_set_error(rpc, "libnfs_rpc_msg failed to decode. " + "Neither CALL not REPLY"); + return FALSE; + } +} + +bool_t libnfs_zdr_callmsg(struct rpc_context *rpc, ZDR *zdrs, struct rpc_msg *msg) +{ + return libnfs_rpc_msg(rpc, zdrs, msg); +} + +bool_t libnfs_zdr_replymsg(struct rpc_context *rpc, ZDR *zdrs, struct rpc_msg *msg) +{ + return libnfs_rpc_msg(rpc, zdrs, msg); +} + +struct AUTH *authnone_create(void) +{ + struct AUTH *auth; + + auth = malloc(sizeof(struct AUTH)); + + auth->ah_cred.oa_flavor = AUTH_NONE; + auth->ah_cred.oa_length = 0; + auth->ah_cred.oa_base = NULL; + + auth->ah_verf.oa_flavor = AUTH_NONE; + auth->ah_verf.oa_length = 0; + auth->ah_verf.oa_base = NULL; + + auth->ah_private = NULL; + + return auth; +} + +struct AUTH *libnfs_authunix_create(const char *host, uint32_t uid, uint32_t gid, uint32_t len, uint32_t *groups) +{ + if (len > 16) { // The maximum number of auxiliary groups is 16, refer to RFC 5531 section 14 + return NULL; + } + + struct AUTH *auth; + int size; + uint32_t *buf; + int idx; + + size = 4 + 4 + ((strlen(host) + 3) & ~3) + 4 + 4 + 4 + len * 4; + auth = calloc(1, sizeof(struct AUTH)); + if (auth == NULL) { + return NULL; + } + + auth->ah_cred.oa_flavor = AUTH_UNIX; + auth->ah_cred.oa_length = size; + auth->ah_cred.oa_base = calloc(1, size); + + buf = (uint32_t *)(void *)auth->ah_cred.oa_base; + idx = 0; + buf[idx++] = htonl((uint32_t)rpc_current_time()); + buf[idx++] = htonl(strlen(host)); + memcpy(&buf[2], host, strlen(host)); + + idx += (strlen(host) + 3) >> 2; + buf[idx++] = htonl(uid); + buf[idx++] = htonl(gid); + buf[idx++] = htonl(len); + while (len-- > 0) { + buf[idx++] = htonl(*groups++); + } + + auth->ah_verf.oa_flavor = AUTH_NONE; + auth->ah_verf.oa_length = 0; + auth->ah_verf.oa_base = NULL; + + auth->ah_private = NULL; + + return auth; +} + +#ifdef HAVE_LIBKRB5 +int libnfs_authgss_init(struct rpc_context *rpc) +{ + rpc->gss_seqno = 0; + rpc->context_len = 0; + free(rpc->context); + rpc->context = NULL; + + free(rpc->auth->ah_cred.oa_base); + rpc->auth->ah_cred.oa_base = NULL; + + rpc->auth->ah_cred.oa_flavor = AUTH_GSS; + + return 0; +} + +int libnfs_authgss_gen_creds(struct rpc_context *rpc, ZDR *zdr, int level) +{ + struct rpc_gss_cred_t gss; + struct rpc_gss_cred_vers_1_t *gss_v1; + + gss.vers = 1; + gss_v1 = &gss.rpc_gss_cred_t_u.rpc_gss_cred_vers_1_t; + if (rpc->gss_seqno == 0) { + gss_v1->gss_proc = RPCSEC_GSS_INIT; + } else { + gss_v1->gss_proc = RPCSEC_GSS_DATA; + } + gss_v1->seq_num = rpc->gss_seqno; + gss_v1->service = level; + gss_v1->handle.handle_val = rpc->context; + gss_v1->handle.handle_len = rpc->context_len; + + if (!zdr_rpc_gss_cred_t(zdr, &gss)) { + return -1; + } + + return 0; +} +#endif /* HAVE_LIBKRB5 */ + +struct AUTH *libnfs_authunix_create_default(void) +{ +#if defined(WIN32) || defined(PS3_PPU) + return libnfs_authunix_create("libnfs", 65534, 65534, 0, NULL); +#else + return libnfs_authunix_create("libnfs", getuid(), getgid(), 0, NULL); +#endif +} + +void libnfs_auth_destroy(struct AUTH *auth) +{ + if (auth->ah_cred.oa_base) { + free(auth->ah_cred.oa_base); + } + if (auth->ah_verf.oa_base) { + free(auth->ah_verf.oa_base); + } + free(auth); +} + diff --git a/deps/libnfs/lib/libnfs.c b/deps/libnfs/lib/libnfs.c new file mode 100755 index 000000000000..79e727b3fe9b --- /dev/null +++ b/deps/libnfs/lib/libnfs.c @@ -0,0 +1,2958 @@ +/* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */ +/* + 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 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ +/* + * High level api to nfs filesystems + */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_UTIME_H +#include +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_PWD_H +#include +#endif + +#ifdef HAVE_SYS_VFS_H +#include +#endif + +#ifdef HAVE_SYS_STATVFS_H +#include +#endif + +#if defined(__ANDROID__) && !defined(HAVE_SYS_STATVFS_H) +#define statvfs statfs +#endif + +#ifdef HAVE_NETINET_IN_H +#include +#endif + +#ifdef HAVE_STRINGS_H +#include +#endif + +#ifdef HAVE_SYS_SYSMACROS_H +#include +#endif + +#ifdef HAVE_SYS_TIME_H +#include +#endif + +#ifdef HAVE_SIGNAL_H +#include +#endif + +#ifdef WIN32 +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include "slist.h" +#include "libnfs.h" +#include "libnfs-raw.h" +#include "libnfs-raw-mount.h" +#include "libnfs-raw-portmap.h" +#include "libnfs-private.h" + +#ifdef HAVE_LIBKRB5 +#include "krb5-wrapper.h" +#endif + +#ifndef discard_const +#define discard_const(ptr) ((void *)((intptr_t)(ptr))) +#endif + +static const char *oom = "out of memory"; + +void +nfs_free_nfsdir(struct nfsdir *nfsdir) +{ + while (nfsdir->entries) { + struct nfsdirent *dirent = nfsdir->entries->next; + if (nfsdir->entries->name != NULL) { + free(nfsdir->entries->name); + } + free(nfsdir->entries); + nfsdir->entries = dirent; + } + free(nfsdir->fh.val); + free(nfsdir); +} + +void +nfs_dircache_add(struct nfs_context *nfs, struct nfsdir *nfsdir) +{ + int i = 0; +#ifdef HAVE_MULTITHREADING + if (nfs->rpc->multithreading_enabled) { + nfs_mt_mutex_lock(&nfs->rpc->rpc_mutex); + } +#endif + LIBNFS_LIST_ADD(&nfs->nfsi->dircache, nfsdir); + + for (nfsdir = nfs->nfsi->dircache; nfsdir; nfsdir = nfsdir->next, i++) { + if (i > MAX_DIR_CACHE) { + LIBNFS_LIST_REMOVE(&nfs->nfsi->dircache, nfsdir); + nfs_free_nfsdir(nfsdir); + break; + } + } +#ifdef HAVE_MULTITHREADING + if (nfs->rpc->multithreading_enabled) { + nfs_mt_mutex_unlock(&nfs->rpc->rpc_mutex); + } +#endif +} + +struct nfsdir * +nfs_dircache_find(struct nfs_context *nfs, struct nfs_fh *fh) +{ + struct nfsdir *nfsdir; + +#ifdef HAVE_MULTITHREADING + if (nfs->rpc->multithreading_enabled) { + nfs_mt_mutex_lock(&nfs->rpc->rpc_mutex); + } +#endif + for (nfsdir = nfs->nfsi->dircache; nfsdir; nfsdir = nfsdir->next) { + if (nfsdir->fh.len == fh->len && + !memcmp(nfsdir->fh.val, fh->val, fh->len)) { + LIBNFS_LIST_REMOVE(&nfs->nfsi->dircache, nfsdir); + break; + } + } + +#ifdef HAVE_MULTITHREADING + if (nfs->rpc->multithreading_enabled) { + nfs_mt_mutex_unlock(&nfs->rpc->rpc_mutex); + } +#endif + return nfsdir; +} + +void +nfs_dircache_drop(struct nfs_context *nfs, struct nfs_fh *fh) +{ + struct nfsdir *cached; + + cached = nfs_dircache_find(nfs, fh); + if (cached) { + nfs_free_nfsdir(cached); + } +} + +void +nfs_set_auth(struct nfs_context *nfs, struct AUTH *auth) +{ + rpc_set_auth(nfs->rpc, auth); +} + +void +nfs_set_security(struct nfs_context *nfs, enum rpc_sec sec) +{ +#ifdef HAVE_LIBKRB5 + nfs->rpc->wanted_sec = sec; +#endif +} + +#ifdef HAVE_TLS +void +nfs_set_xprtsecurity(struct nfs_context *nfs, enum rpc_xprtsec xprtsec) +{ + /* Ensure only permissible values are being set */ + assert(xprtsec == RPC_XPRTSEC_NONE || + xprtsec == RPC_XPRTSEC_TLS || + xprtsec == RPC_XPRTSEC_MTLS); + + nfs->rpc->wanted_xprtsec = xprtsec; +} +#endif /* HAVE_TLS */ + +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); +} + +int +nfs_service(struct nfs_context *nfs, int revents) +{ + return rpc_service(nfs->rpc, revents); +} + +char * +nfs_get_error(struct nfs_context *nfs) +{ +#ifdef HAVE_MULTITHREADING + if (nfs && nfs->rpc->multithreading_enabled) { + struct nfs_thread_context *ntc; + + for(ntc = nfs->nfsi->thread_ctx; ntc; ntc = ntc->next) { + if (nfs_mt_get_tid() == ntc->tid) { + nfs = &ntc->nfs; + break; + } + } + } +#endif + return nfs->error_string ? nfs->error_string : ""; +}; + +#ifdef HAVE_SO_BINDTODEVICE +void +nfs_set_interface(struct nfs_context *nfs, const char *ifname) +{ + rpc_set_interface(nfs_get_rpc_context(nfs), ifname); +} +#endif + +static int +nfs_set_context_args_no_val(struct nfs_context *nfs, const char *arg) +{ + if (!strcmp(arg, "readonly")) { + nfs_set_readonly(nfs, 1); + } else { + nfs_set_error(nfs, "Unknown url argument : %s", + arg); + return -1; + } + return 0; +} + +static int +nfs_set_context_args(struct nfs_context *nfs, const char *arg, const char *val) +{ + if (!strcmp(arg, "tcp-syncnt")) { + rpc_set_tcp_syncnt(nfs_get_rpc_context(nfs), atoi(val)); + } else if (!strcmp(arg, "uid")) { + rpc_set_uid(nfs_get_rpc_context(nfs), atoi(val)); + } else if (!strcmp(arg, "gid")) { + rpc_set_gid(nfs_get_rpc_context(nfs), atoi(val)); + } else if (!strcmp(arg, "timeo")) { + /* val is in deci-seconds */ + const int timeout_msecs = atoi(val) * 100; + if (timeout_msecs < (10 * 1000)) { + nfs_set_error(nfs, "timeo cannot be less than 100: %s", val); + return -1; + } + nfs_set_timeout(nfs, timeout_msecs); + } else if (!strcmp(arg, "retrans")) { + const int retrans = atoi(val); + if (retrans < 0) { + nfs_set_error(nfs, "retrans cannot be less than 0: %s", val); + return -1; + } + nfs_set_retrans(nfs, retrans); + } else if (!strcmp(arg, "debug")) { + rpc_set_debug(nfs_get_rpc_context(nfs), atoi(val)); + } else if (!strcmp(arg, "auto-traverse-mounts")) { + nfs_set_auto_traverse_mounts(nfs, atoi(val)); + } else if (!strcmp(arg, "dircache")) { + nfs_set_dircache(nfs, atoi(val)); + } else if (!strcmp(arg, "autoreconnect")) { + nfs_set_autoreconnect(nfs, atoi(val)); +#ifdef HAVE_SO_BINDTODEVICE + } else if (!strcmp(arg, "if")) { + nfs_set_interface(nfs, val); +#endif + } else if (!strcmp(arg, "version")) { + if (nfs_set_version(nfs, atoi(val)) < 0) { + nfs_set_error(nfs, "NFS version %d is not supported", + atoi(val)); + return -1; + } + } else if (!strcmp(arg, "nfsport")) { + nfs_set_nfsport(nfs, atoi(val)); + } else if (!strcmp(arg, "mountport")) { + nfs_set_mountport(nfs, atoi(val)); + } else if (!strcmp(arg, "rsize")) { + nfs_set_readmax(nfs, atoi(val)); + } else if (!strcmp(arg, "wsize")) { + nfs_set_writemax(nfs, atoi(val)); + } else if (!strcmp(arg, "readdir-buffer")) { + const char *strp = strchr(val, ','); + if (strp) { + strp++; + nfs_set_readdir_max_buffer_size(nfs, atoi(val), atoi(strp)); + } else { + nfs_set_readdir_max_buffer_size(nfs, atoi(val), atoi(val)); + } +#ifdef HAVE_TLS + } else if (nfs->rpc && !strcmp(arg, "xprtsec")) { + if (!strcmp(val, "none")) { + nfs_set_xprtsecurity(nfs, RPC_XPRTSEC_NONE); + } else if (!strcmp(val, "tls")) { + nfs_set_xprtsecurity(nfs, RPC_XPRTSEC_TLS); + } else if (!strcmp(val, "mtls")) { + nfs_set_xprtsecurity(nfs, RPC_XPRTSEC_MTLS); + } else { + nfs_set_error(nfs, "Unknown/unsupported xprtsec type : %s", val); + return -1; + } +#endif /* HAVE_TLS */ +#ifdef HAVE_LIBKRB5 + } else if (nfs->rpc && !strcmp(arg, "sec")) { + /* + * We switch to AUTH_GSS after the first call to NFS/NULL call. + */ + if (!strcmp(val, "krb5p")) { + nfs_set_security(nfs, RPC_SEC_KRB5P); + } else if (!strcmp(val, "krb5i")) { + nfs_set_security(nfs, RPC_SEC_KRB5I); + } else if (!strcmp(val, "krb5")) { + nfs_set_security(nfs, RPC_SEC_KRB5); + } else { + nfs_set_error(nfs, "Unknown/unsupported sec type : %s", + val); + return -1; + } +#endif + } else { + nfs_set_error(nfs, "Unknown url argument : %s", + arg); + return -1; + } + return 0; +} + +static int +tohex(char ch) +{ + if (ch >= '0' && ch <= '9') { + return ch - '0'; + } + ch &= 0xDF; + if (ch >= 'A' && ch <= 'F') { + return ch - 'A' + 10; + } + return -1; +} + +static struct nfs_url * +nfs_parse_url(struct nfs_context *nfs, const char *url, int dir, int incomplete) +{ + struct nfs_url *urls; + char *strp, *flagsp, *strp2, ch, *original_server, *port_str, *slash_pos, *end_ptr; + int tmp; + size_t port_len; + + if (strncmp(url, "nfs://", 6)) { + nfs_set_error(nfs, "Invalid URL specified"); + return NULL; + } + + urls = calloc(1, sizeof(struct nfs_url)); + if (urls == NULL) { + nfs_set_error(nfs, "Out of memory"); + return NULL; + } + + urls->server = strdup(url + 6); + if (urls->server == NULL) { + nfs_destroy_url(urls); + nfs_set_error(nfs, "Out of memory"); + return NULL; + } + + /* unescape all % hex hex characters */ + strp = urls->server; + while (strp && *strp) { + strp = strchr(strp, '%'); + if (strp == NULL) { + break; + } + tmp = tohex(strp[1]); + if (tmp < 0) { + strp++; + continue; + } + ch = (tmp & 0x0f) << 4; + tmp = tohex(strp[2]); + if (tmp < 0) { + strp++; + continue; + } + ch |= tmp & 0x0f; + *strp = ch; + memmove(strp + 1, strp + 3, strlen(strp + 3) + 1); + strp++; + } + + if (urls->server[0] == '/' || urls->server[0] == '\0' || + urls->server[0] == '?') { + if (incomplete) { + flagsp = strchr(urls->server, '?'); + goto flags; + } + nfs_destroy_url(urls); + nfs_set_error(nfs, "Invalid server string"); + return NULL; + } + + strp = strchr(urls->server, ':'); + if (strp) { + strp++; + slash_pos = strchr(strp, '/'); + port_len = slash_pos ? (size_t)(slash_pos - strp) : strlen(strp); + port_str = (char*)malloc(port_len + 1); + if (!port_str) + { + nfs_destroy_url(urls); + nfs_set_error(nfs, "Out of memory"); + return NULL; + } + strncpy(port_str, strp, port_len); + port_str[port_len] = '\0'; + int port_num = strtol(port_str, &end_ptr, 10); + if (end_ptr == port_str || port_num < 0 || port_num > 65535) + { + free(port_str); + nfs_destroy_url(urls); + nfs_set_error(nfs, "Invalid port number"); + return NULL; + } + nfs->nfsi->nfsport = port_num; + if (slash_pos == NULL) + { + *strp = '\0'; + } + else + { + memmove(strp - 1, slash_pos, strlen(slash_pos) + 1); + } + + free(port_str); + } + + if (strp == NULL) + strp = urls->server; + + strp = strchr(urls->server, '/'); + if (strp == NULL) { + if (incomplete) { + flagsp = strchr(urls->server, '?'); + goto flags; + } + nfs_destroy_url(urls); + nfs_set_error(nfs, "Incomplete or invalid URL specified."); + return NULL; + } + + urls->path = strdup(strp); + if (urls->path == NULL) { + nfs_destroy_url(urls); + nfs_set_error(nfs, "Out of memory"); + return NULL; + } + *strp = 0; + + if (dir) { + flagsp = strchr(urls->path, '?'); + goto flags; + } + + strp = strrchr(urls->path, '/'); + if (strp == NULL) { + if (incomplete) { + flagsp = strchr(urls->path, '?'); + goto flags; + } + nfs_destroy_url(urls); + nfs_set_error(nfs, "Incomplete or invalid URL specified."); + return NULL; + } + urls->file = strdup(strp); + if (urls->path == NULL) { + nfs_destroy_url(urls); + nfs_set_error(nfs, "Out of memory"); + return NULL; + } + *strp = 0; + flagsp = strchr(urls->file, '?'); + +flags: + if (flagsp) { + *flagsp = 0; + } + + if (urls->file && !strlen(urls->file)) { + free(urls->file); + urls->file = NULL; + if (!incomplete) { + nfs_destroy_url(urls); + nfs_set_error(nfs, "Incomplete or invalid URL " + "specified."); + return NULL; + } + } + + while (flagsp != NULL && *(flagsp+1) != 0) { + strp = flagsp + 1; + flagsp = strchr(strp, '&'); + if (flagsp) { + *flagsp = 0; + } + strp2 = strchr(strp, '='); + if (strp2) { + *strp2 = 0; + strp2++; + if (nfs_set_context_args(nfs, strp, strp2) != 0) { + nfs_destroy_url(urls); + return NULL; + } + } else { + if (nfs_set_context_args_no_val(nfs, strp) != 0) { + nfs_destroy_url(urls); + return NULL; + } + } + } + + strp =strchr(urls->server, '@'); + if (strp && nfs->rpc) { + *strp++ = '\0'; + if (rpc_set_username(nfs->rpc, urls->server) != 0) { + nfs_destroy_url(urls); + return NULL; + } + original_server = urls->server; + urls->server = strdup(strp); + if (urls->server == NULL) { + urls->server = original_server; + nfs_destroy_url(urls); + rpc_set_error(nfs->rpc, + "Out of memory: Failed to allocate " + "server name"); + return NULL; + } + free(original_server); + } + if (urls->server && strlen(urls->server) <= 1) { + free(urls->server); + urls->server = NULL; + } + + urls->port = nfs->nfsi->nfsport; + if (nfs->nfsi->mountport) + urls->port = nfs->nfsi->mountport; + +#ifdef HAVE_TLS + /* + * Call this in the end after all options are processed, as it uses + * rpc->debug. + */ + if (nfs->rpc->wanted_xprtsec == RPC_XPRTSEC_TLS || + nfs->rpc->wanted_xprtsec == RPC_XPRTSEC_MTLS) { + /* tls_global_init() MUST succeed for us to use TLS security */ + if (tls_global_init(nfs->rpc) != 0) { + nfs_set_error(nfs, "tls_global_init() failed!"); + nfs_destroy_url(urls); + return NULL; + } + } +#endif + + return urls; +} + +struct nfs_url * +nfs_parse_url_full(struct nfs_context *nfs, const char *url) +{ + return nfs_parse_url(nfs, url, 0, 0); +} + +struct nfs_url * +nfs_parse_url_dir(struct nfs_context *nfs, const char *url) +{ + return nfs_parse_url(nfs, url, 1, 0); +} + +struct nfs_url * +nfs_parse_url_incomplete(struct nfs_context *nfs, const char *url) +{ + return nfs_parse_url(nfs, url, 0, 1); +} + + +void +nfs_destroy_url(struct nfs_url *url) +{ + if (url) { + free(url->server); + free(url->path); + free(url->file); + } + free(url); +} + +#define MAX_CLIENT_NAME 64 + +struct nfs_context * +nfs_init_context(void) +{ + struct nfs_context *nfs; + struct nfs_context_internal *nfsi; +#ifdef HAVE_LIBKRB5 + char *login; +#if defined(HAVE_PWD_H) && defined(HAVE_UNISTD_H) + struct passwd *euid_passwd; +#endif +#endif + int i; + uint64_t v; + verifier4 verifier; + char client_name[MAX_CLIENT_NAME]; + + nfsi = calloc(1, sizeof(struct nfs_context_internal)); + if (nfsi == NULL) { + return NULL; + } + + nfs = calloc(1, sizeof(struct nfs_context)); + if (nfs == NULL) { + free(nfsi); + return NULL; + } + + nfs->nfsi = nfsi; + nfs->rpc = rpc_init_context(); + if (nfs->rpc == NULL) { + free(nfs->nfsi); + free(nfs); + return NULL; + } +#ifdef HAVE_LIBKRB5 + login = getenv("USER"); +#if defined(HAVE_PWD_H) && defined(HAVE_UNISTD_H) + if (login == NULL) { + euid_passwd = getpwuid(geteuid()); + if (euid_passwd) { + login = euid_passwd->pw_name; + } + } +#endif + rpc_set_username(nfs->rpc, login ? login : ""); +#endif + nfs->nfsi->cwd = strdup("/"); + nfs->nfsi->mask = 022; + nfs->nfsi->auto_traverse_mounts = 1; + nfs->nfsi->dircache_enabled = 1; + + /* + * Default resiliency parameters are chosen with safe values that + * emulate "hard" mount, which means on any error (RPC or TCP) keep + * retrying indefinitely. + * + * TCP reconnect is indefinitely tried, RPC requests time out after + * 60 secs and we retry an RPC request 2 times before declaring it as + * "major timeout" and running the major timeout recovery workflow, + * after which the whole RPC retransmit cycle restarts and this continues + * indefinitely. + */ + nfs->nfsi->auto_reconnect = -1; + nfs->nfsi->timeout = 60*1000; + nfs->nfsi->retrans = 2; + + nfs->nfsi->default_version = NFS_V3; + nfs->nfsi->version = NFS_V3; + nfs->nfsi->readmax = NFS_DEF_XFER_SIZE; + nfs->nfsi->writemax = NFS_DEF_XFER_SIZE; + nfs->nfsi->readdir_dircount = 8192; + nfs->nfsi->readdir_maxcount = 8192; + + /* NFSv4 parameters */ + /* We need a "random" initial verifier */ + v = rpc_current_time() << 32 | getpid(); + for (i = 0; i < NFS4_VERIFIER_SIZE; i++) { + verifier[i] = v & 0xff; + v >>= 8; + } + nfs4_set_verifier(nfs, verifier); + + snprintf(client_name, MAX_CLIENT_NAME, "Libnfs pid:%d %d", getpid(), + (int)time(NULL)); + nfs4_set_client_name(nfs, client_name); + +#ifdef HAVE_MULTITHREADING + nfs_mt_mutex_init(&nfs->nfsi->nfs_mutex); + nfs_mt_mutex_init(&nfs->nfsi->nfs4_open_counter_mutex); + nfs_mt_mutex_init(&nfs->nfsi->nfs4_open_call_mutex); +#endif /* HAVE_MULTITHREADING */ + +#ifdef HAVE_SIGNAL_H +#if !defined(WIN32) + /* + * Ignore SIGPIPE when writing to sockets where peer decides to close + * the door on us, rather write()/dup2() should fail with EPIPE which + * we can gracefully handle. + */ + if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) { + nfs_destroy_context(nfs); + return NULL; + } +#endif /* WIN32 */ +#endif /* HAVE_SIGNAL_H */ + return nfs; +} + +void +nfs4_set_client_name(struct nfs_context *nfs, const char *client_name) +{ + free(nfs->nfsi->client_name); + nfs->nfsi->client_name = strdup(client_name); +} + +void +nfs4_set_verifier(struct nfs_context *nfs, const char *verifier) +{ + memcpy(nfs->nfsi->verifier, verifier, NFS4_VERIFIER_SIZE); +} + +void +nfs_destroy_context(struct nfs_context *nfs) +{ + while (nfs->nfsi->nested_mounts) { + struct nested_mounts *mnt = nfs->nfsi->nested_mounts; + + LIBNFS_LIST_REMOVE(&nfs->nfsi->nested_mounts, mnt); + free(mnt->path); + free(mnt->fh.val); + free(mnt); + } + + rpc_destroy_context(nfs->rpc); + nfs->rpc = NULL; + + if (nfs->error_string && nfs->error_string != oom) { + free(nfs->error_string); + nfs->error_string = NULL; + } + + free(nfs->nfsi->server); + free(nfs->nfsi->export); + free(nfs->nfsi->cwd); + free(nfs->nfsi->rootfh.val); + free(nfs->nfsi->client_name); + while (nfs->nfsi->dircache) { + struct nfsdir *nfsdir = nfs->nfsi->dircache; + LIBNFS_LIST_REMOVE(&nfs->nfsi->dircache, nfsdir); + nfs_free_nfsdir(nfsdir); + } + +#ifdef HAVE_MULTITHREADING + nfs_mt_mutex_destroy(&nfs->nfsi->nfs4_open_call_mutex); + nfs_mt_mutex_destroy(&nfs->nfsi->nfs4_open_counter_mutex); + nfs_mt_mutex_destroy(&nfs->nfsi->nfs_mutex); + while (nfs->nfsi->thread_ctx) { + struct nfs_thread_context *tmp = nfs->nfsi->thread_ctx->next; + free(nfs->nfsi->thread_ctx->nfs.error_string); + free(nfs->nfsi->thread_ctx); + nfs->nfsi->thread_ctx = tmp; + } +#endif /* HAVE_MULTITHREADING */ + free(nfs->nfsi); + free(nfs); +} + +struct rpc_cb_data { + char *server; + uint32_t program; + uint32_t version; + + rpc_cb cb; + void *private_data; +}; + +void free_rpc_cb_data(struct rpc_cb_data *data) +{ + free(data->server); + data->server = NULL; + free(data); +} + +static int +rpc_connect_port_internal(struct rpc_context *rpc, int port, struct rpc_cb_data *data); + +#ifdef HAVE_LIBKRB5 +struct rpc_pdu * +rpc_null_task_gss(struct rpc_context *rpc, int program, int version, + rpc_gss_init_arg *arg, + rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, program, version, 0, cb, private_data, + (zdrproc_t)zdr_rpc_gss_init_res, sizeof(struct rpc_gss_init_res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu " + "for NULL call"); + return NULL; + } + + /* add the krb5 blob */ + if (zdr_rpc_gss_init_arg(&pdu->zdr, arg) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode blob"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu " + "for NULL call"); + return NULL; + } + + return pdu; +} + +static void +rpc_connect_program_6_cb(struct rpc_context *rpc, int status, + void *command_data, void *private_data) +{ + struct rpc_cb_data *data = private_data; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (status != RPC_STATUS_SUCCESS) { + data->cb(rpc, status, command_data, data->private_data); + free_rpc_cb_data(data); + return; + } + + data->cb(rpc, status, NULL, data->private_data); + free_rpc_cb_data(data); +} +#endif /* HAVE_LIBKRB5 */ + +#ifdef HAVE_TLS +void free_tls_cb_data(struct tls_cb_data *data) +{ + free(data); +} + +/* + * Callback function called when we get a response for an AUTH_TLS NULL RPC + * that we sent to the server. + * On a successful response confirming server support for TLS, this will + * initiate an async TLS handshake process. + */ +static void +rpc_connect_program_4_1_cb(struct rpc_context *rpc, int status, + void *command_data, void *private_data) +{ + struct tls_cb_data *data = private_data; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + RPC_LOG(rpc, 2, "Got AUTH_TLS response, status=%d", status); + + if (status != RPC_STATUS_SUCCESS) { + data->cb(rpc, status, command_data, data->private_data); + free_tls_cb_data(data); + return; + } + + /* + * Ok, server supports RPC-with-TLS, start handshake. + */ + rpc->tls_context.data = *data; + free_tls_cb_data(data); + data = &rpc->tls_context.data; + + rpc->tls_context.state = do_tls_handshake(rpc); + + switch (rpc->tls_context.state) { + case TLS_HANDSHAKE_IN_PROGRESS: + /* + * We will continue this asynchronously in rpc_service(), as we + * hear from the peer. + */ + return; + case TLS_HANDSHAKE_COMPLETED: + RPC_LOG(rpc, 2, "do_tls_handshake: TLS handshake completed " + "synchronously on fd %d", rpc->fd); + data->cb(rpc, RPC_STATUS_SUCCESS, NULL, data->private_data); + break; + case TLS_HANDSHAKE_FAILED: + RPC_LOG(rpc, 2, "do_tls_handshake: Failed to start TLS handshake, or " + "TLS handshake failed synchronously on fd %d", rpc->fd); + data->cb(rpc, RPC_STATUS_ERROR, rpc_get_error(rpc), data->private_data); + break; + default: + /* Should not return any other status */ + assert(0); + } +} +#endif /* HAVE_TLS */ + +static void +rpc_connect_program_5_cb(struct rpc_context *rpc, int status, + void *command_data, void *private_data) +{ + struct rpc_cb_data *data = private_data; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + /* Dont want any more callbacks even if the socket is closed */ + rpc->connect_cb = NULL; + + if (status != RPC_STATUS_SUCCESS) { + data->cb(rpc, status, command_data, data->private_data); + free_rpc_cb_data(data); + return; + } + +#ifdef HAVE_LIBKRB5 + if (data->program == 100003 && rpc->wanted_sec != RPC_SEC_UNDEFINED && rpc->username) { + rpc_gss_init_arg gia; + + rpc->sec = rpc->wanted_sec; + + libnfs_authgss_init(rpc); + rpc->auth_data = krb5_auth_init(rpc, + data->server, + rpc->username, + rpc->wanted_sec); + if (rpc->auth_data == NULL) { + data->cb(rpc, RPC_STATUS_ERROR, rpc_get_error(rpc), + data->private_data); + free_rpc_cb_data(data); + return; + } + + if (krb5_auth_request(rpc, rpc->auth_data, + NULL, 0) < 0) { + data->cb(rpc, RPC_STATUS_ERROR, rpc_get_error(rpc), + data->private_data); + free_rpc_cb_data(data); + return; + } + + + gia.gss_token.gss_token_len = krb5_get_output_token_length(rpc->auth_data); + gia.gss_token.gss_token_val = (char *)krb5_get_output_token_buffer(rpc->auth_data); + if (rpc_null_task_gss(rpc, data->program, data->version, + &gia, + rpc_connect_program_6_cb, data) == NULL) { + data->cb(rpc, RPC_STATUS_ERROR, command_data, data->private_data); + free_rpc_cb_data(data); + return; + } + return; + } +#endif + data->cb(rpc, status, NULL, data->private_data); + free_rpc_cb_data(data); +} + +static void +rpc_connect_program_4_cb(struct rpc_context *rpc, int status, + void *command_data, void *private_data) +{ + struct rpc_cb_data *data = private_data; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + /* Dont want any more callbacks even if the socket is closed */ + rpc->connect_cb = NULL; + + if (status != RPC_STATUS_SUCCESS) { + data->cb(rpc, status, command_data, data->private_data); + free_rpc_cb_data(data); + return; + } + +#ifdef HAVE_TLS + /* + * Connected to RPC endpoint, for NFS connections see if we need to secure them. + * If yes, we query the server TLS support by sending a NULL RPC with auth flavor + * AUTH_TLS and if server supports RPC-with-TLS we initiate the TLS handshake. + */ + rpc->use_tls = (data->program == NFS_PROGRAM) && + (rpc->wanted_xprtsec == RPC_XPRTSEC_TLS || + rpc->wanted_xprtsec == RPC_XPRTSEC_MTLS); + if (rpc->use_tls) { + /* We should not use TLS for anything other than NFS */ + assert(data->program == NFS_PROGRAM); + + if (rpc_null_task_authtls(rpc, data->version, + rpc_connect_program_5_cb, data) == NULL) { + data->cb(rpc, RPC_STATUS_ERROR, command_data, data->private_data); + free_rpc_cb_data(data); + return; + } + } else +#endif + if (rpc_null_task(rpc, data->program, data->version, + rpc_connect_program_5_cb, data) == NULL) { + data->cb(rpc, RPC_STATUS_ERROR, command_data, data->private_data); + free_rpc_cb_data(data); + return; + } +} + +static void +rpc_connect_program_3_cb(struct rpc_context *rpc, int status, + void *command_data, void *private_data) +{ + struct rpc_cb_data *data = private_data; + struct pmap3_string_result *gar; + uint32_t rpc_port = 0; + char *ptr; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (status != RPC_STATUS_SUCCESS) { + data->cb(rpc, status, command_data, data->private_data); + free_rpc_cb_data(data); + return; + } + + switch (rpc->s.ss_family) { + case AF_INET: + rpc_port = *(uint32_t *)(void *)command_data; + break; + case AF_INET6: + /* ouch. portmapper and ipv6 are not great */ + gar = command_data; + if (gar->addr == NULL) { + break; + } + ptr = strrchr(gar->addr, '.'); + if (ptr == NULL) { + break; + } + rpc_port = atoi(ptr + 1); + *ptr = 0; + ptr = strrchr(gar->addr, '.'); + if (ptr == NULL) { + break; + } + rpc_port += 256 * atoi(ptr + 1); + break; + } + if (rpc_port == 0) { + rpc_set_error(rpc, "RPC error. Program is not available on %s", + data->server); + data->cb(rpc, RPC_STATUS_ERROR, rpc_get_error(rpc), + data->private_data); + free_rpc_cb_data(data); + return; + } + + rpc_disconnect(rpc, "normal disconnect"); + rpc->program = data->program; + rpc->version = data->version; + + if (rpc_connect_port_internal(rpc, rpc_port, data)) { + data->cb(rpc, RPC_STATUS_ERROR, command_data, + data->private_data); + free_rpc_cb_data(data); + return; + } +} + +static void +rpc_connect_program_2_cb(struct rpc_context *rpc, int status, + void *command_data, void *private_data) +{ + struct rpc_cb_data *data = private_data; + struct pmap3_mapping map; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (status != RPC_STATUS_SUCCESS) { + data->cb(rpc, status, command_data, data->private_data); + free_rpc_cb_data(data); + return; + } + + switch (rpc->s.ss_family) { + case AF_INET: + if (rpc_pmap2_getport_task(rpc, data->program, data->version, + IPPROTO_TCP, + rpc_connect_program_3_cb, + private_data) == NULL) { + data->cb(rpc, RPC_STATUS_ERROR, command_data, data->private_data); + free_rpc_cb_data(data); + return; + } + break; + case AF_INET6: + map.prog=data->program; + map.vers=data->version; + map.netid=""; + map.addr=""; + map.owner=""; + if (rpc_pmap3_getaddr_task(rpc, &map, + rpc_connect_program_3_cb, + private_data) == NULL) { + data->cb(rpc, RPC_STATUS_ERROR, command_data, data->private_data); + free_rpc_cb_data(data); + return; + } + break; + } +} + +static void +rpc_connect_program_1_cb(struct rpc_context *rpc, int status, + void *command_data, void *private_data) +{ + struct rpc_cb_data *data = private_data; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + /* Dont want any more callbacks even if the socket is closed */ + rpc->connect_cb = NULL; + + if (status != RPC_STATUS_SUCCESS) { + data->cb(rpc, status, command_data, data->private_data); + free_rpc_cb_data(data); + return; + } + + switch (rpc->s.ss_family) { + case AF_INET: + if (rpc_pmap2_null_task(rpc, rpc_connect_program_2_cb, + data) == NULL) { + data->cb(rpc, RPC_STATUS_ERROR, command_data, data->private_data); + free_rpc_cb_data(data); + return; + } + break; + case AF_INET6: + if (rpc_pmap3_null_task(rpc, rpc_connect_program_2_cb, + data) == NULL) { + data->cb(rpc, RPC_STATUS_ERROR, command_data, data->private_data); + free_rpc_cb_data(data); + return; + } + break; + } +} + +static int +rpc_connect_port_internal(struct rpc_context *rpc, int port, struct rpc_cb_data *data) +{ + if (rpc_connect_async(rpc, data->server, port, + rpc_connect_program_4_cb, data) != 0) { + return -1; + } + + return 0; +} + +int +rpc_connect_port_async(struct rpc_context *rpc, const char *server, + int port, + int program, int version, + rpc_cb cb, void *private_data) +{ + struct rpc_cb_data *data; + + rpc->program = program; + rpc->version = version; + + data = calloc(1, sizeof(struct rpc_cb_data)); + if (data == NULL) { + return -1; + } + data->server = strdup(server); + data->program = program; + data->version = version; + + data->cb = cb; + data->private_data = private_data; + + if (rpc_connect_port_internal(rpc, port, data)) { + rpc_set_error(rpc, "Failed to start connection. %s", + rpc_get_error(rpc)); + free_rpc_cb_data(data); + return -1; + } + return 0; +} + +int +rpc_connect_program_async(struct rpc_context *rpc, const char *server, + int program, int version, + rpc_cb cb, void *private_data) +{ + struct rpc_cb_data *data; + + data = calloc(1, sizeof(struct rpc_cb_data)); + if (data == NULL) { + return -1; + } + data->server = strdup(server); + data->program = program; + data->version = version; + + data->cb = cb; + data->private_data = private_data; + + rpc->program = 100001; + rpc->version = 2; + + if (rpc_connect_async(rpc, server, 111, rpc_connect_program_1_cb, + data) != 0) { + rpc_set_error(rpc, "Failed to start connection. %s", + rpc_get_error(rpc)); + free_rpc_cb_data(data); + return -1; + } + return 0; +} + +void +free_nfs_cb_data(struct nfs_cb_data *data) +{ + if (data->continue_data && data->free_continue_data) { + data->free_continue_data(data->continue_data); + } + + free(data->saved_path); + free(data->fh.val); + if (!data->not_my_buffer) { + free(data->buffer); + } + + free(data); +} + +void +nfs_free_nfsfh(struct nfsfh *nfsfh) +{ + if (nfsfh->fh.val != NULL) { + free(nfsfh->fh.val); + nfsfh->fh.len = 0; + nfsfh->fh.val = NULL; + } + free(nfsfh); +} + +/* + * Async call for mounting an nfs share and geting the root filehandle + */ +int +_nfs_mount_async(struct nfs_context *nfs, const char *server, + const char *export, nfs_cb cb, void *private_data) +{ + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_mount_async(nfs, server, export, cb, private_data); + case NFS_V4: + return nfs4_mount_async(nfs, server, export, cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} +int +nfs_mount_async(struct nfs_context *nfs, const char *server, + const char *export, nfs_cb cb, void *private_data) +{ + return _nfs_mount_async(nfs, server, + export, cb, private_data); +} + +/* + * Async call for umounting an nfs share + */ +int +nfs_umount_async(struct nfs_context *nfs, nfs_cb cb, void *private_data) +{ + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_umount_async(nfs, cb, private_data); + case NFS_V4: + /* umount is a no-op in v4 */ + (*cb)(0, nfs, NULL, private_data); + return 0; + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_normalize_path(struct nfs_context *nfs, char *path) +{ + char *str; + size_t len; + + /* // -> / */ + while ((str = strstr(path, "//"))) { + while(*str) { + *str = *(str + 1); + str++; + } + } + + /* /./ -> / */ + while ((str = strstr(path, "/./"))) { + while(*(str + 1)) { + *str = *(str + 2); + str++; + } + } + + /* ^/../ -> error */ + if (!strncmp(path, "/../", 4)) { + nfs_set_error(nfs, + "Absolute path starts with '/../' " + "during normalization"); + return -1; + } + + /* ^[^/] -> error */ + if (path[0] != '/') { + nfs_set_error(nfs, + "Absolute path does not start with '/'"); + return -1; + } + + /* /string/../ -> / */ + while ((str = strstr(path, "/../"))) { + char *tmp; + + if (!strncmp(path, "/../", 4)) { + nfs_set_error(nfs, + "Absolute path starts with '/../' " + "during normalization"); + return -1; + } + + tmp = str - 1; + while (*tmp != '/') { + tmp--; + } + str += 3; + while((*(tmp++) = *(str++)) != '\0') + ; + } + + /* /$ -> \0 */ + len = strlen(path); + if (len > 1) { + if (path[len - 1] == '/') { + path[len - 1] = '\0'; + len--; + } + } + if (path[0] == '\0') { + nfs_set_error(nfs, + "Absolute path became '' " + "during normalization"); + return -1; + } + + /* /.$ -> \0 */ + if (len >= 2) { + if (!strcmp(&path[len - 2], "/.")) { + path[len - 2] = '\0'; + len -= 2; + } + } + + /* ^/..$ -> error */ + if (!strcmp(path, "/..")) { + nfs_set_error(nfs, + "Absolute path is '/..' " + "during normalization"); + return -1; + } + + /* /string/..$ -> / */ + if (len >= 3) { + if (!strcmp(&path[len - 3], "/..")) { + char *tmp = &path[len - 3]; + while (*--tmp != '/') + ; + *tmp = '\0'; + } + } + + return 0; +} + +int +nfs_stat_async(struct nfs_context *nfs, const char *path, + nfs_cb cb, void *private_data) +{ + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_stat_async(nfs, path, cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv4", + __FUNCTION__); + return -1; + } +} + +int +nfs_stat64_async(struct nfs_context *nfs, const char *path, + nfs_cb cb, void *private_data) +{ + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_stat64_async(nfs, path, 0, + cb, private_data); + case NFS_V4: + return nfs4_stat64_async(nfs, path, 0, + cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_lstat64_async(struct nfs_context *nfs, const char *path, + nfs_cb cb, void *private_data) +{ + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_stat64_async(nfs, path, 1, + cb, private_data); + case NFS_V4: + return nfs4_stat64_async(nfs, path, 1, + cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_open2_async(struct nfs_context *nfs, const char *path, int flags, + int mode, nfs_cb cb, void *private_data) +{ + if (nfs->nfsi->readonly && (flags & (O_WRONLY|O_RDWR|O_APPEND|O_CREAT|O_TRUNC))) { + nfs_set_error(nfs, "EROFS. Readonly mount"); + cb(-EROFS, nfs, NULL, private_data); + return 0; + } + + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_open_async(nfs, path, flags, mode, + cb, private_data); + case NFS_V4: + return nfs4_open_async(nfs, path, flags, mode, + cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_open_async(struct nfs_context *nfs, const char *path, int flags, + nfs_cb cb, void *private_data) +{ + return nfs_open2_async(nfs, path, flags, 0666 & ~nfs->nfsi->mask, + cb, private_data); +} + +int +nfs_chdir_async(struct nfs_context *nfs, const char *path, + nfs_cb cb, void *private_data) +{ + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_chdir_async(nfs, path, cb, private_data); + case NFS_V4: + return nfs4_chdir_async(nfs, path, cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +static int +__nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + void *buf, size_t count, uint64_t offset, + nfs_cb cb, void *private_data, int update_pos) +{ + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_pread_async_internal(nfs, nfsfh, + buf, count, offset, + cb, private_data, update_pos); + case NFS_V4: + return nfs4_pread_async_internal(nfs, nfsfh, + buf, count, offset, + cb, private_data, update_pos); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +struct rw_data { + struct nfsfh *nfsfh; + int update_pos; + uint8_t *buf; + size_t count; + size_t remaining; + uint64_t offset; + nfs_cb cb; + void *private_data; +}; + +static void r_cb(int status, struct nfs_context *nfs, + void *data, void *private_data) +{ + struct rw_data *rw_data = private_data; + size_t cnt; + + if (status < 0) { + nfs_set_error(nfs, "%s multi pread failed with %d", + __FUNCTION__, status); + rw_data->cb(status, nfs, NULL, rw_data->private_data); + free(rw_data); + return; + } + + if (status > rw_data->remaining) { + status = rw_data->remaining; + } + rw_data->buf += status; + rw_data->offset += status; + rw_data->remaining -= status; + /* + * Read until we have all the data or the server retruned a short read (eof?) + */ + if (rw_data->remaining == 0 || status < nfs_get_readmax(nfs)) { + rw_data->cb(rw_data->count - rw_data->remaining, nfs, NULL, rw_data->private_data); + free(rw_data); + return; + } + cnt = rw_data->remaining; + if (nfs_get_readmax(nfs) && cnt > nfs_get_readmax(nfs)) { + cnt = nfs_get_readmax(nfs); + } + if (__nfs_pread_async(nfs, rw_data->nfsfh, rw_data->buf, cnt, rw_data->offset, r_cb, rw_data, rw_data->update_pos)) { + nfs_set_error(nfs, "%s multi pread failed with ENOMEM", + __FUNCTION__); + rw_data->cb(-ENOMEM, nfs, NULL, rw_data->private_data); + free(rw_data); + return; + } +} + + +static int +_nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + void *buf, size_t count, uint64_t offset, + nfs_cb cb, void *private_data, int update_pos) +{ + struct rw_data *rw_data; + size_t cnt; + + + if (count < nfs_get_readmax(nfs)) { + return __nfs_pread_async(nfs, nfsfh, buf, count, offset, cb, private_data, update_pos); + } + + rw_data = malloc(sizeof(struct rw_data)); + if (rw_data == NULL) { + return -ENOMEM; + } + rw_data->update_pos = 0; + rw_data->nfsfh = nfsfh; + rw_data->buf = buf; + rw_data->count = count; + rw_data->remaining = count; + rw_data->offset = offset; + rw_data->cb = cb; + rw_data->private_data = private_data; + + cnt = count; + if (nfs_get_readmax(nfs) && cnt > nfs_get_readmax(nfs)) { + cnt = nfs_get_readmax(nfs); + } + return __nfs_pread_async(nfs, rw_data->nfsfh, rw_data->buf, cnt, rw_data->offset, r_cb, rw_data, rw_data->update_pos); +} + +int +nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + void *buf, size_t count, uint64_t offset, + nfs_cb cb, void *private_data) +{ + return _nfs_pread_async(nfs, nfsfh, buf, count, offset, cb, private_data, 0); +} + +int +nfs_read_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + void *buf, size_t count, + nfs_cb cb, void *private_data) +{ + return _nfs_pread_async(nfs, nfsfh, buf, count, nfsfh->offset, cb, private_data, 1); +} + +int +nfs_preadv_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + const struct iovec *iov, int iovcnt, uint64_t offset, + nfs_cb cb, void *private_data) +{ + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_preadv_async_internal(nfs, nfsfh, + iov, iovcnt, offset, + cb, private_data, 0); + case NFS_V4: + return nfs4_preadv_async_internal(nfs, nfsfh, + iov, iovcnt, offset, + cb, private_data, 0); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_readv_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + const struct iovec *iov, int iovcnt, + nfs_cb cb, void *private_data) +{ + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_preadv_async_internal(nfs, nfsfh, + iov, iovcnt, nfsfh->offset, + cb, private_data, 1); + case NFS_V4: + return nfs4_preadv_async_internal(nfs, nfsfh, + iov, iovcnt, nfsfh->offset, + cb, private_data, 1); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_pwrite_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + const void *buf, size_t count, uint64_t offset, + nfs_cb cb, void *private_data) +{ + if (nfsfh->is_readonly) { + nfs_set_error(nfs, "Trying to write to read-only file"); + return -1; + } + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_pwrite_async_internal(nfs, nfsfh, + buf, count, offset, + cb, private_data, 0); + case NFS_V4: + return nfs4_pwrite_async_internal(nfs, nfsfh, + buf, count, offset, + cb, private_data, 0); + default: + nfs_set_error(nfs, "%s does not support NFSv%d.", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_write_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + const void *buf, size_t count, + nfs_cb cb, void *private_data) +{ + if (nfsfh->is_readonly) { + nfs_set_error(nfs, "Trying to write to read-only file"); + return -1; + } + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_write_async(nfs, nfsfh, + buf, count, + cb, private_data); + case NFS_V4: + //qqq + return nfs4_write_async(nfs, nfsfh, count, buf, + cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_close_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, + void *private_data) +{ + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_close_async(nfs, nfsfh, cb, private_data); + case NFS_V4: + return nfs4_close_async(nfs, nfsfh, cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_fstat_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, + void *private_data) +{ + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_fstat_async(nfs, nfsfh, cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv4", + __FUNCTION__); + return -1; + } +} + +int +nfs_fstat64_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, + void *private_data) +{ + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_fstat64_async(nfs, nfsfh, cb, private_data); + case NFS_V4: + return nfs4_fstat64_async(nfs, nfsfh, cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_fsync_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, + void *private_data) +{ + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_fsync_async(nfs, nfsfh, cb, private_data); + case NFS_V4: + return nfs4_fsync_async(nfs, nfsfh, cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_ftruncate_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + uint64_t length, nfs_cb cb, void *private_data) +{ + if (nfsfh->is_readonly) { + nfs_set_error(nfs, "Trying to truncate to read-only file"); + return -1; + } + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_ftruncate_async(nfs, nfsfh, length, + cb, private_data); + case NFS_V4: + return nfs4_ftruncate_async(nfs, nfsfh, length, + cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_truncate_async(struct nfs_context *nfs, const char *path, uint64_t length, + nfs_cb cb, void *private_data) +{ + if (nfs->nfsi->readonly) { + nfs_set_error(nfs, "EROFS. Readonly mount"); + cb(-EROFS, nfs, NULL, private_data); + return 0; + } + + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_truncate_async(nfs, path, length, cb, private_data); + case NFS_V4: + return nfs4_truncate_async(nfs, path, length, cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_mkdir2_async(struct nfs_context *nfs, const char *path, int mode, + nfs_cb cb, void *private_data) +{ + if (nfs->nfsi->readonly) { + nfs_set_error(nfs, "EROFS. Readonly mount"); + cb(-EROFS, nfs, NULL, private_data); + return 0; + } + + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_mkdir2_async(nfs, path, mode, cb, private_data); + case NFS_V4: + return nfs4_mkdir2_async(nfs, path, mode, cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_mkdir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data) +{ + return nfs_mkdir2_async(nfs, path, 0755, cb, private_data); +} + +int +nfs_rmdir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data) +{ + if (nfs->nfsi->readonly) { + nfs_set_error(nfs, "EROFS. Readonly mount"); + cb(-EROFS, nfs, NULL, private_data); + return 0; + } + + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_rmdir_async(nfs, path, cb, private_data); + case NFS_V4: + return nfs4_rmdir_async(nfs, path, cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_creat_async(struct nfs_context *nfs, const char *path, + int mode, nfs_cb cb, void *private_data) +{ + if (nfs->nfsi->readonly) { + nfs_set_error(nfs, "EROFS. Readonly mount"); + cb(-EROFS, nfs, NULL, private_data); + return 0; + } + + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_creat_async(nfs, path, mode, + cb, private_data); + case NFS_V4: + return nfs4_creat_async(nfs, path, mode, + cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_unlink_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data) +{ + if (nfs->nfsi->readonly) { + nfs_set_error(nfs, "EROFS. Readonly mount"); + cb(-EROFS, nfs, NULL, private_data); + return 0; + } + + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_unlink_async(nfs, path, cb, private_data); + case NFS_V4: + return nfs4_unlink_async(nfs, path, cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_mknod_async(struct nfs_context *nfs, const char *path, int mode, int dev, + nfs_cb cb, void *private_data) +{ + if (nfs->nfsi->readonly) { + nfs_set_error(nfs, "EROFS. Readonly mount"); + cb(-EROFS, nfs, NULL, private_data); + return 0; + } + + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_mknod_async(nfs, path, mode, dev, cb, private_data); + case NFS_V4: + return nfs4_mknod_async(nfs, path, mode, dev, cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_opendir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data) +{ + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_opendir_async(nfs, path, cb, private_data); + case NFS_V4: + return nfs4_opendir_async(nfs, path, cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv4", + __FUNCTION__); + return -1; + } +} + +struct nfsdirent * +nfs_readdir(struct nfs_context *nfs _U_, struct nfsdir *nfsdir) +{ + struct nfsdirent *nfsdirent = nfsdir->current; + + if (nfsdir->current != NULL) { + nfsdir->current = nfsdir->current->next; + } + return nfsdirent; +} + +long +nfs_telldir(struct nfs_context *nfs _U_, struct nfsdir *nfsdir) +{ + long i; + struct nfsdirent *tmp; + + for (i = 0, tmp = nfsdir->entries; tmp; i++, tmp = tmp->next) { + if (tmp == nfsdir->current) { + return i; + } + } + return -1; +} + +void +nfs_seekdir(struct nfs_context *nfs _U_, struct nfsdir *nfsdir, long loc) +{ + if (loc < 0) { + return; + } + for (nfsdir->current = nfsdir->entries; + nfsdir->current && loc--; + nfsdir->current = nfsdir->current->next) { + } +} + +void +nfs_rewinddir(struct nfs_context *nfs _U_, struct nfsdir *nfsdir) +{ + nfsdir->current = nfsdir->entries; +} + +void +nfs_closedir(struct nfs_context *nfs, struct nfsdir *nfsdir) +{ + if (nfs && nfs->nfsi->dircache_enabled) { + nfs_dircache_add(nfs, nfsdir); + } else { + nfs_free_nfsdir(nfsdir); + } +} + +void +nfs_getcwd(struct nfs_context *nfs, const char **cwd) +{ + if (cwd) { + *cwd = nfs->nfsi->cwd; + } +} + +int +nfs_lseek_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int64_t offset, + int whence, nfs_cb cb, void *private_data) +{ + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_lseek_async(nfs, nfsfh, offset, whence, + cb, private_data); + case NFS_V4: + return nfs4_lseek_async(nfs, nfsfh, offset, whence, + cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_lockf_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + enum nfs4_lock_op op, uint64_t count, + nfs_cb cb, void *private_data) +{ + switch (nfs->nfsi->version) { + case NFS_V4: + return nfs4_lockf_async(nfs, nfsfh, op, count, + cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_fcntl_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + enum nfs4_fcntl_op cmd, void *arg, + nfs_cb cb, void *private_data) +{ + switch (nfs->nfsi->version) { + case NFS_V4: + return nfs4_fcntl_async(nfs, nfsfh, cmd, arg, + cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_statvfs_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data) +{ + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_statvfs_async(nfs, path, cb, private_data); + case NFS_V4: + return nfs4_statvfs_async(nfs, path, cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_statvfs64_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data) +{ + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_statvfs64_async(nfs, path, cb, private_data); + case NFS_V4: + return nfs4_statvfs64_async(nfs, path, cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_readlink_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data) +{ + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_readlink_async(nfs, path, cb, private_data); + case NFS_V4: + return nfs4_readlink_async(nfs, path, cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_chmod_async(struct nfs_context *nfs, const char *path, int mode, + nfs_cb cb, void *private_data) +{ + if (nfs->nfsi->readonly) { + nfs_set_error(nfs, "EROFS. Readonly mount"); + cb(-EROFS, nfs, NULL, private_data); + return 0; + } + + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_chmod_async_internal(nfs, path, 0, mode, + cb, private_data); + case NFS_V4: + return nfs4_chmod_async_internal(nfs, path, 0, mode, + cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_lchmod_async(struct nfs_context *nfs, const char *path, int mode, + nfs_cb cb, void *private_data) +{ + if (nfs->nfsi->readonly) { + nfs_set_error(nfs, "EROFS. Readonly mount"); + cb(-EROFS, nfs, NULL, private_data); + return 0; + } + + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_chmod_async_internal(nfs, path, 1, mode, + cb, private_data); + case NFS_V4: + return nfs4_chmod_async_internal(nfs, path, 1, mode, + cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_fchmod_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int mode, + nfs_cb cb, void *private_data) +{ + if (nfs->nfsi->readonly) { + nfs_set_error(nfs, "EROFS. Readonly mount"); + cb(-EROFS, nfs, NULL, private_data); + return 0; + } + + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_fchmod_async(nfs, nfsfh, mode, cb, private_data); + case NFS_V4: + return nfs4_fchmod_async(nfs, nfsfh, mode, cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_chown_async(struct nfs_context *nfs, const char *path, int uid, int gid, + nfs_cb cb, void *private_data) +{ + if (nfs->nfsi->readonly) { + nfs_set_error(nfs, "EROFS. Readonly mount"); + cb(-EROFS, nfs, NULL, private_data); + return 0; + } + + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_chown_async_internal(nfs, path, 0, uid, gid, + cb, private_data); + case NFS_V4: + return nfs4_chown_async_internal(nfs, path, 0, uid, gid, + cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_lchown_async(struct nfs_context *nfs, const char *path, int uid, int gid, + nfs_cb cb, void *private_data) +{ + if (nfs->nfsi->readonly) { + nfs_set_error(nfs, "EROFS. Readonly mount"); + cb(-EROFS, nfs, NULL, private_data); + return 0; + } + + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_chown_async_internal(nfs, path, 1, uid, gid, + cb, private_data); + case NFS_V4: + return nfs4_chown_async_internal(nfs, path, 1, uid, gid, + cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_fchown_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int uid, + int gid, nfs_cb cb, void *private_data) +{ + if (nfs->nfsi->readonly) { + nfs_set_error(nfs, "EROFS. Readonly mount"); + cb(-EROFS, nfs, NULL, private_data); + return 0; + } + + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_fchown_async(nfs, nfsfh, uid, gid, + cb, private_data); + case NFS_V4: + return nfs4_fchown_async(nfs, nfsfh, uid, gid, + cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_utimes_async(struct nfs_context *nfs, const char *path, + struct timeval *times, nfs_cb cb, void *private_data) +{ + if (nfs->nfsi->readonly) { + nfs_set_error(nfs, "EROFS. Readonly mount"); + cb(-EROFS, nfs, NULL, private_data); + return 0; + } + + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_utimes_async_internal(nfs, path, 0, times, + cb, private_data); + case NFS_V4: + return nfs4_utimes_async_internal(nfs, path, 0, times, + cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_lutimes_async(struct nfs_context *nfs, const char *path, + struct timeval *times, nfs_cb cb, void *private_data) +{ + if (nfs->nfsi->readonly) { + nfs_set_error(nfs, "EROFS. Readonly mount"); + cb(-EROFS, nfs, NULL, private_data); + return 0; + } + + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_utimes_async_internal(nfs, path, 1, times, + cb, private_data); + case NFS_V4: + return nfs4_utimes_async_internal(nfs, path, 1, times, + cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_utime_async(struct nfs_context *nfs, const char *path, + struct utimbuf *times, nfs_cb cb, void *private_data) +{ + if (nfs->nfsi->readonly) { + nfs_set_error(nfs, "EROFS. Readonly mount"); + cb(-EROFS, nfs, NULL, private_data); + return 0; + } + + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_utime_async(nfs, path, times, cb, private_data); + case NFS_V4: + return nfs4_utime_async(nfs, path, times, cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv4", + __FUNCTION__); + return -1; + } +} + +int +nfs_access_async(struct nfs_context *nfs, const char *path, int mode, + nfs_cb cb, void *private_data) +{ + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_access_async(nfs, path, mode, cb, private_data); + case NFS_V4: + return nfs4_access_async(nfs, path, mode, cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_access2_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data) +{ + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_access2_async(nfs, path, cb, private_data); + case NFS_V4: + return nfs4_access2_async(nfs, path, cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv4", + __FUNCTION__); + return -1; + } +} + +int +nfs_symlink_async(struct nfs_context *nfs, const char *target, + const char *newpath, nfs_cb cb, void *private_data) +{ + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_symlink_async(nfs, target, newpath, + cb, private_data); + case NFS_V4: + return nfs4_symlink_async(nfs, target, newpath, + cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_rename_async(struct nfs_context *nfs, const char *oldpath, + const char *newpath, nfs_cb cb, void *private_data) +{ + if (nfs->nfsi->readonly) { + nfs_set_error(nfs, "EROFS. Readonly mount"); + cb(-EROFS, nfs, NULL, private_data); + return 0; + } + + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_rename_async(nfs, oldpath, newpath, + cb, private_data); + case NFS_V4: + return nfs4_rename_async(nfs, oldpath, newpath, + cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +int +nfs_link_async(struct nfs_context *nfs, const char *oldpath, + const char *newpath, nfs_cb cb, void *private_data) +{ + if (nfs->nfsi->readonly) { + nfs_set_error(nfs, "EROFS. Readonly mount"); + cb(-EROFS, nfs, NULL, private_data); + return 0; + } + + switch (nfs->nfsi->version) { + case NFS_V3: + return nfs3_link_async(nfs, oldpath, newpath, + cb, private_data); + case NFS_V4: + return nfs4_link_async(nfs, oldpath, newpath, + cb, private_data); + default: + nfs_set_error(nfs, "%s does not support NFSv%d", + __FUNCTION__, nfs->nfsi->version); + return -1; + } +} + +/* + * Get/Set the maximum supported READ size by the server + */ +size_t +nfs_get_readmax(struct nfs_context *nfs) +{ + return nfs->nfsi->readmax; +} +void +nfs_set_readmax(struct nfs_context *nfs, size_t readmax) +{ + size_t readmax_adjusted = readmax; + + readmax_adjusted = MIN(readmax_adjusted, NFS_MAX_XFER_SIZE); + readmax_adjusted = MAX(readmax_adjusted, NFS_MIN_XFER_SIZE); + readmax_adjusted = (readmax_adjusted / 4096) * 4096; + + nfs->nfsi->readmax = readmax_adjusted; +} + +/* + * Get/Set the maximum supported WRITE size by the server + */ +size_t +nfs_get_writemax(struct nfs_context *nfs) +{ + return nfs->nfsi->writemax; +} +void +nfs_set_writemax(struct nfs_context *nfs, size_t writemax) +{ + size_t writemax_adjusted = writemax; + + writemax_adjusted = MIN(writemax_adjusted, NFS_MAX_XFER_SIZE); + writemax_adjusted = MAX(writemax_adjusted, NFS_MIN_XFER_SIZE); + writemax_adjusted = (writemax_adjusted / 4096) * 4096; + + nfs->nfsi->writemax = writemax_adjusted; +} + +void +nfs_set_tcp_syncnt(struct nfs_context *nfs, int v) { + rpc_set_tcp_syncnt(nfs->rpc, v); +} + +void +nfs_set_uid(struct nfs_context *nfs, int uid) { + rpc_set_uid(nfs->rpc, uid); +} + +void +nfs_set_gid(struct nfs_context *nfs, int gid) { + rpc_set_gid(nfs->rpc, gid); +} + +void +nfs_set_auxiliary_gids(struct nfs_context *nfs, uint32_t len, uint32_t* gids) { + rpc_set_auxiliary_gids(nfs->rpc, len, gids); +} + +void +nfs_set_debug(struct nfs_context *nfs, int level) { + rpc_set_debug(nfs->rpc, level); +} + +void +nfs_set_auto_traverse_mounts(struct nfs_context *nfs, int enabled) { + nfs->nfsi->auto_traverse_mounts = enabled; +} + +void +nfs_set_readonly(struct nfs_context *nfs, int readonly) { + nfs->nfsi->readonly = readonly; +} + +void +nfs_set_dircache(struct nfs_context *nfs, int enabled) { + nfs->nfsi->dircache_enabled = enabled; +} + +void +nfs_set_autoreconnect(struct nfs_context *nfs, int num_retries) { + /* + * Save the user provided value in nfs_context_internal. + * This will later be set in rpc_context using rpc_set_resiliency() + * once the mount process completes. + */ + nfs->nfsi->auto_reconnect = num_retries; +} + +void +nfs_set_retrans(struct nfs_context *nfs, int retrans) { + /* + * Save the user provided value in nfs_context_internal. + * This will later be set in rpc_context using rpc_set_resiliency() + * once the mount process completes. + */ + assert(retrans >= 0); + nfs->nfsi->retrans = retrans; +} + +int +nfs_set_version(struct nfs_context *nfs, int version) { + switch (version) { + case NFS_V3: + case NFS_V4: +#ifdef HAVE_TLS + nfs->rpc->nfs_version = version; +#endif + nfs->nfsi->version = version; + nfs->nfsi->default_version = 0; + break; + default: + nfs_set_error(nfs, "NFS version %d is not supported", version); + return -1; + } + return 0; +} + +int +nfs_get_version(struct nfs_context *nfs) { + return nfs->nfsi->version; +} + +void +nfs_set_nfsport(struct nfs_context *nfs, int port) { + nfs->nfsi->nfsport = port; +} + +void +nfs_set_mountport(struct nfs_context *nfs, int port) { + nfs->nfsi->mountport = port; + rpc_set_mountport(nfs->rpc, port); +} + +size_t +nfs_get_readdir_maxcount(struct nfs_context *nfs) +{ + return nfs->nfsi->readdir_maxcount; +} + +void +nfs_set_readdir_max_buffer_size(struct nfs_context *nfs, + uint32_t dircount, + uint32_t maxcount) { + size_t dircount_adjusted = dircount; + size_t maxcount_adjusted = maxcount; + + dircount_adjusted = MIN(dircount_adjusted, NFS_MAX_XFER_SIZE); + dircount_adjusted = MAX(dircount_adjusted, NFS_MIN_XFER_SIZE); + dircount_adjusted = (dircount_adjusted / 4096) * 4096; + + maxcount_adjusted = MIN(maxcount_adjusted, NFS_MAX_XFER_SIZE); + maxcount_adjusted = MAX(maxcount_adjusted, NFS_MIN_XFER_SIZE); + maxcount_adjusted = (maxcount_adjusted / 4096) * 4096; + + nfs->nfsi->readdir_dircount = dircount_adjusted; + nfs->nfsi->readdir_maxcount = maxcount_adjusted; +} + +void +nfs_set_error(struct nfs_context *nfs, char *error_string, ...) +{ + va_list ap; + char *old_error_string; + +#ifdef HAVE_MULTITHREADING + /* All thread contexts share the same rpc_context so + * use the mutex from the rpc_context. + */ + if (nfs->rpc->multithreading_enabled) { + nfs_mt_mutex_lock(&nfs->rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ + old_error_string = nfs->error_string; + va_start(ap, error_string); + nfs->error_string = malloc(1024); + if (nfs->error_string == NULL) { + nfs->error_string = discard_const(oom); + goto finished; + } + vsnprintf(nfs->error_string, 1024, error_string, ap); + va_end(ap); + + finished: + /* + * Free old_error_string after vsnprintf() above to support calls like + * nfs_set_error(nfs, "Failed to perform xxx: %s", nfs_get_error(nfs)); + */ + if (old_error_string && old_error_string != oom) { + free(old_error_string); + } +#ifdef HAVE_MULTITHREADING + if (nfs->rpc->multithreading_enabled) { + nfs_mt_mutex_unlock(&nfs->rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ +} + +void +nfs_set_error_locked(struct nfs_context *nfs, char *error_string, ...) +{ + va_list ap; + char *old_error_string = nfs->error_string; + + va_start(ap, error_string); + nfs->error_string = malloc(1024); + if (nfs->error_string == NULL) { + free(old_error_string); + nfs->error_string = discard_const(oom); + return; + } + vsnprintf(nfs->error_string, 1024, error_string, ap); + va_end(ap); + + if (old_error_string && old_error_string != oom) { + free(old_error_string); + } +} + +struct mount_cb_data { + rpc_cb cb; + void *private_data; + char *server; +}; + +static void +free_mount_cb_data(struct mount_cb_data *data) +{ + if (data->server != NULL) { + free(data->server); + data->server = NULL; + } + + free(data); +} + +static void +mount_export_5_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct mount_cb_data *data = private_data; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (status != RPC_STATUS_SUCCESS) { + data->cb(rpc, -EFAULT, command_data, data->private_data); + free_mount_cb_data(data); + return; + } + + data->cb(rpc, 0, command_data, data->private_data); + if (rpc_disconnect(rpc, "normal disconnect") != 0) { + rpc_set_error(rpc, "Failed to disconnect\n"); + } + free_mount_cb_data(data); +} + +static void +mount_export_4_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct mount_cb_data *data = private_data; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + /* Dont want any more callbacks even if the socket is closed */ + rpc->connect_cb = NULL; + + if (status != RPC_STATUS_SUCCESS) { + data->cb(rpc, -EFAULT, command_data, data->private_data); + free_mount_cb_data(data); + return; + } + + if (rpc_mount3_export_task(rpc, mount_export_5_cb, data) == NULL) { + data->cb(rpc, -ENOMEM, command_data, data->private_data); + free_mount_cb_data(data); + return; + } +} + +int +mount_getexports_async(struct rpc_context *rpc, const char *server, rpc_cb cb, + void *private_data) +{ + struct mount_cb_data *data; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + data = calloc(1, sizeof(struct mount_cb_data)); + if (data == NULL) { + return -1; + } + data->cb = cb; + data->private_data = private_data; + data->server = strdup(server); + if (data->server == NULL) { + free_mount_cb_data(data); + return -1; + } + if (rpc->mountport) { + if (rpc_connect_port_async(rpc, data->server, rpc->mountport, MOUNT_PROGRAM, + MOUNT_V3, mount_export_4_cb, data) != 0) { + rpc_set_error(rpc, "Failed to start connection. %s", + rpc_get_error(rpc)); + free_mount_cb_data(data); + return -1; + } + return 0; + } + if (rpc_connect_program_async(rpc, data->server, MOUNT_PROGRAM, + MOUNT_V3, mount_export_4_cb, data) != 0) { + rpc_set_error(rpc, "Failed to start connection. %s", + rpc_get_error(rpc)); + free_mount_cb_data(data); + return -1; + } + + return 0; +} + +struct rpc_context * +nfs_get_rpc_context(struct nfs_context *nfs) +{ + assert(nfs->rpc->magic == RPC_CONTEXT_MAGIC); + return nfs->rpc; +} + +/* + * Get the NFS server address we are currently connected to. + */ +const struct sockaddr_storage * +nfs_get_server_address(struct nfs_context *nfs) +{ + return &nfs->rpc->s; +} + +const char * +nfs_get_server(struct nfs_context *nfs) { + return nfs->nfsi->server; +} + +const char * +nfs_get_export(struct nfs_context *nfs) { + return nfs->nfsi->export; +} + +const struct nfs_fh * +nfs_get_rootfh(struct nfs_context *nfs) { + return &nfs->nfsi->rootfh; +} + +struct nfs_fh * +nfs_get_fh(struct nfsfh *nfsfh) { + return &nfsfh->fh; +} + +uint16_t +nfs_umask(struct nfs_context *nfs, uint16_t mask) { + uint16_t tmp = nfs->nfsi->mask; + nfs->nfsi->mask = mask; + return tmp; +} + +/* +* Sets polling timeout for nfs apis +*/ +void +nfs_set_poll_timeout(struct nfs_context *nfs, int poll_timeout) +{ + rpc_set_poll_timeout(nfs->rpc, poll_timeout); +} + +/* +* Gets polling timeout for nfs apis +*/ +int +nfs_get_poll_timeout(struct nfs_context *nfs) +{ + return rpc_get_poll_timeout(nfs->rpc); +} + +/* +* Sets timeout for nfs apis +*/ +void +nfs_set_timeout(struct nfs_context *nfs, int timeout_msecs) +{ + /* + * Save the timeout in nfs_context_internal and also set it in + * rpc_context. Contrast this with nfs_set_retrans() which only saves + * the user provided value in nfs_context_internal but does not set it + * in rpc_context. Note that it's ok (and needed) to set timeout in the + * rpc_context as timeout is used by all RPC requests while retrans adds + * resiliency to RPC transport and is used only after the mount completes. + */ + nfs->nfsi->timeout = timeout_msecs; + + rpc_set_timeout(nfs->rpc, timeout_msecs); +} + +/* +* Gets timeout for nfs apis +*/ +int +nfs_get_timeout(struct nfs_context *nfs) +{ + return rpc_get_timeout(nfs->rpc); +} + +struct rpc_pdu * +rpc_null_task(struct rpc_context *rpc, int program, int version, rpc_cb cb, + void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, program, version, 0, cb, private_data, + (zdrproc_t)zdr_void, 0); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu " + "for NULL call"); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu " + "for NULL call"); + return NULL; + } + + return pdu; +} + +#ifdef HAVE_TLS +/* + * Call this in place of rpc_null_task() if user wants TLS security for the RPC + * connection. Since we only ever send AUTH_TLS NULL RPC for NFS_PROGRAM it does + * not need the program parameter. + * Callback 'cb' is called not after we get the reply for this AUTH_TLS NULL RPC, + * but after the TLS handshake completes (success or failure). + */ +struct rpc_pdu * +rpc_null_task_authtls(struct rpc_context *rpc, int nfs_version, rpc_cb cb, + void *private_data) +{ + struct rpc_pdu *pdu; + struct tls_cb_data *data; + + /* Must be called only for secure connections to NFS_PROGRAM version 3 or 4 */ + assert(rpc->use_tls); + assert(nfs_version == NFS_V3 || nfs_version == NFS_V4); + + data = calloc(1, sizeof(*data)); + if (data == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate tls_cb_data " + "for AUTH_TLS NULL call"); + return NULL; + } + data->cb = cb; + data->private_data = private_data; + + /* + * Set MSbit in procedure number to convey use of AUTH_TLS + * This should not interfere with valid procedure numbers as they are all + * small numbers. + */ + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, nfs_version, (0 | 0x80000000U), + rpc_connect_program_4_1_cb, data, + (zdrproc_t)zdr_void, 0); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu " + "for AUTH_TLS NULL call"); + free_tls_cb_data(data); + return NULL; + } + + rpc->tls_context.state = TLS_HANDSHAKE_WAITING_FOR_STARTTLS; + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu " + "for AUTH_TLS NULL call"); + free_tls_cb_data(data); + return NULL; + } + + return pdu; +} +#endif /* HAVE_TLS */ + +void rpc_set_stats_cb(struct rpc_context *rpc, rpc_stats_cb cb, + void *private_data) +{ + rpc->stats_cb = cb; + rpc->stats_private_data = private_data; +} + +void rpc_set_log_cb(struct rpc_context *rpc, rpc_log_cb cb, + void *private_data) +{ + rpc->log_cb = cb; + rpc->log_private_data = private_data; +} + +struct rpc_pdu_stats *rpc_get_pdu_stats(struct rpc_context *rpc) +{ + return &rpc->pdu->pdu_stats; +} diff --git a/deps/libnfs/lib/multithreading.c b/deps/libnfs/lib/multithreading.c new file mode 100644 index 000000000000..74a048539e6a --- /dev/null +++ b/deps/libnfs/lib/multithreading.c @@ -0,0 +1,362 @@ +/* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */ +/* + 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 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef AROS +#include "aros_compat.h" +#endif + +#ifdef PS2_EE +#include "ps2_compat.h" +#endif + +#ifdef PS3_PPU +#include "ps3_compat.h" +#endif + +#ifdef WIN32 +#include +#endif + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#ifdef HAVE_POLL_H +#include +#endif + +#ifdef HAVE_SYS_TIME_H +#include +#endif + +#include +#include "libnfs.h" +#include "libnfs-raw.h" +#include "libnfs-private.h" + +#ifdef HAVE_MULTITHREADING + +#ifdef WIN32 +nfs_tid_t nfs_mt_get_tid(void) +{ + return GetCurrentThreadId(); +} +static void* nfs_mt_service_thread(void* arg) +{ + struct nfs_context* nfs = (struct nfs_context*)arg; + struct pollfd pfd; + int revents; + int ret; + + nfs->rpc->multithreading_enabled = 1; + + while (nfs->rpc->multithreading_enabled) { + pfd.fd = nfs_get_fd(nfs); + pfd.events = nfs_which_events(nfs); + pfd.revents = 0; + + ret = poll(&pfd, 1, 0); + if (ret < 0) { + nfs_set_error(nfs, "Poll failed"); + revents = -1; + } + else { + revents = pfd.revents; + } + if (nfs_service(nfs, revents) < 0) { + if (revents != -1) + nfs_set_error(nfs, "nfs_service failed"); + } + } + return NULL; +} + +static DWORD WINAPI service_thread_init(LPVOID lpParam) +{ + HANDLE hStdout; + struct nfs_context* nfs; + + hStdout = GetStdHandle(STD_OUTPUT_HANDLE); + if (hStdout == INVALID_HANDLE_VALUE) { + return 1; + } + nfs = (struct nfs_context *)lpParam; + nfs_mt_service_thread(nfs); + return 0; +} + +int nfs_mt_service_thread_start(struct nfs_context* nfs) +{ + nfs->nfsi->service_thread = CreateThread(NULL, 1024*1024, service_thread_init, nfs, 0, NULL); + if (nfs->nfsi->service_thread == NULL) { + nfs_set_error(nfs, "Failed to start service thread"); + return -1; + } + while (nfs->rpc->multithreading_enabled == 0) { + Sleep(100); + } + return 0; +} + +void nfs_mt_service_thread_stop(struct nfs_context* nfs) +{ + nfs->rpc->multithreading_enabled = 0; + while (WaitForSingleObject(nfs->nfsi->service_thread, INFINITE) != WAIT_OBJECT_0); +} + +int nfs_mt_mutex_init(libnfs_mutex_t* mutex) +{ + *mutex = CreateSemaphoreA(NULL, 1, 1, NULL); + return 0; +} + +int nfs_mt_mutex_destroy(libnfs_mutex_t* mutex) +{ + CloseHandle(*mutex); + return 0; +} + +int nfs_mt_mutex_lock(libnfs_mutex_t* mutex) +{ + while (WaitForSingleObject(*mutex, INFINITE) != WAIT_OBJECT_0); + return 0; +} + +int nfs_mt_mutex_unlock(libnfs_mutex_t* mutex) +{ + ReleaseSemaphore(*mutex, 1, NULL); + return 0; +} + +int nfs_mt_sem_init(libnfs_sem_t* sem, int value) +{ + *sem = CreateSemaphoreA(NULL, 0, 16, NULL); + return 0; +} + +int nfs_mt_sem_destroy(libnfs_sem_t* sem) +{ + CloseHandle(*sem); + return 0; +} + +int nfs_mt_sem_post(libnfs_sem_t* sem) +{ + ReleaseSemaphore(*sem, 1, NULL); + return 0; +} + +int nfs_mt_sem_wait(libnfs_sem_t* sem) +{ + while (WaitForSingleObject(*sem, INFINITE) != WAIT_OBJECT_0); + return 0; +} + +#elif defined(HAVE_PTHREAD) /* WIN32 */ + +#include +#include +#if defined(__FreeBSD__) || defined(__DragonFly__) +#include +#endif +#if defined(__NetBSD__) +#include +#endif + +nfs_tid_t nfs_mt_get_tid(void) +{ +#ifdef HAVE_PTHREAD_THREADID_NP + nfs_tid_t tid; + pthread_threadid_np(NULL, &tid); + return tid; +#elif defined(__FreeBSD__) || defined(__DragonFly__) + int tid = pthread_getthreadid_np(); + return tid; +#elif defined(__OpenBSD__) + pid_t tid = getthrid(); + return tid; +#elif defined(__NetBSD__) + lwpid_t tid = _lwp_self(); + return tid; +#elif defined(SYS_gettid) + pid_t tid = syscall(SYS_gettid); + return tid; +#else +#error "SYS_gettid unavailable on this system" +#endif +} + +static void *nfs_mt_service_thread(void *arg) +{ + struct nfs_context *nfs = (struct nfs_context *)arg; + struct pollfd pfd; + int revents; + int ret; + + nfs->rpc->multithreading_enabled = 1; + + while (nfs->rpc->multithreading_enabled) { + pfd.fd = nfs_get_fd(nfs); + pfd.events = nfs_which_events(nfs); + pfd.revents = 0; + + ret = poll(&pfd, 1, nfs->rpc->poll_timeout); + if (ret < 0) { + nfs_set_error(nfs, "Poll failed"); + revents = -1; + } else { + revents = pfd.revents; + } + if (nfs_service(nfs, revents) < 0) { + if (revents != -1) + nfs_set_error(nfs, "nfs_service failed"); + } + } + return NULL; +} + +int nfs_mt_service_thread_start(struct nfs_context *nfs) +{ + if (pthread_create(&nfs->nfsi->service_thread, NULL, + &nfs_mt_service_thread, nfs)) { + nfs_set_error(nfs, "Failed to start service thread"); + return -1; + } + while (nfs->rpc->multithreading_enabled == 0) { + struct timespec ts = {0, 1000000}; + nanosleep(&ts, NULL); + } + return 0; +} + +void nfs_mt_service_thread_stop(struct nfs_context *nfs) +{ + nfs->rpc->multithreading_enabled = 0; + pthread_join(nfs->nfsi->service_thread, NULL); +} + +/* + * If this is enabled we check for the following locking violations, at the + * (slight) cost of performance: + * - Thread holding the lock again tries to lock. + * - Thread not holding the lock tries to unlock. + * + * This is very useful for catching any coding errors. + * The performance hit is not very significant so you can leave it enabled, + * but if you really care then once the code has been vetted, this can be + * undef'ed to get the perf back. + */ +#define DEBUG_PTHREAD_LOCKING_VIOLATIONS + +int nfs_mt_mutex_init(libnfs_mutex_t *mutex) +{ + int ret; +#ifdef DEBUG_PTHREAD_LOCKING_VIOLATIONS + pthread_mutexattr_t attr; + + ret = pthread_mutexattr_init(&attr); + if (ret != 0) { + return ret; + } + + ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); + if (ret != 0) { + return ret; + } + + ret = pthread_mutex_init(mutex, &attr); + if (ret != 0) { + return ret; + } +#else + ret = pthread_mutex_init(mutex, NULL); + assert(ret == 0); +#endif + return ret; +} + +int nfs_mt_mutex_destroy(libnfs_mutex_t *mutex) +{ + return pthread_mutex_destroy(mutex); +} + +int nfs_mt_mutex_lock(libnfs_mutex_t *mutex) +{ + return pthread_mutex_lock(mutex); +} + +int nfs_mt_mutex_unlock(libnfs_mutex_t *mutex) +{ + return pthread_mutex_unlock(mutex); +} + +#if defined(__APPLE__) && defined(HAVE_DISPATCH_DISPATCH_H) +int nfs_mt_sem_init(libnfs_sem_t *sem, int value) +{ + if ((*sem = dispatch_semaphore_create(value)) != NULL) + return 0; + return -1; +} + +int nfs_mt_sem_destroy(libnfs_sem_t *sem) +{ + dispatch_release(*sem); + return 0; +} + +int nfs_mt_sem_post(libnfs_sem_t *sem) +{ + dispatch_semaphore_signal(*sem); + return 0; +} + +int nfs_mt_sem_wait(libnfs_sem_t *sem) +{ + dispatch_semaphore_wait(*sem, DISPATCH_TIME_FOREVER); + return 0; +} + +#else +int nfs_mt_sem_init(libnfs_sem_t *sem, int value) +{ + return sem_init(sem, 0, value); +} + +int nfs_mt_sem_destroy(libnfs_sem_t *sem) +{ + return sem_destroy(sem); +} + +int nfs_mt_sem_post(libnfs_sem_t *sem) +{ + return sem_post(sem); +} + +int nfs_mt_sem_wait(libnfs_sem_t *sem) +{ + return sem_wait(sem); +} +#endif + +#endif /* HAVE_PTHREAD */ + +#endif /* HAVE_MULTITHREADING */ + diff --git a/deps/libnfs/lib/nfs_v3.c b/deps/libnfs/lib/nfs_v3.c new file mode 100644 index 000000000000..2c32fff74e40 --- /dev/null +++ b/deps/libnfs/lib/nfs_v3.c @@ -0,0 +1,5055 @@ +/* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */ +/* + Copyright (C) 2017 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 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ +/* + * High level api to nfsv3 filesystems + */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef AROS +#include "aros_compat.h" +#endif + +#ifdef PS2_EE +#include "ps2_compat.h" +#endif + +#ifdef PS3_PPU +#include "ps3_compat.h" +#endif + +#ifdef WIN32 +#include +#endif + +#ifdef HAVE_INTTYPES_H +#include +#else +#define PRIu64 "llu" +#endif + +#ifdef HAVE_UTIME_H +#include +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_SYS_VFS_H +#include +#endif + +#ifdef HAVE_SYS_STATVFS_H +#include +#endif + +#if defined(__ANDROID__) && !defined(HAVE_SYS_STATVFS_H) +#define statvfs statfs +#endif + +#ifdef HAVE_NETINET_IN_H +#include +#endif + +#ifdef HAVE_STRINGS_H +#include +#endif + +#ifdef MAJOR_IN_MKDEV +#include +#endif + +#ifdef HAVE_SYS_SYSMACROS_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "libnfs-zdr.h" +#include "slist.h" +#include "libnfs.h" +#include "libnfs-raw.h" +#include "libnfs-raw-mount.h" +#include "libnfs-private.h" + +static uint64_t +specdata3_to_rdev(struct specdata3 *specdata) +{ + uint64_t rdev = specdata->specdata1; + return (rdev << 32) | specdata->specdata2; +} + +struct mount_attr_cb { + int wait_count; + struct nfs_cb_data *data; +}; + +struct mount_attr_item_cb { + struct mount_attr_cb *ma; + struct nested_mounts *mnt; +}; + +struct nfs_mcb_data { + struct nfs_cb_data *data; + uint64_t offset; + size_t count; +}; + +static int +check_nfs3_error(struct nfs_context *nfs, int status, + struct nfs_cb_data *data, void *command_data) +{ + if (status == RPC_STATUS_ERROR) { + data->cb(-EFAULT, nfs, command_data, data->private_data); + return 1; + } + if (status == RPC_STATUS_CANCEL) { + data->cb(-EINTR, nfs, "Command was cancelled", + data->private_data); + return 1; + } + if (status == RPC_STATUS_TIMEOUT) { + data->cb(-EINTR, nfs, "Command timed out", + data->private_data); + return 1; + } + + return 0; +} + +static int nfs3_lookup_path_async_internal(struct nfs_context *nfs, + struct nfs_attr *attr, + struct nfs_cb_data *data, + struct nfs_fh *fh); + +/* + * Functions to first look up a path, component by component, and then finally + * call a specific function once the filehandle for the final component is + * found. + */ +static void +nfs3_lookup_path_2_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + READLINK3res *res; + char *path, *newpath; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + res = command_data; + if (res->status != NFS3_OK) { + nfs_set_error(nfs, "NFS: READLINK 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, + nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + + path = res->READLINK3res_u.resok.data; + + /* Handle absolute paths, ensuring that the path lies within the + * export. */ + if (path[0] == '/') { + if (strstr(path, nfs_get_export(nfs)) == path) { + char *ptr = path + strlen(nfs_get_export(nfs)); + if (*ptr == '/') { + newpath = strdup(ptr); + } else if (*ptr == '\0') { + newpath = strdup("/"); + } else { + data->cb(-ENOENT, nfs, "Symbolic link points " + "outside export", data->private_data); + free_nfs_cb_data(data); + return; + } + } else { + data->cb(-ENOENT, nfs, "Symbolic link points outside " + "export", data->private_data); + free_nfs_cb_data(data); + return; + } + + if (!newpath) + goto nomem; + } else { + /* Handle relative paths, both the case where the current + * component is an intermediate component and when it is the + * final component. */ + if (data->path[0]) { + /* Since path points to a component and saved_path + * always starts with '/', path[-1] is valid. */ + data->path[-1] = '\0'; + newpath = malloc(strlen(data->saved_path) + + strlen(path) + strlen(data->path) + 6); + if (!newpath) + goto nomem; + + sprintf(newpath, "%s/../%s/%s", data->saved_path, path, + data->path); + } else { + newpath = malloc(strlen(data->saved_path) + + strlen(path) + 5); + if (!newpath) + goto nomem; + + sprintf(newpath, "%s/../%s", data->saved_path, path); + } + } + free(data->saved_path); + data->saved_path = newpath; + + if (nfs_normalize_path(nfs, data->saved_path) != 0) { + data->cb(-ENOENT, nfs, "Symbolic link resolves to invalid " + "path", data->private_data); + free_nfs_cb_data(data); + return; + } + + data->path = data->saved_path; + nfs3_lookup_path_async_internal(nfs, NULL, data, &nfs->nfsi->rootfh); + return; + +nomem: + data->cb(-ENOMEM, nfs, "Failed to allocate memory for path", + data->private_data); + free_nfs_cb_data(data); +} + +static void +fattr3_to_nfs_attr(struct nfs_attr *attr, fattr3 *fa3) +{ + attr->type = fa3->type; + attr->mode = fa3->mode; + attr->uid = fa3->uid; + attr->gid = fa3->gid; + attr->nlink = fa3->nlink; + attr->size = fa3->size; + attr->used = fa3->used; + attr->fsid = fa3->fsid; + attr->rdev.specdata1 = fa3->rdev.specdata1; + attr->rdev.specdata2 = fa3->rdev.specdata2; + attr->atime.seconds = fa3->atime.seconds; + attr->atime.nseconds = fa3->atime.nseconds; + attr->mtime.seconds = fa3->mtime.seconds; + attr->mtime.nseconds = fa3->mtime.nseconds; + attr->ctime.seconds = fa3->ctime.seconds; + attr->ctime.nseconds = fa3->ctime.nseconds; +} + +static void +nfs3_lookup_path_1_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + LOOKUP3res *res; + struct nfs_attr attr; + struct nfs_fh fh; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + res = command_data; + if (res->status != NFS3_OK) { + nfs_set_error(nfs, "NFS: Lookup 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, + nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + + memset(&attr, 0, sizeof(attr)); + if (res->LOOKUP3res_u.resok.obj_attributes.attributes_follow) { + fattr3_to_nfs_attr(&attr, &res->LOOKUP3res_u.resok.obj_attributes.post_op_attr_u.attributes); + } + + /* This function will always invoke the callback and cleanup + * for failures. So no need to check the return value. + */ + fh.val = res->LOOKUP3res_u.resok.object.data.data_val; + fh.len = res->LOOKUP3res_u.resok.object.data.data_len; + nfs3_lookup_path_async_internal(nfs, &attr, data, &fh); +} + +static int +nfs3_lookup_path_async_internal(struct nfs_context *nfs, struct nfs_attr *attr, + struct nfs_cb_data *data, struct nfs_fh *fh) +{ + char *path, *slash; + LOOKUP3args args; + + while (*data->path == '/') { + data->path++; + } + + path = data->path; + slash = strchr(path, '/'); + + if (attr && attr->type == NF3LNK) { + if (data->continue_int & O_NOFOLLOW) { + data->cb(-ELOOP, nfs, "Symbolic link encountered", + data->private_data); + free_nfs_cb_data(data); + return -1; + } + if (!data->no_follow || *path != '\0') { + READLINK3args rl_args; + + if (data->link_count++ >= MAX_LINK_COUNT) { + data->cb(-ELOOP, nfs, "Too many levels of " + "symbolic links", data->private_data); + free_nfs_cb_data(data); + return -1; + } + + rl_args.symlink.data.data_len = fh->len; + rl_args.symlink.data.data_val = fh->val; + + if (rpc_nfs3_readlink_task(nfs->rpc, + nfs3_lookup_path_2_cb, + &rl_args, data) == NULL) { + nfs_set_error(nfs, "RPC error: Failed to " + "send READLINK call for %s", + data->path); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return -1; + } + + if (slash != NULL) { + *slash = '/'; + } + return 0; + } + } + + if (slash != NULL) { + /* Clear slash so that path is a zero terminated string for + * the current path component. Set it back to '/' again later + * when we are finished referencing this component so that + * data->saved_path will still point to the full + * normalized path. + */ + *slash = 0; + data->path = slash+1; + } else { + while (*data->path != 0) { + data->path++; + } + } + if (*path == 0) { + data->fh.len = fh->len; + data->fh.val = malloc(data->fh.len); + if (data->fh.val == NULL) { + nfs_set_error(nfs, "Out of memory: Failed to " + "allocate fh for %s", data->path); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return -1; + } + memcpy(data->fh.val, fh->val, data->fh.len); + if (slash != NULL) { + *slash = '/'; + } + data->continue_cb(nfs, attr, data); + return 0; + } + + memset(&args, 0, sizeof(LOOKUP3args)); + args.what.dir.data.data_len = fh->len; + args.what.dir.data.data_val = fh->val; + args.what.name = path; + + if (rpc_nfs3_lookup_task(nfs->rpc, nfs3_lookup_path_1_cb, + &args, data) == NULL) { + nfs_set_error(nfs, "RPC error: Failed to send lookup " + "call for %s", data->path); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return -1; + } + if (slash != NULL) { + *slash = '/'; + } + return 0; +} + +static void +nfs3_lookup_path_getattr_cb(struct rpc_context *rpc, int status, + void *command_data, void *private_data) +{ + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + GETATTR3res *res; + struct nfs_attr attr; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + res = command_data; + if (res->status != NFS3_OK) { + nfs_set_error(nfs, "NFS: GETATTR 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, + nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + + fattr3_to_nfs_attr(&attr, &res->GETATTR3res_u.resok.obj_attributes); + /* This function will always invoke the callback and cleanup + * for failures. So no need to check the return value. + */ + nfs3_lookup_path_async_internal(nfs, &attr, data, &nfs->nfsi->rootfh); +} + +/* This function will free continue_data on error */ +static int +nfs3_lookuppath_async(struct nfs_context *nfs, const char *path, int no_follow, + nfs_cb cb, void *private_data, + continue_func continue_cb, void *continue_data, + void (*free_continue_data)(void *), + uint64_t continue_int) +{ + struct nfs_cb_data *data; + struct GETATTR3args args; + struct nfs_fh *fh; + + if (path == NULL || path[0] == '\0') { + path = "."; + } + + data = calloc(1, sizeof(struct nfs_cb_data)); + if (data == NULL) { + nfs_set_error(nfs, "Out of memory: failed to allocate " + "nfs_cb_data structure"); + if (continue_data) { + free_continue_data(continue_data); + } + return -1; + } + data->nfs = nfs; + data->cb = cb; + data->continue_cb = continue_cb; + data->continue_data = continue_data; + data->free_continue_data = free_continue_data; + data->continue_int = continue_int; + data->private_data = private_data; + data->no_follow = no_follow; + if (path[0] == '/') { + data->saved_path = strdup(path); + } else { + data->saved_path = malloc(strlen(path) + strlen(nfs->nfsi->cwd) + 2); + if (data->saved_path == NULL) { + nfs_set_error(nfs, "Out of memory: failed to " + "allocate path string"); + free_nfs_cb_data(data); + return -1; + } + sprintf(data->saved_path, "%s/%s", nfs->nfsi->cwd, path); + } + + if (data->saved_path == NULL) { + nfs_set_error(nfs, "Out of memory: failed to copy path " + "string"); + free_nfs_cb_data(data); + return -1; + } + if (nfs_normalize_path(nfs, data->saved_path) != 0) { + free_nfs_cb_data(data); + return -1; + } + + data->path = data->saved_path; + fh = &nfs->nfsi->rootfh; + + if (data->path[0]) { + struct nested_mounts *mnt; + /* Make sure we match on longest nested export. + * TODO: If we make sure the list is sorted we can skip this + * check and end the loop on first match. + */ + size_t max_match_len = 0; + + /* Do we need to switch to a different nested export ? */ + for (mnt = nfs->nfsi->nested_mounts; mnt; mnt = mnt->next) { + if (strlen(mnt->path) < max_match_len) + continue; + if (strncmp(mnt->path, data->saved_path, + strlen(mnt->path))) + continue; + if (data->saved_path[strlen(mnt->path)] != '\0' + && data->saved_path[strlen(mnt->path)] != '/') + continue; + + data->saved_path = strdup(data->path + + strlen(mnt->path)); + free(data->path); + data->path = data->saved_path; + fh = &mnt->fh; + max_match_len = strlen(mnt->path); + } + + /* This function will always invoke the callback and cleanup + * for failures. So no need to check the return value. + */ + nfs3_lookup_path_async_internal(nfs, NULL, data, fh); + return 0; + } + + /* We have a request for "", so just perform a GETATTR3 so we can + * return the attributes to the caller. + */ + memset(&args, 0, sizeof(GETATTR3args)); + args.object.data.data_len = fh->len; + args.object.data.data_val = fh->val; + if (rpc_nfs3_getattr_task(nfs->rpc, nfs3_lookup_path_getattr_cb, + &args, data) == NULL) { + free_nfs_cb_data(data); + return -1; + } + return 0; +} + +static void +nfs3_mount_8_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct mount_attr_item_cb *ma_item = private_data; + struct mount_attr_cb *ma = ma_item->ma; + struct nfs_cb_data *data = ma->data; + struct nfs_context *nfs = data->nfs; + GETATTR3res *res; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (status != RPC_STATUS_SUCCESS) { + goto finished; + } + + res = command_data; + if (res->status != NFS3_OK) + goto finished; + + fattr3_to_nfs_attr(&ma_item->mnt->attr, + &res->GETATTR3res_u.resok.obj_attributes); + +finished: + free(ma_item); + ma->wait_count--; + if (ma->wait_count > 0) + return; + + free(ma); + data->cb(0, nfs, NULL, data->private_data); + free_nfs_cb_data(data); +} + +static void +nfs3_mount_7_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + struct mount_attr_cb *ma = NULL; + struct nested_mounts *mnt; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + /* + * Now the entire mount process (including the NFS FSINFO and GETATTR) + * has completed. Any RPC failure till now would have caused the mount + * process to fail. Note that it's desirable for the mount process to + * fail upfront if it encounters any errors (TCP or RPC), rather than + * keep trying indefinitely causing the mount process to "hang", but + * from now on the RPC transport will be used to carry NFS RPCs issued + * by the application which may not be equipped to handle TCP connection + * failure and RPC timeouts, so we set the resiliency parameters of the + * rpc_context as selected by the user using the mount options. The + * default resiliency parameters emulate the common "hard" mount and + * we are resilient to any TCP or RPC connectivity issues. + */ + rpc_set_resiliency(rpc, + nfs->nfsi->auto_reconnect, + nfs->nfsi->timeout, + nfs->nfsi->retrans); + + if (!nfs->nfsi->nested_mounts) + goto finished; + + /* nested mount traversals are best-effort only, so any + * failures just means that we don't get traversal for that + * particular mount. We do not fail the call from the application. + */ + ma = malloc(sizeof(struct mount_attr_cb)); + if (ma == NULL) + goto finished; + memset(ma, 0, sizeof(struct mount_attr_cb)); + ma->data = data; + + for(mnt = nfs->nfsi->nested_mounts; mnt; mnt = mnt->next) { + struct mount_attr_item_cb *ma_item; + struct GETATTR3args args; + + ma_item = malloc(sizeof(struct mount_attr_item_cb)); + if (ma_item == NULL) + goto finished; + ma_item->mnt = mnt; + ma_item->ma = ma; + + memset(&args, 0, sizeof(GETATTR3args)); + args.object.data.data_len = mnt->fh.len; + args.object.data.data_val = mnt->fh.val; + + if (rpc_nfs3_getattr_task(rpc, nfs3_mount_8_cb, &args, + ma_item) == NULL) { + nfs_set_error(nfs, "%s: %s", __FUNCTION__, + nfs_get_error(nfs)); + free(ma_item); + continue; + } + + ma->wait_count++; + } + +finished: + if (ma && ma->wait_count) + return; + + free(ma); + data->cb(0, nfs, NULL, data->private_data); + free_nfs_cb_data(data); +} + +static void +nfs3_mount_6_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + FSINFO3res *res = command_data; + struct GETATTR3args args; + size_t readmax, writemax, dircount, maxcount; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + if (res->status != NFS3_OK) { + nfs_set_error(nfs, "NFS: FSINFO of %s failed with %s(%d)", + nfs_get_export(nfs), nfsstat3_to_str(res->status), + nfsstat3_to_errno(res->status)); + data->cb(nfsstat3_to_errno(res->status), nfs, + nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + + readmax = MIN(nfs->nfsi->readmax, res->FSINFO3res_u.resok.rtmax); + writemax = MIN(nfs->nfsi->writemax, res->FSINFO3res_u.resok.wtmax); + + /* The server supports sizes up to rtmax and wtmax, so it is legal + * to use smaller transfers sizes. + */ + if (nfs->nfsi->readmax < NFSMAXDATA2) { + nfs_set_error(nfs, "server max rsize of %d", + (int)nfs->nfsi->readmax); + data->cb(-EINVAL, nfs, nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } else { + nfs_set_readmax(nfs, readmax); + } + + if (nfs->nfsi->writemax < NFSMAXDATA2) { + nfs_set_error(nfs, "server max wsize of %d", + (int)nfs->nfsi->writemax); + data->cb(-EINVAL, nfs, nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } else { + nfs_set_writemax(nfs, writemax); + } + + dircount = MIN(nfs->nfsi->readdir_dircount, res->FSINFO3res_u.resok.dtpref); + maxcount = MIN(nfs->nfsi->readdir_maxcount, res->FSINFO3res_u.resok.dtpref); + + if (nfs->nfsi->readdir_dircount < NFSMAXDATA2) { + nfs_set_error(nfs, "server dtpref of %d", + (int)nfs->nfsi->readdir_dircount); + data->cb(-EINVAL, nfs, nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } else { + nfs_set_readdir_max_buffer_size(nfs, dircount, maxcount); + } + + memset(&args, 0, sizeof(GETATTR3args)); + args.object.data.data_len = nfs->nfsi->rootfh.len; + args.object.data.data_val = nfs->nfsi->rootfh.val; + + if (rpc_nfs3_getattr_task(rpc, nfs3_mount_7_cb, &args, data) == NULL) { + nfs_set_error(nfs, "%s: %s", __FUNCTION__, nfs_get_error(nfs)); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } +} + +static void +nfs3_mount_5_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + struct FSINFO3args args; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + args.fsroot.data.data_len = nfs->nfsi->rootfh.len; + args.fsroot.data.data_val = nfs->nfsi->rootfh.val; + if (rpc_nfs3_fsinfo_task(rpc, nfs3_mount_6_cb, &args, data) == NULL) { + nfs_set_error(nfs, "%s: %s", __FUNCTION__, nfs_get_error(nfs)); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } +} + +struct mount_discovery_cb { + int wait_count; + int error; + int status; + struct nfs_cb_data *data; +}; + +struct mount_discovery_item_cb { + struct mount_discovery_cb *md_cb; + char *path; +}; + +static void +nfs3_mount_4_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct mount_discovery_item_cb *md_item_cb = private_data; + struct mount_discovery_cb *md_cb = md_item_cb->md_cb; + struct nfs_cb_data *data = md_cb->data; + struct nfs_context *nfs = data->nfs; + mountres3 *res; + struct nested_mounts *mnt; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (status == RPC_STATUS_ERROR) { + nfs_set_error(nfs, "MOUNT failed with RPC_STATUS_ERROR"); + md_cb->error = -EFAULT; + goto finished; + } + if (status == RPC_STATUS_CANCEL) { + nfs_set_error(nfs, "MOUNT failed with RPC_STATUS_CANCEL"); + md_cb->status = RPC_STATUS_CANCEL; + goto finished; + } + if (status == RPC_STATUS_TIMEOUT) { + nfs_set_error(nfs, "MOUNT timed out"); + md_cb->status = RPC_STATUS_TIMEOUT; + goto finished; + } + + res = command_data; + if (res->fhs_status != MNT3_OK) { + nfs_set_error(nfs, "RPC error: Mount failed with error " + "%s(%d) %s(%d)", + mountstat3_to_str(res->fhs_status), + res->fhs_status, + strerror(-mountstat3_to_errno(res->fhs_status)), + -mountstat3_to_errno(res->fhs_status)); + md_cb->error = mountstat3_to_errno(res->fhs_status); + goto finished; + } + + mnt = malloc(sizeof(*mnt)); + if (mnt == NULL) { + nfs_set_error(nfs, "Out of memory. Could not allocate memory " + "to store mount handle"); + md_cb->error = -ENOMEM; + goto finished; + } + memset(mnt, 0, sizeof(*mnt)); + + mnt->fh.len = res->mountres3_u.mountinfo.fhandle.fhandle3_len; + mnt->fh.val = malloc(mnt->fh.len); + if (mnt->fh.val == NULL) { + free(mnt); + goto finished; + } + memcpy(mnt->fh.val, + res->mountres3_u.mountinfo.fhandle.fhandle3_val, + mnt->fh.len); + + mnt->path = md_item_cb->path; + md_item_cb->path = NULL; + + LIBNFS_LIST_ADD(&nfs->nfsi->nested_mounts, mnt); + +finished: + free(md_item_cb->path); + free(md_item_cb); + md_cb->wait_count--; + if (md_cb->wait_count > 0) + return; + + rpc_disconnect(rpc, "normal disconnect"); + + if (md_cb->status == RPC_STATUS_CANCEL) { + data->cb(-EINTR, nfs, "Command was cancelled", + data->private_data); + free(md_cb); + free_nfs_cb_data(data); + return; + } + if (md_cb->error) { + data->cb(md_cb->error, nfs, command_data, data->private_data); + free(md_cb); + free_nfs_cb_data(data); + return; + } + + if (nfs->nfsi->nfsport) { + if (rpc_connect_port_async(nfs->rpc, nfs_get_server(nfs), + nfs->nfsi->nfsport, + NFS_PROGRAM, NFS_V3, + nfs3_mount_5_cb, data) != 0) { + nfs_set_error(nfs, "%s: %s", __FUNCTION__, + nfs_get_error(nfs)); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free(md_cb); + free_nfs_cb_data(data); + return; + } + return; + } + + if (rpc_connect_program_async(nfs->rpc, nfs_get_server(nfs), + NFS_PROGRAM, + NFS_V3, nfs3_mount_5_cb, data) != 0) { + nfs_set_error(nfs, "%s: %s", __FUNCTION__, nfs_get_error(nfs)); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free(md_cb); + free_nfs_cb_data(data); + return; + } + free(md_cb); +} + +static void +nfs3_mount_3_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + exports res; + int len; + struct mount_discovery_cb *md_cb = NULL; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + /* Iterate over all exports and check if there are any mounts nested + * below the current mount. + */ + len = strlen(nfs_get_export(nfs)); + if (!len) { + data->cb(-EFAULT, nfs, "Export is empty", data->private_data); + free_nfs_cb_data(data); + return; + } + res = *(exports *)command_data; + while (res) { + struct mount_discovery_item_cb *md_item_cb; + + if (strncmp(nfs_get_export(nfs), res->ex_dir, len)) { + res = res->ex_next; + continue; + } + if (res->ex_dir[len - 1] != '/' && res->ex_dir[len] != '/') { + res = res->ex_next; + continue; + } + + /* There is no need to fail the whole mount if anything + * below fails. Just clean up and continue. At worst it + * just mean that we might not be able to access any nested + * mounts. + */ + md_item_cb = malloc(sizeof(*md_item_cb)); + if (md_item_cb == NULL) + continue; + + memset(md_item_cb, 0, sizeof(*md_item_cb)); + + md_item_cb->path = strdup(res->ex_dir + len + - (nfs_get_export(nfs)[len -1] == '/')); + if (md_item_cb->path == NULL) { + free(md_item_cb); + continue; + } + + if (md_cb == NULL) { + md_cb = malloc(sizeof(*md_cb)); + if (md_cb == NULL) { + free(md_item_cb->path); + free(md_item_cb); + continue; + } + memset(md_cb, 0, sizeof(*md_cb)); + md_cb->data = data; + md_cb->status = RPC_STATUS_SUCCESS; + md_cb->error = 0; + } + md_item_cb->md_cb = md_cb; + + if (rpc_mount3_mnt_task(rpc, nfs3_mount_4_cb, + res->ex_dir, md_item_cb) == NULL) { + nfs_set_error(nfs, "%s: %s", + __FUNCTION__, nfs_get_error(nfs)); + if (md_cb->wait_count == 0) { + free(md_cb); + md_cb = NULL; + } + free(md_item_cb->path); + free(md_item_cb); + continue; + } + md_cb->wait_count++; + + res = res->ex_next; + } + + if (md_cb) + return; + + /* We did not have any nested mounts to check so we can proceed straight + * to reconnecting to NFSd. + */ + rpc_disconnect(rpc, "normal disconnect"); + + if (nfs->nfsi->nfsport) { + if (rpc_connect_port_async(nfs->rpc, nfs_get_server(nfs), + nfs->nfsi->nfsport, + NFS_PROGRAM, NFS_V3, + nfs3_mount_5_cb, data) != 0) { + nfs_set_error(nfs, "%s: %s", __FUNCTION__, + nfs_get_error(nfs)); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return; + } + return; + } + + if (rpc_connect_program_async(nfs->rpc, nfs_get_server(nfs), + NFS_PROGRAM, + NFS_V3, nfs3_mount_5_cb, data) != 0) { + nfs_set_error(nfs, "%s: %s", __FUNCTION__, nfs_get_error(nfs)); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } +} + +static void +nfs3_mount_2_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + mountres3 *res; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + res = command_data; + if (res->fhs_status != MNT3_OK) { + nfs_set_error(nfs, "RPC error: Mount failed with error " + "%s(%d) %s(%d)", + mountstat3_to_str(res->fhs_status), + res->fhs_status, + strerror(-mountstat3_to_errno(res->fhs_status)), + -mountstat3_to_errno(res->fhs_status)); + data->cb(mountstat3_to_errno(res->fhs_status), nfs, + nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + + nfs->nfsi->rootfh.len = res->mountres3_u.mountinfo.fhandle.fhandle3_len; + nfs->nfsi->rootfh.val = malloc(nfs->nfsi->rootfh.len); + if (nfs->nfsi->rootfh.val == NULL) { + nfs_set_error(nfs, "%s: %s", __FUNCTION__, nfs_get_error(nfs)); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + memcpy(nfs->nfsi->rootfh.val, + res->mountres3_u.mountinfo.fhandle.fhandle3_val, + nfs->nfsi->rootfh.len); + + if (nfs->nfsi->auto_traverse_mounts) { + if (rpc_mount3_export_task(rpc, nfs3_mount_3_cb, data) == NULL) { + nfs_set_error(nfs, "%s: %s", __FUNCTION__, + nfs_get_error(nfs)); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return; + } + return; + } + + rpc_disconnect(rpc, "normal disconnect"); + + if (nfs->nfsi->nfsport) { + if (rpc_connect_port_async(nfs->rpc, nfs_get_server(nfs), + nfs->nfsi->nfsport, + NFS_PROGRAM, NFS_V3, + nfs3_mount_5_cb, data) != 0) { + nfs_set_error(nfs, "%s: %s", __FUNCTION__, + nfs_get_error(nfs)); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return; + } + return; + } + + if (rpc_connect_program_async(nfs->rpc, nfs_get_server(nfs), + NFS_PROGRAM, + NFS_V3, nfs3_mount_5_cb, data) != 0) { + nfs_set_error(nfs, "%s: %s", __FUNCTION__, nfs_get_error(nfs)); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } +} + + +static void +nfs3_mount_1_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + if (rpc_mount3_mnt_task(rpc, nfs3_mount_2_cb, nfs->nfsi->export, + data) == NULL) { + nfs_set_error(nfs, "%s: %s.", __FUNCTION__, nfs_get_error(nfs)); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } +} + +int +nfs3_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; + + new_server = strdup(server); + if (new_server == NULL) { + nfs_set_error(nfs, "out of memory. failed to allocate " + "memory for nfs server string"); + return -1; + } + free(nfs->nfsi->server); + nfs->nfsi->server = new_server; + + free(nfs->rpc->server); + nfs->rpc->server = strdup(nfs->nfsi->server); + + new_export = strdup(export); + if (new_export == NULL) { + nfs_set_error(nfs, "out of memory. failed to allocate " + "memory for nfs export string"); + return -1; + } + free(nfs->nfsi->export); + nfs->nfsi->export = new_export; + + data = calloc(1, sizeof(*data)); + if (data == NULL) { + nfs_set_error(nfs, "out of memory. failed to allocate " + "memory for nfs mount data"); + return -1; + } + + data->nfs = nfs; + data->cb = cb; + data->private_data = private_data; + + if (nfs->nfsi->mountport) { + if (rpc_connect_port_async(nfs->rpc, server, nfs->nfsi->mountport, + MOUNT_PROGRAM, MOUNT_V3, + nfs3_mount_1_cb, data) != 0) { + nfs_set_error(nfs, "Failed to start connection. %s", + nfs_get_error(nfs)); + free_nfs_cb_data(data); + return -1; + } + return 0; + } + + if (rpc_connect_program_async(nfs->rpc, server, + MOUNT_PROGRAM, MOUNT_V3, + nfs3_mount_1_cb, data) != 0) { + nfs_set_error(nfs, "Failed to start connection. %s", + nfs_get_error(nfs)); + free_nfs_cb_data(data); + return -1; + } + + return 0; +} + +static void +nfs3_umount_2_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + rpc_disconnect(rpc, "umount"); + data->cb(0, nfs, NULL, data->private_data); + free_nfs_cb_data(data); +} + +static void +nfs3_umount_1_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + if (rpc_mount3_umnt_task(rpc, nfs3_umount_2_cb, nfs->nfsi->export, + data) == NULL) { + nfs_set_error(nfs, "%s: %s.", __FUNCTION__, nfs_get_error(nfs)); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } +} + +int +nfs3_umount_async(struct nfs_context *nfs, nfs_cb cb, void *private_data) +{ + struct nfs_cb_data *data; + + data = malloc(sizeof(struct nfs_cb_data)); + if (data == NULL) { + nfs_set_error(nfs, "out of memory. failed to allocate " + "memory for nfs mount data"); + return -1; + } + memset(data, 0, sizeof(struct nfs_cb_data)); + + data->nfs = nfs; + data->cb = cb; + data->private_data = private_data; + + rpc_disconnect(nfs->rpc, "umount"); + + if (nfs->nfsi->mountport) { + if (rpc_connect_port_async(nfs->rpc, nfs_get_server(nfs), + nfs->nfsi->mountport, + MOUNT_PROGRAM, MOUNT_V3, + nfs3_umount_1_cb, data) != 0) { + nfs_set_error(nfs, "Failed to start connection. %s", + nfs_get_error(nfs)); + free_nfs_cb_data(data); + return -1; + } + return 0; + } + + if (rpc_connect_program_async(nfs->rpc, nfs_get_server(nfs), + MOUNT_PROGRAM, MOUNT_V3, + nfs3_umount_1_cb, data) != 0) { + nfs_set_error(nfs, "Failed to start connection. %s", + nfs_get_error(nfs)); + free_nfs_cb_data(data); + return -1; + } + + return 0; +} + + +struct nfs_link_data { + char *oldpath; + struct nfs_fh oldfh; + char *newparent; + char *newobject; + struct nfs_fh newdir; +}; + +static void +free_nfs_link_data(void *mem) +{ + struct nfs_link_data *data = mem; + + free(data->oldpath); + free(data->oldfh.val); + free(data->newparent); + free(data->newobject); + free(data->newdir.val); + free(data); +} + +static void +nfs3_link_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + LINK3res *res; + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + struct nfs_link_data *link_data = data->continue_data; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + res = command_data; + if (res->status != NFS3_OK) { + nfs_set_error(nfs, "NFS: LINK %s -> %s/%s failed with " + "%s(%d)", link_data->oldpath, + link_data->newparent, + link_data->newobject, + nfsstat3_to_str(res->status), + nfsstat3_to_errno(res->status)); + data->cb(nfsstat3_to_errno(res->status), nfs, + nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + + nfs_dircache_drop(nfs, &link_data->newdir); + data->cb(0, nfs, NULL, data->private_data); + free_nfs_cb_data(data); +} + +static int +nfs3_link_continue_2_internal(struct nfs_context *nfs, + struct nfs_attr *attr _U_, + struct nfs_cb_data *data) +{ + struct nfs_link_data *link_data = data->continue_data; + LINK3args args; + + /* steal the filehandle */ + link_data->newdir = data->fh; + data->fh.val = NULL; + + memset(&args, 0, sizeof(LINK3args)); + args.file.data.data_len = link_data->oldfh.len; + args.file.data.data_val = link_data->oldfh.val; + args.link.dir.data.data_len = link_data->newdir.len; + args.link.dir.data.data_val = link_data->newdir.val; + args.link.name = link_data->newobject; + if (rpc_nfs3_link_task(nfs->rpc, nfs3_link_cb, &args, data) == NULL) { + nfs_set_error(nfs, "RPC error: Failed to send LINK " + "call for %s", data->path); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return -1; + } + return 0; +} + +static int +nfs3_link_continue_1_internal(struct nfs_context *nfs, + struct nfs_attr *attr _U_, + struct nfs_cb_data *data) +{ + struct nfs_link_data *link_data = data->continue_data; + + /* steal the filehandle */ + link_data->oldfh = data->fh; + data->fh.val = NULL; + + if (nfs3_lookuppath_async(nfs, link_data->newparent, 0, + data->cb, data->private_data, + nfs3_link_continue_2_internal, + link_data, free_nfs_link_data, 0) != 0) { + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + data->continue_data = NULL; + free_nfs_cb_data(data); + return -1; + } + data->continue_data = NULL; + free_nfs_cb_data(data); + + return 0; +} + +int +nfs3_link_async(struct nfs_context *nfs, const char *oldpath, + const char *newpath, nfs_cb cb, void *private_data) +{ + char *ptr; + struct nfs_link_data *link_data; + + link_data = calloc(1, sizeof(struct nfs_link_data)); + if (link_data == NULL) { + nfs_set_error(nfs, "Out of memory, failed to allocate " + "buffer for link data"); + return -1; + } + + link_data->oldpath = strdup(oldpath); + if (link_data->oldpath == NULL) { + nfs_set_error(nfs, "Out of memory, failed to allocate " + "buffer for oldpath"); + free_nfs_link_data(link_data); + return -1; + } + + link_data->newobject = strdup(newpath); + if (link_data->newobject == NULL) { + nfs_set_error(nfs, "Out of memory, failed to strdup " + "newpath"); + free_nfs_link_data(link_data); + return -1; + } + ptr = strrchr(link_data->newobject, '/'); + if (ptr == NULL) { + link_data->newparent = NULL; + } else { + *ptr = 0; + link_data->newparent = link_data->newobject; + + ptr++; + link_data->newobject = strdup(ptr); + } + if (link_data->newobject == NULL) { + nfs_set_error(nfs, "Out of memory, failed to allocate " + "buffer for newobject"); + free_nfs_link_data(link_data); + return -1; + } + + if (nfs3_lookuppath_async(nfs, link_data->oldpath, 0, + cb, private_data, + nfs3_link_continue_1_internal, + link_data, free_nfs_link_data, 0) != 0) { + return -1; + } + + return 0; +} + +struct nfs_rename_data { + char *oldparent; + char *oldobject; + struct nfs_fh olddir; + char *newparent; + char *newobject; + struct nfs_fh newdir; +}; + +static void +free_nfs_rename_data(void *mem) +{ + struct nfs_rename_data *data = mem; + + free(data->oldparent); + free(data->oldobject); + free(data->olddir.val); + free(data->newparent); + free(data->newobject); + free(data->newdir.val); + free(data); +} + +static void +nfs3_rename_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + RENAME3res *res; + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + struct nfs_rename_data *rename_data = data->continue_data; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + res = command_data; + if (res->status != NFS3_OK) { + nfs_set_error(nfs, "NFS: RENAME %s/%s -> %s/%s failed " + "with %s(%d)", rename_data->oldparent, + rename_data->oldobject, rename_data->newparent, + rename_data->newobject, + nfsstat3_to_str(res->status), + nfsstat3_to_errno(res->status)); + data->cb(nfsstat3_to_errno(res->status), nfs, + nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + + data->cb(0, nfs, NULL, data->private_data); + free_nfs_cb_data(data); +} + +static int +nfs3_rename_continue_2_internal(struct nfs_context *nfs, + struct nfs_attr *attr _U_, + struct nfs_cb_data *data) +{ + struct nfs_rename_data *rename_data = data->continue_data; + RENAME3args args; + + /* Drop the destination directory from the cache */ + nfs_dircache_drop(nfs, &data->fh); + + /* steal the filehandle */ + rename_data->newdir = data->fh; + data->fh.val = NULL; + + args.from.dir.data.data_len = rename_data->olddir.len; + args.from.dir.data.data_val = rename_data->olddir.val; + args.from.name = rename_data->oldobject; + args.to.dir.data.data_len = rename_data->newdir.len; + args.to.dir.data.data_val = rename_data->newdir.val; + args.to.name = rename_data->newobject; + if (rpc_nfs3_rename_task(nfs->rpc, nfs3_rename_cb, &args, data) == NULL) { + nfs_set_error(nfs, "RPC error: Failed to send RENAME " + "call for %s", data->path); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return -1; + } + return 0; +} + +static int +nfs3_rename_continue_1_internal(struct nfs_context *nfs, + struct nfs_attr *attr _U_, + struct nfs_cb_data *data) +{ + struct nfs_rename_data *rename_data = data->continue_data; + + /* Drop the source directory from the cache */ + nfs_dircache_drop(nfs, &data->fh); + + /* steal the filehandle */ + rename_data->olddir = data->fh; + data->fh.val = NULL; + + if (nfs3_lookuppath_async(nfs, rename_data->newparent, 0, + data->cb, data->private_data, + nfs3_rename_continue_2_internal, + rename_data, free_nfs_rename_data, 0) != 0) { + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + data->continue_data = NULL; + free_nfs_cb_data(data); + return -1; + } + data->continue_data = NULL; + free_nfs_cb_data(data); + + return 0; +} + +int +nfs3_rename_async(struct nfs_context *nfs, const char *oldpath, + const char *newpath, nfs_cb cb, void *private_data) +{ + char *ptr; + struct nfs_rename_data *rename_data; + + rename_data = calloc(1, sizeof(struct nfs_rename_data)); + if (rename_data == NULL) { + nfs_set_error(nfs, "Out of memory, failed to allocate " + "buffer for rename data"); + return -1; + } + + rename_data->oldobject = strdup(oldpath); + if (rename_data->oldobject == NULL) { + nfs_set_error(nfs, "Out of memory, failed to strdup " + "oldpath"); + free_nfs_rename_data(rename_data); + return -1; + } + ptr = strrchr(rename_data->oldobject, '/'); + if (ptr == NULL) { + rename_data->oldparent = NULL; + } else { + *ptr = 0; + rename_data->oldparent = rename_data->oldobject; + + ptr++; + rename_data->oldobject = strdup(ptr); + } + if (rename_data->oldobject == NULL) { + nfs_set_error(nfs, "Out of memory, failed to allocate " + "buffer for oldobject"); + free_nfs_rename_data(rename_data); + return -1; + } + + rename_data->newobject = strdup(newpath); + if (rename_data->newobject == NULL) { + nfs_set_error(nfs, "Out of memory, failed to strdup " + "newpath"); + free_nfs_rename_data(rename_data); + return -1; + } + ptr = strrchr(rename_data->newobject, '/'); + if (ptr == NULL) { + rename_data->newparent = NULL; + } else { + *ptr = 0; + rename_data->newparent = rename_data->newobject; + + ptr++; + rename_data->newobject = strdup(ptr); + } + if (rename_data->newobject == NULL) { + nfs_set_error(nfs, "Out of memory, failed to allocate " + "buffer for newobject"); + free_nfs_rename_data(rename_data); + return -1; + } + + if (nfs3_lookuppath_async(nfs, rename_data->oldparent, 0, + cb, private_data, + nfs3_rename_continue_1_internal, + rename_data, free_nfs_rename_data, 0) != 0) { + return -1; + } + + return 0; +} + + +struct nfs_symlink_data { + char *target; + char *linkparent; + char *linkobject; +}; + +static void +free_nfs_symlink_data(void *mem) +{ + struct nfs_symlink_data *data = mem; + + free(data->target); + free(data->linkparent); + free(data->linkobject); + free(data); +} + +static void +nfs3_symlink_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + SYMLINK3res *res; + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + struct nfs_symlink_data *symlink_data = data->continue_data; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + res = command_data; + if (res->status != NFS3_OK) { + nfs_set_error(nfs, "NFS: SYMLINK %s/%s -> %s failed with " + "%s(%d)", symlink_data->linkparent, + symlink_data->linkobject, + symlink_data->target, + nfsstat3_to_str(res->status), + nfsstat3_to_errno(res->status)); + data->cb(nfsstat3_to_errno(res->status), nfs, + nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + + nfs_dircache_drop(nfs, &data->fh); + data->cb(0, nfs, NULL, data->private_data); + free_nfs_cb_data(data); +} + +static int +nfs3_symlink_continue_internal(struct nfs_context *nfs, + struct nfs_attr *attr _U_, + struct nfs_cb_data *data) +{ + struct nfs_symlink_data *symlink_data = data->continue_data; + SYMLINK3args args; + + memset(&args, 0, sizeof(SYMLINK3args)); + args.where.dir.data.data_len = data->fh.len; + args.where.dir.data.data_val = data->fh.val; + args.where.name = symlink_data->linkobject; + args.symlink.symlink_attributes.mode.set_it = 1; + args.symlink.symlink_attributes.mode.set_mode3_u.mode = S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH; + args.symlink.symlink_data = symlink_data->target; + + if (rpc_nfs3_symlink_task(nfs->rpc, nfs3_symlink_cb, + &args, data) == NULL) { + nfs_set_error(nfs, "RPC error: Failed to send SYMLINK " + "call for %s", data->path); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return -1; + } + return 0; +} + +int +nfs3_symlink_async(struct nfs_context *nfs, const char *target, + const char *linkname, nfs_cb cb, void *private_data) +{ + char *ptr; + struct nfs_symlink_data *symlink_data; + + symlink_data = calloc(1, sizeof(struct nfs_symlink_data)); + if (symlink_data == NULL) { + nfs_set_error(nfs, "Out of memory, failed to allocate " + "buffer for symlink data"); + return -1; + } + + symlink_data->target = strdup(target); + if (symlink_data->target == NULL) { + nfs_set_error(nfs, "Out of memory, failed to allocate " + "buffer for target"); + free_nfs_symlink_data(symlink_data); + return -1; + } + + symlink_data->linkobject = strdup(linkname); + if (symlink_data->linkobject == NULL) { + nfs_set_error(nfs, "Out of memory, failed to strdup " + "linkname"); + free_nfs_symlink_data(symlink_data); + return -1; + } + ptr = strrchr(symlink_data->linkobject, '/'); + if (ptr == NULL) { + symlink_data->linkparent = NULL; + } else { + *ptr = 0; + symlink_data->linkparent = symlink_data->linkobject; + + ptr++; + symlink_data->linkobject = strdup(ptr); + } + + if (symlink_data->linkobject == NULL) { + nfs_set_error(nfs, "Out of memory, failed to allocate " + "mode buffer for new path"); + free_nfs_symlink_data(symlink_data); + return -1; + } + + if (nfs3_lookuppath_async(nfs, symlink_data->linkparent, 0, + cb, private_data, + nfs3_symlink_continue_internal, + symlink_data, free_nfs_symlink_data, 0) + != 0) { + return -1; + } + + return 0; +} + + +static void +nfs3_access2_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + ACCESS3res *res; + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + unsigned int result = 0; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + res = command_data; + if (res->status != NFS3_OK) { + nfs_set_error(nfs, "NFS: ACCESS 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, + nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + + if (res->ACCESS3res_u.resok.access & ACCESS3_READ) { + result |= R_OK; + } + if (res->ACCESS3res_u.resok.access & (ACCESS3_MODIFY | ACCESS3_EXTEND | ACCESS3_DELETE)) { + result |= W_OK; + } + if (res->ACCESS3res_u.resok.access & (ACCESS3_LOOKUP | ACCESS3_EXECUTE)) { + result |= X_OK; + } + + data->cb(result, nfs, NULL, data->private_data); + free_nfs_cb_data(data); +} + +static int +nfs3_access2_continue_internal(struct nfs_context *nfs, + struct nfs_attr *attr _U_, + struct nfs_cb_data *data) +{ + ACCESS3args args; + + memset(&args, 0, sizeof(ACCESS3args)); + args.object.data.data_len = data->fh.len; + args.object.data.data_val = data->fh.val; + args.access = ACCESS3_READ | ACCESS3_LOOKUP | ACCESS3_MODIFY | ACCESS3_EXTEND | ACCESS3_DELETE | ACCESS3_EXECUTE; + + if (rpc_nfs3_access_task(nfs->rpc, nfs3_access2_cb, + &args, data) == NULL) { + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return -1; + } + return 0; +} + +int +nfs3_access2_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data) +{ + if (nfs3_lookuppath_async(nfs, path, 0, cb, private_data, + nfs3_access2_continue_internal, + NULL, NULL, 0) != 0) { + return -1; + } + + return 0; +} + + +static void +nfs3_access_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + ACCESS3res *res; + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + unsigned int mode = 0; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + res = command_data; + if (res->status != NFS3_OK) { + nfs_set_error(nfs, "NFS: ACCESS 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, + nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + + if ((data->continue_int & R_OK) && (res->ACCESS3res_u.resok.access & ACCESS3_READ)) { + mode |= R_OK; + } + if ((data->continue_int & W_OK) && (res->ACCESS3res_u.resok.access & (ACCESS3_MODIFY | ACCESS3_EXTEND | ACCESS3_DELETE))) { + mode |= W_OK; + } + if ((data->continue_int & X_OK) && (res->ACCESS3res_u.resok.access & (ACCESS3_LOOKUP | ACCESS3_EXECUTE))) { + mode |= X_OK; + } + + if (data->continue_int != mode) { + nfs_set_error(nfs, "NFS: ACCESS denied. Required access " + "%c%c%c. Allowed access %c%c%c", + data->continue_int&R_OK?'r':'-', + data->continue_int&W_OK?'w':'-', + data->continue_int&X_OK?'x':'-', + mode&R_OK?'r':'-', + mode&W_OK?'w':'-', + mode&X_OK?'x':'-'); + data->cb(-EACCES, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return; + } + + data->cb(0, nfs, NULL, data->private_data); + free_nfs_cb_data(data); +} + +static int +nfs3_access_continue_internal(struct nfs_context *nfs, + struct nfs_attr *attr _U_, + struct nfs_cb_data *data) +{ + int nfsmode = 0; + ACCESS3args args; + + if (data->continue_int & R_OK) { + nfsmode |= ACCESS3_READ; + } + if (data->continue_int & W_OK) { + nfsmode |= ACCESS3_MODIFY | ACCESS3_EXTEND | ACCESS3_DELETE; + } + if (data->continue_int & X_OK) { + nfsmode |= ACCESS3_LOOKUP | ACCESS3_EXECUTE; + } + + memset(&args, 0, sizeof(ACCESS3args)); + args.object.data.data_len = data->fh.len; + args.object.data.data_val = data->fh.val; + args.access = nfsmode; + + if (rpc_nfs3_access_task(nfs->rpc, nfs3_access_cb, &args, data) == NULL) { + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return -1; + } + return 0; +} + +int +nfs3_access_async(struct nfs_context *nfs, const char *path, int mode, + nfs_cb cb, void *private_data) +{ + if (nfs3_lookuppath_async(nfs, path, 0, cb, private_data, + nfs3_access_continue_internal, + NULL, NULL, + mode & (R_OK | W_OK | X_OK)) != 0) { + return -1; + } + + return 0; +} + +static void +nfs3_utimes_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + SETATTR3res *res; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + res = command_data; + if (res->status != NFS3_OK) { + nfs_set_error(nfs, "NFS: SETATTR failed with %s(%d)", + nfsstat3_to_str(res->status), + nfsstat3_to_errno(res->status)); + data->cb(nfsstat3_to_errno(res->status), nfs, + nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + + nfs_dircache_drop(nfs, &data->fh); + data->cb(0, nfs, NULL, data->private_data); + free_nfs_cb_data(data); +} + +static int +nfs3_utimes_continue_internal(struct nfs_context *nfs, + struct nfs_attr *attr _U_, + struct nfs_cb_data *data) +{ + SETATTR3args args; + struct timeval *utimes_data = data->continue_data; + + memset(&args, 0, sizeof(SETATTR3args)); + args.object.data.data_len = data->fh.len; + args.object.data.data_val = data->fh.val; + if (utimes_data != NULL) { + args.new_attributes.atime.set_it = SET_TO_CLIENT_TIME; + args.new_attributes.atime.set_atime_u.atime.seconds = utimes_data[0].tv_sec; + args.new_attributes.atime.set_atime_u.atime.nseconds = utimes_data[0].tv_usec * 1000; + args.new_attributes.mtime.set_it = SET_TO_CLIENT_TIME; + args.new_attributes.mtime.set_mtime_u.mtime.seconds = utimes_data[1].tv_sec; + args.new_attributes.mtime.set_mtime_u.mtime.nseconds = utimes_data[1].tv_usec * 1000; + } else { + args.new_attributes.atime.set_it = SET_TO_SERVER_TIME; + args.new_attributes.mtime.set_it = SET_TO_SERVER_TIME; + } + + if (rpc_nfs3_setattr_task(nfs->rpc, nfs3_utimes_cb, + &args, data) == NULL) { + nfs_set_error(nfs, "RPC error: Failed to send SETATTR " + "call for %s", data->path); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return -1; + } + return 0; +} + +int +nfs3_utimes_async_internal(struct nfs_context *nfs, const char *path, + int no_follow, struct timeval *times, + nfs_cb cb, void *private_data) +{ + struct timeval *new_times = NULL; + + if (times != NULL) { + new_times = malloc(sizeof(struct timeval)*2); + if (new_times == NULL) { + nfs_set_error(nfs, "Failed to allocate memory " + "for timeval structure"); + return -1; + } + + memcpy(new_times, times, sizeof(struct timeval)*2); + } + + if (nfs3_lookuppath_async(nfs, path, no_follow, cb, private_data, + nfs3_utimes_continue_internal, + new_times, free, 0) != 0) { + return -1; + } + + return 0; +} + +int +nfs3_utime_async(struct nfs_context *nfs, const char *path, + struct utimbuf *times, nfs_cb cb, void *private_data) +{ + struct timeval *new_times = NULL; + + if (times != NULL) { + new_times = malloc(sizeof(struct timeval)*2); + if (new_times == NULL) { + nfs_set_error(nfs, "Failed to allocate memory " + "for timeval structure"); + return -1; + } + + new_times[0].tv_sec = times->actime; + new_times[0].tv_usec = 0; + new_times[1].tv_sec = times->modtime; + new_times[1].tv_usec = 0; + } + + if (nfs3_lookuppath_async(nfs, path, 0, cb, private_data, + nfs3_utimes_continue_internal, + new_times, free, 0) != 0) { + return -1; + } + + return 0; +} + + +static void +nfs3_chown_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + SETATTR3res *res; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + res = command_data; + if (res->status != NFS3_OK) { + nfs_set_error(nfs, "NFS: SETATTR failed with %s(%d)", + nfsstat3_to_str(res->status), + nfsstat3_to_errno(res->status)); + data->cb(nfsstat3_to_errno(res->status), nfs, + nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + + data->cb(0, nfs, NULL, data->private_data); + free_nfs_cb_data(data); +} + +struct nfs_chown_data { + uid_t uid; + gid_t gid; +}; + +static int +nfs3_chown_continue_internal(struct nfs_context *nfs, + struct nfs_attr *attr _U_, + struct nfs_cb_data *data) +{ + SETATTR3args args; + struct nfs_chown_data *chown_data = data->continue_data; + + memset(&args, 0, sizeof(SETATTR3args)); + args.object.data.data_len = data->fh.len; + args.object.data.data_val = data->fh.val; + if (chown_data->uid != (uid_t)-1) { + args.new_attributes.uid.set_it = 1; + args.new_attributes.uid.set_uid3_u.uid = chown_data->uid; + } + if (chown_data->gid != (gid_t)-1) { + args.new_attributes.gid.set_it = 1; + args.new_attributes.gid.set_gid3_u.gid = chown_data->gid; + } + + if (rpc_nfs3_setattr_task(nfs->rpc, nfs3_chown_cb, &args, data) == NULL) { + nfs_set_error(nfs, "RPC error: Failed to send SETATTR " + "call for %s", data->path); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return -1; + } + return 0; +} + +int +nfs3_chown_async_internal(struct nfs_context *nfs, const char *path, + int no_follow, int uid, int gid, + nfs_cb cb, void *private_data) +{ + struct nfs_chown_data *chown_data; + + chown_data = malloc(sizeof(struct nfs_chown_data)); + if (chown_data == NULL) { + nfs_set_error(nfs, "Failed to allocate memory for " + "chown data structure"); + return -1; + } + + chown_data->uid = uid; + chown_data->gid = gid; + + if (nfs3_lookuppath_async(nfs, path, no_follow, cb, private_data, + nfs3_chown_continue_internal, + chown_data, free, 0) != 0) { + return -1; + } + + return 0; +} + +int +nfs3_fchown_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int uid, + int gid, nfs_cb cb, void *private_data) +{ + struct nfs_cb_data *data; + struct nfs_chown_data *chown_data; + + chown_data = malloc(sizeof(struct nfs_chown_data)); + if (chown_data == NULL) { + nfs_set_error(nfs, "Failed to allocate memory for " + "fchown data structure"); + return -1; + } + + chown_data->uid = uid; + chown_data->gid = gid; + + data = calloc(1, sizeof(struct nfs_cb_data)); + if (data == NULL) { + nfs_set_error(nfs, "out of memory. failed to allocate " + "memory for fchown data"); + free(chown_data); + return -1; + } + data->nfs = nfs; + data->cb = cb; + data->private_data = private_data; + data->continue_data = chown_data; + data->free_continue_data = free; + data->fh.len = nfsfh->fh.len; + data->fh.val = malloc(data->fh.len); + if (data->fh.val == NULL) { + nfs_set_error(nfs, "Out of memory: Failed to allocate fh"); + free_nfs_cb_data(data); + return -1; + } + memcpy(data->fh.val, nfsfh->fh.val, data->fh.len); + + if (nfs3_chown_continue_internal(nfs, NULL, data) != 0) { + return -1; + } + + return 0; +} + +static void +nfs3_chmod_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + SETATTR3res *res; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + res = command_data; + if (res->status != NFS3_OK) { + nfs_set_error(nfs, "NFS: SETATTR failed with %s(%d)", + nfsstat3_to_str(res->status), + nfsstat3_to_errno(res->status)); + data->cb(nfsstat3_to_errno(res->status), nfs, + nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + + nfs_dircache_drop(nfs, &data->fh); + data->cb(0, nfs, NULL, data->private_data); + free_nfs_cb_data(data); +} + +static int +nfs3_chmod_continue_internal(struct nfs_context *nfs, + struct nfs_attr *attr _U_, + struct nfs_cb_data *data) +{ + SETATTR3args args; + + memset(&args, 0, sizeof(SETATTR3args)); + args.object.data.data_len = data->fh.len; + args.object.data.data_val = data->fh.val; + args.new_attributes.mode.set_it = 1; + args.new_attributes.mode.set_mode3_u.mode = (mode3)data->continue_int; + + if (rpc_nfs3_setattr_task(nfs->rpc, nfs3_chmod_cb, &args, data) == NULL) { + nfs_set_error(nfs, "RPC error: Failed to send SETATTR " + "call for %s", data->path); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return -1; + } + return 0; +} + +int +nfs3_chmod_async_internal(struct nfs_context *nfs, const char *path, + int no_follow, int mode, nfs_cb cb, + void *private_data) +{ + if (nfs3_lookuppath_async(nfs, path, no_follow, cb, private_data, + nfs3_chmod_continue_internal, + NULL, NULL, mode) != 0) { + return -1; + } + + return 0; +} + +int +nfs3_fchmod_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int mode, + nfs_cb cb, void *private_data) +{ + struct nfs_cb_data *data; + + data = calloc(1, sizeof(struct nfs_cb_data)); + if (data == NULL) { + nfs_set_error(nfs, "out of memory. failed to allocate " + "memory for fchmod data"); + return -1; + } + data->nfs = nfs; + data->cb = cb; + data->private_data = private_data; + data->continue_int = mode; + data->fh.len = nfsfh->fh.len; + data->fh.val = malloc(data->fh.len); + if (data->fh.val == NULL) { + nfs_set_error(nfs, "Out of memory: Failed to allocate fh"); + free_nfs_cb_data(data); + return -1; + } + memcpy(data->fh.val, nfsfh->fh.val, data->fh.len); + + if (nfs3_chmod_continue_internal(nfs, NULL, data) != 0) { + return -1; + } + + return 0; +} + + +static void +nfs3_readlink_1_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + READLINK3res *res; + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + res = command_data; + if (res->status != NFS3_OK) { + nfs_set_error(nfs, "NFS: READLINK 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, + nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + + data->cb(0, nfs, res->READLINK3res_u.resok.data, data->private_data); + free_nfs_cb_data(data); +} + +static int +nfs3_readlink_continue_internal(struct nfs_context *nfs, + struct nfs_attr *attr _U_, + struct nfs_cb_data *data) +{ + READLINK3args args; + + args.symlink.data.data_val = data->fh.val; + args.symlink.data.data_len = data->fh.len; + + if (rpc_nfs3_readlink_task(nfs->rpc, nfs3_readlink_1_cb, + &args, data) == NULL) { + nfs_set_error(nfs, "RPC error: Failed to send READLINK " + "call for %s", data->path); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return -1; + } + return 0; +} + +int +nfs3_readlink_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data) +{ + if (nfs3_lookuppath_async(nfs, path, 1, cb, private_data, + nfs3_readlink_continue_internal, + NULL, NULL, 0) != 0) { + return -1; + } + + return 0; +} + +static void +nfs3_statvfs_1_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + FSSTAT3res *res; + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + struct statvfs svfs; + struct nfs_statvfs_64 svfs64; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + res = command_data; + if (res->status != NFS3_OK) { + nfs_set_error(nfs, "NFS: FSSTAT 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, + nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + + if (data->continue_int == 0) { + /* statvfs */ + svfs.f_bsize = NFS_BLKSIZE; + svfs.f_frsize = NFS_BLKSIZE; + svfs.f_blocks = res->FSSTAT3res_u.resok.tbytes/NFS_BLKSIZE; + svfs.f_bfree = res->FSSTAT3res_u.resok.fbytes/NFS_BLKSIZE; + svfs.f_bavail = res->FSSTAT3res_u.resok.abytes/NFS_BLKSIZE; + svfs.f_files = (uint32_t)res->FSSTAT3res_u.resok.tfiles; + svfs.f_ffree = (uint32_t)res->FSSTAT3res_u.resok.ffiles; +#if !defined(__ANDROID__) + svfs.f_favail = (uint32_t)res->FSSTAT3res_u.resok.afiles; + svfs.f_fsid = 0; + svfs.f_flag = 0; + svfs.f_namemax = 256; +#endif + data->cb(0, nfs, &svfs, data->private_data); + } else { + /* statvfs64 */ + svfs64.f_bsize = NFS_BLKSIZE; + svfs64.f_frsize = NFS_BLKSIZE; + svfs64.f_blocks = res->FSSTAT3res_u.resok.tbytes/NFS_BLKSIZE; + svfs64.f_bfree = res->FSSTAT3res_u.resok.fbytes/NFS_BLKSIZE; + svfs64.f_bavail = res->FSSTAT3res_u.resok.abytes/NFS_BLKSIZE; + svfs64.f_files = res->FSSTAT3res_u.resok.tfiles; + svfs64.f_ffree = res->FSSTAT3res_u.resok.ffiles; + svfs64.f_favail = res->FSSTAT3res_u.resok.afiles; + svfs64.f_fsid = 0; + svfs64.f_flag = 0; + svfs64.f_namemax = 256; + + data->cb(0, nfs, &svfs64, data->private_data); + } + + free_nfs_cb_data(data); +} + +static int +nfs3_statvfs_continue_internal(struct nfs_context *nfs, + struct nfs_attr *attr _U_, + struct nfs_cb_data *data) +{ + FSSTAT3args args; + + args.fsroot.data.data_len = data->fh.len; + args.fsroot.data.data_val = data->fh.val; + if (rpc_nfs3_fsstat_task(nfs->rpc, nfs3_statvfs_1_cb, + &args, data) == NULL) { + nfs_set_error(nfs, "RPC error: Failed to send FSSTAT " + "call for %s", data->path); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return -1; + } + return 0; +} + +int +nfs3_statvfs_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data) +{ + if (nfs3_lookuppath_async(nfs, path, 0, cb, private_data, + nfs3_statvfs_continue_internal, + NULL, NULL, 0) != 0) { + return -1; + } + + return 0; +} + +int +nfs3_statvfs64_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data) +{ + if (nfs3_lookuppath_async(nfs, path, 0, cb, private_data, + nfs3_statvfs_continue_internal, + NULL, NULL, 1) != 0) { + return -1; + } + + return 0; +} + +static void +nfs3_lseek_1_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + GETATTR3res *res; + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + int64_t size = 0; + int64_t offset = (int64_t) data->offset; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + res = command_data; + if (res->status != NFS3_OK) { + nfs_set_error(nfs, "NFS: GETATTR failed with " + "%s(%d)", nfsstat3_to_str(res->status), + nfsstat3_to_errno(res->status)); + data->cb(nfsstat3_to_errno(res->status), nfs, + nfs_get_error(nfs), data->private_data); + free(data); + return; + } + + size = (int64_t)res->GETATTR3res_u.resok.obj_attributes.size; + + if (offset < 0 && + -offset > (int64_t)size) { + data->cb(-EINVAL, nfs, &data->nfsfh->offset, + data->private_data); + } else { + data->nfsfh->offset = data->offset + size; + data->cb(0, nfs, &data->nfsfh->offset, data->private_data); + } + + free(data); +} + +int +nfs3_lseek_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int64_t offset, + int whence, nfs_cb cb, void *private_data) +{ + struct nfs_cb_data *data; + struct GETATTR3args args; + + if (whence == SEEK_SET) { + if (offset < 0) { + cb(-EINVAL, nfs, &nfsfh->offset, private_data); + } else { + nfsfh->offset = offset; + cb(0, nfs, &nfsfh->offset, private_data); + } + return 0; + } + if (whence == SEEK_CUR) { + if (offset < 0 && + nfsfh->offset < (uint64_t)(-offset)) { + cb(-EINVAL, nfs, &nfsfh->offset, private_data); + } else { + nfsfh->offset += offset; + cb(0, nfs, &nfsfh->offset, private_data); + } + return 0; + } + + data = calloc(1, sizeof(struct nfs_cb_data)); + if (data == NULL) { + nfs_set_error(nfs, "Out Of Memory: Failed to malloc nfs " + "cb data"); + return -1; + } + + data->nfs = nfs; + data->nfsfh = nfsfh; + data->offset = offset; + data->cb = cb; + data->private_data = private_data; + + memset(&args, 0, sizeof(GETATTR3args)); + args.object.data.data_len = nfsfh->fh.len; + args.object.data.data_val = nfsfh->fh.val; + + if (rpc_nfs3_getattr_task(nfs->rpc, nfs3_lseek_1_cb, + &args, data) == NULL) { + free(data); + return -1; + } + return 0; +} + + +/* 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 +nfs3_opendir_3_cb(struct rpc_context *rpc, 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; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + free(rdpe_lookup_cb_data); + + rdpe_cb_data->getattrcount--; + + if (status == RPC_STATUS_ERROR) { + + nfs_set_error(nfs, "LOOKUP during READDIRPLUS emulation " + "failed with RPC_STATUS_ERROR"); + rdpe_cb_data->status = RPC_STATUS_ERROR; + } + if (status == RPC_STATUS_CANCEL) { + nfs_set_error(nfs, "LOOKUP during READDIRPLUS emulation " + "failed with RPC_STATUS_CANCEL"); + rdpe_cb_data->status = RPC_STATUS_CANCEL; + } + if (status == RPC_STATUS_TIMEOUT) { + nfs_set_error(nfs, "LOOKUP during READDIRPLUS emulation " + "timed out"); + rdpe_cb_data->status = RPC_STATUS_CANCEL; + } + 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; + switch (nfsdirent->type) { + case NF3REG: nfsdirent->mode |= S_IFREG; break; + case NF3DIR: nfsdirent->mode |= S_IFDIR; break; + case NF3BLK: nfsdirent->mode |= S_IFBLK; break; + case NF3CHR: nfsdirent->mode |= S_IFCHR; break; + case NF3LNK: nfsdirent->mode |= S_IFLNK; break; + case NF3SOCK: nfsdirent->mode |= S_IFSOCK; break; + case NF3FIFO: nfsdirent->mode |= S_IFIFO; break; + }; + nfsdirent->size = attributes->size; + + nfsdirent->atime.tv_sec = attributes->atime.seconds; + nfsdirent->atime.tv_usec = attributes->atime.nseconds/1000; + nfsdirent->atime_nsec = attributes->atime.nseconds; + nfsdirent->mtime.tv_sec = attributes->mtime.seconds; + nfsdirent->mtime.tv_usec = attributes->mtime.nseconds/1000; + nfsdirent->mtime_nsec = attributes->mtime.nseconds; + nfsdirent->ctime.tv_sec = attributes->ctime.seconds; + nfsdirent->ctime.tv_usec = attributes->ctime.nseconds/1000; + nfsdirent->ctime_nsec = attributes->ctime.nseconds; + nfsdirent->uid = attributes->uid; + nfsdirent->gid = attributes->gid; + nfsdirent->nlink = attributes->nlink; + nfsdirent->dev = attributes->fsid; + nfsdirent->rdev = specdata3_to_rdev(&attributes->rdev); + nfsdirent->blksize = NFS_BLKSIZE; + nfsdirent->blocks = (attributes->used + 512 - 1) / 512; + nfsdirent->used = attributes->used; + } + } + + if (rdpe_cb_data->getattrcount == 0) { + if (rdpe_cb_data->status != RPC_STATUS_SUCCESS) { + nfs_set_error(nfs, "READDIRPLUS emulation " + "failed: %s", rpc_get_error(rpc)); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + 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 int +lookup_missing_attributes(struct nfs_context *nfs, + struct nfsdir *nfsdir, + struct nfs_cb_data *data) +{ + struct rdpe_cb_data *rdpe_cb_data = NULL; + struct nfsdirent *nfsdirent; + + for (nfsdirent = nfsdir->entries; + nfsdirent; + nfsdirent = nfsdirent->next) { + struct rdpe_lookup_cb_data *rdpe_lookup_cb_data; + LOOKUP3args args; + + /* If type == 0 we assume it is a case of the server not + * giving us the attributes for this entry during READIR[PLUS] + * so we fallback to LOOKUP3 + */ + if (nfsdirent->type != 0) { + continue; + } + + if (rdpe_cb_data == NULL) { + 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; + } + 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; + + memset(&args, 0, sizeof(LOOKUP3args)); + args.what.dir.data.data_len = data->fh.len; + args.what.dir.data.data_val = data->fh.val; + args.what.name = nfsdirent->name; + + if (rpc_nfs3_lookup_task(nfs->rpc, nfs3_opendir_3_cb, &args, + rdpe_lookup_cb_data) == NULL) { + nfs_set_error(nfs, "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 + */ + continue; + } + rdpe_cb_data->getattrcount++; + } + if (rdpe_cb_data != NULL) { + return rdpe_cb_data->getattrcount; + } + return 0; +} + +static void +nfs3_opendir_2_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + READDIR3res *res = command_data; + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + struct nfsdir *nfsdir = data->continue_data; + struct nfsdirent *nfsdirent; + struct entry3 *entry; + uint64_t cookie = 0; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + nfs_free_nfsdir(nfsdir); + data->continue_data = NULL; + free_nfs_cb_data(data); + return; + } + + if (res->status != NFS3_OK) { + nfs_set_error(nfs, "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, + nfs_get_error(nfs), data->private_data); + nfs_free_nfsdir(nfsdir); + data->continue_data = NULL; + free_nfs_cb_data(data); + return; + } + + entry =res->READDIR3res_u.resok.reply.entries; + while (entry != NULL) { + nfsdirent = calloc(1, 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; + } + nfsdirent->name = strdup(entry->name); + if (nfsdirent->name == NULL) { + data->cb(-ENOMEM, nfs, "Failed to allocate " + "dirent->name", data->private_data); + free(nfsdirent); + nfs_free_nfsdir(nfsdir); + data->continue_data = NULL; + free_nfs_cb_data(data); + return; + } + nfsdirent->inode = entry->fileid; + + nfsdirent->next = nfsdir->entries; + nfsdir->entries = nfsdirent; + + cookie = entry->cookie; + entry = entry->nextentry; + } + + if (res->READDIR3res_u.resok.reply.eof == 0) { + READDIR3args args; + + args.dir.data.data_len = data->fh.len; + args.dir.data.data_val = data->fh.val; + args.cookie = cookie; + memcpy(&args.cookieverf, res->READDIR3res_u.resok.cookieverf, + sizeof(cookieverf3)); + args.count = nfs->nfsi->readdir_dircount; + + if (rpc_nfs3_readdir_task(nfs->rpc, nfs3_opendir_2_cb, + &args, data) == NULL) { + nfs_set_error(nfs, "RPC error: Failed to send " + "READDIR call for %s", data->path); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + nfs_free_nfsdir(nfsdir); + data->continue_data = NULL; + free_nfs_cb_data(data); + return; + } + return; + } + + if (res->READDIR3res_u.resok.dir_attributes.attributes_follow) + fattr3_to_nfs_attr(&nfsdir->attr, &res->READDIR3res_u.resok.dir_attributes.post_op_attr_u.attributes); + + /* steal the dirhandle */ + nfsdir->current = nfsdir->entries; + + if (lookup_missing_attributes(nfs, nfsdir, data) == 0) { + data->cb(0, nfs, nfsdir, data->private_data); + data->continue_data = NULL; + free_nfs_cb_data(data); + return; + } +} + +static void +nfs3_opendir_cb(struct rpc_context *rpc, 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 = 0; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + nfs_free_nfsdir(nfsdir); + data->continue_data = NULL; + free_nfs_cb_data(data); + return; + } + + if (status == RPC_STATUS_SUCCESS && res->status == NFS3ERR_NOTSUPP) { + READDIR3args args; + + args.dir.data.data_len = data->fh.len; + args.dir.data.data_val = data->fh.val; + args.cookie = cookie; + memset(&args.cookieverf, 0, sizeof(cookieverf3)); + args.count = nfs->nfsi->readdir_dircount; + + if (rpc_nfs3_readdir_task(nfs->rpc, nfs3_opendir_2_cb, + &args, data) == NULL) { + nfs_set_error(nfs, "RPC error: Failed to send " + "READDIR call for %s", data->path); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + nfs_free_nfsdir(nfsdir); + data->continue_data = NULL; + free_nfs_cb_data(data); + return; + } + return; + } + + if (res->status != NFS3_OK) { + nfs_set_error(nfs, "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, + nfs_get_error(nfs), 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; + struct nfs_attr attr; + int has_attr = 0; + + memset(&attr, 0, sizeof(attr)); + + nfsdirent = calloc(1, 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; + } + nfsdirent->name = strdup(entry->name); + if (nfsdirent->name == NULL) { + data->cb(-ENOMEM, nfs, "Failed to allocate " + "dirent->name", data->private_data); + free(nfsdirent); + nfs_free_nfsdir(nfsdir); + data->continue_data = NULL; + free_nfs_cb_data(data); + return; + } + nfsdirent->inode = entry->fileid; + + if (entry->name_attributes.attributes_follow) { + fattr3_to_nfs_attr(&attr, &entry->name_attributes.post_op_attr_u.attributes); + has_attr = 1; + } + + if (!has_attr) { + struct nested_mounts *mnt; + int splen = strlen(data->saved_path); + + /* A single '/' is a special case, treat it as + * zero-length below. */ + if (splen == 1) + splen = 0; + + /* No name attributes. Is it a nested mount then?*/ + for(mnt = nfs->nfsi->nested_mounts; mnt; mnt = mnt->next) { + if (strncmp(data->saved_path, mnt->path, splen)) + continue; + if (mnt->path[splen] != '/') + continue; + if (strcmp(mnt->path + splen + 1, entry->name)) + continue; + attr = mnt->attr; + has_attr = 1; + break; + } + } + if (has_attr) { + struct specdata3 sd3 = { attr.rdev.specdata1, + attr.rdev.specdata2 }; + + nfsdirent->type = attr.type; + nfsdirent->mode = attr.mode; + switch (nfsdirent->type) { + case NF3REG: nfsdirent->mode |= S_IFREG; break; + case NF3DIR: nfsdirent->mode |= S_IFDIR; break; + case NF3BLK: nfsdirent->mode |= S_IFBLK; break; + case NF3CHR: nfsdirent->mode |= S_IFCHR; break; + case NF3LNK: nfsdirent->mode |= S_IFLNK; break; + case NF3SOCK: nfsdirent->mode |= S_IFSOCK; break; + case NF3FIFO: nfsdirent->mode |= S_IFIFO; break; + }; + nfsdirent->size = attr.size; + + nfsdirent->atime.tv_sec = attr.atime.seconds; + nfsdirent->atime.tv_usec = attr.atime.nseconds/1000; + nfsdirent->atime_nsec = attr.atime.nseconds; + nfsdirent->mtime.tv_sec = attr.mtime.seconds; + nfsdirent->mtime.tv_usec = attr.mtime.nseconds/1000; + nfsdirent->mtime_nsec = attr.mtime.nseconds; + nfsdirent->ctime.tv_sec = attr.ctime.seconds; + nfsdirent->ctime.tv_usec = attr.ctime.nseconds/1000; + nfsdirent->ctime_nsec = attr.ctime.nseconds; + nfsdirent->uid = attr.uid; + nfsdirent->gid = attr.gid; + nfsdirent->nlink = attr.nlink; + nfsdirent->dev = attr.fsid; + nfsdirent->rdev = specdata3_to_rdev(&sd3); + nfsdirent->blksize = NFS_BLKSIZE; + nfsdirent->blocks = (attr.used + 512 - 1) / 512; + nfsdirent->used = attr.used; + } + + nfsdirent->next = nfsdir->entries; + nfsdir->entries = nfsdirent; + + cookie = entry->cookie; + entry = entry->nextentry; + } + + if (res->READDIRPLUS3res_u.resok.reply.eof == 0) { + READDIRPLUS3args args; + + args.dir.data.data_len = data->fh.len; + args.dir.data.data_val = data->fh.val; + args.cookie = cookie; + memcpy(&args.cookieverf, + res->READDIRPLUS3res_u.resok.cookieverf, + sizeof(cookieverf3)); + args.dircount = nfs->nfsi->readdir_dircount; + args.maxcount = nfs->nfsi->readdir_maxcount; + + if (rpc_nfs3_readdirplus_task(nfs->rpc, nfs3_opendir_cb, + &args, data) == NULL) { + nfs_set_error(nfs, "RPC error: Failed to send " + "READDIRPLUS call for %s", data->path); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + nfs_free_nfsdir(nfsdir); + data->continue_data = NULL; + free_nfs_cb_data(data); + return; + } + return; + } + + if (res->READDIRPLUS3res_u.resok.dir_attributes.attributes_follow) { + fattr3_to_nfs_attr(&nfsdir->attr, &res->READDIRPLUS3res_u.resok.dir_attributes.post_op_attr_u.attributes); + } + + /* steal the dirhandle */ + nfsdir->current = nfsdir->entries; + + if (lookup_missing_attributes(nfs, nfsdir, data) == 0) { + data->cb(0, nfs, nfsdir, data->private_data); + /* We can not free data->continue_data here */ + data->continue_data = NULL; + free_nfs_cb_data(data); + return; + } +} + +static int +nfs3_opendir_continue_internal(struct nfs_context *nfs, + struct nfs_attr *attr, + struct nfs_cb_data *data) +{ + READDIRPLUS3args args; + struct nfsdir *nfsdir = data->continue_data; + struct nfsdir *cached; + + cached = nfs_dircache_find(nfs, &data->fh); + if (cached) { + if (attr && attr->mtime.seconds == cached->attr.mtime.seconds + && attr->mtime.nseconds == cached->attr.mtime.nseconds) { + cached->current = cached->entries; + data->cb(0, nfs, cached, data->private_data); + free_nfs_cb_data(data); + return 0; + } else { + /* cache must be stale */ + nfs_free_nfsdir(cached); + } + } + + nfsdir->fh.len = data->fh.len; + nfsdir->fh.val = malloc(nfsdir->fh.len); + if (nfsdir->fh.val == NULL) { + nfs_set_error(nfs, "OOM when allocating fh for nfsdir"); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return -1; + } + memcpy(nfsdir->fh.val, data->fh.val, data->fh.len); + + args.dir.data.data_len = data->fh.len; + args.dir.data.data_val = data->fh.val; + args.cookie = 0; + memset(&args.cookieverf, 0, sizeof(cookieverf3)); + args.dircount = nfs->nfsi->readdir_dircount; + args.maxcount = nfs->nfsi->readdir_maxcount; + if (rpc_nfs3_readdirplus_task(nfs->rpc, nfs3_opendir_cb, + &args, data) == NULL) { + nfs_set_error(nfs, "RPC error: Failed to send " + "READDIRPLUS call for %s", data->path); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return -1; + } + return 0; +} + +int +nfs3_opendir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data) +{ + struct nfsdir *nfsdir; + + nfsdir = calloc(1, sizeof(struct nfsdir)); + if (nfsdir == NULL) { + nfs_set_error(nfs, "failed to allocate buffer for nfsdir"); + return -1; + } + + if (nfs3_lookuppath_async(nfs, path, 0, cb, private_data, + nfs3_opendir_continue_internal, + nfsdir, free, 0) != 0) { + return -1; + } + + return 0; +} + +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 +nfs3_mknod_cb(struct rpc_context *rpc, 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; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + str = &str[strlen(str) + 1]; + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + res = command_data; + if (res->status != NFS3_OK) { + nfs_set_error(nfs, "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, + nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + + nfs_dircache_drop(nfs, &data->fh); + data->cb(0, nfs, NULL, data->private_data); + free_nfs_cb_data(data); +} + +static int +nfs3_mknod_continue_internal(struct nfs_context *nfs, + struct nfs_attr *attr _U_, + struct nfs_cb_data *data) +{ + struct mknod_cb_data *cb_data = data->continue_data; + char *str = cb_data->path; + MKNOD3args args; + + memset(&args, 0, sizeof(args)); + + str = &str[strlen(str) + 1]; + + args.where.dir.data.data_len = data->fh.len; + args.where.dir.data.data_val = data->fh.val; + args.where.name = str; + switch (cb_data->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 = cb_data->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 = cb_data->major; + args.what.mknoddata3_u.chr_device.spec.specdata2 = cb_data->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 = cb_data->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 = cb_data->major; + args.what.mknoddata3_u.blk_device.spec.specdata2 = cb_data->minor; + break; + 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 = cb_data->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 = cb_data->mode & (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH); + break; + default: + nfs_set_error(nfs, "Invalid file type for " + "NFS3/MKNOD call"); + data->cb(-EINVAL, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return -1; + } + + if (rpc_nfs3_mknod_task(nfs->rpc, nfs3_mknod_cb, &args, data) == NULL) { + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return -1; + } + return 0; +} + +int +nfs3_mknod_async(struct nfs_context *nfs, const char *path, int mode, int dev, + nfs_cb cb, void *private_data) +{ + const char *ptr; + struct mknod_cb_data *cb_data; + + cb_data = malloc(sizeof(struct mknod_cb_data)); + if (cb_data == NULL) { + nfs_set_error(nfs, "Out of memory, failed to allocate " + "mode buffer for cb data"); + return -1; + } + + ptr = strrchr(path, '/'); + if (ptr) { + cb_data->path = strdup(path); + if (cb_data->path == NULL) { + nfs_set_error(nfs, "Out of memory, failed to allocate " + "buffer for mknod path"); + return -1; + } + char *ptr2 = strrchr(cb_data->path, '/'); + *ptr2 = 0; + } else { + cb_data->path = malloc(strlen(path) + 2); + if (cb_data->path == NULL) { + nfs_set_error(nfs, "Out of memory, failed to allocate " + "buffer for mknod path"); + return -1; + } + sprintf(cb_data->path, "%c%s", '\0', path); + } + + 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 + * null terminator is the new node to create */ + if (nfs3_lookuppath_async(nfs, cb_data->path, 0, cb, private_data, + nfs3_mknod_continue_internal, + cb_data, free_mknod_cb_data, 0) != 0) { + return -1; + } + + return 0; +} + +static void +nfs3_unlink_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + REMOVE3res *res; + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + char *str = data->continue_data; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + str = &str[strlen(str) + 1]; + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + res = command_data; + if (res->status != NFS3_OK) { + nfs_set_error(nfs, "NFS: REMOVE 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, + nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + + nfs_dircache_drop(nfs, &data->fh); + data->cb(0, nfs, NULL, data->private_data); + free_nfs_cb_data(data); +} + +static int +nfs3_unlink_continue_internal(struct nfs_context *nfs, + struct nfs_attr *attr _U_, + struct nfs_cb_data *data) +{ + char *str = data->continue_data; + struct REMOVE3args args; + + str = &str[strlen(str) + 1]; + + args.object.dir.data.data_len = data->fh.len; + args.object.dir.data.data_val = data->fh.val; + args.object.name = str; + if (rpc_nfs3_remove_task(nfs->rpc, nfs3_unlink_cb, &args, data) == NULL) { + nfs_set_error(nfs, "RPC error: Failed to send REMOVE " + "call for %s", data->path); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return -1; + } + return 0; +} + +int +nfs3_unlink_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data) +{ + char *new_path; + const char *ptr; + + ptr = strrchr(path, '/'); + if (ptr) { + new_path = strdup(path); + if (new_path == NULL) { + nfs_set_error(nfs, "Out of memory, failed to allocate " + "buffer for unlink path"); + return -1; + } + char *ptr2 = strrchr(new_path, '/'); + *ptr2 = 0; + } else { + new_path = malloc(strlen(path) + 2); + if (new_path == NULL) { + nfs_set_error(nfs, "Out of memory, failed to allocate " + "buffer for unlink path"); + return -1; + } + sprintf(new_path, "%c%s", '\0', path); + } + + /* new_path now points to the parent directory and beyond the + * null terminator is the object to unlink */ + if (nfs3_lookuppath_async(nfs, new_path, 0, cb, private_data, + nfs3_unlink_continue_internal, + new_path, free, 0) != 0) { + return -1; + } + + return 0; +} + +struct create_cb_data { + char *path; + int flags; + int mode; +}; + +int +nfs3_creat_async(struct nfs_context *nfs, const char *path, + int mode, nfs_cb cb, void *private_data) +{ + return nfs3_open_async(nfs, path, O_CREAT|O_WRONLY|O_TRUNC, + mode, cb, private_data); +} + +static void +nfs3_rmdir_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + RMDIR3res *res; + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + char *str = data->continue_data; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + str = &str[strlen(str) + 1]; + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + res = command_data; + if (res->status != NFS3_OK) { + nfs_set_error(nfs, "NFS: RMDIR 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, + nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + + nfs_dircache_drop(nfs, &data->fh); + data->cb(0, nfs, NULL, data->private_data); + free_nfs_cb_data(data); +} + +static int +nfs3_rmdir_continue_internal(struct nfs_context *nfs, + struct nfs_attr *attr _U_, + struct nfs_cb_data *data) +{ + char *str = data->continue_data; + RMDIR3args args; + + str = &str[strlen(str) + 1]; + + args.object.dir.data.data_len = data->fh.len; + args.object.dir.data.data_val = data->fh.val; + args.object.name = str; + if (rpc_nfs3_rmdir_task(nfs->rpc, nfs3_rmdir_cb, &args, data) == NULL) { + nfs_set_error(nfs, "RPC error: Failed to send RMDIR " + "call for %s", data->path); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return -1; + } + return 0; +} + +int +nfs3_rmdir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data) +{ + char *new_path; + const char *ptr; + + ptr = strrchr(path, '/'); + if (ptr) { + new_path = strdup(path); + if (new_path == NULL) { + nfs_set_error(nfs, "Out of memory, failed to allocate " + "buffer for rmdir path"); + return -1; + } + char *ptr2 = strrchr(new_path, '/'); + *ptr2 = 0; + } else { + new_path = malloc(strlen(path) + 2); + if (new_path == NULL) { + nfs_set_error(nfs, "Out of memory, failed to allocate " + "buffer for rmdir path"); + return -1; + } + sprintf(new_path, "%c%s", '\0', path); + } + + /* new_path now points to the parent directory and beyond the + * null terminator is the directory to remove */ + if (nfs3_lookuppath_async(nfs, new_path, 0, cb, private_data, + nfs3_rmdir_continue_internal, + new_path, free, 0) != 0) { + return -1; + } + + return 0; +} + +static void +nfs3_mkdir_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + MKDIR3res *res; + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + char *str = data->continue_data; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + str = &str[strlen(str) + 1]; + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + res = command_data; + if (res->status != NFS3_OK) { + nfs_set_error(nfs, "NFS: MKDIR 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, + nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + + nfs_dircache_drop(nfs, &data->fh); + data->cb(0, nfs, NULL, data->private_data); + free_nfs_cb_data(data); +} + +static int +nfs3_mkdir_continue_internal(struct nfs_context *nfs, + struct nfs_attr *attr _U_, + struct nfs_cb_data *data) +{ + char *str = data->continue_data; + int mode = (int)data->continue_int; + MKDIR3args args; + + str = &str[strlen(str) + 1]; + + memset(&args, 0, sizeof(MKDIR3args)); + args.where.dir.data.data_len = data->fh.len; + args.where.dir.data.data_val = data->fh.val; + args.where.name = str; + args.attributes.mode.set_it = 1; + args.attributes.mode.set_mode3_u.mode = mode; + + if (rpc_nfs3_mkdir_task(nfs->rpc, nfs3_mkdir_cb, &args, data) == NULL) { + nfs_set_error(nfs, "RPC error: Failed to send MKDIR " + "call for %s", data->path); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return -1; + } + return 0; +} + +int +nfs3_mkdir2_async(struct nfs_context *nfs, const char *path, int mode, + nfs_cb cb, void *private_data) +{ + char *new_path; + const char *ptr; + + ptr = strrchr(path, '/'); + if (ptr) { + new_path = strdup(path); + if (new_path == NULL) { + nfs_set_error(nfs, "Out of memory, failed to allocate " + "buffer for mkdir path"); + return -1; + } + char *ptr2 = strrchr(new_path, '/'); + *ptr2 = 0; + } else { + new_path = malloc(strlen(path) + 2); + if (new_path == NULL) { + nfs_set_error(nfs, "Out of memory, failed to allocate " + "buffer for mkdir path"); + return -1; + } + sprintf(new_path, "%c%s", '\0', path); + } + + /* new_path now points to the parent directory and beyond the + * null terminator is the new directory to create */ + if (nfs3_lookuppath_async(nfs, new_path, 0, cb, private_data, + nfs3_mkdir_continue_internal, + new_path, free, mode) != 0) { + return -1; + } + + return 0; +} + +static int +nfs3_truncate_continue_internal(struct nfs_context *nfs, + struct nfs_attr *attr _U_, + struct nfs_cb_data *data) +{ + uint64_t offset = data->continue_int; + struct nfsfh nfsfh; + + memset(&nfsfh, 0, sizeof(struct nfsfh)); + nfsfh.fh = data->fh; + + if (nfs_ftruncate_async(nfs, &nfsfh, offset, data->cb, + data->private_data) != 0) { + nfs_set_error(nfs, "RPC error: Failed to send SETATTR " + "call for %s", data->path); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return -1; + } + free_nfs_cb_data(data); + return 0; +} + +int +nfs3_truncate_async(struct nfs_context *nfs, const char *path, uint64_t length, + nfs_cb cb, void *private_data) +{ + uint64_t offset; + + offset = length; + + if (nfs3_lookuppath_async(nfs, path, 0, cb, private_data, + nfs3_truncate_continue_internal, + NULL, NULL, offset) != 0) { + return -1; + } + + return 0; +} + +static void +nfs3_ftruncate_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + SETATTR3res *res; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + res = command_data; + if (res->status != NFS3_OK) { + nfs_set_error(nfs, "NFS: Setattr failed with %s(%d)", + nfsstat3_to_str(res->status), + nfsstat3_to_errno(res->status)); + data->cb(nfsstat3_to_errno(res->status), nfs, + nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + + nfs_dircache_drop(nfs, &data->fh); + data->cb(0, nfs, NULL, data->private_data); + free_nfs_cb_data(data); +} + +int +nfs3_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; + + data = calloc(1, sizeof(struct nfs_cb_data)); + if (data == NULL) { + nfs_set_error(nfs, "out of memory: failed to allocate " + "nfs_cb_data structure"); + return -1; + } + data->nfs = nfs; + data->cb = cb; + data->private_data = private_data; + + memset(&args, 0, sizeof(SETATTR3args)); + args.object.data.data_len = nfsfh->fh.len; + args.object.data.data_val = nfsfh->fh.val; + args.new_attributes.size.set_it = 1; + args.new_attributes.size.set_size3_u.size = length; + + if (rpc_nfs3_setattr_task(nfs->rpc, nfs3_ftruncate_cb, + &args, data) == NULL) { + nfs_set_error(nfs, "RPC error: Failed to send SETATTR " + "call for %s", data->path); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return -1; + } + return 0; +} + +static void +nfs3_fsync_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMMIT3res *res; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + res = command_data; + if (res->status != NFS3_OK) { + nfs_set_error(nfs, "NFS: Commit failed with %s(%d)", + nfsstat3_to_str(res->status), + nfsstat3_to_errno(res->status)); + data->cb(nfsstat3_to_errno(res->status), nfs, + nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + + data->cb(0, nfs, NULL, data->private_data); + free_nfs_cb_data(data); +} + +int +nfs3_fsync_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, + void *private_data) +{ + struct nfs_cb_data *data; + struct COMMIT3args args; + + data = calloc(1, sizeof(struct nfs_cb_data)); + if (data == NULL) { + nfs_set_error(nfs, "out of memory: failed to allocate " + "nfs_cb_data structure"); + return -1; + } + data->nfs = nfs; + data->cb = cb; + data->private_data = private_data; + + args.file.data.data_len = nfsfh->fh.len; + args.file.data.data_val = nfsfh->fh.val; + args.offset = 0; + args.count = 0; + if (rpc_nfs3_commit_task(nfs->rpc, nfs3_fsync_cb, &args, data) == NULL) { + nfs_set_error(nfs, "RPC error: Failed to send COMMIT " + "call for %s", data->path); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return -1; + } + return 0; +} + +static void +nfs3_getacl_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + GETACL3res *res; + GETACL3resok *resok; + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + fattr3_acl acl; + int i; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + res = command_data; + if (res->status != NFS3_OK) { + nfs_set_error(nfs, "NFS: GETACL 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, + nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + memset(&acl, 0, sizeof(acl)); + resok = &res->GETACL3res_u.resok; + acl.ace_count = resok->ace_count; + if (acl.ace_count) { + acl.ace = calloc(acl.ace_count, sizeof(struct nfsacl_ace)); + if (acl.ace == NULL) { + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + for (i = 0; i < acl.ace_count; i++) { + acl.ace[i] = resok->ace.ace_val[i]; + } + } + acl.default_ace_count = resok->default_ace_count; + if (acl.default_ace_count) { + acl.default_ace = calloc(acl.default_ace_count, sizeof(struct nfsacl_ace)); + if (acl.default_ace == NULL) { + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + for (i = 0; i < acl.default_ace_count; i++) { + acl.default_ace[i] = resok->default_ace.default_ace_val[i]; + } + } + data->cb(0, nfs, &acl, data->private_data); + free_nfs_cb_data(data); +} + + +int +nfs3_getacl_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, + void *private_data) +{ + struct nfs_cb_data *data; + GETACL3args args; + + data = calloc(1, sizeof(struct nfs_cb_data)); + if (data == NULL) { + nfs_set_error(nfs, "out of memory: failed to allocate " + "nfs_cb_data structure"); + return -1; + } + data->nfs = nfs; + data->cb = cb; + data->private_data = private_data; + + memset(&args, 0, sizeof(GETACL3args)); + args.dir.data.data_len = nfsfh->fh.len; + args.dir.data.data_val = nfsfh->fh.val; + args.mask = NFSACL_MASK_ACL_ENTRY|NFSACL_MASK_ACL_COUNT|NFSACL_MASK_ACL_DEFAULT_ENTRY|NFSACL_MASK_ACL_DEFAULT_COUNT; + if (rpc_nfsacl3_getacl_task(nfs->rpc, nfs3_getacl_cb, &args, data) == NULL) { + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return -1; + } + return 0; +} + +static void +nfs3_stat_1_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + GETATTR3res *res; + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; +#ifdef WIN32 + struct __stat64 st; +#else + struct stat st; +#endif + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + res = command_data; + if (res->status != NFS3_OK) { + nfs_set_error(nfs, "NFS: GETATTR 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, + nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + + st.st_dev = (dev_t)res->GETATTR3res_u.resok.obj_attributes.fsid; + st.st_ino = (ino_t)res->GETATTR3res_u.resok.obj_attributes.fileid; + st.st_mode = res->GETATTR3res_u.resok.obj_attributes.mode; + switch (res->GETATTR3res_u.resok.obj_attributes.type) { + case NF3REG: + st.st_mode |= S_IFREG; + break; + case NF3DIR: + st.st_mode |= S_IFDIR; + break; + case NF3BLK: + st.st_mode |= S_IFBLK; + break; + case NF3CHR: + st.st_mode |= S_IFCHR; + break; + case NF3LNK: + st.st_mode |= S_IFLNK; + break; + case NF3SOCK: + st.st_mode |= S_IFSOCK; + break; + case NF3FIFO: + st.st_mode |= S_IFIFO; + break; + } + 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 = specdata3_to_rdev(&res->GETATTR3res_u.resok.obj_attributes.rdev); + st.st_size = res->GETATTR3res_u.resok.obj_attributes.size; +#ifndef WIN32 + st.st_blksize = NFS_BLKSIZE; + st.st_blocks = (res->GETATTR3res_u.resok.obj_attributes.used + 512 - 1) / 512; +#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; +#ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC + st.st_atim.tv_nsec = res->GETATTR3res_u.resok.obj_attributes.atime.nseconds; + st.st_mtim.tv_nsec = res->GETATTR3res_u.resok.obj_attributes.mtime.nseconds; + st.st_ctim.tv_nsec = res->GETATTR3res_u.resok.obj_attributes.ctime.nseconds; +#endif + + data->cb(0, nfs, &st, data->private_data); + free_nfs_cb_data(data); +} + +int +nfs3_fstat_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, + void *private_data) +{ + struct nfs_cb_data *data; + struct GETATTR3args args; + + data = calloc(1, sizeof(struct nfs_cb_data)); + if (data == NULL) { + nfs_set_error(nfs, "out of memory: failed to allocate " + "nfs_cb_data structure"); + return -1; + } + data->nfs = nfs; + data->cb = cb; + data->private_data = private_data; + + memset(&args, 0, sizeof(GETATTR3args)); + args.object.data.data_len = nfsfh->fh.len; + args.object.data.data_val = nfsfh->fh.val; + + if (rpc_nfs3_getattr_task(nfs->rpc, nfs3_stat_1_cb, &args, + data) == NULL) { + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return -1; + } + return 0; +} + +static void +nfs3_stat64_1_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + GETATTR3res *res; + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + struct nfs_stat_64 st; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + res = command_data; + if (res->status != NFS3_OK) { + nfs_set_error(nfs, "NFS: GETATTR 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, + nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + + st.nfs_dev = res->GETATTR3res_u.resok.obj_attributes.fsid; + st.nfs_ino = res->GETATTR3res_u.resok.obj_attributes.fileid; + st.nfs_mode = res->GETATTR3res_u.resok.obj_attributes.mode; + switch (res->GETATTR3res_u.resok.obj_attributes.type) { + case NF3REG: + st.nfs_mode |= S_IFREG; + break; + case NF3DIR: + st.nfs_mode |= S_IFDIR; + break; + case NF3BLK: + st.nfs_mode |= S_IFBLK; + break; + case NF3CHR: + st.nfs_mode |= S_IFCHR; + break; + case NF3LNK: + st.nfs_mode |= S_IFLNK; + break; + case NF3SOCK: + st.nfs_mode |= S_IFSOCK; + break; + case NF3FIFO: + st.nfs_mode |= S_IFIFO; + break; + } + st.nfs_nlink = res->GETATTR3res_u.resok.obj_attributes.nlink; + st.nfs_uid = res->GETATTR3res_u.resok.obj_attributes.uid; + st.nfs_gid = res->GETATTR3res_u.resok.obj_attributes.gid; + st.nfs_rdev = specdata3_to_rdev(&res->GETATTR3res_u.resok.obj_attributes.rdev); + st.nfs_size = res->GETATTR3res_u.resok.obj_attributes.size; + st.nfs_blksize = NFS_BLKSIZE; + st.nfs_blocks = (res->GETATTR3res_u.resok.obj_attributes.used + 512 - 1) / 512; + st.nfs_atime = res->GETATTR3res_u.resok.obj_attributes.atime.seconds; + st.nfs_mtime = res->GETATTR3res_u.resok.obj_attributes.mtime.seconds; + st.nfs_ctime = res->GETATTR3res_u.resok.obj_attributes.ctime.seconds; + st.nfs_atime_nsec = res->GETATTR3res_u.resok.obj_attributes.atime.nseconds; + st.nfs_mtime_nsec = res->GETATTR3res_u.resok.obj_attributes.mtime.nseconds; + st.nfs_ctime_nsec = res->GETATTR3res_u.resok.obj_attributes.ctime.nseconds; + st.nfs_used = res->GETATTR3res_u.resok.obj_attributes.used; + + data->cb(0, nfs, &st, data->private_data); + free_nfs_cb_data(data); +} + +static int +nfs3_stat64_continue_internal(struct nfs_context *nfs, + struct nfs_attr *attr _U_, + struct nfs_cb_data *data) +{ + struct GETATTR3args args; + + memset(&args, 0, sizeof(GETATTR3args)); + args.object.data.data_len = data->fh.len; + args.object.data.data_val = data->fh.val; + + if (rpc_nfs3_getattr_task(nfs->rpc, nfs3_stat64_1_cb, + &args, data) == NULL) { + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return -1; + } + return 0; +} + +int +nfs3_stat64_async(struct nfs_context *nfs, const char *path, + int no_follow, nfs_cb cb, void *private_data) +{ + if (nfs3_lookuppath_async(nfs, path, no_follow, cb, private_data, + nfs3_stat64_continue_internal, + NULL, NULL, 0) != 0) { + return -1; + } + + return 0; +} + +int +nfs3_fstat64_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, + void *private_data) +{ + struct nfs_cb_data *data; + struct GETATTR3args args; + + data = calloc(1, sizeof(struct nfs_cb_data)); + if (data == NULL) { + nfs_set_error(nfs, "out of memory: failed to allocate " + "nfs_cb_data structure"); + return -1; + } + data->nfs = nfs; + data->cb = cb; + data->private_data = private_data; + + memset(&args, 0, sizeof(GETATTR3args)); + args.object.data.data_len = nfsfh->fh.len; + args.object.data.data_val = nfsfh->fh.val; + + if (rpc_nfs3_getattr_task(nfs->rpc, nfs3_stat64_1_cb, &args, + data) == NULL) { + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return -1; + } + return 0; +} + +static int +nfs3_stat_continue_internal(struct nfs_context *nfs, + struct nfs_attr *attr _U_, + struct nfs_cb_data *data) +{ + struct GETATTR3args args; + + memset(&args, 0, sizeof(GETATTR3args)); + args.object.data.data_len = data->fh.len; + args.object.data.data_val = data->fh.val; + + if (rpc_nfs3_getattr_task(nfs->rpc, nfs3_stat_1_cb, &args, + data) == NULL) { + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return -1; + } + return 0; +} + +int +nfs3_stat_async(struct nfs_context *nfs, const char *path, + nfs_cb cb, void *private_data) +{ + if (nfs3_lookuppath_async(nfs, path, 0, cb, private_data, + nfs3_stat_continue_internal, + NULL, NULL, 0) != 0) { + return -1; + } + + return 0; +} + +static void +nfs3_close_cb(int err, struct nfs_context *nfs, void *ret_data, + void *private_data) { + struct nfs_cb_data *data = private_data; + nfs_free_nfsfh(data->nfsfh); + data->cb(err, nfs, ret_data, data->private_data); + free_nfs_cb_data(data); +} + +int +nfs3_close_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, + void *private_data) +{ + struct nfs_cb_data *data; + + if (!nfsfh->is_dirty) { + nfs_free_nfsfh(nfsfh); + cb(0, nfs, NULL, private_data); + return 0; + } + + data = calloc(1, sizeof(struct nfs_cb_data)); + if (data == NULL) { + nfs_set_error(nfs, "out of memory: failed to allocate " + "nfs_cb_data structure"); + return -1; + } + + data->nfsfh = nfsfh; + data->cb = cb; + data->private_data = private_data; + + return nfs_fsync_async(nfs, nfsfh, nfs3_close_cb, data); +} + +static void +nfs3_write_append_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + GETATTR3res *res; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + res = command_data; + if (res->status != NFS3_OK) { + nfs_set_error(nfs, "NFS: GETATTR failed with %s(%d)", + nfsstat3_to_str(res->status), + nfsstat3_to_errno(res->status)); + data->cb(nfsstat3_to_errno(res->status), nfs, + nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + + if (nfs3_pwrite_async_internal(nfs, data->nfsfh, + data->usrbuf, data->count, res->GETATTR3res_u.resok.obj_attributes.size, + data->cb, data->private_data, 1) != 0) { + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return; + } + free_nfs_cb_data(data); +} + +static void +nfs3_fill_WRITE3args (WRITE3args *args, struct nfsfh *fh, uint64_t offset, + uint64_t count, const void *buf) +{ + memset(args, 0, sizeof(WRITE3args)); + args->file.data.data_len = fh->fh.len; + args->file.data.data_val = fh->fh.val; + args->offset = offset; + args->count = (count3)count; + args->stable = fh->is_sync ? FILE_SYNC : UNSTABLE; + args->data.data_len = (count3)count; + args->data.data_val = (char *)buf; +} + +static void +nfs3_pwrite_mcb(struct rpc_context *rpc, 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; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + ATOMIC_DEC(nfs->rpc, data->num_calls); + + /* Flag the failure but do not invoke callback until we have + * received all responses. + */ + if (status == RPC_STATUS_ERROR) { + data->error = -EFAULT; + } + if (status == RPC_STATUS_CANCEL) { + data->cancel = 1; + } + if (status == RPC_STATUS_TIMEOUT) { + data->cancel = 1; + } + + if (status == RPC_STATUS_SUCCESS) { + res = command_data; + if (res->status != NFS3_OK) { + nfs_set_error(nfs, "NFS: Write failed with %s(%d)", nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); + data->error = nfsstat3_to_errno(res->status); + } else { + size_t count = res->WRITE3res_u.resok.count; + + if (count < mdata->count) { + if (count == 0) { + nfs_set_error(nfs, "NFS: Write failed. No bytes written!"); + data->error = -EFAULT; + } else { + /* reissue reminder of this write request */ + WRITE3args args; + mdata->offset += count; + mdata->count -= count; + + nfs3_fill_WRITE3args(&args, + data->nfsfh, + mdata->offset, + mdata->count, + &data->usrbuf[mdata->offset - data->offset]); + ATOMIC_INC(nfs->rpc, data->num_calls); + if (rpc_nfs3_write_task(nfs->rpc, + nfs3_pwrite_mcb, + &args, mdata)) { + return; + } else { + ATOMIC_DEC(nfs->rpc, data->num_calls); + nfs_set_error(nfs, "RPC error: Failed to send WRITE call for %s", data->path); + data->oom = 1; + } + } + } + if (count > 0) { + if (data->max_offset < mdata->offset + count) { + data->max_offset = mdata->offset + count; + } + } + } + } + + free(mdata); + + if (data->num_calls > 0) { + /* still waiting for more replies */ + return; + } + if (data->oom != 0) { + data->cb(-ENOMEM, nfs, command_data, data->private_data); + free_nfs_cb_data(data); + return; + } + if (data->error != 0) { + data->cb(data->error, nfs, command_data, data->private_data); + free_nfs_cb_data(data); + return; + } + if (data->cancel != 0) { + data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); + free_nfs_cb_data(data); + return; + } + + + if (data->update_pos) { + data->nfsfh->offset = data->max_offset; + } + + data->cb((int)(data->max_offset - data->offset), nfs, NULL, data->private_data); + + free_nfs_cb_data(data); +} + +int +nfs3_pwrite_async_internal(struct nfs_context *nfs, struct nfsfh *nfsfh, + const char *buf, size_t count, uint64_t offset, + nfs_cb cb, void *private_data, int update_pos) +{ + struct nfs_cb_data *data; + + if (count > nfs_get_writemax(nfs)) { + count = nfs_get_writemax(nfs); + } + + nfsfh->is_dirty = 1; + data = calloc(1, sizeof(struct nfs_cb_data)); + if (data == NULL) { + nfs_set_error(nfs, "out of memory: failed to allocate " + "nfs_cb_data structure"); + return -1; + } + data->nfs = nfs; + data->cb = cb; + data->private_data = private_data; + data->nfsfh = nfsfh; + data->usrbuf = buf; + data->update_pos = update_pos; + + /* hello, clang-analyzer */ + assert(data->num_calls == 0); + + /* chop requests into chunks of at most WRITEMAX bytes if necessary. + * we send all writes in parallel so that performance is still good. + */ + data->max_offset = offset; + data->offset = offset; + data->count = count; + + do { + size_t writecount = count; + struct nfs_mcb_data *mdata; + WRITE3args args; + + if (writecount > nfs_get_writemax(nfs)) { + writecount = nfs_get_writemax(nfs); + } + + mdata = calloc(1, sizeof(struct nfs_mcb_data)); + if (mdata == NULL) { + nfs_set_error(nfs, "out of memory: failed to allocate " + "nfs_mcb_data structure"); + if (data->num_calls == 0) { + free_nfs_cb_data(data); + return -1; + } + data->oom = 1; + break; + } + mdata->data = data; + mdata->offset = offset; + mdata->count = writecount; + + nfs3_fill_WRITE3args(&args, nfsfh, offset, writecount, + &buf[offset - data->offset]); + ATOMIC_INC(nfs->rpc, data->num_calls); + if (rpc_nfs3_write_task(nfs->rpc, nfs3_pwrite_mcb, + &args, mdata) == NULL) { + ATOMIC_DEC(nfs->rpc, data->num_calls); + nfs_set_error(nfs, "RPC error: Failed to send WRITE " + "call for %s", data->path); + free(mdata); + if (data->num_calls == 0) { + free_nfs_cb_data(data); + return -1; + } + data->oom = 1; + break; + } + + count -= writecount; + offset += writecount; + } while (count > 0); + + return 0; +} + +int +nfs3_write_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + const void *buf, size_t count, + nfs_cb cb, void *private_data) +{ + if (nfsfh->is_append) { + struct GETATTR3args args; + struct nfs_cb_data *data; + + data = calloc(1, sizeof(struct nfs_cb_data)); + if (data == NULL) { + nfs_set_error(nfs, "Out of memory."); + return -1; + } + data->nfs = nfs; + data->cb = cb; + data->private_data = private_data; + data->nfsfh = nfsfh; + data->usrbuf = buf; + data->count = (size_t)count; + + memset(&args, 0, sizeof(GETATTR3args)); + args.object.data.data_len = nfsfh->fh.len; + args.object.data.data_val = nfsfh->fh.val; + + if (rpc_nfs3_getattr_task(nfs->rpc, nfs3_write_append_cb, + &args, data) == NULL) { + free_nfs_cb_data(data); + return -1; + } + return 0; + } + return nfs3_pwrite_async_internal(nfs, nfsfh, + buf, count, nfsfh->offset, + cb, private_data, 1); +} + +static void +nfs3_fill_READ3args(READ3args *args, struct nfsfh *fh, uint64_t offset, + uint64_t count) +{ + memset(args, 0, sizeof(READ3args)); + args->file.data.data_len = fh->fh.len; + args->file.data.data_val = fh->fh.val; + args->offset = offset; + args->count = (count3)count; +} + +static void +nfs3_pread_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + READ3res *res; + int count; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + res = command_data; + if (res->status != NFS3_OK) { + nfs_set_error(nfs, "NFS: Read failed with %s(%d)", + nfsstat3_to_str(res->status), + nfsstat3_to_errno(res->status)); + data->cb(nfsstat3_to_errno(res->status), nfs, command_data, data->private_data); + free_nfs_cb_data(data); + return; + } + + count = (int)res->READ3res_u.resok.count; + if (data->update_pos) { + data->nfsfh->offset = data->offset + count; + } + + if (count > rpc->pdu->requested_read_count) { + count = rpc->pdu->requested_read_count; + } + + data->cb(count, nfs, NULL, data->private_data); + free_nfs_cb_data(data); + return; +} + +int +nfs3_pread_async_internal(struct nfs_context *nfs, struct nfsfh *nfsfh, + void *buf, size_t count, uint64_t offset, + nfs_cb cb, void *private_data, int update_pos) +{ + struct nfs_cb_data *data; + READ3args args; + struct rpc_pdu *pdu; + + if (count > nfs_get_readmax(nfs)) { + count = nfs_get_readmax(nfs); + } + + data = calloc(1, sizeof(struct nfs_cb_data)); + if (data == NULL) { + nfs_set_error(nfs, "out of memory: failed to allocate " + "nfs_cb_data structure"); + return -1; + } + data->nfs = nfs; + data->cb = cb; + data->private_data = private_data; + data->nfsfh = nfsfh; + data->org_offset = offset; + data->org_count = count; + data->update_pos = update_pos; + + assert(data->num_calls == 0); + + data->offset = offset; + data->count = (count3)count; + data->max_offset = data->offset; + + nfs3_fill_READ3args(&args, nfsfh, offset, count); + pdu = rpc_nfs3_read_task(nfs->rpc, nfs3_pread_cb, buf, count, &args, data); + if (pdu == NULL) { + nfs_set_error(nfs, "RPC error: Failed to send READ " + "call for %s", data->path); + free_nfs_cb_data(data); + return -1; + } + + return 0; +} + +int +nfs3_preadv_async_internal(struct nfs_context *nfs, struct nfsfh *nfsfh, + const struct iovec *iov, int iovcnt, uint64_t offset, + nfs_cb cb, void *private_data, int update_pos) +{ + struct nfs_cb_data *data; + READ3args args; + struct rpc_pdu *pdu; + size_t count = 0; + int i; + + for (i = 0; i < iovcnt; i++) { + count += iov[i].iov_len; + } + if (count > nfs_get_readmax(nfs)) { + count = nfs_get_readmax(nfs); + } + + data = calloc(1, sizeof(struct nfs_cb_data)); + if (data == NULL) { + nfs_set_error(nfs, "out of memory: failed to allocate " + "nfs_cb_data structure"); + return -1; + } + data->nfs = nfs; + data->cb = cb; + data->private_data = private_data; + data->nfsfh = nfsfh; + data->org_offset = offset; + data->org_count = count; + data->update_pos = update_pos; + + assert(data->num_calls == 0); + + data->offset = offset; + data->count = (count3)count; + data->max_offset = data->offset; + + nfs3_fill_READ3args(&args, nfsfh, offset, count); + pdu = rpc_nfs3_readv_task(nfs->rpc, nfs3_pread_cb, iov, iovcnt, &args, data); + if (pdu == NULL) { + nfs_set_error(nfs, "RPC error: Failed to send READ " + "call for %s", data->path); + free_nfs_cb_data(data); + return -1; + } + + return 0; +} + +static int +nfs3_chdir_continue_internal(struct nfs_context *nfs, + struct nfs_attr *attr _U_, + struct nfs_cb_data *data) +{ + /* steal saved_path */ +#ifdef HAVE_MULTITHREADING + if (nfs->rpc->multithreading_enabled) { + nfs_mt_mutex_lock(&nfs->rpc->rpc_mutex); + } +#endif + free(nfs->nfsi->cwd); + nfs->nfsi->cwd = data->saved_path; +#ifdef HAVE_MULTITHREADING + if (nfs->rpc->multithreading_enabled) { + nfs_mt_mutex_unlock(&nfs->rpc->rpc_mutex); + } +#endif + + data->saved_path = NULL; + + data->cb(0, nfs, NULL, data->private_data); + free_nfs_cb_data(data); + + return 0; +} + +int +nfs3_chdir_async(struct nfs_context *nfs, const char *path, + nfs_cb cb, void *private_data) +{ + if (nfs3_lookuppath_async(nfs, path, 0, cb, private_data, + nfs3_chdir_continue_internal, + NULL, NULL, 0) != 0) { + return -1; + } + + return 0; +} + +static void +nfs3_open_trunc_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + struct nfsfh *nfsfh; + SETATTR3res *res; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + res = command_data; + if (res->status != NFS3_OK) { + nfs_set_error(nfs, "NFS: Setattr failed with %s(%d)", + nfsstat3_to_str(res->status), + nfsstat3_to_errno(res->status)); + data->cb(nfsstat3_to_errno(res->status), nfs, + nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + + nfsfh = calloc(1, sizeof(struct nfsfh)); + if (nfsfh == NULL) { + nfs_set_error(nfs, "NFS: Failed to allocate nfsfh " + "structure"); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return; + } + + if (data->continue_int & O_SYNC) { + nfsfh->is_sync = 1; + } + if (data->continue_int & O_APPEND) { + nfsfh->is_append = 1; + } + + /* steal the filehandle */ + nfsfh->fh = data->fh; + data->fh.val = NULL; + + data->cb(0, nfs, nfsfh, data->private_data); + free_nfs_cb_data(data); +} + +static void +nfs3_open_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + ACCESS3res *res; + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + struct nfsfh *nfsfh; + unsigned int nfsmode = 0; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + res = command_data; + if (res->status != NFS3_OK) { + nfs_set_error(nfs, "NFS: ACCESS 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, + nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + + if (data->continue_int & O_WRONLY) { + nfsmode |= ACCESS3_MODIFY; + } + if (data->continue_int & O_RDWR) { + nfsmode |= ACCESS3_READ|ACCESS3_MODIFY; + } + if (!(data->continue_int & (O_WRONLY|O_RDWR))) { + nfsmode |= ACCESS3_READ; + } + + + if (res->ACCESS3res_u.resok.access != nfsmode) { + nfs_set_error(nfs, "NFS: ACCESS denied. Required " + "access %c%c%c. Allowed access %c%c%c", + nfsmode&ACCESS3_READ?'r':'-', + nfsmode&ACCESS3_MODIFY?'w':'-', + nfsmode&ACCESS3_EXECUTE?'x':'-', + res->ACCESS3res_u.resok.access&ACCESS3_READ ? 'r':'-', + res->ACCESS3res_u.resok.access&ACCESS3_MODIFY ?'w':'-', + res->ACCESS3res_u.resok.access&ACCESS3_EXECUTE ?'x':'-'); + data->cb(-EACCES, nfs, nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + + /* Try to truncate it if we were requested to */ + if ((data->continue_int & O_TRUNC) && + (data->continue_int & (O_RDWR|O_WRONLY))) { + SETATTR3args args; + + memset(&args, 0, sizeof(SETATTR3args)); + args.object.data.data_len = data->fh.len; + args.object.data.data_val = data->fh.val; + args.new_attributes.size.set_it = 1; + args.new_attributes.size.set_size3_u.size = 0; + + if (rpc_nfs3_setattr_task(nfs->rpc, nfs3_open_trunc_cb, &args, + data) == NULL) { + nfs_set_error(nfs, "RPC error: Failed to send " + "SETATTR call for %s", data->path); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return; + } + return; + } + + nfsfh = calloc(1, sizeof(struct nfsfh)); + if (nfsfh == NULL) { + nfs_set_error(nfs, "NFS: Failed to allocate nfsfh structure"); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + + if (data->continue_int & O_SYNC) { + nfsfh->is_sync = 1; + } + if (data->continue_int & O_APPEND) { + nfsfh->is_append = 1; + } + if (!(data->continue_int & (O_WRONLY|O_RDWR))) { + nfsfh->is_readonly = 1; + } + + /* steal the filehandle */ + nfsfh->fh = data->fh; + data->fh.val = NULL; + + data->cb(0, nfs, nfsfh, data->private_data); + free_nfs_cb_data(data); +} + +static int +nfs3_open_continue_internal(struct nfs_context *nfs, + struct nfs_attr *attr _U_, + struct nfs_cb_data *data) +{ + int nfsmode = 0; + ACCESS3args args; + + if ((data->continue_int & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL)) { + nfs_set_error(nfs, "File allready exist when opening with O_CREAT|O_EXCL"); + data->cb(-EEXIST, nfs, nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return -1; + } + if (data->continue_int & O_WRONLY) { + nfsmode |= ACCESS3_MODIFY; + } + if (data->continue_int & O_RDWR) { + nfsmode |= ACCESS3_READ|ACCESS3_MODIFY; + } + if (!(data->continue_int & (O_WRONLY|O_RDWR))) { + nfsmode |= ACCESS3_READ; + } + + memset(&args, 0, sizeof(ACCESS3args)); + args.object.data.data_len = data->fh.len; + args.object.data.data_val = data->fh.val; + args.access = nfsmode; + + if (rpc_nfs3_access_task(nfs->rpc, nfs3_open_cb, &args, data) == NULL) { + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return -1; + } + return 0; +} + +struct open_cb_data { + nfs_cb cb; + void *private_data; + char *path; + int flags; + int mode; +}; + +static void +free_open_cb_data(void *ptr) +{ + struct open_cb_data *data = ptr; + + free(data->path); + free(data); +} + + + +static void nfs3_open_create_cb(int err, struct nfs_context *nfs, void *ret_data, + void *private_data) +{ + struct open_cb_data *cb_data = private_data; + + if (err) { + cb_data->cb(nfsstat3_to_errno(err), nfs, + nfs_get_error(nfs), cb_data->private_data); + free_open_cb_data(cb_data); + return; + } + + cb_data->cb(0, nfs, ret_data, cb_data->private_data); + free_open_cb_data(cb_data); +} + +static void +nfs3_create_1_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + CREATE3res *res; + struct nfs_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + struct open_cb_data *cb_data = data->continue_data; + struct nfsfh *nfsfh; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + res = command_data; + if (check_nfs3_error(nfs, status, data, command_data)) { + free_nfs_cb_data(data); + return; + } + + if (res->status != NFS3_OK) { + nfs_set_error(nfs, "NFS: CREATE3 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, + nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + return; + } + + nfsfh = calloc(1, sizeof(struct nfsfh)); + if (nfsfh == NULL) { + nfs_set_error(nfs, "NFS: Failed to allocate nfsfh structure"); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs_cb_data(data); + return; + } + + if (cb_data->flags & O_SYNC) { + nfsfh->is_sync = 1; + } + if (cb_data->flags & O_APPEND) { + nfsfh->is_append = 1; + } + + /* copy the filehandle */ + nfsfh->fh.len = res->CREATE3res_u.resok.obj.post_op_fh3_u.handle.data.data_len; + nfsfh->fh.val = malloc(nfsfh->fh.len); + if (nfsfh->fh.val == NULL) { + nfs_set_error(nfs, "Out of memory: Failed to allocate " + "fh structure"); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs_cb_data(data); + free(nfsfh); + return; + } + memcpy(nfsfh->fh.val, + res->CREATE3res_u.resok.obj.post_op_fh3_u.handle.data.data_val, + nfsfh->fh.len); + + + nfs_dircache_drop(nfs, &data->fh); + data->cb(0, nfs, nfsfh, data->private_data); + free_nfs_cb_data(data); + return; +} + +static int +nfs3_create_continue_internal(struct nfs_context *nfs, + struct nfs_attr *attr _U_, + struct nfs_cb_data *data) +{ + struct open_cb_data *cb_data = data->continue_data; + char *str = cb_data->path; + CREATE3args args; + + str = &str[strlen(str) + 1]; + + memset(&args, 0, sizeof(CREATE3args)); + args.where.dir.data.data_len = data->fh.len; + args.where.dir.data.data_val = data->fh.val; + args.where.name = str; + args.how.mode = (cb_data->flags & O_EXCL) ? GUARDED : UNCHECKED; + args.how.createhow3_u.obj_attributes.mode.set_it = 1; + args.how.createhow3_u.obj_attributes.mode.set_mode3_u.mode = cb_data->mode; + + if (rpc_nfs3_create_task(nfs->rpc, nfs3_create_1_cb, + &args, data) == NULL) { + nfs_set_error(nfs, "RPC error: Failed to send CREATE " + "call for %s/%s", data->path, str); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_open_cb_data(data); + return -1; + } + return 0; +} + +static void nfs3_initial_open_cb(int err, struct nfs_context *nfs, void *ret_data, + void *private_data) +{ + struct open_cb_data *cb_data = private_data; + char *ptr; + + if (err == -EEXIST && (cb_data->flags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL)) { + cb_data->cb(-EEXIST, nfs, + nfs_get_error(nfs), cb_data->private_data); + free_open_cb_data(cb_data); + return; + } + if (err == -NFS3ERR_NOENT && (cb_data->flags & O_CREAT)) { + ptr = strrchr(cb_data->path, '/'); + if (ptr) { + *ptr++ = 0; + } else { + /* + * We have a simple path to a top level name and no + * leading slashes. Make room for an extra character so + * we can create a path that is '\0' and then followed + * by the object we wish to create. + */ + ptr = calloc(1, strlen(cb_data->path) + 2); + if (ptr == NULL) { + cb_data->cb(-ENOMEM, nfs, + nfs_get_error(nfs), + cb_data->private_data); + free_open_cb_data(cb_data); + return; + } + ptr[0] = 0; + memcpy(&ptr[1], cb_data->path, strlen(cb_data->path)); + free(cb_data->path); + cb_data->path = ptr; + } + /* + * New_path now points to the parent directory and beyond the + * null terminator is the new object to create + */ + if (nfs3_lookuppath_async(nfs, cb_data->path, 0, + nfs3_open_create_cb, cb_data, + nfs3_create_continue_internal, cb_data, + NULL, 0) != 0) { + cb_data->cb(-ENOMEM, nfs, + nfs_get_error(nfs), cb_data->private_data); + free_open_cb_data(cb_data); + return; + } + return; + } + if (err) { + cb_data->cb(nfsstat3_to_errno(err), nfs, + nfs_get_error(nfs), cb_data->private_data); + free_open_cb_data(cb_data); + return; + } + cb_data->cb(0, nfs, ret_data, cb_data->private_data); + free_open_cb_data(cb_data); +} + +/* TODO add the plumbing for mode */ +int +nfs3_open_async(struct nfs_context *nfs, const char *path, int flags, + int mode, nfs_cb cb, void *private_data) +{ + struct open_cb_data *cb_data; + + cb_data = calloc(1, sizeof(struct open_cb_data)); + if (cb_data == NULL) { + nfs_set_error(nfs, "Out of memory: failed to allocate " + "nfs_cb_data structure"); + return -ENOMEM; + } + cb_data->path = strdup(path); + if (cb_data->path == NULL) { + nfs_set_error(nfs, "Out of memory: failed to strup path"); + free_open_cb_data(cb_data); + return -ENOMEM; + } + cb_data->cb = cb; + cb_data->private_data = private_data; + cb_data->flags = flags; + cb_data->mode = mode; + + if (nfs3_lookuppath_async(nfs, path, 0, nfs3_initial_open_cb, cb_data, + nfs3_open_continue_internal, NULL, + NULL, flags) != 0) { + free_open_cb_data(cb_data); + return -1; + } + return 0; +} + diff --git a/deps/libnfs/lib/nfs_v4.c b/deps/libnfs/lib/nfs_v4.c new file mode 100644 index 000000000000..4d7e997ac32b --- /dev/null +++ b/deps/libnfs/lib/nfs_v4.c @@ -0,0 +1,5408 @@ +/* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */ +/* + Copyright (C) 2017 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 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ +/* + * High level api to nfsv4 filesystems + */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef AROS +#include "aros_compat.h" +#endif + +#ifdef PS2_EE +#include "ps2_compat.h" +#endif + +#ifdef PS3_PPU +#include "ps3_compat.h" +#endif + +#ifdef WIN32 +#include +#endif + +#ifdef HAVE_INTTYPES_H +#include +#else +#define PRIu64 "llu" +#endif + +#ifdef HAVE_UTIME_H +#include +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_SYS_VFS_H +#include +#endif + +#ifdef HAVE_SYS_STATVFS_H +#include +#endif + +#if defined(__ANDROID__) && !defined(HAVE_SYS_STATVFS_H) +#define statvfs statfs +#endif + +#ifdef HAVE_NETINET_IN_H +#include +#endif + +#ifdef HAVE_STRINGS_H +#include +#endif + +#ifdef MAJOR_IN_MKDEV +#include +#endif + +#ifdef HAVE_SYS_SYSMACROS_H +#include +#endif + +#ifdef HAVE_GETPWNAM +#include +#endif + +#ifdef WIN32 +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "libnfs-zdr.h" +#include "slist.h" +#include "libnfs.h" +#include "libnfs-raw.h" +#include "libnfs-raw-nfs4.h" +#include "libnfs-private.h" + +#ifndef discard_const +#define discard_const(ptr) ((void *)((intptr_t)(ptr))) +#endif + +struct nfs4_cb_data; +typedef int (*op_filler)(struct nfs4_cb_data *data, nfs_argop4 *op); + +struct lookup_link_data { + unsigned int idx; +}; + +typedef void (*blob_free)(void *); + +struct nfs4_blob { + int len; + void *val; + blob_free free; +}; + +/* Function and arguments to append the requested operations we want + * for the resolved path. + */ +struct lookup_filler { + op_filler func; + int max_op; + int flags; + void *data; /* Freed by nfs4_cb_data destructor */ + + struct nfs4_blob blob0; + struct nfs4_blob blob1; + struct nfs4_blob blob2; + struct nfs4_blob blob3; +}; + +struct rw_data { + uint64_t offset; + int update_pos; +}; + +struct nfs4_cb_data { + struct nfs_context *nfs; +/* Do not follow symlinks for the final component on a lookup. + * I.e. stat vs lstat + */ +#define LOOKUP_FLAG_NO_FOLLOW 0x0001 +#define LOOKUP_FLAG_IS_STATVFS64 0x0002 +#define MUTEX_HELD 0x0004 + int flags; + + /* Internal callback for open-with-continuation use */ + rpc_cb open_cb; + + /* Application callback and data */ + nfs_cb cb; + void *private_data; + + /* Used to track open_owner during open() */ + uint32_t open_owner; + + /* internal callback */ + rpc_cb continue_cb; + + char *path; /* path to lookup */ + struct lookup_filler filler; + + /* Data we need when resolving a symlink in the path */ + struct lookup_link_data link; + + /* Data we need for updating offset in read/write */ + struct rw_data rw_data; +}; + +static uint32_t standard_attributes[2] = { + (1 << FATTR4_TYPE | + 1 << FATTR4_SIZE | + 1 << FATTR4_FSID | + 1 << FATTR4_FILEID), + (1 << (FATTR4_MODE - 32) | + 1 << (FATTR4_NUMLINKS - 32) | + 1 << (FATTR4_OWNER - 32) | + 1 << (FATTR4_OWNER_GROUP - 32) | + 1 << (FATTR4_RAWDEV - 32) | + 1 << (FATTR4_SPACE_USED - 32) | + 1 << (FATTR4_TIME_ACCESS - 32) | + 1 << (FATTR4_TIME_METADATA - 32) | + 1 << (FATTR4_TIME_MODIFY - 32)) +}; +static uint32_t statvfs_attributes[2] = { + (1 << FATTR4_FSID | + 1 << FATTR4_FILES_AVAIL | + 1 << FATTR4_FILES_FREE | + 1 << FATTR4_FILES_TOTAL | + 1 << FATTR4_MAXNAME), + (1 << (FATTR4_SPACE_AVAIL - 32) | + 1 << (FATTR4_SPACE_FREE - 32) | + 1 << (FATTR4_SPACE_TOTAL - 32)) +}; + +static uint32_t getacl_attributes[1] = { + (1 << FATTR4_ACL ) +}; + +static uint32_t rwmax_attributes[1] = { + (1 << FATTR4_MAXREAD | + 1 << FATTR4_MAXWRITE ) +}; + +static int +nfs4_open_async_internal(struct nfs_context *nfs, struct nfs4_cb_data *data, + int flags, int mode); + +/* Caller will free the returned path. */ +static char * +nfs4_resolve_path(struct nfs_context *nfs, const char *path) +{ + char *new_path = NULL; + + /* Absolute paths we just use as is. + * Relateive paths have cwd prepended to them and then become + * absolute paths too. + */ + if (path[0] == '/') { + new_path = strdup(path); + } else { + new_path = malloc(strlen(path) + strlen(nfs->nfsi->cwd) + 2); + if (new_path != NULL) { + sprintf(new_path, "%s/%s", nfs->nfsi->cwd, path); + } + } + if (new_path == NULL) { + nfs_set_error(nfs, "Out of memory: failed to " + "allocate path string"); + return NULL; + } + + if (nfs_normalize_path(nfs, new_path)) { + nfs_set_error(nfs, "Failed to normalize real path. %s", + nfs_get_error(nfs)); + free(new_path); + return NULL; + } + + return new_path; +} + +static void +free_nfs4_cb_data(struct nfs4_cb_data *data) +{ +#ifdef HAVE_MULTITHREADING + if (data->flags & MUTEX_HELD) { + nfs_mt_mutex_unlock(&data->nfs->nfsi->nfs4_open_call_mutex); + } +#endif + free(data->path); + free(data->filler.data); + if (data->filler.blob0.val && data->filler.blob0.free) { + data->filler.blob0.free(data->filler.blob0.val); + } + if (data->filler.blob1.val && data->filler.blob1.free) { + data->filler.blob1.free(data->filler.blob1.val); + } + if (data->filler.blob2.val && data->filler.blob2.free) { + data->filler.blob2.free(data->filler.blob2.val); + } + if (data->filler.blob3.val && data->filler.blob3.free) { + data->filler.blob3.free(data->filler.blob3.val); + } + free(data); +} + +static struct nfs4_cb_data * +init_cb_data_full_path(struct nfs_context *nfs, const char *path) +{ + struct nfs4_cb_data *data; + + data = calloc(1, sizeof(*data)); + if (data == NULL) { + nfs_set_error(nfs, "Out of memory. Failed to allocate " + "cb data"); + return NULL; + } + + data->nfs = nfs; + data->path = nfs4_resolve_path(nfs, path); + if (data->path == NULL) { + free_nfs4_cb_data(data); + return NULL; + } + + return data; +} + +static void +data_split_path(struct nfs4_cb_data *data) +{ + char *path; + path = strrchr(data->path, '/'); + if (path == data->path) { + char *ptr; + + for (ptr = data->path; *ptr; ptr++) { + *ptr = *(ptr + 1); + } + /* No path to lookup */ + data->filler.data = data->path; + data->path = strdup("/"); + } else { + *path++ = 0; + data->filler.data = strdup(path); + } +} + +static struct nfs4_cb_data * +init_cb_data_split_path(struct nfs_context *nfs, const char *orig_path) +{ + struct nfs4_cb_data *data; + + data = init_cb_data_full_path(nfs, orig_path); + if (data == NULL) { + return NULL; + } + + data_split_path(data); + return data; +} + +static int +check_nfs4_error(struct nfs_context *nfs, int status, + struct nfs4_cb_data *data, void *command_data, + char *op_name) +{ + COMPOUND4res *res = command_data; + + if (status == RPC_STATUS_ERROR) { + data->cb(-EFAULT, nfs, res, data->private_data); + free_nfs4_cb_data(data); + return 1; + } + if (status == RPC_STATUS_CANCEL) { + data->cb(-EINTR, nfs, "Command was cancelled", + data->private_data); + free_nfs4_cb_data(data); + return 1; + } + if (status == RPC_STATUS_TIMEOUT) { + data->cb(-EINTR, nfs, "Command timed out", + data->private_data); + free_nfs4_cb_data(data); + return 1; + } + if (res && res->status != NFS4_OK) { + nfs_set_error(nfs, "NFS4: %s (path %s) failed with " + "%s(%d)", op_name, + data->path, + nfsstat4_to_str(res->status), + nfsstat4_to_errno(res->status)); + data->cb(nfsstat4_to_errno(res->status), nfs, + nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + return 1; + } + + return 0; +} + +static int +nfs4_find_op(struct nfs_context *nfs, struct nfs4_cb_data *data, + COMPOUND4res *res, int op, const char *op_name) +{ + int i; + + for (i = 0; i < (int)res->resarray.resarray_len; i++) { + if (res->resarray.resarray_val[i].resop == op) { + break; + } + } + if (i == res->resarray.resarray_len) { + nfs_set_error(nfs, "No %s result.", op_name); + data->cb(-EINVAL, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + return -1; + } + + return i; +} + +static uint64_t +nfs_hton64(uint64_t val) +{ + int i; + uint64_t res; + unsigned char *ptr = (void *)&res; + + for (i = 0; i < 8; i++) { + ptr[7 - i] = val & 0xff; + val >>= 8; + } + return res; +} + +static uint64_t +nfs_ntoh64(uint64_t val) +{ + int i; + uint64_t res; + unsigned char *ptr = (void *)&res; + + for (i = 0; i < 8; i++) { + ptr[7 - i] = val & 0xff; + val >>= 8; + } + return res; +} + +static uint64_t +nfs_pntoh64(const uint32_t *buf) +{ + uint64_t val; + + val = ntohl(*(uint32_t *)(void *)buf); + buf++; + val <<= 32; + val |= ntohl(*(uint32_t *)(void *)buf); + + return val; +} + +static int +nfs_get_ugid(struct nfs_context *nfs, const char *buf, int slen, int is_user) +{ + int ugid = 0; + const char *name = buf; + + while (slen) { + if (isdigit(*buf)) { + ugid *= 10; + ugid += *buf - '0'; + } else { +#ifdef HAVE_GETPWNAM + struct passwd *pwd = getpwnam(name); + if (pwd) { + if (is_user) { + return pwd->pw_uid; + } else { + return pwd->pw_gid; + } + } +#else + (void) name; // Let the compiler know that this variable is intentionally unused, build would fail with -Werror=unused-variable otherwise +#endif + return 65534; + } + buf++; + slen--; + } + return ugid; +} + +#define CHECK_GETATTR_BUF_SPACE(len, size) \ + if (len < size) { \ + nfs_set_error(nfs, "Not enough data in fattr4"); \ + return -1; \ + } + +static uint64_t +specdata4_to_rdev(uint32_t *specdata) +{ + uint64_t rdev = ntohl(specdata[0]); + return (rdev << 32) | ntohl(specdata[1]); +} + +static int +nfs_parse_attributes(struct nfs_context *nfs, struct nfs4_cb_data *data, + struct nfs_stat_64 *st, const char *buf, int len) +{ + int type, slen, pad; + + /* Type */ + CHECK_GETATTR_BUF_SPACE(len, 4); + type = ntohl(*(uint32_t *)(void *)buf); + buf += 4; + len -= 4; + /* Size */ + CHECK_GETATTR_BUF_SPACE(len, 8); + st->nfs_size = nfs_pntoh64((uint32_t *)(void *)buf); + buf += 8; + len -= 8; + /* FSID */ + CHECK_GETATTR_BUF_SPACE(len, 16); + st->nfs_dev = ((uint64_t *)buf)[0] ^ ((uint64_t *)buf)[1]; + buf += 16; + len -= 16; + /* Inode */ + CHECK_GETATTR_BUF_SPACE(len, 8); + st->nfs_ino = nfs_pntoh64((uint32_t *)(void *)buf); + buf += 8; + len -= 8; + /* Mode */ + CHECK_GETATTR_BUF_SPACE(len, 4); + st->nfs_mode = ntohl(*(uint32_t *)(void *)buf); + buf += 4; + len -= 4; + switch (type) { + case NF4REG: + st->nfs_mode |= S_IFREG; + break; + case NF4DIR: + st->nfs_mode |= S_IFDIR; + break; + case NF4BLK: + st->nfs_mode |= S_IFBLK; + break; + case NF4CHR: + st->nfs_mode |= S_IFCHR; + break; + case NF4LNK: + st->nfs_mode |= S_IFLNK; + break; + case NF4SOCK: + st->nfs_mode |= S_IFSOCK; + break; + case NF4FIFO: + st->nfs_mode |= S_IFIFO; + break; + default: + break; + } + /* Num Links */ + CHECK_GETATTR_BUF_SPACE(len, 4); + st->nfs_nlink = ntohl(*(uint32_t *)(void *)buf); + buf += 4; + len -= 4; + /* Owner */ + CHECK_GETATTR_BUF_SPACE(len, 4); + slen = ntohl(*(uint32_t *)(void *)buf); + if (slen < 0) { + return -1; + } + buf += 4; + len -= 4; + pad = (4 - (slen & 0x03)) & 0x03; + CHECK_GETATTR_BUF_SPACE(len, slen); + st->nfs_uid = nfs_get_ugid(nfs, buf, slen, 1); + buf += slen; + CHECK_GETATTR_BUF_SPACE(len, pad); + buf += pad; + len -= pad; + /* Group */ + CHECK_GETATTR_BUF_SPACE(len, 4); + slen = ntohl(*(uint32_t *)(void *)buf); + if (slen < 0) { + return -1; + } + buf += 4; + len -= 4; + pad = (4 - (slen & 0x03)) & 0x03; + CHECK_GETATTR_BUF_SPACE(len, slen); + st->nfs_gid = nfs_get_ugid(nfs, buf, slen, 0); + buf += slen; + CHECK_GETATTR_BUF_SPACE(len, pad); + buf += pad; + len -= pad; + /* raw device */ + CHECK_GETATTR_BUF_SPACE(len, 8); + st->nfs_rdev = specdata4_to_rdev((uint32_t *)buf); + buf += 8; + len -= 8; + /* Space Used */ + CHECK_GETATTR_BUF_SPACE(len, 8); + st->nfs_used = nfs_pntoh64((uint32_t *)(void *)buf); + buf += 8; + len -= 8; + /* ATime */ + CHECK_GETATTR_BUF_SPACE(len, 12); + st->nfs_atime = nfs_pntoh64((uint32_t *)(void *)buf); + buf += 8; + len -= 8; + st->nfs_atime_nsec = ntohl(*(uint32_t *)(void *)buf); + buf += 4; + len -= 4; + /* CTime */ + CHECK_GETATTR_BUF_SPACE(len, 12); + st->nfs_ctime = nfs_pntoh64((uint32_t *)(void *)buf); + buf += 8; + len -= 8; + st->nfs_ctime_nsec = ntohl(*(uint32_t *)(void *)buf); + buf += 4; + len -= 4; + /* MTime */ + CHECK_GETATTR_BUF_SPACE(len, 12); + st->nfs_mtime = nfs_pntoh64((uint32_t *)(void *)buf); + buf += 8; + len -= 8; + st->nfs_mtime_nsec = ntohl(*(uint32_t *)(void *)buf); + buf += 4; + len -= 4; + + st->nfs_blksize = NFS_BLKSIZE; + st->nfs_blocks = (st->nfs_used + NFS_BLKSIZE -1) / NFS_BLKSIZE; + + return 0; +} + +static int +nfs4_num_path_components(struct nfs_context *nfs, const char *path) +{ + int i; + + for (i = 0; (path = strchr(path, '/')); path++, i++) + ; + + return i; +} + +static int +nfs4_op_create(struct nfs_context *nfs, nfs_argop4 *op, const char *name, + nfs_ftype4 type, struct nfs4_blob *attrmask, + struct nfs4_blob *attr_vals, const char *linkdata, int dev) +{ + CREATE4args *cargs; + + op[0].argop = OP_CREATE; + cargs = &op[0].nfs_argop4_u.opcreate; + memset(cargs, 0, sizeof(*cargs)); + cargs->objtype.type = type; + cargs->objname.utf8string_len = strlen(name); + cargs->objname.utf8string_val = discard_const(name); + if (attrmask) { + cargs->createattrs.attrmask.bitmap4_len = attrmask->len; + cargs->createattrs.attrmask.bitmap4_val = attrmask->val; + } + if (attr_vals) { + cargs->createattrs.attr_vals.attrlist4_len = attr_vals->len; + cargs->createattrs.attr_vals.attrlist4_val = attr_vals->val; + } + if (linkdata) { + cargs->objtype.createtype4_u.linkdata.utf8string_len = + strlen(linkdata); + cargs->objtype.createtype4_u.linkdata.utf8string_val = + discard_const(linkdata); + } + switch (type) { + case NF4CHR: + cargs->objtype.type = NF4CHR; + cargs->objtype.createtype4_u.devdata.specdata1 = major(dev); + cargs->objtype.createtype4_u.devdata.specdata2 = minor(dev); + break; + case NF4BLK: + cargs->objtype.type = NF4BLK; + cargs->objtype.createtype4_u.devdata.specdata1 = major(dev); + cargs->objtype.createtype4_u.devdata.specdata2 = minor(dev); + break; + default: + ; + } + return 1; +} + +static int +nfs4_op_commit(struct nfs_context *nfs, nfs_argop4 *op) +{ + COMMIT4args *coargs; + + op[0].argop = OP_COMMIT; + coargs = &op[0].nfs_argop4_u.opcommit; + coargs->offset = 0; + coargs->count = 0; + + return 1; +} + +static int +nfs4_op_close(struct nfs_context *nfs, nfs_argop4 *op, struct nfsfh *fh) +{ + CLOSE4args *clargs; + int i = 0; + + if (fh->is_dirty) { + i += nfs4_op_commit(nfs, &op[i]); + } + + op[i].argop = OP_CLOSE; + clargs = &op[i++].nfs_argop4_u.opclose; + clargs->seqid = fh->open_seqid; + clargs->open_stateid.seqid = fh->stateid.seqid; + memcpy(clargs->open_stateid.other, fh->stateid.other, 12); + + return i; +} + +static int +nfs4_op_access(struct nfs_context *nfs, nfs_argop4 *op, uint32_t access_mask) +{ + ACCESS4args *aargs; + + op[0].argop = OP_ACCESS; + aargs = &op[0].nfs_argop4_u.opaccess; + memset(aargs, 0, sizeof(*aargs)); + aargs->access = access_mask; + + return 1; +} + +static int +nfs4_op_setclientid(struct nfs_context *nfs, nfs_argop4 *op, verifier4 verifier, + const char *client_name) +{ + SETCLIENTID4args *scidargs; + + op[0].argop = OP_SETCLIENTID; + scidargs = &op[0].nfs_argop4_u.opsetclientid; + memcpy(scidargs->client.verifier, verifier, sizeof(verifier4)); + scidargs->client.id.id_len = strlen(client_name); + scidargs->client.id.id_val = discard_const(client_name); + /* TODO: Decide what we should do here. As long as we only + * expose a single FD to the application we will not be able to + * do NFSv4 callbacks easily. + * Just give it garbage for now until we figure out how we should + * solve this. Until then we will just have to avoid doing things + * that require a callback. + * ( Clients (i.e. Linux) ignore this anyway and just call back to + * the originating address and program anyway. ) + */ + scidargs->callback.cb_program = 0; /* NFS4_CALLBACK */ + scidargs->callback.cb_location.r_netid = "tcp"; + scidargs->callback.cb_location.r_addr = "0.0.0.0.0.0"; + scidargs->callback_ident = 0x00000001; + + return 1; +} + +static int +nfs4_op_open_confirm(struct nfs_context *nfs, nfs_argop4 *op, struct nfsfh *fh) +{ + OPEN_CONFIRM4args *ocargs; + + op[0].argop = OP_OPEN_CONFIRM; + ocargs = &op[0].nfs_argop4_u.opopen_confirm; + ocargs->open_stateid.seqid = fh->stateid.seqid; + memcpy(&ocargs->open_stateid.other, fh->stateid.other, 12); + ocargs->seqid = fh->open_seqid; + + return 1; +} + +static int +nfs4_op_truncate(struct nfs_context *nfs, nfs_argop4 *op, struct nfsfh *fh, + void *sabuf) +{ + SETATTR4args *saargs; + static uint32_t mask[2] = {1 << (FATTR4_SIZE), + 1 << (FATTR4_TIME_MODIFY_SET - 32)}; + + op[0].argop = OP_SETATTR; + saargs = &op[0].nfs_argop4_u.opsetattr; + saargs->stateid.seqid = fh->stateid.seqid; + memcpy(saargs->stateid.other, fh->stateid.other, 12); + + saargs->obj_attributes.attrmask.bitmap4_len = 2; + saargs->obj_attributes.attrmask.bitmap4_val = mask; + + saargs->obj_attributes.attr_vals.attrlist4_len = 12; + saargs->obj_attributes.attr_vals.attrlist4_val = sabuf; + + return 1; +} + +static int +nfs4_op_chmod(struct nfs_context *nfs, nfs_argop4 *op, struct nfsfh *fh, + void *sabuf) +{ + SETATTR4args *saargs; + static uint32_t mask[2] = {0, + 1 << (FATTR4_MODE - 32)}; + + op[0].argop = OP_SETATTR; + saargs = &op[0].nfs_argop4_u.opsetattr; + if (fh) { + saargs->stateid.seqid = fh->stateid.seqid; + memcpy(saargs->stateid.other, fh->stateid.other, 12); + } + + saargs->obj_attributes.attrmask.bitmap4_len = 2; + saargs->obj_attributes.attrmask.bitmap4_val = mask; + + saargs->obj_attributes.attr_vals.attrlist4_len = 4; + saargs->obj_attributes.attr_vals.attrlist4_val = sabuf; + + return 1; +} + +static int +nfs4_op_chown(struct nfs_context *nfs, nfs_argop4 *op, struct nfsfh *fh, + void *sabuf, int len) +{ + SETATTR4args *saargs; + static uint32_t mask[2] = {0, + 1 << (FATTR4_OWNER - 32) | + 1 << (FATTR4_OWNER_GROUP - 32)}; + + op[0].argop = OP_SETATTR; + saargs = &op[0].nfs_argop4_u.opsetattr; + if (fh) { + saargs->stateid.seqid = fh->stateid.seqid; + memcpy(saargs->stateid.other, fh->stateid.other, 12); + } + + saargs->obj_attributes.attrmask.bitmap4_len = 2; + saargs->obj_attributes.attrmask.bitmap4_val = mask; + + saargs->obj_attributes.attr_vals.attrlist4_len = len; + saargs->obj_attributes.attr_vals.attrlist4_val = sabuf; + + return 1; +} + +static int +nfs4_op_utimes(struct nfs_context *nfs, nfs_argop4 *op, struct nfsfh *fh, + void *sabuf, int len) +{ + SETATTR4args *saargs; + static uint32_t mask[2] = {0, + 1 << (FATTR4_TIME_ACCESS_SET - 32) | + 1 << (FATTR4_TIME_MODIFY_SET - 32)}; + + op[0].argop = OP_SETATTR; + saargs = &op[0].nfs_argop4_u.opsetattr; + if (fh) { + saargs->stateid.seqid = fh->stateid.seqid; + memcpy(saargs->stateid.other, fh->stateid.other, 12); + } + + saargs->obj_attributes.attrmask.bitmap4_len = 2; + saargs->obj_attributes.attrmask.bitmap4_val = mask; + + saargs->obj_attributes.attr_vals.attrlist4_len = len; + saargs->obj_attributes.attr_vals.attrlist4_val = sabuf; + + return 1; +} + +static int +nfs4_op_readdir(struct nfs_context *nfs, nfs_argop4 *op, uint64_t cookie) +{ + READDIR4args *rdargs; + + op[0].argop = OP_READDIR; + rdargs = &op[0].nfs_argop4_u.opreaddir; + memset(rdargs, 0, sizeof(*rdargs)); + + rdargs->cookie = cookie; + rdargs->dircount = nfs->nfsi->readdir_dircount; + rdargs->maxcount = nfs->nfsi->readdir_maxcount; + rdargs->attr_request.bitmap4_len = 2; + rdargs->attr_request.bitmap4_val = standard_attributes; + + return 1; +} + +static int +nfs4_op_rename(struct nfs_context *nfs, nfs_argop4 *op, const char *oldname, + const char *newname) +{ + RENAME4args *rargs; + + op[0].argop = OP_RENAME; + rargs = &op[0].nfs_argop4_u.oprename; + memset(rargs, 0, sizeof(*rargs)); + rargs->oldname.utf8string_len = strlen(oldname); + rargs->oldname.utf8string_val = discard_const(oldname); + rargs->newname.utf8string_len = strlen(newname); + rargs->newname.utf8string_val = discard_const(newname); + + return 1; +} + +static int +nfs4_op_read(struct nfs_context *nfs, nfs_argop4 *op, struct nfsfh *fh, + uint64_t offset, size_t count) +{ + READ4args *rargs; + + op[0].argop = OP_READ; + rargs = &op[0].nfs_argop4_u.opread; + rargs->stateid.seqid = fh->stateid.seqid; + memcpy(rargs->stateid.other, fh->stateid.other, 12); + rargs->offset = offset; + rargs->count = count; + + return 1; +} + +static int +nfs4_op_write(struct nfs_context *nfs, nfs_argop4 *op, struct nfsfh *fh, + uint64_t offset, size_t count, const char *buf) +{ + WRITE4args *wargs; + + op[0].argop = OP_WRITE; + wargs = &op[0].nfs_argop4_u.opwrite; + wargs->stateid.seqid = fh->stateid.seqid; + memcpy(wargs->stateid.other, fh->stateid.other, 12); + wargs->offset = offset; + if (fh->is_sync) { + wargs->stable = DATA_SYNC4; + } else { + wargs->stable = UNSTABLE4; + fh->is_dirty = 1; + } + wargs->data.data_len = count; + wargs->data.data_val = discard_const(buf); + + return 1; +} + +static int +nfs4_op_getfh(struct nfs_context *nfs, nfs_argop4 *op) +{ + op[0].argop = OP_GETFH; + + return 1; +} + +static int +nfs4_op_savefh(struct nfs_context *nfs, nfs_argop4 *op) +{ + op[0].argop = OP_SAVEFH; + + return 1; +} + +static int +nfs4_op_link(struct nfs_context *nfs, nfs_argop4 *op, const char *newname) +{ + LINK4args *largs; + + op[0].argop = OP_LINK; + largs = &op[0].nfs_argop4_u.oplink; + memset(largs, 0, sizeof(*largs)); + largs->newname.utf8string_len = strlen(newname); + largs->newname.utf8string_val = discard_const(newname); + + return 1; +} + +static int +nfs4_op_putfh(struct nfs_context *nfs, nfs_argop4 *op, struct nfsfh *nfsfh) +{ + PUTFH4args *pfargs; + op[0].argop = OP_PUTFH; + + pfargs = &op[0].nfs_argop4_u.opputfh; + pfargs->object.nfs_fh4_len = nfsfh->fh.len; + pfargs->object.nfs_fh4_val = nfsfh->fh.val; + + return 1; +} + +static int +nfs4_op_lock(struct nfs_context *nfs, nfs_argop4 *op, struct nfsfh *fh, + nfs_opnum4 cmd, nfs_lock_type4 locktype, + int reclaim, uint64_t offset, length4 length) +{ + LOCK4args *largs; + op[0].argop = cmd; + + largs = &op[0].nfs_argop4_u.oplock; + largs->locktype = locktype; + largs->reclaim = reclaim; + largs->offset = offset; + largs->length = length; + + if (nfs->nfsi->has_lock_owner) { + largs->locker.new_lock_owner = 0; + largs->locker.locker4_u.lock_owner.lock_stateid.seqid = + fh->lock_stateid.seqid; + memcpy(largs->locker.locker4_u.lock_owner.lock_stateid.other, + fh->lock_stateid.other, 12); + largs->locker.locker4_u.lock_owner.lock_seqid = + fh->lock_seqid; + } else { + largs->locker.new_lock_owner = 1; + largs->locker.locker4_u.open_owner.open_seqid = + fh->open_seqid; + largs->locker.locker4_u.open_owner.open_stateid.seqid = + fh->stateid.seqid; + memcpy(largs->locker.locker4_u.open_owner.open_stateid.other, + fh->stateid.other, 12); + largs->locker.locker4_u.open_owner.lock_owner.clientid = + nfs->nfsi->clientid; + largs->locker.locker4_u.open_owner.lock_owner.owner.owner_len = + strlen(nfs->nfsi->client_name); + largs->locker.locker4_u.open_owner.lock_owner.owner.owner_val = + nfs->nfsi->client_name; + largs->locker.locker4_u.open_owner.lock_seqid = + fh->lock_seqid; + } + fh->lock_seqid++; + + return 1; +} + +static int +nfs4_op_locku(struct nfs_context *nfs, nfs_argop4 *op, struct nfsfh *fh, + nfs_lock_type4 locktype, uint64_t offset, length4 length) +{ + LOCKU4args *luargs; + op[0].argop = OP_LOCKU; + + luargs = &op[0].nfs_argop4_u.oplocku; + luargs->locktype = locktype; + luargs->offset = offset; + luargs->length = length; + + luargs->seqid = fh->lock_seqid; + luargs->lock_stateid.seqid = fh->lock_stateid.seqid; + memcpy(luargs->lock_stateid.other, fh->lock_stateid.other, 12); + + fh->lock_seqid++; + + return 1; +} + +static int +nfs4_op_lockt(struct nfs_context *nfs, nfs_argop4 *op, struct nfsfh *fh, + nfs_lock_type4 locktype, uint64_t offset, length4 length) +{ + LOCKT4args *ltargs; + op[0].argop = OP_LOCKT; + + ltargs = &op[0].nfs_argop4_u.oplockt; + ltargs->locktype = locktype; + ltargs->offset = offset; + ltargs->length = length; + + ltargs->owner.clientid = nfs->nfsi->clientid; + ltargs->owner.owner.owner_len = strlen(nfs->nfsi->client_name); + ltargs->owner.owner.owner_val = nfs->nfsi->client_name; + + return 1; +} + +static int +nfs4_op_lookup(struct nfs_context *nfs, nfs_argop4 *op, const char *path) +{ + LOOKUP4args *largs; + + op[0].argop = OP_LOOKUP; + largs = &op[0].nfs_argop4_u.oplookup; + largs->objname.utf8string_len = strlen(path); + largs->objname.utf8string_val = discard_const(path); + + return 1; +} + +static int +nfs4_op_setclientid_confirm(struct nfs_context *nfs, struct nfs_argop4 *op, + uint64_t clientid, verifier4 verifier) +{ + SETCLIENTID_CONFIRM4args *scidcargs; + + op[0].argop = OP_SETCLIENTID_CONFIRM; + scidcargs = &op[0].nfs_argop4_u.opsetclientid_confirm; + scidcargs->clientid = clientid; + memcpy(scidcargs->setclientid_confirm, verifier, NFS4_VERIFIER_SIZE); + + return 1; +} + +static int +nfs4_op_putrootfh(struct nfs_context *nfs, nfs_argop4 *op) +{ + op[0].argop = OP_PUTROOTFH; + + return 1; +} + +static int +nfs4_op_readlink(struct nfs_context *nfs, nfs_argop4 *op) +{ + op[0].argop = OP_READLINK; + + return 1; +} + +static int +nfs4_op_remove(struct nfs_context *nfs, nfs_argop4 *op, const char *name) +{ + REMOVE4args *rmargs; + + op[0].argop = OP_REMOVE; + rmargs = &op[0].nfs_argop4_u.opremove; + memset(rmargs, 0, sizeof(*rmargs)); + rmargs->target.utf8string_len = strlen(name); + rmargs->target.utf8string_val = discard_const(name); + + return 1; +} + +static int +nfs4_op_getattr(struct nfs_context *nfs, nfs_argop4 *op, + uint32_t *attributes, int count) +{ + GETATTR4args *gaargs; + + op[0].argop = OP_GETATTR; + gaargs = &op[0].nfs_argop4_u.opgetattr; + memset(gaargs, 0, sizeof(*gaargs)); + + gaargs->attr_request.bitmap4_val = attributes; + gaargs->attr_request.bitmap4_len = count; + + return 1; +} + +/* + * Allocate op and populate the path components. + * Will mutate path. + * + * Returns: + * -1 : On error. + * : On success. Idx represents the next free index in op. + * Caller must free op. + */ +static int +nfs4_allocate_op(struct nfs_context *nfs, nfs_argop4 **op, + char *path, int num_extra) +{ + char *ptr; + int i, count; + + *op = NULL; + + count = nfs4_num_path_components(nfs, path); + + *op = malloc(sizeof(**op) * (2 + count + num_extra)); + if (*op == NULL) { + nfs_set_error(nfs, "Failed to allocate op array"); + return -1; + } + + i = 0; + if (nfs->nfsi->rootfh.len) { + struct nfsfh fh; + + fh.fh.len = nfs->nfsi->rootfh.len; + fh.fh.val = nfs->nfsi->rootfh.val; + i += nfs4_op_putfh(nfs, &(*op)[i], &fh); + } else { + i += nfs4_op_putrootfh(nfs, &(*op)[i]); + } + + ptr = &path[1]; + while (ptr && *ptr != 0) { + char *tmp; + + tmp = strchr(ptr, '/'); + if (tmp) { + *tmp = 0; + tmp = tmp + 1; + } + i += nfs4_op_lookup(nfs, &(*op)[i], ptr); + + ptr = tmp; + } + + i += nfs4_op_getattr(nfs, &(*op)[i], standard_attributes, 2); + + return i; +} + +static int +nfs4_lookup_path_async(struct nfs_context *nfs, + struct nfs4_cb_data *data, + rpc_cb cb); + +static void +nfs4_lookup_path_2_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + READLINK4res *rlres = NULL; + char *path, *tmp, *end; + int i; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs4_error(nfs, status, data, res, "READLINK")) { + return; + } + + path = strdup(data->path); + if (path == NULL) { + nfs_set_error(nfs, "Out of memory duplicating path."); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs4_cb_data(data); + return; + } + + tmp = &path[0]; + while (data->link.idx-- > 1) { + tmp = strchr(tmp + 1, '/'); + } + *tmp++ = 0; + end = strchr(tmp, '/'); + if (end == NULL) { + /* Symlink was the last component. */ + end = ""; + } else { + *end++ = 0; + } + + if ((i = nfs4_find_op(nfs, data, res, OP_READLINK, "READLINK")) < 0) { + free(path); + return; + } + rlres = &res->resarray.resarray_val[i].nfs_resop4_u.opreadlink; + + tmp = malloc(strlen(data->path) + 3 + rlres->READLINK4res_u.resok4.link.utf8string_len); + if (tmp == NULL) { + nfs_set_error(nfs, "Out of memory duplicating path."); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs4_cb_data(data); + free(path); + return; + } + + sprintf(tmp, "%s/%.*s/%s", + path, (int)rlres->READLINK4res_u.resok4.link.utf8string_len, + rlres->READLINK4res_u.resok4.link.utf8string_val, end); + free(path); + free(data->path); + data->path = tmp; + + if (nfs4_lookup_path_async(nfs, data, data->continue_cb) < 0) { + data->cb(-ENOMEM, nfs, res, data->private_data); + free_nfs4_cb_data(data); + return; + } +} + +static int +nfs4_open_readlink(struct rpc_context *rpc, COMPOUND4res *res, + struct nfs4_cb_data *data); + +static void +nfs4_lookup_path_1_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4args args; + nfs_argop4 *op; + COMPOUND4res *res = command_data; + int i; + int resolve_link = 0; + char *path, *tmp; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (status == RPC_STATUS_ERROR) { + data->cb(-EFAULT, nfs, res, data->private_data); + free_nfs4_cb_data(data); + return; + } + if (status == RPC_STATUS_CANCEL) { + data->cb(-EINTR, nfs, "Command was cancelled", + data->private_data); + free_nfs4_cb_data(data); + return; + } + if (status == RPC_STATUS_TIMEOUT) { + data->cb(-EINTR, nfs, "Command timed out", + data->private_data); + free_nfs4_cb_data(data); + return; + } + if (res->status != NFS4_OK && + res->status != NFS4ERR_SYMLINK) { + nfs_set_error(nfs, "NFS4: (path %s) failed with " + "%s(%d)", + data->path, + nfsstat4_to_str(res->status), + nfsstat4_to_errno(res->status)); + data->cb(nfsstat4_to_errno(res->status), nfs, + nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + return; + } + + for (i = 0; i < (int)res->resarray.resarray_len; i++) { + if (res->resarray.resarray_val[i].resop == OP_GETATTR) { + GETATTR4resok *garesok; + struct nfs_stat_64 st; + + garesok = &res->resarray.resarray_val[i].nfs_resop4_u.opgetattr.GETATTR4res_u.resok4; + + memset(&st, 0, sizeof(st)); + if (nfs_parse_attributes(nfs, data, &st, + garesok->obj_attributes.attr_vals.attrlist4_val, + garesok->obj_attributes.attr_vals.attrlist4_len) < 0) { + data->cb(-EINVAL, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + return; + } + if ((st.nfs_mode & S_IFMT) == S_IFLNK) { + /* The final component of the path was a + * symlink so we may need to resolve it. + */ + resolve_link = 1; + } + } + } + + /* Open/create is special since the final component for the file + * object is sent as part of the OP_OPEN command. So even if the + * directory path is all good and resolved, we still need to check + * the attributes for the final component and resolve it if it too + * is a symlink. + */ + if (!resolve_link) { + if (nfs4_open_readlink(rpc, res, data) < 0) { + /* It was a symlink and we have started trying to + * resolve it. Nothing more to do here. + */ + return; + } + } + + if (data->flags & LOOKUP_FLAG_NO_FOLLOW) { + /* Do not resolve the final component of the path + * if it is a symlink. + */ + resolve_link = 0; + } + + /* Everything is good so we can just pass it on to the next + * phase. + */ + if (res->status == NFS4_OK && !resolve_link) { + data->continue_cb(rpc, NFS4_OK, res, data); + return; + } + + /* Find the lookup that failed and the associated fh */ + data->link.idx = 0; + for (i = 0; i < (int)res->resarray.resarray_len; i++) { + if (res->resarray.resarray_val[i].resop == OP_LOOKUP) { + if (res->resarray.resarray_val[i].nfs_resop4_u.oplookup.status == NFS4ERR_SYMLINK) { + break; + } + data->link.idx++; + } + } + + if (!resolve_link && i == res->resarray.resarray_len) { + nfs_set_error(nfs, "Symlink not found during lookup."); + data->cb(-EFAULT, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + return; + } + + /* Build a new path that strips of everything after the symlink. */ + path = strdup(data->path); + if (path == NULL) { + nfs_set_error(nfs, "Out of memory. Failed to duplicate " + "path."); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs4_cb_data(data); + return; + } + + /* The symlink is not the last component, so find the '/' before + * the symlink and zero it out. + */ + if (!resolve_link) { + tmp = path; + for (i = 0; i < (int)data->link.idx; i++) { + tmp = strchr(tmp + 1, '/'); + } + *tmp = 0; + } + + /* We need to resolve the symlink */ + if ((i = nfs4_allocate_op(nfs, &op, path, 1)) < 0) { + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + free(path); + return; + } + + /* Append a READLINK command */ + i += nfs4_op_readlink(nfs, &op[i]); + + memset(&args, 0, sizeof(args)); + args.argarray.argarray_len = i; + args.argarray.argarray_val = op; + + if (rpc_nfs4_compound_task(nfs->rpc, nfs4_lookup_path_2_cb, &args, + data) == NULL) { + nfs_set_error(nfs, "Failed to queue READLINK command. %s", + nfs_get_error(nfs)); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + free(path); + free(op); + return; + } + free(path); + free(op); +} + +static int +nfs4_lookup_path_async(struct nfs_context *nfs, + struct nfs4_cb_data *data, + rpc_cb cb) +{ + COMPOUND4args args; + nfs_argop4 *op; + char *path; + int i, num_op; + + path = nfs4_resolve_path(nfs, data->path); + if (path == NULL) { + return -1; + } + free(data->path); + data->path = path; + + path = strdup(path); + if (path == NULL) { + return -1; + } + + if ((i = nfs4_allocate_op(nfs, &op, path, data->filler.max_op)) < 0) { + free(path); + return -1; + } + + num_op = data->filler.func(data, &op[i]); + data->continue_cb = cb; + + memset(&args, 0, sizeof(args)); + args.argarray.argarray_len = i + num_op; + args.argarray.argarray_val = op; + + if (rpc_nfs4_compound_task(nfs->rpc, nfs4_lookup_path_1_cb, &args, + data) == NULL) { + nfs_set_error(nfs, "Failed to queue LOOKUP command. %s", + nfs_get_error(nfs)); + free(path); + free(op); + return -1; + } + + free(path); + free(op); + return 0; +} + +static int +nfs4_populate_getfh(struct nfs4_cb_data *data, nfs_argop4 *op) +{ + return nfs4_op_getfh(data->nfs, op); +} + +static int +nfs4_populate_getattr(struct nfs4_cb_data *data, nfs_argop4 *op) +{ + return nfs4_op_getfh(data->nfs, op); +} + +static int +nfs4_populate_access(struct nfs4_cb_data *data, nfs_argop4 *op) +{ + uint32_t mode; + + memcpy(&mode, data->filler.blob3.val, sizeof(uint32_t)); + + return nfs4_op_access(data->nfs, op, mode); +} + + +static int +nfs_parse_rwmax(struct nfs_context *nfs, const char *buf, int len) +{ + /* READ MAX */ + CHECK_GETATTR_BUF_SPACE(len, 8); + nfs_set_readmax(nfs, nfs_pntoh64((uint32_t *)(void *)buf)); + buf += 8; + len -= 8; + /* WRITE MAX */ + CHECK_GETATTR_BUF_SPACE(len, 8); + nfs_set_writemax(nfs, nfs_pntoh64((uint32_t *)(void *)buf)); + buf += 8; + len -= 8; + + return 0; +} + +static void +nfs4_mount_5_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + GETATTR4resok *garesok; + int i; + + if (check_nfs4_error(nfs, status, data, res, "RWMAX")) { + return; + } + + if ((i = nfs4_find_op(nfs, data, res, OP_GETATTR, "GETATTR")) < 0) { + return; + } + garesok = &res->resarray.resarray_val[i].nfs_resop4_u.opgetattr.GETATTR4res_u.resok4; + if (nfs_parse_rwmax(nfs, + garesok->obj_attributes.attr_vals.attrlist4_val, + garesok->obj_attributes.attr_vals.attrlist4_len) < 0) { + data->cb(-EINVAL, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + } + + /* + * Now the entire mount process (including the NFS FSINFO and GETATTR) + * has completed. Any RPC failure till now would have caused the mount + * process to fail. Note that it's desirable for the mount process to + * fail upfront if it encounters any errors (TCP or RPC), rather than + * keep trying indefinitely causing the mount process to "hang", but + * from now on the RPC transport will be used to carry NFS RPCs issued + * by the application which may not be equipped to handle TCP connection + * failure and RPC timeouts, so we set the resiliency parameters of the + * rpc_context as selected by the user using the mount options. The + * default resiliency parameters emulate the common "hard" mount and + * we are resilient to any TCP or RPC connectivity issues. + */ + rpc_set_resiliency(rpc, + nfs->nfsi->auto_reconnect, + nfs->nfsi->timeout, + nfs->nfsi->retrans); + + data->cb(0, nfs, NULL, data->private_data); + free_nfs4_cb_data(data); +} + +static void +nfs4_mount_4_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + GETFH4resok *gfhresok; + COMPOUND4args args; + nfs_argop4 op[2]; + struct nfsfh nfsfh; + int i; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs4_error(nfs, status, data, res, "GETFH")) { + return; + } + + if ((i = nfs4_find_op(nfs, data, res, OP_GETFH, "GETFH")) < 0) { + return; + } + gfhresok = &res->resarray.resarray_val[i].nfs_resop4_u.opgetfh.GETFH4res_u.resok4; + + nfs->nfsi->rootfh.len = gfhresok->object.nfs_fh4_len; + nfs->nfsi->rootfh.val = malloc(nfs->nfsi->rootfh.len); + if (nfs->nfsi->rootfh.val == NULL) { + nfs_set_error(nfs, "%s: %s", __FUNCTION__, nfs_get_error(nfs)); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + return; + } + memcpy(nfs->nfsi->rootfh.val, + gfhresok->object.nfs_fh4_val, + nfs->nfsi->rootfh.len); + + memset(op, 0, sizeof(op)); + nfsfh.fh = nfs->nfsi->rootfh; + i = nfs4_op_putfh(nfs, &op[0], &nfsfh); + i += nfs4_op_getattr(nfs, &op[i], rwmax_attributes, 1); + + memset(&args, 0, sizeof(args)); + args.argarray.argarray_len = i; + args.argarray.argarray_val = op; + + if (rpc_nfs4_compound_task(rpc, nfs4_mount_5_cb, &args, + private_data) == NULL) { + nfs_set_error(nfs, "Failed to queue GETATTR rwmax. %s", + nfs_get_error(nfs)); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + return; + } +} + +static void +nfs4_mount_3_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs4_error(nfs, status, data, res, "SETCLIENTID_CONFIRM")) { + return; + } + + data->filler.func = nfs4_populate_getfh; + data->filler.max_op = 1; + data->filler.data = calloc(2, sizeof(uint32_t)); + if (data->filler.data == NULL) { + nfs_set_error(nfs, "Out of memory. Failed to allocate " + "data structure."); + data->cb(-ENOMEM, nfs, res, data->private_data); + free_nfs4_cb_data(data); + return; + } + + + if (nfs4_lookup_path_async(nfs, data, nfs4_mount_4_cb) < 0) { + data->cb(-ENOMEM, nfs, res, data->private_data); + free_nfs4_cb_data(data); + return; + } +} + +static void +nfs4_mount_2_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + COMPOUND4args args; + nfs_argop4 op[1]; + SETCLIENTID4resok *scidresok; + int i; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs4_error(nfs, status, data, res, "SETCLIENTID")) { + return; + } + + scidresok = &res->resarray.resarray_val[0].nfs_resop4_u.opsetclientid.SETCLIENTID4res_u.resok4; + nfs->nfsi->clientid = scidresok->clientid; + memcpy(nfs->nfsi->setclientid_confirm, + scidresok->setclientid_confirm, + NFS4_VERIFIER_SIZE); + + memset(op, 0, sizeof(op)); + + i = nfs4_op_setclientid_confirm(nfs, &op[0], nfs->nfsi->clientid, + nfs->nfsi->setclientid_confirm); + + memset(&args, 0, sizeof(args)); + args.argarray.argarray_len = i; + args.argarray.argarray_val = op; + + if (rpc_nfs4_compound_task(rpc, nfs4_mount_3_cb, &args, + private_data) == NULL) { + nfs_set_error(nfs, "Failed to queue SETCLIENTID_CONFIRM. %s", + nfs_get_error(nfs)); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + return; + } +} + +static void +nfs4_mount_1_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4args args; + nfs_argop4 op[1]; + int i; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs4_error(nfs, status, data, NULL, "CONNECT")) { + return; + } + + memset(op, 0, sizeof(op)); + + i = nfs4_op_setclientid(nfs, &op[0], nfs->nfsi->verifier, nfs->nfsi->client_name); + + memset(&args, 0, sizeof(args)); + args.argarray.argarray_len = i; + args.argarray.argarray_val = op; + + if (rpc_nfs4_compound_task(rpc, nfs4_mount_2_cb, &args, data) == NULL) { + nfs_set_error(nfs, "Failed to queue SETCLIENTID. %s", + nfs_get_error(nfs)); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + return; + } +} + +int +nfs4_mount_async(struct nfs_context *nfs, const char *server, + const char *export, nfs_cb cb, void *private_data) +{ + struct nfs4_cb_data *data; + char *new_server, *new_export; + int port; + + new_server = strdup(server); + if (new_server == NULL) { + nfs_set_error(nfs, "out of memory. failed to allocate " + "memory for nfs server string"); + return -1; + } + free(nfs->nfsi->server); + nfs->nfsi->server = new_server; + + free(nfs->rpc->server); + nfs->rpc->server = strdup(nfs->nfsi->server); + + new_export = strdup(export); + if (new_export == NULL) { + nfs_set_error(nfs, "out of memory. failed to allocate " + "memory for nfs export string"); + return -1; + } + if (nfs_normalize_path(nfs, new_export)) { + nfs_set_error(nfs, "Bad export path. %s", + nfs_get_error(nfs)); + free(new_export); + return -1; + } + free(nfs->nfsi->export); + nfs->nfsi->export = new_export; + + + data = calloc(1, sizeof(*data)); + if (data == NULL) { + nfs_set_error(nfs, "Out of memory. Failed to allocate " + "memory for nfs mount data"); + return -1; + } + + data->nfs = nfs; + data->cb = cb; + data->private_data = private_data; + data->path = strdup(new_export); + + port = nfs->nfsi->nfsport ? nfs->nfsi->nfsport : 2049; + if (rpc_connect_port_async(nfs->rpc, server, port, + NFS4_PROGRAM, NFS_V4, + nfs4_mount_1_cb, data) != 0) { + nfs_set_error(nfs, "Failed to start connection. %s", + nfs_get_error(nfs)); + free_nfs4_cb_data(data); + return -1; + } + return 0; +} + +static void +nfs4_chdir_1_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs4_error(nfs, status, data, res, "CHDIR")) { + return; + } + + /* Ok, all good. Lets steal the path string. */ +#ifdef HAVE_MULTITHREADING + if (nfs->rpc->multithreading_enabled) { + nfs_mt_mutex_lock(&nfs->rpc->rpc_mutex); + } +#endif + free(nfs->nfsi->cwd); + nfs->nfsi->cwd = data->path; +#ifdef HAVE_MULTITHREADING + if (nfs->rpc->multithreading_enabled) { + nfs_mt_mutex_unlock(&nfs->rpc->rpc_mutex); + } +#endif + + data->path = NULL; + + data->cb(0, nfs, NULL, data->private_data); + free_nfs4_cb_data(data); +} + +int nfs4_chdir_async(struct nfs_context *nfs, const char *path, + nfs_cb cb, void *private_data) +{ + struct nfs4_cb_data *data; + + data = init_cb_data_full_path(nfs, path); + if (data == NULL) { + return -1; + } + + data->cb = cb; + data->private_data = private_data; + data->filler.func = nfs4_populate_getattr; + data->filler.max_op = 1; + data->filler.data = calloc(2, sizeof(uint32_t)); + if (data->filler.data == NULL) { + nfs_set_error(nfs, "Out of memory. Failed to allocate " + "data structure."); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + return -1; + } + + if (nfs4_lookup_path_async(nfs, data, nfs4_chdir_1_cb) < 0) { + free_nfs4_cb_data(data); + return -1; + } + + return 0; +} + +static void +nfs4_xstat64_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + GETATTR4resok *garesok; + struct nfs_stat_64 st; + int i; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs4_error(nfs, status, data, res, "STAT64")) { + return; + } + + if ((i = nfs4_find_op(nfs, data, res, OP_GETATTR, "GETATTR")) < 0) { + return; + } + garesok = &res->resarray.resarray_val[i].nfs_resop4_u.opgetattr.GETATTR4res_u.resok4; + + memset(&st, 0, sizeof(st)); + if (nfs_parse_attributes(nfs, data, &st, + garesok->obj_attributes.attr_vals.attrlist4_val, + garesok->obj_attributes.attr_vals.attrlist4_len) < 0) { + data->cb(-EINVAL, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + } + + data->cb(0, nfs, &st, data->private_data); + free_nfs4_cb_data(data); +} + +int +nfs4_stat64_async(struct nfs_context *nfs, const char *path, + int no_follow, nfs_cb cb, void *private_data) +{ + struct nfs4_cb_data *data; + + data = init_cb_data_full_path(nfs, path); + if (data == NULL) { + return -1; + } + + if (no_follow) { + data->flags |= LOOKUP_FLAG_NO_FOLLOW; + } + data->cb = cb; + data->private_data = private_data; + data->filler.func = nfs4_populate_getattr; + data->filler.max_op = 1; + data->filler.data = calloc(2, sizeof(uint32_t)); + if (data->filler.data == NULL) { + nfs_set_error(nfs, "Out of memory. Failed to allocate " + "data structure."); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + return -1; + } + + if (nfs4_lookup_path_async(nfs, data, nfs4_xstat64_cb) < 0) { + free_nfs4_cb_data(data); + return -1; + } + + return 0; +} + +/* Takes object name as filler.data + * blob0 as the fattr4 attribute mask + * blob1 as the fattr4 attribute list + */ +static int +nfs4_populate_mkdir(struct nfs4_cb_data *data, nfs_argop4 *op) +{ + struct nfs_context *nfs = data->nfs; + + return nfs4_op_create(nfs, op, data->filler.data, NF4DIR, + &data->filler.blob0, &data->filler.blob1, + NULL, 0); +} + +static void +nfs4_mkdir_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs4_error(nfs, status, data, res, "MKDIR")) { + return; + } + + data->cb(0, nfs, NULL, data->private_data); + free_nfs4_cb_data(data); +} + +int +nfs4_mkdir2_async(struct nfs_context *nfs, const char *path, int mode, + nfs_cb cb, void *private_data) +{ + struct nfs4_cb_data *data; + uint32_t *u32ptr; + + data = init_cb_data_split_path(nfs, path); + if (data == NULL) { + return -1; + } + + data->cb = cb; + data->private_data = private_data; + data->filler.func = nfs4_populate_mkdir; + data->filler.max_op = 1; + + /* attribute mask */ + u32ptr = malloc(2 * sizeof(uint32_t)); + if (u32ptr == NULL) { + nfs_set_error(nfs, "Out of memory allocating bitmap"); + free_nfs4_cb_data(data); + return -1; + } + u32ptr[0] = 0; + u32ptr[1] = 1 << (FATTR4_MODE - 32); + data->filler.blob0.len = 2; + data->filler.blob0.val = u32ptr; + data->filler.blob0.free = free; + + /* attribute values */ + u32ptr = malloc(1 * sizeof(uint32_t)); + if (u32ptr == NULL) { + nfs_set_error(nfs, "Out of memory allocating attributes"); + free_nfs4_cb_data(data); + return -1; + } + u32ptr[0] = htonl(mode); + data->filler.blob1.len = 4; + data->filler.blob1.val = u32ptr; + data->filler.blob1.free = free; + + if (nfs4_lookup_path_async(nfs, data, nfs4_mkdir_cb) < 0) { + free_nfs4_cb_data(data); + return -1; + } + + return 0; +} + +/* Takes object name as filler.data + */ +static int +nfs4_populate_remove(struct nfs4_cb_data *data, nfs_argop4 *op) +{ + struct nfs_context *nfs = data->nfs; + + return nfs4_op_remove(nfs, op, data->filler.data); +} + +static void +nfs4_remove_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs4_error(nfs, status, data, res, "REMOVE")) { + return; + } + + data->cb(0, nfs, NULL, data->private_data); + free_nfs4_cb_data(data); +} + +static int +nfs4_remove_async(struct nfs_context *nfs, const char *path, + nfs_cb cb, void *private_data) +{ + struct nfs4_cb_data *data; + + data = init_cb_data_split_path(nfs, path); + if (data == NULL) { + return -1; + } + + data->cb = cb; + data->private_data = private_data; + data->filler.func = nfs4_populate_remove; + data->filler.max_op = 1; + + if (nfs4_lookup_path_async(nfs, data, nfs4_remove_cb) < 0) { + free_nfs4_cb_data(data); + return -1; + } + + return 0; +} + +int +nfs4_rmdir_async(struct nfs_context *nfs, const char *path, + nfs_cb cb, void *private_data) +{ + return nfs4_remove_async(nfs, path, cb, private_data); +} + +static void +nfs_increment_seqid(struct nfsfh *nfsfh, uint32_t status) +{ + /* RFC3530 8.1.5 */ + switch (status) { + case NFS4ERR_STALE_CLIENTID: + case NFS4ERR_STALE_STATEID: + case NFS4ERR_BAD_STATEID: + case NFS4ERR_BAD_SEQID: + case NFS4ERR_BADZDR: + case NFS4ERR_RESOURCE: + case NFS4ERR_NOFILEHANDLE: + break; + default: + nfsfh->open_seqid++; + } +} + +static void +nfs4_open_setattr_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + struct nfsfh *fh; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs4_error(nfs, status, data, res, "SETATTR")) { + return; + } + + fh = data->filler.blob0.val; + data->filler.blob0.val = NULL; + data->cb(0, nfs, fh, data->private_data); + free_nfs4_cb_data(data); +} + +static void +nfs4_open_truncate_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + struct nfsfh *fh = data->filler.blob0.val; + COMPOUND4res *res = command_data; + COMPOUND4args args; + nfs_argop4 op[2]; + int i; + + if (check_nfs4_error(nfs, status, data, res, "OPEN")) { + return; + } + + i = nfs4_op_putfh(nfs, op, fh); + i += nfs4_op_truncate(nfs, &op[i], fh, data->filler.blob3.val); + + memset(&args, 0, sizeof(args)); + args.argarray.argarray_len = i; + args.argarray.argarray_val = op; + + if (rpc_nfs4_compound_task(nfs->rpc, nfs4_open_setattr_cb, &args, + data) == NULL) { + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + return; + } +} + +static void +nfs4_open_chmod_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + struct nfsfh *fh = data->filler.blob0.val; + COMPOUND4res *res = command_data; + COMPOUND4args args; + nfs_argop4 op[2]; + int i; + + if (check_nfs4_error(nfs, status, data, res, "OPEN")) { + return; + } + + i = nfs4_op_putfh(nfs, op, fh); + i += nfs4_op_chmod(nfs, &op[i], fh, data->filler.blob3.val); + + memset(&args, 0, sizeof(args)); + args.argarray.argarray_len = i; + args.argarray.argarray_val = op; + + if (rpc_nfs4_compound_task(nfs->rpc, nfs4_open_setattr_cb, &args, + data) == NULL) { + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + return; + } +} + +static void +nfs4_open_confirm_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + OPEN_CONFIRM4resok *ocresok; + int i; + struct nfsfh *fh = data->filler.blob0.val; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (res) { + nfs_increment_seqid(fh, res->status); + } + + if (check_nfs4_error(nfs, status, data, res, "OPEN_CONFIRM")) { + return; + } + + if ((i = nfs4_find_op(nfs, data, res, OP_OPEN_CONFIRM, + "OPEN_CONFIRM")) < 0) { + return; + } + ocresok = &res->resarray.resarray_val[i].nfs_resop4_u.opopen_confirm.OPEN_CONFIRM4res_u.resok4; + + fh = data->filler.blob0.val; + + fh->stateid.seqid = ocresok->open_stateid.seqid; + memcpy(fh->stateid.other, ocresok->open_stateid.other, 12); + + if (data->open_cb) { + data->open_cb(rpc, status, command_data, private_data); + return; + } + data->filler.blob0.val = NULL; + data->cb(0, nfs, fh, data->private_data); + free_nfs4_cb_data(data); +} + +static void +nfs4_open_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + ACCESS4resok *aresok; + OPEN4resok *oresok; + GETFH4resok *gresok; + int i; + struct nfsfh *fh; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs4_error(nfs, status, data, res, "OPEN")) { + return; + } + + /* Parse Access and check that we have the access that we need */ + if ((i = nfs4_find_op(nfs, data, res, OP_ACCESS, "ACCESS")) < 0) { + return; + } + aresok = &res->resarray.resarray_val[i].nfs_resop4_u.opaccess.ACCESS4res_u.resok4; + if (aresok->supported != aresok->access) { + nfs_set_error(nfs, "Insufficient ACCESS. Wanted %08x but " + "got %08x.", (int)aresok->access, (int)aresok->supported); + data->cb(-EINVAL, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + return; + } + + /* Parse GetFH */ + if ((i = nfs4_find_op(nfs, data, res, OP_GETFH, "GETFH")) < 0) { + return; + } + gresok = &res->resarray.resarray_val[i].nfs_resop4_u.opgetfh.GETFH4res_u.resok4; + + fh = calloc(1, sizeof(*fh)); + if (fh == NULL) { + nfs_set_error(nfs, "Out of memory. Failed to allocate " + "nfsfh"); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + return; + } + + data->filler.blob0.val = fh; + data->filler.blob0.free = (blob_free)nfs_free_nfsfh; + + fh->fh.len = gresok->object.nfs_fh4_len; + fh->fh.val = malloc(fh->fh.len); + if (fh->fh.val == NULL) { + nfs_set_error(nfs, "Out of memory. Failed to allocate " + "nfsfh"); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + return; + } + memcpy(fh->fh.val, gresok->object.nfs_fh4_val, fh->fh.len); + fh->open_seqid = 1; + fh->open_owner = data->open_owner; + + if (data->filler.flags & O_SYNC) { + fh->is_sync = 1; + } + + if (data->filler.flags & O_APPEND) { + fh->is_append = 1; + } + + if (!(data->filler.flags & (O_WRONLY|O_RDWR))) { + fh->is_readonly = 1; + } + + /* Parse Open */ + if ((i = nfs4_find_op(nfs, data, res, OP_OPEN, "OPEN")) < 0) { + return; + } + oresok = &res->resarray.resarray_val[i].nfs_resop4_u.opopen.OPEN4res_u.resok4; + fh->stateid.seqid = oresok->stateid.seqid; + memcpy(fh->stateid.other, oresok->stateid.other, 12); + + + if (oresok->rflags & OPEN4_RESULT_CONFIRM) { + COMPOUND4args args; + nfs_argop4 op[2]; + + memset(op, 0, sizeof(op)); + i = nfs4_op_putfh(nfs, &op[0], fh); + i += nfs4_op_open_confirm(nfs, &op[i], fh); + + memset(&args, 0, sizeof(args)); + args.argarray.argarray_len = i; + args.argarray.argarray_val = op; + + if (rpc_nfs4_compound_task(rpc, nfs4_open_confirm_cb, &args, + private_data) == NULL) { + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs4_cb_data(data); + return; + } + return; + } + + if (data->open_cb) { + data->open_cb(rpc, status, command_data, private_data); + return; + } + data->filler.blob0.val = NULL; + data->cb(0, nfs, fh, data->private_data); + free_nfs4_cb_data(data); +} + +static void +nfs4_init_random_verifier(char *verifier) +{ + static uint64_t seed = 0, v; + int i; + + if (seed == 0) { + seed = ~rpc_current_time() << 32 | getpid(); + } else { + seed *= 1337; + } + + v = seed; + for (i = 0; i < NFS4_VERIFIER_SIZE; i++) { + verifier[i] = v & 0xff; + v >>= 8; + } +} + +/* filler.flags are the open flags + * filler.data is the object name + */ +static int +nfs4_populate_open(struct nfs4_cb_data *data, nfs_argop4 *op) +{ + struct nfs_context *nfs = data->nfs; + OPEN4args *oargs; + uint32_t access_mask = 0; + verifier4 verifier; + int i; + + if (data->filler.flags & O_WRONLY) { + access_mask |= ACCESS4_MODIFY; + } + if (data->filler.flags & O_RDWR) { + access_mask |= ACCESS4_READ|ACCESS4_MODIFY; + } + if (!(data->filler.flags & O_WRONLY)) { + access_mask |= ACCESS4_READ; + } + + /* Access */ + i = nfs4_op_access(nfs, &op[0], access_mask); + + /* Open */ + op[i].argop = OP_OPEN; + oargs = &op[i++].nfs_argop4_u.opopen; + memset(oargs, 0, sizeof(*oargs)); + + if (access_mask & ACCESS4_READ) { + oargs->share_access |= OPEN4_SHARE_ACCESS_READ; + } + if (access_mask & ACCESS4_MODIFY) { + oargs->share_access |= OPEN4_SHARE_ACCESS_WRITE; + } + oargs->share_deny = OPEN4_SHARE_DENY_NONE; + oargs->owner.clientid = nfs->nfsi->clientid; + oargs->owner.owner.owner_len = 4; + oargs->owner.owner.owner_val = (char *)&data->open_owner; + oargs->seqid = 0; + if (data->filler.flags & O_CREAT) { + createhow4 *ch; + fattr4 *fa; + + ch = &oargs->openhow.openflag4_u.how; + fa = &ch->createhow4_u.createattrs; + + oargs->openhow.opentype = OPEN4_CREATE; + if (data->filler.flags & O_EXCL) { + ch->mode = EXCLUSIVE4; + + nfs4_init_random_verifier(&verifier[0]); + memcpy(ch->createhow4_u.createverf, verifier, + sizeof(verifier4)); + } else { + ch->mode = UNCHECKED4; + fa->attrmask.bitmap4_len = data->filler.blob1.len; + fa->attrmask.bitmap4_val = data->filler.blob1.val; + + fa->attr_vals.attrlist4_len = data->filler.blob2.len; + fa->attr_vals.attrlist4_val = data->filler.blob2.val; + } + } else { + oargs->openhow.opentype = OPEN4_NOCREATE; + } + oargs->claim.claim = CLAIM_NULL; + oargs->claim.open_claim4_u.file.utf8string_len = + strlen(data->filler.data); + oargs->claim.open_claim4_u.file.utf8string_val = + data->filler.data; + + /* GetFH */ + i += nfs4_op_getfh(nfs, &op[i]); + + return i; +} + +static void +nfs4_open_readlink_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + READLINK4resok *rlresok; + int i; + char *path; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs4_error(nfs, status, data, res, "READLINK")) { + return; + } + + if ((i = nfs4_find_op(nfs, data, res, OP_READLINK, "READLINK")) < 0) { + return; + } + + rlresok = &res->resarray.resarray_val[i].nfs_resop4_u.opreadlink.READLINK4res_u.resok4; + + path = malloc(2 + strlen(data->path) + + rlresok->link.utf8string_len); + if (path == NULL) { + nfs_set_error(nfs, "Out of memory. Failed to allocate " + "path"); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs4_cb_data(data); + return; + } + sprintf(path, "%s/%.*s", data->path, + (int)rlresok->link.utf8string_len, rlresok->link.utf8string_val); + + + free(data->path); + data->path = NULL; + free(data->filler.data); + data->filler.data = NULL; + + data->path = nfs4_resolve_path(nfs, path); + free(path); + if (data->path == NULL) { + data->cb(-EINVAL, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs4_cb_data(data); + return; + } + + data_split_path(data); + +#ifdef HAVE_MULTITHREADING + if (nfs->rpc->multithreading_enabled) { + nfs_mt_mutex_lock(&nfs->nfsi->nfs4_open_counter_mutex); + } +#endif + data->open_owner = nfs->nfsi->open_counter++; +#ifdef HAVE_MULTITHREADING + if (nfs->rpc->multithreading_enabled) { + nfs_mt_mutex_unlock(&nfs->nfsi->nfs4_open_counter_mutex); + } +#endif + + data->filler.func = nfs4_populate_open; + data->filler.max_op = 3; + + if (nfs4_lookup_path_async(nfs, data, nfs4_open_cb) < 0) { + data->cb(-ENOMEM, nfs, res, data->private_data); + free_nfs4_cb_data(data); + return; + } +} + +static int +nfs4_populate_lookup_readlink(struct nfs4_cb_data *data, nfs_argop4 *op) +{ + struct nfs_context *nfs = data->nfs; + int i; + + i = nfs4_op_lookup(nfs, &op[0], data->filler.data); + i += nfs4_op_readlink(nfs, &op[i]); + + return i; +} + +/* If the final component in the open was a symlink we need to resolve it and + * re-try the nfs4_open_async() + */ +static int +nfs4_open_readlink(struct rpc_context *rpc, COMPOUND4res *res, + struct nfs4_cb_data *data) +{ + struct nfs_context *nfs = data->nfs; + int i; + + for (i = 0; i < (int)res->resarray.resarray_len; i++) { + OPEN4res *ores; + + if (res->resarray.resarray_val[i].resop != OP_OPEN) { + continue; + } + ores = &res->resarray.resarray_val[i].nfs_resop4_u.opopen; + + if (ores->status != NFS4ERR_SYMLINK) { + continue; + } + + if (data->filler.flags & O_NOFOLLOW) { + nfs_set_error(nfs, "Symlink encountered during " + "open(O_NOFOLLOW)"); + data->cb(-ELOOP, nfs, nfs_get_error(nfs), + data->private_data); + return -1; + } + + /* The object we need to do readlink on is already stored in + * data->filler.data so *populate* can just grab it from there. + */ + data->filler.func = nfs4_populate_lookup_readlink; + data->filler.max_op = 2; + + if (nfs4_lookup_path_async(nfs, data, + nfs4_open_readlink_cb) < 0) { + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs4_cb_data(data); + return -1; + } + return -1; + } + + return 0; +} + +/* + * data.blob0 is used for nfsfh + * data.blob1 is used for the attribute mask in case on O_CREAT + * data.blob2 is the attribute value in case of O_CREAT + */ +static int +nfs4_open_async_internal(struct nfs_context *nfs, struct nfs4_cb_data *data, + int flags, int mode) +{ + if (flags & O_APPEND && !(flags & (O_RDWR|O_WRONLY))) { + flags &= ~O_APPEND; + } + + if (flags & O_CREAT) { + uint32_t *d; + + /* Attribute mask */ + d = malloc(2 * sizeof(uint32_t)); + if (d == NULL) { + nfs_set_error(nfs, "Out of memory"); + free_nfs4_cb_data(data); + return -1; + } + d[0] = 0; + d[1] = 1 << (FATTR4_MODE - 32); + + data->filler.blob1.val = d; + data->filler.blob1.len = 2; + data->filler.blob1.free = free; + + /* Attribute value */ + d = malloc(sizeof(uint32_t)); + if (d == NULL) { + nfs_set_error(nfs, "Out of memory"); + free_nfs4_cb_data(data); + return -1; + } + + *d = htonl(mode); + + data->filler.blob2.val = d; + data->filler.blob2.len = 4; + data->filler.blob2.free = free; + } + +#ifdef HAVE_MULTITHREADING + if (nfs->rpc->multithreading_enabled) { + nfs_mt_mutex_lock(&nfs->nfsi->nfs4_open_counter_mutex); + } +#endif + data->open_owner = nfs->nfsi->open_counter++; +#ifdef HAVE_MULTITHREADING + if (nfs->rpc->multithreading_enabled) { + nfs_mt_mutex_unlock(&nfs->nfsi->nfs4_open_counter_mutex); + } +#endif + data->filler.func = nfs4_populate_open; + data->filler.max_op = 3; + data->filler.flags = flags; + + if (nfs4_lookup_path_async(nfs, data, nfs4_open_cb) < 0) { + free_nfs4_cb_data(data); + return -1; + } + + return 0; +} + +int +nfs4_open_async(struct nfs_context *nfs, const char *path, int flags, + int mode, nfs_cb cb, void *private_data) +{ + struct nfs4_cb_data *data; + uint32_t m; + int ret; + + data = init_cb_data_split_path(nfs, path); + if (data == NULL) { + return -1; + } + + data->cb = cb; + data->private_data = private_data; + + /* O_TRUNC is only valid for O_RDWR or O_WRONLY */ + if (flags & O_TRUNC && !(flags & (O_RDWR|O_WRONLY))) { + flags &= ~O_TRUNC; + } + /* Successful O_EXCL means the file is 0 size already. */ + if (flags & O_EXCL) { + flags &= ~O_TRUNC; + } + + if (flags & O_TRUNC) { + data->open_cb = nfs4_open_truncate_cb; + + data->filler.blob3.val = malloc(12); + if (data->filler.blob3.val == NULL) { + nfs_set_error(nfs, "Out of memory"); + free_nfs4_cb_data(data); + return -1; + } + data->filler.blob3.free = free; + + memset(data->filler.blob3.val, 0, 12); + } + if (flags & O_EXCL) { + data->open_cb = nfs4_open_chmod_cb; + + data->filler.blob3.val = malloc(4); + if (data->filler.blob3.val == NULL) { + nfs_set_error(nfs, "Out of memory"); + free_nfs4_cb_data(data); + return -1; + } + data->filler.blob3.free = free; + + m = htonl(mode); + memcpy(data->filler.blob3.val, &m, sizeof(uint32_t)); + } + +#ifdef HAVE_MULTITHREADING + if (nfs->rpc->multithreading_enabled) { + nfs_mt_mutex_lock(&nfs->nfsi->nfs4_open_call_mutex); + data->flags |= MUTEX_HELD; + } +#endif + ret = nfs4_open_async_internal(nfs, data, flags, mode); + return ret; +} + +int +nfs4_fstat64_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, + void *private_data) +{ + COMPOUND4args args; + nfs_argop4 op[2]; + struct nfs4_cb_data *data; + int i; + + data = calloc(1, sizeof(*data)); + if (data == NULL) { + nfs_set_error(nfs, "Out of memory. Failed to allocate " + "cb data"); + return -1; + } + + data->nfs = nfs; + data->cb = cb; + data->private_data = private_data; + + i = nfs4_op_putfh(nfs, &op[0], nfsfh); + i += nfs4_op_getattr(nfs, &op[i], standard_attributes, 2); + + memset(&args, 0, sizeof(args)); + args.argarray.argarray_len = i; + args.argarray.argarray_val = op; + + if (rpc_nfs4_compound_task(nfs->rpc, nfs4_xstat64_cb, &args, + data) == NULL) { + free_nfs4_cb_data(data); + return -1; + } + + return 0; +} + +static void +nfs4_getacl_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + GETATTR4resok *garesok; + fattr4_acl acl; + ZDR zdr; + int i; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs4_error(nfs, status, data, res, "GETACL")) { + return; + } + + if ((i = nfs4_find_op(nfs, data, res, OP_GETATTR, "GETATTR")) < 0) { + return; + } + garesok = &res->resarray.resarray_val[i].nfs_resop4_u.opgetattr.GETATTR4res_u.resok4; + + memset(&acl, 0, sizeof(acl)); + zdrmem_create(&zdr, + garesok->obj_attributes.attr_vals.attrlist4_val, + garesok->obj_attributes.attr_vals.attrlist4_len, + ZDR_DECODE); + if (zdr_fattr4_acl(&zdr, &acl)) { + data->cb(0, nfs, &acl, data->private_data); + } else { + data->cb(-EIO, nfs, "Failed to unmarshall fattr4_acl", data->private_data); + } + + zdr_destroy(&zdr); + free_nfs4_cb_data(data); +} + +int +nfs4_getacl_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, + void *private_data) +{ + COMPOUND4args args; + nfs_argop4 op[2]; + struct nfs4_cb_data *data; + int i; + + data = calloc(1, sizeof(*data)); + if (data == NULL) { + nfs_set_error(nfs, "Out of memory. Failed to allocate " + "cb data"); + return -1; + } + + data->nfs = nfs; + data->cb = cb; + data->private_data = private_data; + + i = nfs4_op_putfh(nfs, &op[0], nfsfh); + i += nfs4_op_getattr(nfs, &op[i], getacl_attributes, 1); + + memset(&args, 0, sizeof(args)); + args.argarray.argarray_len = i; + args.argarray.argarray_val = op; + + if (rpc_nfs4_compound_task(nfs->rpc, nfs4_getacl_cb, &args, + data) == NULL) { + free_nfs4_cb_data(data); + return -1; + } + + return 0; +} + + +static void +nfs4_close_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + struct nfsfh *nfsfh = data->filler.blob0.val; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (res) { + nfs_increment_seqid(nfsfh, res->status); + } + + if (check_nfs4_error(nfs, status, data, res, "CLOSE")) { + return; + } + + data->cb(0, nfs, NULL, data->private_data); + free_nfs4_cb_data(data); +} + +int +nfs4_close_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, + void *private_data) +{ + COMPOUND4args args; + nfs_argop4 op[3]; + struct nfs4_cb_data *data; + int i; + + data = calloc(1, sizeof(*data)); + if (data == NULL) { + nfs_set_error(nfs, "Out of memory. Failed to allocate " + "cb data"); + return -1; + } + +#ifdef HAVE_MULTITHREADING + if (nfs->rpc->multithreading_enabled) { + nfs_mt_mutex_lock(&nfs->nfsi->nfs4_open_call_mutex); + data->flags |= MUTEX_HELD; + } +#endif + data->nfs = nfs; + data->cb = cb; + data->private_data = private_data; + + memset(op, 0, sizeof(op)); + + i = nfs4_op_putfh(nfs, &op[0], nfsfh); + i += nfs4_op_close(nfs, &op[i], nfsfh); + + data->filler.blob0.val = nfsfh; + data->filler.blob0.free = (blob_free)nfs_free_nfsfh; + + memset(&args, 0, sizeof(args)); + args.argarray.argarray_len = i; + args.argarray.argarray_val = op; + + if (rpc_nfs4_compound_task(nfs->rpc, nfs4_close_cb, &args, + data) == NULL) { + data->filler.blob0.val = NULL; + free_nfs4_cb_data(data); + return -1; + } + + return 0; +} + +static void +nfs4_pread_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + READ4resok *rres = NULL; + struct nfsfh *nfsfh; + int i, count; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + nfsfh = data->filler.blob0.val; + + if (check_nfs4_error(nfs, status, data, res, "READ")) { + return; + } + + if ((i = nfs4_find_op(nfs, data, res, OP_READ, "READ")) < 0) { + return; + } + rres = &res->resarray.resarray_val[i].nfs_resop4_u.opread.READ4res_u.resok4; + + if (data->rw_data.update_pos) { + nfsfh->offset = data->rw_data.offset + rres->data.data_len; + } + + count = rres->data.data_len; + + if (count > rpc->pdu->requested_read_count) { + count = rpc->pdu->requested_read_count; + } + + data->cb(count, nfs, NULL, data->private_data); + free_nfs4_cb_data(data); +} + +int +nfs4_pread_async_internal(struct nfs_context *nfs, struct nfsfh *nfsfh, + void *buf, size_t count, uint64_t offset, + nfs_cb cb, void *private_data, int update_pos) +{ + COMPOUND4args args; + nfs_argop4 op[2]; + struct nfs4_cb_data *data; + int i; + struct rpc_pdu *pdu; + + data = calloc(1, sizeof(*data)); + if (data == NULL) { + nfs_set_error(nfs, "Out of memory. Failed to allocate " + "cb data"); + return -1; + } + + data->nfs = nfs; + data->cb = cb; + data->private_data = private_data; + + data->filler.blob0.val = nfsfh; + data->filler.blob0.free = NULL; + data->rw_data.offset = offset; + data->rw_data.update_pos = update_pos; + + memset(op, 0, sizeof(op)); + + i = nfs4_op_putfh(nfs, &op[0], nfsfh); + i += nfs4_op_read(nfs, &op[i], nfsfh, offset, count); + + memset(&args, 0, sizeof(args)); + args.argarray.argarray_len = i; + args.argarray.argarray_val = op; + + pdu = rpc_nfs4_read_task(nfs->rpc, nfs4_pread_cb, buf, count, &args, + data); + if (pdu == NULL) { + free_nfs4_cb_data(data); + return -1; + } + + return 0; +} + +int +nfs4_preadv_async_internal(struct nfs_context *nfs, struct nfsfh *nfsfh, + const struct iovec *iov, int iovcnt, uint64_t offset, + nfs_cb cb, void *private_data, int update_pos) +{ + COMPOUND4args args; + nfs_argop4 op[2]; + struct nfs4_cb_data *data; + int i; + struct rpc_pdu *pdu; + size_t count = 0; + + for (i = 0; i < iovcnt; i++) { + count += iov[i].iov_len; + } + + data = calloc(1, sizeof(*data)); + if (data == NULL) { + nfs_set_error(nfs, "Out of memory. Failed to allocate " + "cb data"); + return -1; + } + + data->nfs = nfs; + data->cb = cb; + data->private_data = private_data; + + data->filler.blob0.val = nfsfh; + data->filler.blob0.free = NULL; + data->rw_data.offset = offset; + data->rw_data.update_pos = update_pos; + + memset(op, 0, sizeof(op)); + + i = nfs4_op_putfh(nfs, &op[0], nfsfh); + i += nfs4_op_read(nfs, &op[i], nfsfh, offset, count); + + memset(&args, 0, sizeof(args)); + args.argarray.argarray_len = i; + args.argarray.argarray_val = op; + + pdu = rpc_nfs4_readv_task(nfs->rpc, nfs4_pread_cb, iov, iovcnt, &args, + data); + if (pdu == NULL) { + free_nfs4_cb_data(data); + return -1; + } + + return 0; +} + +static void +nfs4_symlink_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs4_error(nfs, status, data, res, "SYMLINK")) { + return; + } + + data->cb(0, nfs, NULL, data->private_data); + free_nfs4_cb_data(data); +} + +/* Takes object name as filler.data + * blob0 as the target + */ +static int +nfs4_populate_symlink(struct nfs4_cb_data *data, nfs_argop4 *op) +{ + struct nfs_context *nfs = data->nfs; + + return nfs4_op_create(nfs, op, data->filler.data, NF4LNK, + NULL, NULL, data->filler.blob0.val, 0); + + return 1; +} + +int +nfs4_symlink_async(struct nfs_context *nfs, const char *target, + const char *linkname, nfs_cb cb, void *private_data) +{ + struct nfs4_cb_data *data; + + data = init_cb_data_split_path(nfs, linkname); + if (data == NULL) { + return -1; + } + + data->cb = cb; + data->private_data = private_data; + data->filler.func = nfs4_populate_symlink; + data->filler.max_op = 1; + + data->filler.blob0.val = strdup(target); + data->filler.blob0.free = free; + + if (nfs4_lookup_path_async(nfs, data, nfs4_symlink_cb) < 0) { + free_nfs4_cb_data(data); + return -1; + } + + return 0; +} + +static void +nfs4_readlink_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + READLINK4resok *rlresok; + char* target; + int i; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs4_error(nfs, status, data, res, "READLINK")) { + return; + } + + if ((i = nfs4_find_op(nfs, data, res, OP_READLINK, "READLINK")) < 0) { + return; + } + + rlresok = &res->resarray.resarray_val[i].nfs_resop4_u.opreadlink.READLINK4res_u.resok4; + + target = strndup(rlresok->link.utf8string_val, + rlresok->link.utf8string_len); + if (target == NULL) { + data->cb(-ENOMEM, nfs, "Failed to allocate memory", + data->private_data); + free_nfs4_cb_data(data); + return; + } + data->filler.blob0.val = target; + data->filler.blob0.free = free; + data->cb(0, nfs, target, data->private_data); + free_nfs4_cb_data(data); +} + +static int +nfs4_populate_readlink(struct nfs4_cb_data *data, nfs_argop4 *op) +{ + struct nfs_context *nfs = data->nfs; + int i; + + i = nfs4_op_readlink(nfs, &op[0]); + + return i; +} + +int +nfs4_readlink_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data) +{ + struct nfs4_cb_data *data; + + data = init_cb_data_full_path(nfs, path); + if (data == NULL) { + return -1; + } + + data->cb = cb; + data->private_data = private_data; + data->filler.func = nfs4_populate_readlink; + data->filler.max_op = 1; + data->flags |= LOOKUP_FLAG_NO_FOLLOW; + + if (nfs4_lookup_path_async(nfs, data, nfs4_readlink_cb) < 0) { + free_nfs4_cb_data(data); + return -1; + } + + return 0; +} + +static void +nfs4_pwrite_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + WRITE4resok *wres = NULL; + struct nfsfh *nfsfh; + int i; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + nfsfh = data->filler.blob0.val; + + if (check_nfs4_error(nfs, status, data, res, "WRITE")) { + return; + } + + if ((i = nfs4_find_op(nfs, data, res, OP_WRITE, "WRITE")) < 0) { + return; + } + wres = &res->resarray.resarray_val[i].nfs_resop4_u.opwrite.WRITE4res_u.resok4; + + if (data->rw_data.update_pos) { + nfsfh->offset = data->rw_data.offset + wres->count; + } + + data->cb(wres->count, nfs, NULL, data->private_data); + free_nfs4_cb_data(data); +} + +int +nfs4_pwrite_async_internal(struct nfs_context *nfs, struct nfsfh *nfsfh, + const void *buf, size_t count, uint64_t offset, + nfs_cb cb, void *private_data, int update_pos) +{ + COMPOUND4args args; + nfs_argop4 op[2]; + struct nfs4_cb_data *data; + int i; + + data = calloc(1, sizeof(*data)); + if (data == NULL) { + nfs_set_error(nfs, "Out of memory. Failed to allocate " + "cb data"); + return -1; + } + + data->nfs = nfs; + data->cb = cb; + data->private_data = private_data; + + data->filler.blob0.val = nfsfh; + data->filler.blob0.free = NULL; + data->rw_data.offset = offset; + data->rw_data.update_pos = update_pos; + + memset(op, 0, sizeof(op)); + + i = nfs4_op_putfh(nfs, &op[0], nfsfh); + i += nfs4_op_write(nfs, &op[i], nfsfh, offset, count, buf); + + memset(&args, 0, sizeof(args)); + args.argarray.argarray_len = i; + args.argarray.argarray_val = op; + + if (rpc_nfs4_write_task(nfs->rpc, nfs4_pwrite_cb, buf, count, + &args, data) == NULL) { + nfs_set_error(nfs, "PWRITE " + "failed: %s", rpc_get_error(nfs->rpc)); + free_nfs4_cb_data(data); + return -EIO; + } + + return 0; +} + +static void +nfs4_write_append_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + GETATTR4resok *garesok = NULL; + struct nfsfh *nfsfh; + int i; + uint64_t offset; + char *buf; + uint32_t count; + struct nfs_stat_64 st; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + nfsfh = data->filler.blob0.val; + + buf = data->filler.blob1.val; + count = data->filler.blob1.len; + + if (check_nfs4_error(nfs, status, data, res, "GETATTR")) { + return; + } + + if ((i = nfs4_find_op(nfs, data, res, OP_GETATTR, "GETATTR")) < 0) { + return; + } + + + garesok = &res->resarray.resarray_val[i].nfs_resop4_u.opgetattr.GETATTR4res_u.resok4; + if (garesok->obj_attributes.attr_vals.attrlist4_len < 8) { + data->cb(-EINVAL, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + return; + } + + memset(&st, 0, sizeof(st)); + nfs_parse_attributes(nfs, data, &st, + garesok->obj_attributes.attr_vals.attrlist4_val, + garesok->obj_attributes.attr_vals.attrlist4_len); + offset = st.nfs_size; + + if (nfs4_pwrite_async_internal(nfs, nfsfh, + buf, (size_t)count, offset, + data->cb, data->private_data, 1) < 0) { + free_nfs4_cb_data(data); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + return; + } + + free_nfs4_cb_data(data); +} + +int +nfs4_write_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t count, + const void *buf, nfs_cb cb, void *private_data) +{ + if (nfsfh->is_append) { + COMPOUND4args args; + nfs_argop4 op[2]; + struct nfs4_cb_data *data; + int i; + + data = calloc(1, sizeof(*data)); + if (data == NULL) { + nfs_set_error(nfs, "Out of memory. Failed to allocate " + "cb data"); + return -1; + } + + data->nfs = nfs; + data->cb = cb; + data->private_data = private_data; + + data->filler.blob0.val = nfsfh; + data->filler.blob0.free = NULL; + + memset(op, 0, sizeof(op)); + + i = nfs4_op_putfh(nfs, &op[0], nfsfh); + i += nfs4_op_getattr(nfs, &op[i], standard_attributes, 2); + + memset(&args, 0, sizeof(args)); + args.argarray.argarray_len = i; + args.argarray.argarray_val = op; + + data->filler.blob0.val = nfsfh; + data->filler.blob0.free = NULL; + + data->filler.blob1.val = discard_const(buf); + data->filler.blob1.len = (int)count; + data->filler.blob1.free = NULL; + + if (rpc_nfs4_compound_task2(nfs->rpc, nfs4_write_append_cb, + &args, data, count) == NULL) { + nfs_set_error(nfs, "PWRITE " + "failed: %s", rpc_get_error(nfs->rpc)); + free_nfs4_cb_data(data); + return -EIO; + } + + return 0; + } + + return nfs4_pwrite_async_internal(nfs, nfsfh, + buf, (size_t)count, nfsfh->offset, + cb, private_data, 1); +} + +int +nfs4_creat_async(struct nfs_context *nfs, const char *path, + int mode, nfs_cb cb, void *private_data) +{ + return nfs4_open_async(nfs, path, O_CREAT|O_WRONLY|O_TRUNC, mode, + cb, private_data); +} + +int +nfs4_unlink_async(struct nfs_context *nfs, const char *path, + nfs_cb cb, void *private_data) +{ + return nfs4_remove_async(nfs, path, cb, private_data); +} + +static void +nfs4_link_2_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs4_error(nfs, status, data, res, "LINK")) { + return; + } + + data->cb(0, nfs, NULL, data->private_data); + free_nfs4_cb_data(data); +} + +static int +nfs4_populate_link(struct nfs4_cb_data *data, nfs_argop4 *op) +{ + struct nfs_context *nfs = data->nfs; + struct nfsfh *nfsfh = data->filler.blob0.val; + + int i; + + i = nfs4_op_savefh(nfs, &op[0]); + i += nfs4_op_putfh(nfs, &op[i], nfsfh); + i += nfs4_op_link(nfs, &op[i], data->filler.data); + + return i; +} + +static void +nfs4_link_1_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + GETFH4resok *gfhresok; + int i; + struct nfsfh *fh; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs4_error(nfs, status, data, res, "LINK")) { + return; + } + + if ((i = nfs4_find_op(nfs, data, res, OP_GETFH, "GETFH")) < 0) { + return; + } + gfhresok = &res->resarray.resarray_val[i].nfs_resop4_u.opgetfh.GETFH4res_u.resok4; + + /* oldpath fh */ + fh = calloc(1, sizeof(*fh)); + if (fh == NULL) { + nfs_set_error(nfs, "Out of memory. Failed to allocate " + "nfsfh"); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + return; + } + data->filler.blob0.val = fh; + data->filler.blob0.free = (blob_free)nfs_free_nfsfh; + + fh->fh.len = gfhresok->object.nfs_fh4_len; + fh->fh.val = malloc(fh->fh.len); + if (fh->fh.val == NULL) { + nfs_set_error(nfs, "Out of memory. Failed to allocate " + "nfsfh"); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + return; + } + memcpy(fh->fh.val, gfhresok->object.nfs_fh4_val, fh->fh.len); + + + data->filler.func = nfs4_populate_link; + data->filler.max_op = 3; + + free(data->path); + data->path = data->filler.blob1.val; + data->filler.blob1.val = NULL; + data->filler.blob1.free = NULL; + + if (nfs4_lookup_path_async(nfs, data, nfs4_link_2_cb) < 0) { + data->cb(-EFAULT, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + return; + } +} + +/* + * filler.data is the name of the new object + * blob0 is the filehandle for newpath parent directory. + * blob1 is oldpath. + */ +int +nfs4_link_async(struct nfs_context *nfs, const char *oldpath, + const char *newpath, nfs_cb cb, void *private_data) +{ + struct nfs4_cb_data *data; + + data = init_cb_data_split_path(nfs, newpath); + if (data == NULL) { + return -1; + } + + data->cb = cb; + data->private_data = private_data; + data->filler.func = nfs4_populate_getfh; + data->filler.max_op = 1; + + /* oldpath */ + data->filler.blob1.val = strdup(oldpath); + if (data->filler.blob1.val == NULL) { + nfs_set_error(nfs, "Out of memory"); + free_nfs4_cb_data(data); + return -1; + } + data->filler.blob1.free = free; + + if (nfs4_lookup_path_async(nfs, data, nfs4_link_1_cb) < 0) { + free_nfs4_cb_data(data); + return -1; + } + + return 0; +} + +static void +nfs4_rename_2_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs4_error(nfs, status, data, res, "RENAME")) { + return; + } + + data->cb(0, nfs, NULL, data->private_data); + free_nfs4_cb_data(data); +} + +static int +nfs4_populate_rename(struct nfs4_cb_data *data, nfs_argop4 *op) +{ + struct nfs_context *nfs = data->nfs; + struct nfsfh *nfsfh = data->filler.blob0.val; + int i; + + i = nfs4_op_savefh(nfs, &op[0]); + i += nfs4_op_putfh(nfs, &op[i], nfsfh); + i += nfs4_op_rename(nfs, &op[i], data->filler.data, + data->filler.blob1.val); + + return i; +} + +static void +nfs4_rename_1_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + GETFH4resok *gfhresok; + int i; + struct nfsfh *fh; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs4_error(nfs, status, data, res, "RENAME")) { + return; + } + + if ((i = nfs4_find_op(nfs, data, res, OP_GETFH, "GETFH")) < 0) { + return; + } + gfhresok = &res->resarray.resarray_val[i].nfs_resop4_u.opgetfh.GETFH4res_u.resok4; + + /* newpath fh */ + fh = calloc(1, sizeof(*fh)); + if (fh == NULL) { + nfs_set_error(nfs, "Out of memory. Failed to allocate " + "nfsfh"); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + return; + } + data->filler.blob0.val = fh; + data->filler.blob0.free = (blob_free)nfs_free_nfsfh; + + fh->fh.len = gfhresok->object.nfs_fh4_len; + fh->fh.val = malloc(fh->fh.len); + if (fh->fh.val == NULL) { + nfs_set_error(nfs, "Out of memory. Failed to allocate " + "nfsfh"); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + return; + } + memcpy(fh->fh.val, gfhresok->object.nfs_fh4_val, fh->fh.len); + + data->filler.blob1.val = data->filler.data; + data->filler.blob1.free = free; + data->filler.data = NULL; + + /* Update path and data to point to the old path/name */ + free(data->path); + data->path = nfs4_resolve_path(nfs, data->filler.blob2.val); + if (data->path == NULL) { + data->cb(-EINVAL, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + return; + } + data_split_path(data); + + data->filler.func = nfs4_populate_rename; + data->filler.max_op = 3; + + if (nfs4_lookup_path_async(nfs, data, nfs4_rename_2_cb) < 0) { + nfs_set_error(nfs, "Out of memory."); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + return; + } +} + +/* + * blob0 is the filehandle for newpath parent directory. + * blob1 is the new name + * blob2 is oldpath. + */ +int +nfs4_rename_async(struct nfs_context *nfs, const char *oldpath, + const char *newpath, nfs_cb cb, void *private_data) +{ + struct nfs4_cb_data *data; + + data = init_cb_data_split_path(nfs, newpath); + if (data == NULL) { + return -1; + } + + data->cb = cb; + data->private_data = private_data; + data->filler.func = nfs4_populate_getfh; + data->filler.max_op = 1; + + /* oldpath */ + data->filler.blob2.val = strdup(oldpath); + if (data->filler.blob2.val == NULL) { + nfs_set_error(nfs, "Out of memory"); + free_nfs4_cb_data(data); + return -1; + } + data->filler.blob2.free = free; + + if (nfs4_lookup_path_async(nfs, data, nfs4_rename_1_cb) < 0) { + free_nfs4_cb_data(data); + return -1; + } + + return 0; +} + +static void +nfs4_mknod_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs4_error(nfs, status, data, res, "MKNOD")) { + return; + } + + data->cb(0, nfs, NULL, data->private_data); + free_nfs4_cb_data(data); +} + +static int +nfs4_populate_mknod(struct nfs4_cb_data *data, nfs_argop4 *op) +{ + struct nfs_context *nfs = data->nfs; + uint32_t mode, *ptr; + int dev; + + /* Strip off the file type before we marshall it */ + ptr = (void *)data->filler.blob1.val; + mode = *ptr; + *ptr = htonl(mode & ~S_IFMT); + + dev = data->filler.blob2.len; + + switch (mode & S_IFMT) { + case S_IFBLK: + return nfs4_op_create(nfs, op, data->filler.data, NF4BLK, + &data->filler.blob0, &data->filler.blob1, + NULL, dev); + case S_IFCHR: + return nfs4_op_create(nfs, op, data->filler.data, NF4CHR, + &data->filler.blob0, &data->filler.blob1, + NULL, dev); + } + + return 1; +} + +/* Takes object name as filler.data + * blob0 as attribute mask + * blob1 as attribute value + * blob2.len as dev + */ +int +nfs4_mknod_async(struct nfs_context *nfs, const char *path, int mode, int dev, + nfs_cb cb, void *private_data) +{ + struct nfs4_cb_data *data; + uint32_t *u32ptr; + + switch (mode & S_IFMT) { + case S_IFCHR: + case S_IFBLK: + break; + default: + nfs_set_error(nfs, "Invalid file type for " + "MKNOD call"); + return -1; + } + + data = init_cb_data_split_path(nfs, path); + if (data == NULL) { + return -1; + } + + data->cb = cb; + data->private_data = private_data; + data->filler.func = nfs4_populate_mknod; + data->filler.max_op = 1; + + /* attribute mask */ + u32ptr = malloc(2 * sizeof(uint32_t)); + if (u32ptr == NULL) { + nfs_set_error(nfs, "Out of memory allocating bitmap"); + return 0; + } + u32ptr[0] = 0; + u32ptr[1] = 1 << (FATTR4_MODE - 32); + data->filler.blob0.len = 2; + data->filler.blob0.val = u32ptr; + data->filler.blob0.free = free; + + /* attribute values */ + u32ptr = malloc(1 * sizeof(uint32_t)); + if (u32ptr == NULL) { + nfs_set_error(nfs, "Out of memory allocating attributes"); + free_nfs4_cb_data(data); + return -1; + } + u32ptr[0] = mode; + data->filler.blob1.len = 4; + data->filler.blob1.val = u32ptr; + data->filler.blob1.free = free; + + data->filler.blob2.len = dev; + + if (nfs4_lookup_path_async(nfs, data, nfs4_mknod_cb) < 0) { + free_nfs4_cb_data(data); + return -1; + } + + return 0; +} + +static void +nfs4_parse_readdir(struct nfs_context *nfs, struct nfs4_cb_data *data, + READDIR4resok *res); + +static void +nfs4_opendir_2_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + READDIR4resok *rdresok; + int i; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs4_error(nfs, status, data, res, "READDIR")) { + return; + } + + if ((i = nfs4_find_op(nfs, data, res, OP_READDIR, "READDIR")) < 0) { + return; + } + rdresok = &res->resarray.resarray_val[i].nfs_resop4_u.opreaddir.READDIR4res_u.resok4; + nfs4_parse_readdir(nfs, data, rdresok); +} + +static void +nfs4_opendir_continue(struct nfs_context *nfs, struct nfs4_cb_data *data) +{ + COMPOUND4args args; + nfs_argop4 op[2]; + struct nfsfh *fh = data->filler.blob0.val; + uint64_t cookie; + int i; + + memcpy(&cookie, data->filler.blob2.val, sizeof(uint64_t)); + + memset(op, 0, sizeof(op)); + + i = nfs4_op_putfh(nfs, &op[0], fh); + i += nfs4_op_readdir(nfs, &op[i], cookie); + + memset(&args, 0, sizeof(args)); + args.argarray.argarray_len = i; + args.argarray.argarray_val = op; + + if (rpc_nfs4_compound_task(nfs->rpc, nfs4_opendir_2_cb, &args, + data) == NULL) { + nfs_set_error(nfs, "Failed to queue READDIR command. %s", + nfs_get_error(nfs)); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + return; + } +} + +static void +nfs4_parse_readdir(struct nfs_context *nfs, struct nfs4_cb_data *data, + READDIR4resok *res) +{ + struct nfsdir *nfsdir = data->filler.blob1.val; + struct entry4 *e; + + e = res->reply.entries; + while (e) { + struct nfsdirent *nfsdirent; + struct nfs_stat_64 st; + + memcpy(data->filler.blob2.val, &e->cookie, sizeof(uint64_t)); + + nfsdirent = malloc(sizeof(struct nfsdirent)); + if (nfsdirent == NULL) { + nfs_set_error(nfs, "Out of memory."); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs4_cb_data(data); + return; + } + nfsdirent->name = strdup(e->name.utf8string_val); + if (nfsdirent->name == NULL) { + nfs_set_error(nfs, "Out of memory."); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs4_cb_data(data); + free(nfsdirent); + return; + } + + memset(&st, 0, sizeof(st)); + if (nfs_parse_attributes(nfs, data, &st, + e->attrs.attr_vals.attrlist4_val, + e->attrs.attr_vals.attrlist4_len) < 0) { + data->cb(-EINVAL, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs4_cb_data(data); + free(nfsdirent->name); + free(nfsdirent); + return; + } + + nfsdirent->inode = st.nfs_ino; + nfsdirent->mode = (uint32_t)st.nfs_mode; + switch (st.nfs_mode & S_IFMT) { + case S_IFREG: + nfsdirent->type = NF4REG; + break; + case S_IFDIR: + nfsdirent->type = NF4DIR; + break; + case S_IFBLK: + nfsdirent->type = NF4BLK; + break; + case S_IFCHR: + nfsdirent->type = NF4CHR; + break; + case S_IFLNK: + nfsdirent->type = NF4LNK; + break; + case S_IFSOCK: + nfsdirent->type = NF4SOCK; + break; + case S_IFIFO: + nfsdirent->type = NF4FIFO; + break; + } + nfsdirent->size = st.nfs_size; + nfsdirent->atime.tv_sec = (long)st.nfs_atime; + nfsdirent->atime.tv_usec = (long)(st.nfs_atime_nsec/1000); + nfsdirent->atime_nsec = (uint32_t)st.nfs_atime_nsec; + nfsdirent->mtime.tv_sec = (long)st.nfs_mtime; + nfsdirent->mtime.tv_usec = (long)(st.nfs_mtime_nsec/1000); + nfsdirent->mtime_nsec = (uint32_t)st.nfs_mtime_nsec; + nfsdirent->ctime.tv_sec = (long)st.nfs_ctime; + nfsdirent->ctime.tv_usec = (long)(st.nfs_ctime_nsec/1000); + nfsdirent->ctime_nsec = (uint32_t)st.nfs_ctime_nsec; + nfsdirent->uid = (uint32_t)st.nfs_uid; + nfsdirent->gid = (uint32_t)st.nfs_gid; + nfsdirent->nlink = (uint32_t)st.nfs_nlink; + nfsdirent->dev = st.nfs_dev; + nfsdirent->rdev = st.nfs_rdev; + nfsdirent->blksize = NFS_BLKSIZE; + nfsdirent->blocks = st.nfs_blocks; + nfsdirent->used = st.nfs_used; + + nfsdirent->next = nfsdir->entries; + nfsdir->entries = nfsdirent; + e = e->nextentry; + } + + if (res->reply.eof == 0) { + nfs4_opendir_continue(nfs, data); + return; + } + + nfsdir->current = nfsdir->entries; + data->filler.blob1.val = NULL; + data->cb(0, nfs, nfsdir, data->private_data); + free_nfs4_cb_data(data); +} + +static void +nfs4_opendir_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + struct nfsfh *fh; + GETFH4resok *gresok; + READDIR4resok *rdresok; + int i; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs4_error(nfs, status, data, res, "READDIR")) { + return; + } + + /* Parse GetFH */ + if ((i = nfs4_find_op(nfs, data, res, OP_GETFH, "GETFH")) < 0) { + return; + } + gresok = &res->resarray.resarray_val[i].nfs_resop4_u.opgetfh.GETFH4res_u.resok4; + + fh = calloc(1, sizeof(*fh)); + if (fh == NULL) { + nfs_set_error(nfs, "Out of memory. Failed to allocate " + "nfsfh"); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + return; + } + + data->filler.blob0.val = fh; + data->filler.blob0.free = (blob_free)nfs_free_nfsfh; + + fh->fh.len = gresok->object.nfs_fh4_len; + fh->fh.val = malloc(fh->fh.len); + if (fh->fh.val == NULL) { + nfs_set_error(nfs, "Out of memory. Failed to allocate " + "nfsfh"); + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + return; + } + memcpy(fh->fh.val, gresok->object.nfs_fh4_val, fh->fh.len); + + if ((i = nfs4_find_op(nfs, data, res, OP_READDIR, "READDIR")) < 0) { + return; + } + rdresok = &res->resarray.resarray_val[i].nfs_resop4_u.opreaddir.READDIR4res_u.resok4; + nfs4_parse_readdir(nfs, data, rdresok); +} + +static int +nfs4_populate_readdir(struct nfs4_cb_data *data, nfs_argop4 *op) +{ + struct nfs_context *nfs = data->nfs; + uint64_t cookie; + int i; + + memcpy(&cookie, data->filler.blob2.val, sizeof(uint64_t)); + + i = nfs4_op_getfh(nfs, &op[0]); + i += nfs4_op_readdir(nfs, &op[i], cookie); + + return i; +} + + +/* blob0 is the directory filehandle + * blob1 is nfsdir + * blob2 is the cookie + */ +int +nfs4_opendir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data) +{ + struct nfs4_cb_data *data; + struct nfsdir *nfsdir; + + data = init_cb_data_full_path(nfs, path); + if (data == NULL) { + return -1; + } + + data->cb = cb; + data->private_data = private_data; + data->filler.func = nfs4_populate_readdir; + data->filler.max_op = 2; + + nfsdir = calloc(1, sizeof(struct nfsdir)); + if (nfsdir == NULL) { + free_nfs4_cb_data(data); + nfs_set_error(nfs, "failed to allocate buffer for nfsdir"); + return -1; + } + + data->filler.blob1.val = nfsdir; + data->filler.blob1.free = (blob_free)nfs_free_nfsdir; + + data->filler.blob2.val = calloc(1, sizeof(uint64_t)); + if (data->filler.blob2.val == NULL) { + free_nfs4_cb_data(data); + nfs_set_error(nfs, "failed to allocate buffer for cookie"); + return -1; + } + data->filler.blob2.free = (blob_free)free; + + if (nfs4_lookup_path_async(nfs, data, nfs4_opendir_cb) < 0) { + free_nfs4_cb_data(data); + return -1; + } + + return 0; +} + +static void +nfs4_truncate_close_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + struct nfsfh *fh = data->filler.blob0.val; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (res) { + nfs_increment_seqid(fh, res->status); + } + + if (check_nfs4_error(nfs, status, data, res, "CLOSE")) { + return; + } + + data->cb(0, nfs, NULL, data->private_data); + free_nfs4_cb_data(data); +} + +static void +nfs4_truncate_open_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + struct nfsfh *fh = data->filler.blob0.val; + COMPOUND4res *res = command_data; + COMPOUND4args args; + nfs_argop4 op[4]; + int i; + + if (check_nfs4_error(nfs, status, data, res, "OPEN")) { + return; + } + + i = nfs4_op_putfh(nfs, &op[0], fh); + i += nfs4_op_truncate(nfs, &op[i], fh, data->filler.blob3.val); + i += nfs4_op_close(nfs, &op[i], fh); + + memset(&args, 0, sizeof(args)); + args.argarray.argarray_len = i; + args.argarray.argarray_val = op; + + if (rpc_nfs4_compound_task(nfs->rpc, nfs4_truncate_close_cb, &args, + data) == NULL) { + /* Not much we can do but leak one fd on the server :( */ + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + return; + } +} + +/* + * data.blob3.val is a 12 byte SETATTR buffer for length+update_mtime + */ +int +nfs4_truncate_async(struct nfs_context *nfs, const char *path, uint64_t length, + nfs_cb cb, void *private_data) +{ + struct nfs4_cb_data *data; + + data = init_cb_data_split_path(nfs, path); + if (data == NULL) { + return -1; + } + + data->cb = cb; + data->private_data = private_data; + data->open_cb = nfs4_truncate_open_cb; + + data->filler.blob3.val = malloc(12); + if (data->filler.blob3.val == NULL) { + nfs_set_error(nfs, "Out of memory"); + free_nfs4_cb_data(data); + return -1; + } + data->filler.blob3.free = free; + + memset(data->filler.blob3.val, 0, 12); + length = nfs_hton64(length); + memcpy(data->filler.blob3.val, &length, sizeof(uint64_t)); + +#ifdef HAVE_MULTITHREADING + if (nfs->rpc->multithreading_enabled) { + nfs_mt_mutex_lock(&nfs->nfsi->nfs4_open_call_mutex); + data->flags |= MUTEX_HELD; + } +#endif + if (nfs4_open_async_internal(nfs, data, O_WRONLY, 0) < 0) { + return -1; + } + + return 0; +} + +static void +nfs4_fsync_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs4_error(nfs, status, data, res, "FSYNC")) { + return; + } + + data->cb(0, nfs, NULL, data->private_data); + free_nfs4_cb_data(data); +} + +int +nfs4_fsync_async(struct nfs_context *nfs, struct nfsfh *fh, nfs_cb cb, + void *private_data) +{ + COMPOUND4args args; + nfs_argop4 op[2]; + struct nfs4_cb_data *data; + int i; + + data = calloc(1, sizeof(*data)); + if (data == NULL) { + nfs_set_error(nfs, "Out of memory."); + return -1; + } + + data->nfs = nfs; + data->cb = cb; + data->private_data = private_data; + + memset(op, 0, sizeof(op)); + + i = nfs4_op_putfh(nfs, &op[0], fh); + i += nfs4_op_commit(nfs, &op[i]); + + memset(&args, 0, sizeof(args)); + args.argarray.argarray_len = i; + args.argarray.argarray_val = op; + + if (rpc_nfs4_compound_task(nfs->rpc, nfs4_fsync_cb, &args, + data) == NULL) { + data->filler.blob0.val = NULL; + free_nfs4_cb_data(data); + return -1; + } + + return 0; +} + +int +nfs4_ftruncate_async(struct nfs_context *nfs, struct nfsfh *fh, + uint64_t length, nfs_cb cb, void *private_data) +{ + COMPOUND4args args; + nfs_argop4 op[2]; + struct nfs4_cb_data *data; + int i; + + data = calloc(1, sizeof(*data)); + if (data == NULL) { + nfs_set_error(nfs, "Out of memory."); + return -1; + } + + data->nfs = nfs; + data->cb = cb; + data->private_data = private_data; + + data->filler.blob3.val = calloc(1, 12); + if (data->filler.blob3.val == NULL) { + nfs_set_error(nfs, "Out of memory"); + free_nfs4_cb_data(data); + return -1; + } + data->filler.blob3.free = free; + + length = nfs_hton64(length); + memcpy(data->filler.blob3.val, &length, sizeof(uint64_t)); + + memset(op, 0, sizeof(op)); + + i = nfs4_op_putfh(nfs, &op[0], fh); + i += nfs4_op_truncate(nfs, &op[i], fh, data->filler.blob3.val); + + memset(&args, 0, sizeof(args)); + args.argarray.argarray_len = i; + args.argarray.argarray_val = op; + + if (rpc_nfs4_compound_task(nfs->rpc, nfs4_fsync_cb, &args, + data) == NULL) { + data->filler.blob0.val = NULL; + free_nfs4_cb_data(data); + return -1; + } + + return 0; +} + +static void +nfs4_lseek_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + GETATTR4resok *garesok = NULL; + struct nfsfh *fh = data->filler.blob0.val; + struct nfs_stat_64 st; + int64_t offset; + int i; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + memcpy(&offset, data->filler.blob1.val, sizeof(int64_t)); + + if (check_nfs4_error(nfs, status, data, res, "LSEEK")) { + return; + } + + if ((i = nfs4_find_op(nfs, data, res, OP_GETATTR, "GETATTR")) < 0) { + return; + } + garesok = &res->resarray.resarray_val[i].nfs_resop4_u.opgetattr.GETATTR4res_u.resok4; + + memset(&st, 0, sizeof(st)); + nfs_parse_attributes(nfs, data, &st, + garesok->obj_attributes.attr_vals.attrlist4_val, + garesok->obj_attributes.attr_vals.attrlist4_len); + + if (offset < 0 && + -offset > (int64_t)st.nfs_size) { + nfs_set_error(nfs, "Negative offset for lseek(" + "SEET_END)"); + data->cb(-EINVAL, nfs, &fh->offset, + data->private_data); + } else { + fh->offset = offset + st.nfs_size; + data->cb(0, nfs, &fh->offset, data->private_data); + } + + free_nfs4_cb_data(data); +} + +/* blob0.val is nfsfh + * blob1.val is offset + */ +int +nfs4_lseek_async(struct nfs_context *nfs, struct nfsfh *fh, int64_t offset, + int whence, nfs_cb cb, void *private_data) +{ + COMPOUND4args args; + nfs_argop4 op[2]; + struct nfs4_cb_data *data; + int i; + + if (whence == SEEK_SET) { + if (offset < 0) { + nfs_set_error(nfs, "Negative offset for lseek(" + "SEET_SET)"); + cb(-EINVAL, nfs, &fh->offset, private_data); + } else { + fh->offset = offset; + cb(0, nfs, &fh->offset, private_data); + } + return 0; + } + if (whence == SEEK_CUR) { + if (offset < 0 && + fh->offset < (uint64_t)(-offset)) { + nfs_set_error(nfs, "Negative offset for lseek(" + "SEET_CUR)"); + cb(-EINVAL, nfs, &fh->offset, private_data); + } else { + fh->offset += offset; + cb(0, nfs, &fh->offset, private_data); + } + return 0; + } + + data = calloc(1, sizeof(*data)); + if (data == NULL) { + nfs_set_error(nfs, "Out of memory."); + return -1; + } + + data->nfs = nfs; + data->cb = cb; + data->private_data = private_data; + + data->filler.blob0.val = fh; + data->filler.blob0.free = NULL; + + data->filler.blob1.val = malloc(sizeof(uint64_t)); + if (data->filler.blob1.val == NULL) { + nfs_set_error(nfs, "Out of memory."); + free_nfs4_cb_data(data); + return -1; + } + memcpy(data->filler.blob1.val, &offset, sizeof(uint64_t)); + + i = nfs4_op_putfh(nfs, &op[0], fh); + i += nfs4_op_getattr(nfs, &op[i], standard_attributes, 2); + + memset(&args, 0, sizeof(args)); + args.argarray.argarray_len = i; + args.argarray.argarray_val = op; + + if (rpc_nfs4_compound_task(nfs->rpc, nfs4_lseek_cb, &args, + data) == NULL) { + free_nfs4_cb_data(data); + return -1; + } + + return 0; +} + +static void +nfs4_lockf_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + LOCK4resok *lresok = NULL; + LOCKU4res *lures = NULL; + struct nfsfh *fh = data->filler.blob0.val; + enum nfs4_lock_op cmd; + int i; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + cmd = data->filler.blob1.len; + + if (check_nfs4_error(nfs, status, data, res, "LOCKF")) { + return; + } + + switch (cmd) { + case NFS4_F_LOCK: + case NFS4_F_TLOCK: + if ((i = nfs4_find_op(nfs, data, res, OP_LOCK, "LOCK")) < 0) { + return; + } + + lresok = &res->resarray.resarray_val[i].nfs_resop4_u.oplock.LOCK4res_u.resok4; + nfs->nfsi->has_lock_owner = 1; + fh->lock_stateid.seqid = lresok->lock_stateid.seqid; + memcpy(fh->lock_stateid.other, lresok->lock_stateid.other, 12); + break; + case NFS4_F_ULOCK: + if ((i = nfs4_find_op(nfs, data, res, OP_LOCKU, "LOCKU")) < 0) { + return; + } + lures = &res->resarray.resarray_val[i].nfs_resop4_u.oplocku; + fh->lock_stateid.seqid = lures->LOCKU4res_u.lock_stateid.seqid; + memcpy(fh->lock_stateid.other, + lures->LOCKU4res_u.lock_stateid.other, 12); + break; + case NFS4_F_TEST: + break; + } + + data->cb(0, nfs, NULL, data->private_data); + + free_nfs4_cb_data(data); +} + +/* blob0.val is nfsfh + * blob1.len is cmd + */ +int +nfs4_lockf_async(struct nfs_context *nfs, struct nfsfh *fh, + enum nfs4_lock_op cmd, uint64_t count, + nfs_cb cb, void *private_data) +{ + COMPOUND4args args; + nfs_argop4 op[2]; + struct nfs4_cb_data *data; + int i; + + data = calloc(1, sizeof(*data)); + if (data == NULL) { + nfs_set_error(nfs, "Out of memory."); + return -1; + } + + data->nfs = nfs; + data->cb = cb; + data->private_data = private_data; + + data->filler.blob0.val = fh; + data->filler.blob0.free = NULL; + + data->filler.blob1.len = cmd; + + i = nfs4_op_putfh(nfs, &op[0], fh); + switch (cmd) { + case NFS4_F_LOCK: + i += nfs4_op_lock(nfs, &op[i], fh, OP_LOCK, WRITEW_LT, + 0, fh->offset, count); + break; + case NFS4_F_TLOCK: + i += nfs4_op_lock(nfs, &op[i], fh, OP_LOCK, WRITE_LT, + 0, fh->offset, count); + break; + case NFS4_F_ULOCK: + i += nfs4_op_locku(nfs, &op[i], fh, WRITE_LT, + fh->offset, count); + break; + case NFS4_F_TEST: + i += nfs4_op_lockt(nfs, &op[i], fh, WRITEW_LT, + fh->offset, count); + break; + } + + memset(&args, 0, sizeof(args)); + args.argarray.argarray_len = i; + args.argarray.argarray_val = op; + + if (rpc_nfs4_compound_task(nfs->rpc, nfs4_lockf_cb, &args, + data) == NULL) { + free_nfs4_cb_data(data); + return -1; + } + + return 0; +} + +static void +nfs4_fcntl_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + LOCK4resok *lresok = NULL; + struct nfsfh *fh = data->filler.blob0.val; + enum nfs4_fcntl_op cmd; + struct nfs4_flock *fl; + int i; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + cmd = data->filler.blob1.len; + + if (check_nfs4_error(nfs, status, data, res, "FCNTL")) { + return; + } + + switch (cmd) { + case NFS4_F_SETLK: + case NFS4_F_SETLKW: + fl = (struct nfs4_flock *)data->filler.blob1.val; + + switch (fl->l_type) { + case F_RDLCK: + case F_WRLCK: + if ((i = nfs4_find_op(nfs, data, res, OP_LOCK, + "LOCK")) < 0) { + return; + } + + lresok = &res->resarray.resarray_val[i].nfs_resop4_u.oplock.LOCK4res_u.resok4; + nfs->nfsi->has_lock_owner = 1; + fh->lock_stateid.seqid = lresok->lock_stateid.seqid; + memcpy(fh->lock_stateid.other, + lresok->lock_stateid.other, 12); + break; + case F_UNLCK: + if ((i = nfs4_find_op(nfs, data, res, OP_LOCKU, + "UNLOCK")) < 0) { + return; + } + break; + } + break; + } + + data->cb(0, nfs, NULL, data->private_data); + + free_nfs4_cb_data(data); +} + +static int +nfs4_fcntl_async_internal(struct nfs_context *nfs, struct nfsfh *fh, + struct nfs4_cb_data *data) +{ + COMPOUND4args args; + nfs_argop4 op[2]; + struct nfs4_flock *fl; + enum nfs4_fcntl_op cmd; + int i, lock_type; + + cmd = data->filler.blob1.len; + + i = nfs4_op_putfh(nfs, &op[0], fh); + switch (cmd) { + case NFS4_F_SETLK: + case NFS4_F_SETLKW: + fl = data->filler.blob1.val; + + switch (fl->l_type) { + case F_RDLCK: + lock_type = cmd == NFS4_F_SETLK ? READ_LT : READW_LT; + i += nfs4_op_lock(nfs, &op[i], fh, OP_LOCK, lock_type, + 0, fl->l_start, fl->l_len); + break; + case F_WRLCK: + lock_type = cmd == NFS4_F_SETLK ? WRITE_LT : WRITEW_LT; + i += nfs4_op_lock(nfs, &op[i], fh, OP_LOCK, lock_type, + 0, fl->l_start, fl->l_len); + break; + case F_UNLCK: + i += nfs4_op_locku(nfs, &op[i], fh, WRITE_LT, + fl->l_start, fl->l_len); + break; + } + break; + } + + memset(&args, 0, sizeof(args)); + args.argarray.argarray_len = i; + args.argarray.argarray_val = op; + + if (rpc_nfs4_compound_task(nfs->rpc, nfs4_fcntl_cb, &args, + data) == NULL) { + free_nfs4_cb_data(data); + return -1; + } + + return 0; +} + +static void +nfs4_fcntl_stat_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + struct nfsfh *fh = data->filler.blob0.val; + enum nfs4_fcntl_op cmd = data->filler.blob1.len; + COMPOUND4res *res = command_data; + GETATTR4resok *garesok; + struct nfs4_flock *fl; + struct nfs_stat_64 st; + int i; + + if (check_nfs4_error(nfs, status, data, res, "STAT64")) { + return; + } + + if ((i = nfs4_find_op(nfs, data, res, OP_GETATTR, "GETATTR")) < 0) { + return; + } + garesok = &res->resarray.resarray_val[i].nfs_resop4_u.opgetattr.GETATTR4res_u.resok4; + memset(&st, 0, sizeof(st)); + if (nfs_parse_attributes(nfs, data, &st, + garesok->obj_attributes.attr_vals.attrlist4_val, + garesok->obj_attributes.attr_vals.attrlist4_len) < 0) { + data->cb(-EINVAL, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + } + + switch (cmd) { + case NFS4_F_SETLK: + case NFS4_F_SETLKW: + fl = data->filler.blob1.val; + + fl->l_whence = SEEK_SET; + fl->l_start = st.nfs_size + fl->l_start; + if (nfs4_fcntl_async_internal(nfs, fh, data)) { + data->cb(-ENOMEM, nfs, nfs_get_error(nfs), + data->private_data); + free_nfs4_cb_data(data); + } + } +} + +/* blob0.val is nfsfh + * blob1.len is cmd + * blob1.val is arg + */ +int +nfs4_fcntl_async(struct nfs_context *nfs, struct nfsfh *fh, + enum nfs4_fcntl_op cmd, void *arg, + nfs_cb cb, void *private_data) +{ + struct nfs4_cb_data *data; + struct nfs4_flock *fl; + COMPOUND4args args; + nfs_argop4 op[2]; + int i; + + data = calloc(1, sizeof(*data)); + if (data == NULL) { + nfs_set_error(nfs, "Out of memory."); + return -1; + } + + data->nfs = nfs; + data->cb = cb; + data->private_data = private_data; + + data->filler.blob0.val = fh; + data->filler.blob0.free = NULL; + + data->filler.blob1.len = cmd; + data->filler.blob1.val = arg; + data->filler.blob1.free = NULL; + + switch (cmd) { + case NFS4_F_SETLK: + case NFS4_F_SETLKW: + fl = arg; + switch (fl->l_whence) { + case SEEK_SET: + return nfs4_fcntl_async_internal(nfs, fh, data); + case SEEK_CUR: + fl->l_whence = SEEK_SET; + fl->l_start = fh->offset + fl->l_start; + return nfs4_fcntl_async_internal(nfs, fh, data); + case SEEK_END: + i = nfs4_op_putfh(nfs, &op[0], fh); + i += nfs4_op_getattr(nfs, &op[i], standard_attributes, + 2); + + memset(&args, 0, sizeof(args)); + args.argarray.argarray_len = i; + args.argarray.argarray_val = op; + + if (rpc_nfs4_compound_task(nfs->rpc, + nfs4_fcntl_stat_cb, + &args, data) == NULL) { + free_nfs4_cb_data(data); + return -1; + } + return 0; + } + nfs_set_error(nfs, "fcntl: unknown fl->whence:%d\n", + fl->l_whence); + free_nfs4_cb_data(data); + return -1; + } + nfs_set_error(nfs, "fcntl: unknown cmd:%d\n", cmd); + free_nfs4_cb_data(data); + return -1; +} + +static int +nfs_parse_statvfs(struct nfs_context *nfs, struct nfs4_cb_data *data, + struct statvfs *svfs, const char *buf, int len) +{ + uint64_t u64; + uint32_t u32; + + svfs->f_bsize = NFS_BLKSIZE; + svfs->f_frsize = NFS_BLKSIZE; + +#if !defined(__ANDROID__) + svfs->f_flag = 0; +#endif + + /* FSID + * NFSv4 FSID is 2*64 bit but statvfs fsid is just an + * unsigmed long. Mix the 2*64 bits and hope for the best. + */ + CHECK_GETATTR_BUF_SPACE(len, 16); + memcpy(&u64, buf, 8); + svfs->f_fsid = (unsigned long)nfs_ntoh64(u64); + buf += 8; + len -= 8; + memcpy(&u64, buf, 8); + svfs->f_fsid |= (unsigned long)nfs_ntoh64(u64); + buf += 8; + len -= 8; + + /* Files Avail */ + CHECK_GETATTR_BUF_SPACE(len, 8); + memcpy(&u64, buf, 8); +#if !defined(__ANDROID__) + svfs->f_favail = (fsfilcnt_t)nfs_ntoh64(u64); +#endif + buf += 8; + len -= 8; + + /* Files Free */ + CHECK_GETATTR_BUF_SPACE(len, 8); + memcpy(&u64, buf, 8); + svfs->f_ffree = (fsfilcnt_t)nfs_ntoh64(u64); + buf += 8; + len -= 8; + + /* Files Total */ + CHECK_GETATTR_BUF_SPACE(len, 8); + memcpy(&u64, buf, 8); + svfs->f_files = (fsfilcnt_t)nfs_ntoh64(u64); + buf += 8; + len -= 8; + + /* Max Name */ + CHECK_GETATTR_BUF_SPACE(len, 4); + memcpy(&u32, buf, 4); +#if !defined(__ANDROID__) + svfs->f_namemax = ntohl(u32); +#endif + buf += 4; + len -= 4; + + /* Space Avail */ + CHECK_GETATTR_BUF_SPACE(len, 8); + memcpy(&u64, buf, 8); + svfs->f_bavail = (fsblkcnt_t)(nfs_ntoh64(u64) / svfs->f_frsize); + buf += 8; + len -= 8; + + /* Space Free */ + CHECK_GETATTR_BUF_SPACE(len, 8); + memcpy(&u64, buf, 8); + svfs->f_bfree = (fsblkcnt_t)(nfs_ntoh64(u64) / svfs->f_frsize); + buf += 8; + len -= 8; + + /* Space Total */ + CHECK_GETATTR_BUF_SPACE(len, 8); + memcpy(&u64, buf, 8); + svfs->f_blocks = (fsblkcnt_t)(nfs_ntoh64(u64) / svfs->f_frsize); + buf += 8; + len -= 8; + + return 0; +} + +static int +nfs_parse_statvfs64(struct nfs_context *nfs, struct nfs4_cb_data *data, + struct nfs_statvfs_64 *svfs64, const char *buf, int len) +{ + uint64_t u64; + uint32_t u32; + + svfs64->f_bsize = NFS_BLKSIZE; + svfs64->f_frsize = NFS_BLKSIZE; + svfs64->f_flag = 0; + + /* FSID + * NFSv4 FSID is 2*64 bit but statvfs fsid is just an + * unsigmed long. Mix the 2*64 bits and hope for the best. + */ + CHECK_GETATTR_BUF_SPACE(len, 16); + memcpy(&u64, buf, 8); + svfs64->f_fsid = nfs_ntoh64(u64); + buf += 8; + len -= 8; + memcpy(&u64, buf, 8); + svfs64->f_fsid |= nfs_ntoh64(u64); + buf += 8; + len -= 8; + + /* Files Avail */ + CHECK_GETATTR_BUF_SPACE(len, 8); + memcpy(&u64, buf, 8); + svfs64->f_favail = nfs_ntoh64(u64); + buf += 8; + len -= 8; + + /* Files Free */ + CHECK_GETATTR_BUF_SPACE(len, 8); + memcpy(&u64, buf, 8); + svfs64->f_ffree = nfs_ntoh64(u64); + buf += 8; + len -= 8; + + /* Files Total */ + CHECK_GETATTR_BUF_SPACE(len, 8); + memcpy(&u64, buf, 8); + svfs64->f_files = nfs_ntoh64(u64); + buf += 8; + len -= 8; + + /* Max Name */ + CHECK_GETATTR_BUF_SPACE(len, 4); + memcpy(&u32, buf, 4); + svfs64->f_namemax = ntohl(u32); + buf += 4; + len -= 4; + + /* Space Avail */ + CHECK_GETATTR_BUF_SPACE(len, 8); + memcpy(&u64, buf, 8); + svfs64->f_bavail = nfs_ntoh64(u64) / svfs64->f_frsize; + buf += 8; + len -= 8; + + /* Space Free */ + CHECK_GETATTR_BUF_SPACE(len, 8); + memcpy(&u64, buf, 8); + svfs64->f_bfree = nfs_ntoh64(u64) / svfs64->f_frsize; + buf += 8; + len -= 8; + + /* Space Total */ + CHECK_GETATTR_BUF_SPACE(len, 8); + memcpy(&u64, buf, 8); + svfs64->f_blocks = nfs_ntoh64(u64) / svfs64->f_frsize; + buf += 8; + len -= 8; + + return 0; +} + +static void +nfs4_statvfs_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + GETATTR4resok *garesok; + struct statvfs svfs; + struct nfs_statvfs_64 svfs64; + int i; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs4_error(nfs, status, data, res, "STATVFS")) { + return; + } + + memset(&svfs, 0, sizeof(svfs)); + memset(&svfs64, 0, sizeof(svfs64)); + + if ((i = nfs4_find_op(nfs, data, res, OP_GETATTR, "GETATTR")) < 0) { + return; + } + garesok = &res->resarray.resarray_val[i].nfs_resop4_u.opgetattr.GETATTR4res_u.resok4; + + if (data->flags & LOOKUP_FLAG_IS_STATVFS64) { + /* statvfs64 */ + if (nfs_parse_statvfs64(nfs, data, &svfs64, + garesok->obj_attributes.attr_vals.attrlist4_val, + garesok->obj_attributes.attr_vals.attrlist4_len) < 0) { + data->cb(-EINVAL, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + return; + } + + data->cb(0, nfs, &svfs64, data->private_data); + } else { + /* statvfs */ + if (nfs_parse_statvfs(nfs, data, &svfs, + garesok->obj_attributes.attr_vals.attrlist4_val, + garesok->obj_attributes.attr_vals.attrlist4_len) < 0) { + data->cb(-EINVAL, nfs, nfs_get_error(nfs), data->private_data); + free_nfs4_cb_data(data); + return; + } + + data->cb(0, nfs, &svfs, data->private_data); + } + + free_nfs4_cb_data(data); +} + +static int +nfs4_statvfs_async_internal(struct nfs_context *nfs, const char *path, + int is_statvfs64, + nfs_cb cb, void *private_data) +{ + struct nfs4_cb_data *data; + COMPOUND4args args; + struct nfsfh fh; + nfs_argop4 op[2]; + int i; + + data = calloc(1, sizeof(*data)); + if (data == NULL) { + nfs_set_error(nfs, "Out of memory."); + return -1; + } + + data->nfs = nfs; + data->cb = cb; + data->private_data = private_data; + if (is_statvfs64) { + data->flags |= LOOKUP_FLAG_IS_STATVFS64; + } + + fh.fh.len = nfs->nfsi->rootfh.len; + fh.fh.val = nfs->nfsi->rootfh.val; + + i = nfs4_op_putfh(nfs, &op[0], &fh); + i += nfs4_op_getattr(nfs, &op[i], statvfs_attributes, 2); + + memset(&args, 0, sizeof(args)); + args.argarray.argarray_len = i; + args.argarray.argarray_val = op; + + if (rpc_nfs4_compound_task(nfs->rpc, nfs4_statvfs_cb, &args, + data) == NULL) { + free_nfs4_cb_data(data); + return -1; + } + + return 0; +} + +int +nfs4_statvfs_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data) +{ + return nfs4_statvfs_async_internal(nfs, path, 0, + cb, private_data); +} + +int +nfs4_statvfs64_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data) +{ + return nfs4_statvfs_async_internal(nfs, path, 1, + cb, private_data); +} + +static void +nfs4_chmod_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + + if (check_nfs4_error(nfs, status, data, res, "CHMOD")) { + return; + } + + data->cb(0, nfs, NULL, data->private_data); + free_nfs4_cb_data(data); +} + +static int +nfs4_populate_chmod(struct nfs4_cb_data *data, nfs_argop4 *op) +{ + return nfs4_op_chmod(data->nfs, op, NULL, data->filler.blob3.val); +} + +int +nfs4_chmod_async_internal(struct nfs_context *nfs, const char *path, + int no_follow, int mode, nfs_cb cb, + void *private_data) +{ + struct nfs4_cb_data *data; + uint32_t m; + + data = init_cb_data_full_path(nfs, path); + if (data == NULL) { + return -1; + } + + data->cb = cb; + data->private_data = private_data; + data->filler.func = nfs4_populate_chmod; + data->filler.max_op = 1; + + if (no_follow) { + data->flags |= LOOKUP_FLAG_NO_FOLLOW; + } + + data->filler.blob3.val = malloc(sizeof(uint32_t)); + if (data->filler.blob3.val == NULL) { + nfs_set_error(nfs, "Out of memory"); + free_nfs4_cb_data(data); + return -1; + } + data->filler.blob3.free = free; + + m = htonl(mode); + memcpy(data->filler.blob3.val, &m, sizeof(uint32_t)); + + if (nfs4_lookup_path_async(nfs, data, nfs4_chmod_cb) < 0) { + return -1; + } + + return 0; +} + +int +nfs4_fchmod_async(struct nfs_context *nfs, struct nfsfh *fh, int mode, + nfs_cb cb, void *private_data) +{ + COMPOUND4args args; + nfs_argop4 op[2]; + struct nfs4_cb_data *data; + uint32_t m; + int i; + + data = calloc(1, sizeof(*data)); + if (data == NULL) { + nfs_set_error(nfs, "Out of memory."); + return -1; + } + + data->nfs = nfs; + data->cb = cb; + data->private_data = private_data; + + data->filler.blob3.val = malloc(sizeof(uint32_t)); + if (data->filler.blob3.val == NULL) { + nfs_set_error(nfs, "Out of memory"); + free_nfs4_cb_data(data); + return -1; + } + data->filler.blob3.free = free; + + m = htonl(mode); + memcpy(data->filler.blob3.val, &m, sizeof(uint32_t)); + + memset(op, 0, sizeof(op)); + + i = nfs4_op_putfh(nfs, &op[0], fh); + i += nfs4_op_chmod(nfs, &op[i], fh, data->filler.blob3.val); + + memset(&args, 0, sizeof(args)); + args.argarray.argarray_len = i; + args.argarray.argarray_val = op; + + if (rpc_nfs4_compound_task(nfs->rpc, nfs4_fsync_cb, &args, + data) == NULL) { + data->filler.blob0.val = NULL; + free_nfs4_cb_data(data); + return -1; + } + + return 0; +} + +#define CHOWN_BLOB_SIZE 64 +static int +nfs4_create_chown_buffer(struct nfs_context *nfs, struct nfs4_cb_data *data, + int uid, int gid) +{ + char *str; + int i, l; + uint32_t len; + + data->filler.blob3.val = calloc(1, CHOWN_BLOB_SIZE); + if (data->filler.blob3.val == NULL) { + nfs_set_error(nfs, "Out of memory"); + return -1; + } + data->filler.blob3.free = free; + + i = 0; + str = data->filler.blob3.val; + /* UID */ + l = snprintf(&str[i + 4], CHOWN_BLOB_SIZE - 4 - i, + "%d", uid); + if (l < 0) { + nfs_set_error(nfs, "snprintf failed"); + return -1; + } + len = htonl(l); + /* UID length prefix */ + memcpy(&str[i], &len, sizeof(uint32_t)); + i += 4 + l; + i = (i + 3) & ~0x03; + + /* GID */ + l = snprintf(&str[i + 4], CHOWN_BLOB_SIZE - 4 - i, + "%d", gid); + if (l < 0) { + nfs_set_error(nfs, "snprintf failed"); + return -1; + } + len = htonl(l); + /* GID length prefix */ + memcpy(&str[i], &len, sizeof(uint32_t)); + i += 4 + l; + i = (i + 3) & ~0x03; + + data->filler.blob3.len = i; + + return 0; +} + +static void +nfs4_chown_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + + if (check_nfs4_error(nfs, status, data, res, "OPEN")) { + return; + } + + data->cb(0, nfs, NULL, data->private_data); + free_nfs4_cb_data(data); +} + +static int +nfs4_populate_chown(struct nfs4_cb_data *data, nfs_argop4 *op) +{ + return nfs4_op_chown(data->nfs, op, NULL, data->filler.blob3.val, + data->filler.blob3.len); +} + +int +nfs4_chown_async_internal(struct nfs_context *nfs, const char *path, + int no_follow, int uid, int gid, + nfs_cb cb, void *private_data) +{ + struct nfs4_cb_data *data; + + data = init_cb_data_split_path(nfs, path); + if (data == NULL) { + return -1; + } + + data->cb = cb; + data->private_data = private_data; + data->filler.func = nfs4_populate_chown; + data->filler.max_op = 1; + + if (no_follow) { + data->flags |= LOOKUP_FLAG_NO_FOLLOW; + } + + if (nfs4_create_chown_buffer(nfs, data, uid, gid) < 0) { + free_nfs4_cb_data(data); + return -1; + } + + if (nfs4_lookup_path_async(nfs, data, nfs4_chown_cb) < 0) { + return -1; + } + + return 0; +} + +int +nfs4_fchown_async(struct nfs_context *nfs, struct nfsfh *fh, int uid, int gid, + nfs_cb cb, void *private_data) +{ + COMPOUND4args args; + nfs_argop4 op[2]; + struct nfs4_cb_data *data; + int i; + + data = calloc(1, sizeof(*data)); + if (data == NULL) { + nfs_set_error(nfs, "Out of memory."); + return -1; + } + + data->nfs = nfs; + data->cb = cb; + data->private_data = private_data; + + if (nfs4_create_chown_buffer(nfs, data, uid, gid) < 0) { + free_nfs4_cb_data(data); + return -1; + } + + memset(op, 0, sizeof(op)); + + i = nfs4_op_putfh(nfs, &op[0], fh); + i += nfs4_op_chown(nfs, &op[i], fh, data->filler.blob3.val, + data->filler.blob3.len); + + memset(&args, 0, sizeof(args)); + args.argarray.argarray_len = i; + args.argarray.argarray_val = op; + + if (rpc_nfs4_compound_task(nfs->rpc, nfs4_fsync_cb, &args, + data) == NULL) { + data->filler.blob0.val = NULL; + free_nfs4_cb_data(data); + return -1; + } + + return 0; +} + +static void +nfs4_access_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + ACCESS4resok *aresok; + int i; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs4_error(nfs, status, data, res, "ACCESS")) { + return; + } + + if ((i = nfs4_find_op(nfs, data, res, OP_ACCESS, "ACCESS")) < 0) { + return; + } + + aresok = &res->resarray.resarray_val[i].nfs_resop4_u.opaccess.ACCESS4res_u.resok4; + + /* access2 */ + if (data->filler.flags) { + int mode = 0; + + if (aresok->access & ACCESS4_READ) { + mode |= R_OK; + } + if (aresok->access & ACCESS4_MODIFY) { + mode |= W_OK; + } + if (aresok->access & ACCESS4_EXECUTE) { + mode |= X_OK; + } + data->cb(mode, nfs, NULL, data->private_data); + free_nfs4_cb_data(data); + return; + } + + if (aresok->supported != aresok->access) { + data->cb(-EACCES, nfs, NULL, data->private_data); + free_nfs4_cb_data(data); + return; + } + + data->cb(0, nfs, NULL, data->private_data); + free_nfs4_cb_data(data); +} + +static int +nfs4_access_internal(struct nfs_context *nfs, const char *path, int mode, + int is_access2, nfs_cb cb, void *private_data) +{ + struct nfs4_cb_data *data; + uint32_t m; + + data = init_cb_data_full_path(nfs, path); + if (data == NULL) { + return -1; + } + + data->cb = cb; + data->private_data = private_data; + data->filler.func = nfs4_populate_access; + data->filler.max_op = 1; + data->filler.flags = is_access2; + + data->filler.blob3.val = malloc(sizeof(uint32_t)); + if (data->filler.blob3.val == NULL) { + nfs_set_error(nfs, "Out of memory"); + return -1; + } + data->filler.blob3.free = free; + + m = 0; + if (mode & R_OK) { + m |= ACCESS4_READ; + } + if (mode & W_OK) { + m |= ACCESS4_MODIFY; + } + if (mode & X_OK) { + m |= ACCESS4_EXECUTE; + } + memcpy(data->filler.blob3.val, &m, sizeof(uint32_t)); + + if (nfs4_lookup_path_async(nfs, data, nfs4_access_cb) < 0) { + free_nfs4_cb_data(data); + return -1; + } + + return 0; +} + +int +nfs4_access_async(struct nfs_context *nfs, const char *path, int mode, + nfs_cb cb, void *private_data) +{ + return nfs4_access_internal(nfs, path, mode, 0, + cb, private_data); +} + +int +nfs4_access2_async(struct nfs_context *nfs, const char *path, nfs_cb cb, + void *private_data) +{ + return nfs4_access_internal(nfs, path, R_OK|W_OK|X_OK, 1, + cb, private_data); +} + +static void +nfs4_utimes_cb(struct rpc_context *rpc, int status, void *command_data, + void *private_data) +{ + struct nfs4_cb_data *data = private_data; + struct nfs_context *nfs = data->nfs; + COMPOUND4res *res = command_data; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (check_nfs4_error(nfs, status, data, res, "UTIMES")) { + return; + } + + data->cb(0, nfs, NULL, data->private_data); + free_nfs4_cb_data(data); +} + +static int +nfs4_populate_utimes(struct nfs4_cb_data *data, nfs_argop4 *op) +{ + return nfs4_op_utimes(data->nfs, op, NULL, data->filler.blob3.val, + data->filler.blob3.len); +} + +int +nfs4_utimes_async_internal(struct nfs_context *nfs, const char *path, + int no_follow, struct timeval *times, + nfs_cb cb, void *private_data) +{ + struct nfs4_cb_data *data; + char *buf; + uint32_t u32; + uint64_t u64; + + data = init_cb_data_full_path(nfs, path); + if (data == NULL) { + return -1; + } + + data->cb = cb; + data->private_data = private_data; + data->filler.func = nfs4_populate_utimes; + data->filler.max_op = 1; + + if (no_follow) { + data->flags |= LOOKUP_FLAG_NO_FOLLOW; + } + + data->filler.blob3.len = 2 * (4 + 8 + 4); + buf = data->filler.blob3.val = calloc(1, data->filler.blob3.len); + if (data->filler.blob3.val == NULL) { + nfs_set_error(nfs, "Out of memory"); + return -1; + } + data->filler.blob3.free = free; + + if (times != NULL) { + /* atime */ + u32 = htonl(SET_TO_CLIENT_TIME4); + memcpy(buf, &u32, sizeof(uint32_t)); + u64 = nfs_hton64(times[0].tv_sec); + memcpy(buf + 4, &u64, sizeof(uint64_t)); + u32 = htonl(times[0].tv_usec * 1000); + memcpy(buf + 12, &u32, sizeof(uint32_t)); + buf += 16; + /* mtime */ + u32 = htonl(SET_TO_CLIENT_TIME4); + memcpy(buf, &u32, sizeof(uint32_t)); + u64 = nfs_hton64(times[1].tv_sec); + memcpy(buf + 4, &u64, sizeof(uint64_t)); + u32 = htonl(times[1].tv_usec * 1000); + memcpy(buf + 12, &u32, sizeof(uint32_t)); + } else { + /* atime */ + u32 = htonl(SET_TO_SERVER_TIME4); + memcpy(buf, &u32, sizeof(uint32_t)); + /* mtime */ + u32 = htonl(SET_TO_SERVER_TIME4); + memcpy(buf + 4, &u32, sizeof(uint32_t)); + data->filler.blob3.len = 8; + } + + if (nfs4_lookup_path_async(nfs, data, nfs4_utimes_cb) < 0) { + free_nfs4_cb_data(data); + return -1; + } + + return 0; +} + +int +nfs4_utime_async(struct nfs_context *nfs, const char *path, + struct utimbuf *times, nfs_cb cb, void *private_data) +{ + if (times == NULL) { + return nfs4_utimes_async_internal(nfs, path, 0, NULL, + cb, private_data); + } + struct timeval new_times[2]; + + new_times[0].tv_sec = times->actime; + new_times[0].tv_usec = 0; + new_times[1].tv_sec = times->modtime; + new_times[1].tv_usec = 0; + + return nfs4_utimes_async_internal(nfs, path, 0, new_times, + cb, private_data); +} diff --git a/deps/libnfs/lib/pdu.c b/deps/libnfs/lib/pdu.c new file mode 100644 index 000000000000..12c3794e1bb4 --- /dev/null +++ b/deps/libnfs/lib/pdu.c @@ -0,0 +1,1335 @@ +/* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */ +/* + 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 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef AROS +#include "aros_compat.h" +#endif + +#ifdef PS2_EE +#include "ps2_compat.h" +#endif + +#ifdef PS3_PPU +#include "ps3_compat.h" +#endif + +#ifdef WIN32 +#include +#endif + +#ifdef HAVE_NETINET_IN_H +#include +#endif + +#ifdef HAVE_SYS_SOCKET_H +#include +#endif + +#if defined(HAVE_SYS_UIO_H) || (defined(__APPLE__) && defined(__MACH__)) +#include +#endif + +#ifdef HAVE_STRINGS_H +#include +#endif + +#include +#include +#include +#include +#include +#include "slist.h" +#include "libnfs-zdr.h" +#include "libnfs.h" +#include "libnfs-raw.h" +#include "libnfs-private.h" + +#ifdef HAVE_LIBKRB5 +#include "krb5-wrapper.h" +#endif + +void rpc_reset_queue(struct rpc_queue *q) +{ + q->head = NULL; + q->tail = NULL; +} + +/* + * Push to the tail end of the queue + */ +void rpc_enqueue(struct rpc_queue *q, struct rpc_pdu *pdu) +{ + if (q->head == NULL) { + assert(q->tail == NULL); + q->head = pdu; + } else { + assert(pdu != q->head); + assert(pdu != q->tail); + q->tail->next = pdu; + } + q->tail = pdu; + pdu->next = NULL; +} + +/* + * Return pdu to outqueue to be retransmitted. + * If there are more than one PDUs already in outqueue, this adds it right + * after the head, not at the head. The idea is that the PDU at the head + * may be half-sent, so it's not safe to replace the head. Also since we + * usually want this pdu to be sent immediately we don't want to add it to + * the end. + * Even when it's safe to add to head (from rpc_reconnect_requeue()), it's ok + * to add after head. + */ +void rpc_return_to_outqueue(struct rpc_context *rpc, struct rpc_pdu *pdu) +{ + if (rpc->outqueue.head == NULL) { + rpc->outqueue.head = rpc->outqueue.tail = pdu; + pdu->next = NULL; + } else if (rpc->outqueue.head == rpc->outqueue.tail) { + rpc->outqueue.head->next = pdu; + rpc->outqueue.tail = pdu; + pdu->next = NULL; + } else { + pdu->next = rpc->outqueue.head->next; + rpc->outqueue.head->next = pdu; + } + + /* + * Only already transmitted PDUs are added back to outqueue, so sending + * it out will entail a retransmit. + */ + INC_STATS(rpc, num_retransmitted); + + /* + * Reset output and input cursors as we have to re-send the whole pdu + * again (and read back the response fresh into pdu->in). + */ + pdu->out.num_done = 0; + rpc_reset_cursor(rpc, &pdu->in); +} + +/* + * Remove pdu from q. + * If found it'll remove the pdu and update q->head and q->tail correctly. + * Returns 0 if remove_pdu not found in q else returns 1. + */ +int rpc_remove_pdu_from_queue(struct rpc_queue *q, struct rpc_pdu *remove_pdu) +{ + if (q->head != NULL) { + struct rpc_pdu *pdu = q->head; + + assert(q->tail != NULL); + + /* + * remove_pdu is the head pdu. + * Change the head to point to the next pdu. + * If tail is also pointing to remove_pdu, this means it's the + * only PDU and after removing that we will have an empty list. + */ + if (q->head == remove_pdu) { + q->head = remove_pdu->next; + if (q->tail == remove_pdu) { + assert(remove_pdu->next == NULL); + q->tail = NULL; + assert(q->head == NULL); + } else { + assert(q->head != NULL); + } + + remove_pdu->next = NULL; + return 1; + } + + /* + * remove_pdu is not the head pdu. + * Search for it and if found, remove it, and update tail if + * tail is pointing to remove_pdu. + */ + while (pdu->next && pdu->next != remove_pdu) { + pdu = pdu->next; + } + + if (pdu->next == NULL) { + /* remove_pdu not found in q */ + return 0; + } + + pdu->next = remove_pdu->next; + + if (q->tail == remove_pdu) { + q->tail = pdu; + } + + remove_pdu->next = NULL; + + return 1; + } else { + assert(q->tail == NULL); + /* not found */ + return 0; + } +} + +static int rpc_remove_pdu_from_queue_unlocked(struct rpc_context *rpc, + struct rpc_queue *q, + struct rpc_pdu *remove_pdu) +{ + int ret; + +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_lock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ + ret = rpc_remove_pdu_from_queue(q, remove_pdu); +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_unlock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ + return ret; +} + +unsigned int rpc_hash_xid(struct rpc_context *rpc, uint32_t xid) +{ + return (xid * 7919) % rpc->num_hashes; +} + +#define PAD_TO_8_BYTES(x) ((x + 0x07) & ~0x07) + +static struct rpc_pdu *rpc_allocate_reply_pdu(struct rpc_context *rpc, + struct rpc_msg *res, + size_t alloc_hint) +{ + struct rpc_pdu *pdu; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + pdu = malloc(sizeof(struct rpc_pdu) + ZDR_ENCODEBUF_MINSIZE + alloc_hint); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory: Failed to allocate pdu structure and encode buffer"); + return NULL; + } + memset(pdu, 0, sizeof(struct rpc_pdu)); + pdu->discard_after_sending = 1; + pdu->xid = 0; + pdu->cb = NULL; + pdu->private_data = NULL; + pdu->zdr_decode_fn = NULL; + pdu->zdr_decode_bufsize = 0; + + pdu->outdata.data = (char *)(pdu + 1); + + pdu->out.iov = pdu->out.fast_iov; + pdu->out.iov_capacity = RPC_FAST_VECTORS; + + /* Add an iovector for the record marker. Ignored for UDP */ + rpc_add_iovector(rpc, &pdu->out, pdu->outdata.data, 4, NULL); + + zdrmem_create(&pdu->zdr, &pdu->outdata.data[4], + ZDR_ENCODEBUF_MINSIZE + alloc_hint, ZDR_ENCODE); + + if (zdr_replymsg(rpc, &pdu->zdr, res) == 0) { + rpc_set_error(rpc, "zdr_replymsg failed with %s", + rpc_get_error(rpc)); + zdr_destroy(&pdu->zdr); + free(pdu); + return NULL; + } + + /* Add an iovector for the header */ + rpc_add_iovector(rpc, &pdu->out, &pdu->outdata.data[4], + zdr_getpos(&pdu->zdr), NULL); + + return pdu; +} + +struct rpc_pdu *rpc_allocate_pdu2(struct rpc_context *rpc, int program, int version, int procedure, rpc_cb cb, void *private_data, zdrproc_t zdr_decode_fn, int zdr_decode_bufsize, size_t alloc_hint, int iovcnt_hint) +{ + struct rpc_pdu *pdu; + int pdu_size; +#ifdef HAVE_LIBKRB5 + uint32_t val; +#endif + +#ifdef HAVE_TLS + /* + * Caller overloads procedure to convey they want to send AUTH_TLS instead of + * AUTH_NONE for the NULL RPC. + */ + const bool_t send_auth_tls = !!(procedure & 0x80000000U); + procedure = (procedure & 0x7FFFFFFFU); + + /* AUTH_TLS can only be sent for NFS NULL RPC */ + assert(!send_auth_tls || (program == NFS_PROGRAM && procedure == 0)); +#endif /* HAVE_TLS */ + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + /* Since we already know how much buffer we need for the decoding + * we can just piggyback in the same alloc as for the pdu. + */ + pdu_size = PAD_TO_8_BYTES(sizeof(struct rpc_pdu)); + pdu_size += PAD_TO_8_BYTES(zdr_decode_bufsize); + + pdu = malloc(pdu_size + ZDR_ENCODEBUF_MINSIZE + alloc_hint); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory: Failed to allocate pdu structure and encode buffer"); + return NULL; + } + memset(pdu, 0, pdu_size); +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_lock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ + pdu->xid = rpc->xid++; +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_unlock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ + pdu->cb = cb; + pdu->private_data = private_data; + pdu->zdr_decode_fn = zdr_decode_fn; + pdu->zdr_decode_bufsize = zdr_decode_bufsize; + + if (iovcnt_hint > RPC_FAST_VECTORS) { + pdu->out.iov = (struct rpc_iovec *) calloc(iovcnt_hint, sizeof(struct rpc_iovec)); + if (pdu->out.iov == NULL) { + rpc_set_error(rpc, "Out of memory: Failed to allocate out.iov"); + goto failed2; + } + pdu->out.iov_capacity = iovcnt_hint; + } else { + pdu->out.iov = pdu->out.fast_iov; + pdu->out.iov_capacity = RPC_FAST_VECTORS; + } + + /* + * Rest of the code depends on this, so assert it here. + * If the caller uses this pdu for issuing a zero-copy READ, + * pdu->in.base will be set to point to the dynamically allocated + * iovec array. + */ + assert(pdu->in.base == NULL); + + pdu->outdata.data = ((char *)pdu + pdu_size); + + /* Add an iovector for the record marker. Ignored for UDP */ + rpc_add_iovector(rpc, &pdu->out, pdu->outdata.data, 4, NULL); + + zdrmem_create(&pdu->zdr, &pdu->outdata.data[4], + ZDR_ENCODEBUF_MINSIZE + alloc_hint - 4, ZDR_ENCODE); + memset(&pdu->msg, 0, sizeof(struct rpc_msg)); + pdu->msg.xid = pdu->xid; + pdu->msg.direction = CALL; + pdu->msg.body.cbody.rpcvers = RPC_MSG_VERSION; + pdu->msg.body.cbody.prog = program; + pdu->msg.body.cbody.vers = version; + pdu->msg.body.cbody.proc = procedure; + + pdu->do_not_retry = (program != NFS_PROGRAM); + + /* For NULL RPC RFC recommends to use NULL authentication */ + if (procedure == 0) { + pdu->msg.body.cbody.cred.oa_flavor = AUTH_NONE; + pdu->msg.body.cbody.cred.oa_length = 0; + pdu->msg.body.cbody.cred.oa_base = NULL; + /* + * NULL RPC is like a ping which is sent right after connection + * establishment. The transport is still not used for sending + * other RPCs. It's best not to retry NULL RPC and let the caller + * truthfully know about the transport status. + */ + pdu->do_not_retry = TRUE; + } else { + pdu->msg.body.cbody.cred = rpc->auth->ah_cred; + } + + pdu->msg.body.cbody.verf = rpc->auth->ah_verf; + +#ifdef HAVE_TLS + /* Should not be already set */ + assert(pdu->expect_starttls == FALSE); + + if (send_auth_tls) { + pdu->msg.body.cbody.cred.oa_flavor = AUTH_TLS; + pdu->msg.body.cbody.cred.oa_length = 0; + pdu->msg.body.cbody.cred.oa_base = NULL; + + pdu->expect_starttls = TRUE; + } +#endif /* HAVE_TLS */ + +#ifdef HAVE_LIBKRB5 +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_lock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ + if (rpc->sec != RPC_SEC_UNDEFINED) { + ZDR tmpzdr; + int level = RPC_GSS_SVC_NONE; + + pdu->gss_seqno = rpc->gss_seqno; + + zdrmem_create(&tmpzdr, pdu->creds, 64, ZDR_ENCODE); + switch (rpc->sec) { + case RPC_SEC_UNDEFINED: + break; + case RPC_SEC_KRB5: + level = RPC_GSS_SVC_NONE; + break; + case RPC_SEC_KRB5I: + if (pdu->gss_seqno > 0) { + level = RPC_GSS_SVC_INTEGRITY; + } + break; + case RPC_SEC_KRB5P: + if (pdu->gss_seqno > 0) { + level = RPC_GSS_SVC_PRIVACY; + } + break; + } + if (libnfs_authgss_gen_creds(rpc, &tmpzdr, level) < 0) { + zdr_destroy(&tmpzdr); + rpc_set_error(rpc, "zdr_callmsg failed with %s", + rpc_get_error(rpc)); + goto failed; + } + pdu->msg.body.cbody.cred.oa_flavor = AUTH_GSS; + pdu->msg.body.cbody.cred.oa_length = tmpzdr.pos; + pdu->msg.body.cbody.cred.oa_base = pdu->creds; + zdr_destroy(&tmpzdr); + + rpc->gss_seqno++; + if (rpc->gss_seqno > 1) { + pdu->msg.body.cbody.verf.oa_flavor = AUTH_GSS; + pdu->msg.body.cbody.verf.gss_context = rpc->gss_context; + } + } +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_unlock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ +#endif /* HAVE_LIBKRB5 */ + + if (zdr_callmsg(rpc, &pdu->zdr, &pdu->msg) == 0) { + rpc_set_error(rpc, "zdr_callmsg failed with %s", + rpc_get_error(rpc)); + goto failed; + } + +#ifdef HAVE_LIBKRB5 + switch (rpc->sec) { + case RPC_SEC_UNDEFINED: + case RPC_SEC_KRB5: + break; + case RPC_SEC_KRB5P: + case RPC_SEC_KRB5I: + if (pdu->gss_seqno > 0) { + pdu->start_of_payload = zdr_getpos(&pdu->zdr); + val = 0; /* dummy length, will fill in below once we know */ + if (!libnfs_zdr_u_int(&pdu->zdr, &val)) { + goto failed; + } + val = pdu->gss_seqno; + if (!libnfs_zdr_u_int(&pdu->zdr, &val)) { + goto failed; + } + } + break; + } +#endif /* HAVE_LIBKRB5 */ + + /* Add an iovector for the header */ + rpc_add_iovector(rpc, &pdu->out, &pdu->outdata.data[4], + zdr_getpos(&pdu->zdr), NULL); + + return pdu; + failed: + rpc_set_error(rpc, "zdr_callmsg failed with %s", + rpc_get_error(rpc)); + zdr_destroy(&pdu->zdr); + failed2: + free(pdu); + return NULL; +} + +struct rpc_pdu *rpc_allocate_pdu(struct rpc_context *rpc, int program, int version, int procedure, rpc_cb cb, void *private_data, zdrproc_t zdr_decode_fn, int zdr_decode_bufsize) +{ + return rpc_allocate_pdu2(rpc, program, version, procedure, cb, private_data, zdr_decode_fn, zdr_decode_bufsize, 0, 0); +} + +void rpc_free_pdu(struct rpc_context *rpc, struct rpc_pdu *pdu) +{ +#ifdef HAVE_LIBKRB5 + uint32_t min; +#endif /* HAVE_LIBKRB5 */ + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (pdu->zdr_decode_buf != NULL) { + zdr_free(pdu->zdr_decode_fn, pdu->zdr_decode_buf); + } + +#ifdef HAVE_LIBKRB5 + gss_release_buffer(&min, &pdu->output_buffer); +#endif /* HAVE_LIBKRB5 */ + zdr_destroy(&pdu->zdr); + + rpc_free_iovector(rpc, &pdu->out); + rpc_free_cursor(rpc, &pdu->in); + free(pdu); +} + +void rpc_set_next_xid(struct rpc_context *rpc, uint32_t xid) +{ +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_lock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ + rpc->xid = xid; +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_unlock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ +} + +void pdu_set_timeout(struct rpc_context *rpc, struct rpc_pdu *pdu, uint64_t now_msecs) +{ + if (rpc->timeout <= 0) { + /* RPC request never times out */ + pdu->timeout = 0; + return; + } + + /* If user hasn't passed the current time, get it now */ + if (now_msecs == 0) { + now_msecs = rpc_current_time(); + } + + /* + * If pdu->timeout is 0 it means either this is the first time we are + * setting the timeout for this RPC request or it has already timed out. + * In both these cases we reset pdu->timeout to rpc->timeout from now. + * If pdu->timeout is not 0 it means that the RPC has not yet timed out + * and hence we leave it unchanged. + */ + if (pdu->timeout == 0) { + pdu->timeout = now_msecs + rpc->timeout; +#ifndef HAVE_CLOCK_GETTIME + /* If we do not have GETTIME we fallback to time() which + * has 1s granularity for its timestamps. + * We thus need to bump the timeout by 1000ms + * so that the PDU will timeout within 1.0 - 2.0 seconds. + * Otherwise setting a 1s timeout would trigger within + * 0.001 - 1.0s. + */ + pdu->timeout += 1000; +#endif + } + + /* + * On major timeout we reset both major_timeout and timeout. + * Note that timeout can be updated multiple times before a major + * timeout, depending on the value of rpc->retrans. + */ + if (pdu->major_timeout == 0) { + pdu->major_timeout = now_msecs + (rpc->timeout * rpc->retrans); + pdu->timeout = now_msecs + rpc->timeout; +#ifndef HAVE_CLOCK_GETTIME + pdu->major_timeout += 1000; + pdu->timeout += 1000; +#endif + /* Never less than pdu->timeout */ + if (pdu->major_timeout < pdu->timeout) { + pdu->major_timeout = pdu->timeout; + } + } +} + +int rpc_queue_pdu(struct rpc_context *rpc, struct rpc_pdu *pdu) +{ + int i, size = 0, pos; + uint32_t recordmarker; +#ifdef HAVE_LIBKRB5 + uint32_t maj, min, val, len; + gss_buffer_desc message_buffer, output_token; + char *buf; +#endif /* HAVE_LIBKRB5 */ + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + +#ifdef HAVE_LIBKRB5 + switch (rpc->sec) { + case RPC_SEC_UNDEFINED: + case RPC_SEC_KRB5: + break; + case RPC_SEC_KRB5I: + if (pdu->gss_seqno == 0) { + break; + } + pos = zdr_getpos(&pdu->zdr); + zdr_setpos(&pdu->zdr, pdu->start_of_payload); + val = pos - pdu->start_of_payload - 4; + if (!libnfs_zdr_u_int(&pdu->zdr, &val)) { + rpc_free_pdu(rpc, pdu); + return -1; + } + zdr_setpos(&pdu->zdr, pos); + + /* checksum */ + message_buffer.length = zdr_getpos(&pdu->zdr) - pdu->start_of_payload - 4; + message_buffer.value = zdr_getptr(&pdu->zdr) + pdu->start_of_payload + 4; + maj = gss_get_mic(&min, rpc->gss_context, + GSS_C_QOP_DEFAULT, + &message_buffer, + &output_token); + if (maj != GSS_S_COMPLETE) { + rpc_free_pdu(rpc, pdu); + return -1; + } + buf = output_token.value; + len = output_token.length; + if (!libnfs_zdr_bytes(&pdu->zdr, &buf, &len, len)) { + gss_release_buffer(&min, &output_token); + rpc_free_pdu(rpc, pdu); + return -1; + } + gss_release_buffer(&min, &output_token); + break; + case RPC_SEC_KRB5P: + if (pdu->gss_seqno == 0) { + break; + } + pos = zdr_getpos(&pdu->zdr); + message_buffer.length = zdr_getpos(&pdu->zdr) - pdu->start_of_payload - 4; + message_buffer.value = zdr_getptr(&pdu->zdr) + pdu->start_of_payload + 4; + maj = gss_wrap (&min, rpc->gss_context, 1, + GSS_C_QOP_DEFAULT, + &message_buffer, + NULL, + &output_token); + if (maj != GSS_S_COMPLETE) { + rpc_free_pdu(rpc, pdu); + return -1; + } + zdr_setpos(&pdu->zdr, pdu->start_of_payload); + buf = output_token.value; + len = output_token.length; + if (!libnfs_zdr_bytes(&pdu->zdr, &buf, &len, len)) { + gss_release_buffer(&min, &output_token); + rpc_free_pdu(rpc, pdu); + return -1; + } + gss_release_buffer(&min, &output_token); + break; + } +#endif /* HAVE_LIBKRB5 */ + + pos = zdr_getpos(&pdu->zdr); + + /* + * Now that the RPC is about to be queued, set absolute timeout values + * for it. + */ + pdu_set_timeout(rpc, pdu, 0); + + for (i = 1; i < pdu->out.niov; i++) { + size += pdu->out.iov[i].len; + } + pdu->out.total_size = size + 4; + + /* If we need to add any additional iovectors + * + * We expect to almost always add an iovector here for the remainder + * of the outdata marshalling buffer. + * The exception is WRITE where we add an explicit iovector instead + * of marshalling it in ZDR. This so that we can do zero-copy for + * the WRITE path. + */ + if (pos > size) { + int count = pos - size; + + if (rpc_add_iovector(rpc, &pdu->out, + &pdu->outdata.data[pdu->out.total_size], + count, NULL) < 0) { + rpc_free_pdu(rpc, pdu); + return -1; + } + pdu->out.total_size += count; + size = pos; + } + + /* write recordmarker */ + recordmarker = htonl(size | 0x80000000); + memcpy(pdu->out.iov[0].buf, &recordmarker, 4); + + pdu->pdu_stats.enqueue_timestamp = rpc_current_time_us(); + pdu->pdu_stats.size = size; + pdu->pdu_stats.xid = pdu->msg.xid; + pdu->pdu_stats.direction = CALL; + pdu->pdu_stats.status = 0; + pdu->pdu_stats.prog = pdu->msg.body.cbody.prog; + pdu->pdu_stats.vers = pdu->msg.body.cbody.vers; + pdu->pdu_stats.proc = pdu->msg.body.cbody.proc; + pdu->pdu_stats.response_time = 0; + + /* + * For udp we dont queue, we just send it straight away. + * + * Another case where we send straight away is the AUTH_TLS NULL RPC. + * This is particularly important for the reconnect case where we want to + * ensure TLS handshake completes successfully before we can send any of + * the queued RPCs waiting. If we do not send here this AUTH_TLS NULL + * RPC will need to be queued before all other waiting RPCs and even then + * we need to be careful that we don't send any of those RPCs till the + * TLS handshake is completed and the connection is secure. + * Sending inline here makes the handling simpler in rpc_service(). + */ + if (rpc->is_udp && rpc->is_server_context) { + if (sendto(rpc->fd, pdu->zdr.buf, size, MSG_DONTWAIT, + (struct sockaddr *)&rpc->udp_dest, + sizeof(rpc->udp_dest)) < 0) { + rpc_set_error(rpc, "Sendto failed with errno %s", strerror(errno)); + rpc_free_pdu(rpc, pdu); + return -1; + } + rpc_free_pdu(rpc, pdu); + return 0; + } + + if (rpc->is_udp != 0 +#ifdef HAVE_TLS + || pdu->expect_starttls +#endif + ) { + unsigned int hash; + +#ifdef HAVE_TLS + if (pdu->expect_starttls) { + /* Currently we don't support RPC-with-TLS over UDP */ + assert(!rpc->is_udp); + assert(!rpc->is_broadcast); + + RPC_LOG(rpc, 2, "Sending AUTH_TLS NULL RPC (%u bytes)", + (int)pdu->out.total_size); + } +#endif + + hash = rpc_hash_xid(rpc, pdu->xid); + +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_lock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ + rpc_enqueue(&rpc->waitpdu[hash], pdu); + rpc->waitpdu_len++; +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_unlock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ + + if (rpc->is_broadcast || rpc->is_server_context) { + if (sendto(rpc->fd, pdu->zdr.buf, size, MSG_DONTWAIT, + (struct sockaddr *)&rpc->udp_dest, + sizeof(rpc->udp_dest)) < 0) { + rpc_set_error(rpc, "Sendto failed with errno %s", strerror(errno)); + rpc_remove_pdu_from_queue_unlocked(rpc, &rpc->waitpdu[hash], pdu); + rpc_free_pdu(rpc, pdu); + return -1; + } + if (rpc->is_server_context) { + rpc_remove_pdu_from_queue_unlocked(rpc, &rpc->waitpdu[hash], pdu); + rpc_free_pdu(rpc, pdu); + return 0; + } + } else { + /* + * For UDP we don't support vectored write and for TLS + * the data will be less, so RPC_FAST_VECTORS should + * be sufficient for both cases. + */ + struct iovec iov[RPC_FAST_VECTORS]; + int niov = pdu->out.niov; + /* No record marker for UDP */ + struct iovec *iovp = (rpc->is_udp ? &iov[1] : &iov[0]); + const int iovn = (rpc->is_udp ? niov - 1 : niov); + + assert(niov <= RPC_FAST_VECTORS); + + for (i = 0; i < niov; i++) { + iov[i].iov_base = pdu->out.iov[i].buf; + iov[i].iov_len = pdu->out.iov[i].len; + } + if (writev(rpc->fd, iovp, iovn) < 0) { + rpc_set_error(rpc, "Sendto failed with errno %s", strerror(errno)); + rpc_remove_pdu_from_queue_unlocked(rpc, &rpc->waitpdu[hash], pdu); + rpc_free_pdu(rpc, pdu); + return -1; + } + } + + return 0; + } + + pdu->outdata.size = size; +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_lock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ + /* Fresh PDU being queued to outqueue, num_done must be 0 */ + assert(pdu->out.num_done == 0); + rpc_enqueue(&rpc->outqueue, pdu); +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_unlock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ + if (rpc->outqueue.head == pdu) { + rpc_write_to_socket(rpc); + } + + return 0; +} + +static int rpc_process_reply(struct rpc_context *rpc, ZDR *zdr) +{ + struct rpc_msg msg; + struct rpc_pdu *pdu = rpc->pdu; + uint32_t status = 0xffffffff; + void *data = NULL; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + /* Client got a response for its request */ + INC_STATS(rpc, num_resp_rcvd); + + memset(&msg, 0, sizeof(struct rpc_msg)); + msg.body.rbody.reply.areply.verf = _null_auth; + if (pdu->zdr_decode_bufsize > 0) { + pdu->zdr_decode_buf = (char *)pdu + PAD_TO_8_BYTES(sizeof(struct rpc_pdu)); + } + msg.body.rbody.reply.areply.reply_data.results.where = pdu->zdr_decode_buf; + msg.body.rbody.reply.areply.reply_data.results.proc = pdu->zdr_decode_fn; +#ifdef HAVE_LIBKRB5 + if (rpc->sec == RPC_SEC_KRB5I && pdu->gss_seqno > 0) { + msg.body.rbody.reply.areply.reply_data.results.krb5i = 1; + } + if (rpc->sec == RPC_SEC_KRB5P && pdu->gss_seqno > 0) { + msg.body.rbody.reply.areply.reply_data.results.krb5p = 1; + msg.body.rbody.reply.areply.reply_data.results.output_buffer = &pdu->output_buffer; + msg.body.rbody.reply.areply.verf.gss_context = rpc->gss_context; + } +#endif + if (zdr_replymsg(rpc, zdr, &msg) == 0) { + rpc_set_error(rpc, "zdr_replymsg failed in rpc_process_reply: " + "%s", rpc_get_error(rpc)); + pdu->cb(rpc, RPC_STATUS_ERROR, "Message rejected by server", + pdu->private_data); + if (pdu->zdr_decode_buf != NULL) { + pdu->zdr_decode_buf = NULL; + } + return 0; + } + if (msg.body.rbody.stat != MSG_ACCEPTED) { + pdu->cb(rpc, RPC_STATUS_ERROR, "RPC Packet not accepted by the server", pdu->private_data); + return 0; + } + switch (msg.body.rbody.reply.areply.stat) { + case SUCCESS: + /* Last RPC response time for tracking RPC transport health */ + rpc->last_successful_rpc_response = rpc_current_time(); + if (pdu->snr_logged) { + RPC_LOG(rpc, 1, "[pdu %p] Server %s OK", + pdu, rpc->server); + } + + /* + * pdu->in.base will be non-NULL if this pdu is used for + * zero-copy READ. In that case we still need to read the + * data from the socket into the user's zero-copy buffers, + * so don't complete it as yet. Caller will arrange to read + * the data and complete the PDU once completed. + */ +#ifdef HAVE_LIBKRB5 + if (rpc->sec != RPC_SEC_KRB5P) +#endif /* HAVE_LIBKRB5 */ + if (pdu->in.base) { + rpc->pdu->free_pdu = 1; + break; + } + +#ifdef HAVE_TLS + /* + * If we are expecting STARTTLS that means we have sent AUTH_TLS + * NULL RPC which means user has selected xprtsec=[tls,mtls], in + * which case the server MUST support TLS else we must terminate + * the RPC session. + */ + if (pdu->expect_starttls) { + const char *const starttls_str = "STARTTLS"; + const int starttls_len = 8; + + if (msg.body.rbody.reply.areply.verf.oa_flavor != AUTH_NONE) { + RPC_LOG(rpc, 1, "Server sent bad verifier flavor (%d) in response " + "to AUTH_TLS NULL RPC", + msg.body.rbody.reply.areply.verf.oa_flavor); + status = RPC_STATUS_ERROR; + data = "Server sent bad verifier flavor"; + break; + } else if (msg.body.rbody.reply.areply.verf.oa_length != starttls_len || + memcmp(msg.body.rbody.reply.areply.verf.oa_base, + starttls_str, starttls_len)) { + RPC_LOG(rpc, 1, "Server does not support TLS"); + status = RPC_STATUS_ERROR; + data = "Server does not support TLS"; + break; + } + } +#endif /* HAVE_TLS */ + +#ifdef HAVE_LIBKRB5 + if (msg.body.rbody.reply.areply.verf.oa_flavor == AUTH_GSS) { + uint32_t maj, min; + gss_buffer_desc message_buffer, token_buffer; + uint32_t seqno; + + /* This is the the gss token from the NULL reply + * that finished authentication. + */ + if (pdu->gss_seqno == 0) { + struct rpc_gss_init_res *gir = (struct rpc_gss_init_res *)(void *)pdu->zdr_decode_buf; + + rpc->context_len = gir->handle.handle_len; + free(rpc->context); + rpc->context = malloc(rpc->context_len); + if (rpc->context == NULL) { + status = RPC_STATUS_ERROR; + data = "Failed to allocate rpc->context"; + break; + } + memcpy(rpc->context, gir->handle.handle_val, rpc->context_len); + + if (krb5_auth_request(rpc, rpc->auth_data, + (unsigned char *)gir->gss_token.gss_token_val, + gir->gss_token.gss_token_len) < 0) { + status = RPC_STATUS_ERROR; + + data = "krb5_auth_request returned error"; + break; + } + } + + if (pdu->gss_seqno > 0) { + seqno = htonl(pdu->gss_seqno); + message_buffer.value = (char *)&seqno; + message_buffer.length = 4; + + token_buffer.value = msg.body.rbody.reply.areply.verf.oa_base; + token_buffer.length = msg.body.rbody.reply.areply.verf.oa_length; + maj = gss_verify_mic(&min, + rpc->gss_context, + &message_buffer, + &token_buffer, + GSS_C_QOP_DEFAULT); + if (maj) { + status = RPC_STATUS_ERROR; + data = "gss_verify_mic failed for the verifier"; + break; + } + } + } + if (pdu->zero_copy_iov && rpc->sec == RPC_SEC_KRB5P) { + struct iovec *iov; + int num_iov, num, count; + + if (!zdr_uint32_t(&pdu->zdr, &pdu->read_count)) { + status = RPC_STATUS_ERROR; + data = "rpc_process_reply: failed to read onc-rpc array length"; + break; + } + count = pdu->read_count; + if (count > libnfs_zdr_getsize(&pdu->zdr) - libnfs_zdr_getpos(&pdu->zdr)) { + count = libnfs_zdr_getsize(&pdu->zdr) - libnfs_zdr_getpos(&pdu->zdr); + } + iov = pdu->in.iov; + num_iov = pdu->in.iovcnt; + while(count && num_iov) { + num = count; + if (num > iov->iov_len) { + num = iov->iov_len; + } + memcpy(iov->iov_base, libnfs_zdr_getptr(&pdu->zdr) + libnfs_zdr_getpos(&pdu->zdr), num); + libnfs_zdr_setpos(&pdu->zdr, libnfs_zdr_getpos(&pdu->zdr) + num); + count -= num; + iov++; + num_iov--; + } + } +#endif /* HAVE_LIBKRB5 */ + + status = RPC_STATUS_SUCCESS; + data = pdu->zdr_decode_buf; + break; + case PROG_UNAVAIL: + status = RPC_STATUS_ERROR; + data = "Server responded: Program not available"; + break; + case PROG_MISMATCH: + status = RPC_STATUS_ERROR; + data = "Server responded: Program version mismatch"; + break; + case PROC_UNAVAIL: + status = RPC_STATUS_ERROR; + data = "Server responded: Procedure not available"; + break; + case GARBAGE_ARGS: + status = RPC_STATUS_ERROR; + data = "Server responded: Garbage arguments"; + break; + case SYSTEM_ERR: + status = RPC_STATUS_ERROR; + data = "Server responded: System Error"; + break; + default: + status = RPC_STATUS_ERROR; + data = "Unknown rpc response from server"; + break; + } + + pdu->pdu_stats.size = rpc->rm_xid[0]; + pdu->pdu_stats.direction = REPLY; + pdu->pdu_stats.status = msg.body.rbody.stat; + pdu->pdu_stats.response_time = rpc_current_time_us() - pdu->pdu_stats.send_timestamp; + if (rpc->stats_cb) { + rpc->stats_cb(rpc, &pdu->pdu_stats, rpc->stats_private_data); + } + + if (status != 0xffffffff) { + pdu->cb(rpc, status, data, pdu->private_data); + } + return 0; +} + +struct _rpc_msg { + struct rpc_msg call; + struct sockaddr_storage udp_src; +}; + +struct rpc_msg *rpc_copy_deferred_call(struct rpc_context *rpc, + struct rpc_msg *call) +{ + struct _rpc_msg *c; + + c = malloc(sizeof(struct _rpc_msg)); + if (c == NULL) { + return NULL; + } + memcpy(c, call, sizeof(struct _rpc_msg)); + + return &c->call; +} + +void rpc_free_deferred_call(struct rpc_context *rpc, + struct rpc_msg *call) +{ + free(call); +} + +static int rpc_send_error_reply(struct rpc_context *rpc, + struct rpc_msg *call, + enum accept_stat err, + int min_vers, int max_vers) +{ + struct rpc_pdu *pdu; + struct _rpc_msg *c = (struct _rpc_msg *)call; + struct rpc_msg res; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + memset(&res, 0, sizeof(struct rpc_msg)); + res.xid = call->xid; + res.direction = REPLY; + res.body.rbody.stat = MSG_ACCEPTED; + res.body.rbody.reply.areply.reply_data.mismatch_info.low = min_vers; + res.body.rbody.reply.areply.reply_data.mismatch_info.high = max_vers; + res.body.rbody.reply.areply.verf = _null_auth; + res.body.rbody.reply.areply.stat = err; + + if (rpc->is_udp) { + /* send the reply back to the client */ + memcpy(&rpc->udp_dest, &c->udp_src, sizeof(rpc->udp_dest)); + } + + pdu = rpc_allocate_reply_pdu(rpc, &res, 0); + if (pdu == NULL) { + rpc_set_error(rpc, "Failed to send error_reply: %s", + rpc_get_error(rpc)); + return -1; + } + return rpc_queue_pdu(rpc, pdu); +} + +int rpc_send_reply(struct rpc_context *rpc, + struct rpc_msg *call, + void *reply, + zdrproc_t encode_fn, + int alloc_hint) +{ + struct rpc_pdu *pdu; + struct _rpc_msg *c = (struct _rpc_msg *)call; + struct rpc_msg res; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + memset(&res, 0, sizeof(struct rpc_msg)); + res.xid = call->xid; + res.direction = REPLY; + res.body.rbody.stat = MSG_ACCEPTED; + res.body.rbody.reply.areply.verf = _null_auth; + res.body.rbody.reply.areply.stat = SUCCESS; + + res.body.rbody.reply.areply.reply_data.results.where = reply; + res.body.rbody.reply.areply.reply_data.results.proc = encode_fn; + + if (rpc->is_udp) { + /* send the reply back to the client */ + memcpy(&rpc->udp_dest, &c->udp_src, sizeof(rpc->udp_dest)); + } + + pdu = rpc_allocate_reply_pdu(rpc, &res, alloc_hint); + if (pdu == NULL) { + rpc_set_error(rpc, "Failed to send error_reply: %s", + rpc_get_error(rpc)); + return -1; + } + + return rpc_queue_pdu(rpc, pdu); +} + +static int rpc_process_call(struct rpc_context *rpc, ZDR *zdr) +{ + struct _rpc_msg c; + struct rpc_endpoint *endpoint; + int i, min_version = 0, max_version = 0, found_program = 0; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + memset(&c.call, 0, sizeof(struct rpc_msg)); + if (rpc->is_udp) { + memcpy(&c.udp_src, &rpc->udp_src, sizeof(rpc->udp_src)); + } + if (zdr_callmsg(rpc, zdr, &c.call) == 0) { + rpc_set_error(rpc, "Failed to decode CALL message. %s", + rpc_get_error(rpc)); + return rpc_send_error_reply(rpc, &c.call, GARBAGE_ARGS, 0, 0); + } + for (endpoint = rpc->endpoints; endpoint; endpoint = endpoint->next) { + if (c.call.body.cbody.prog == endpoint->program) { + if (!found_program) { + min_version = max_version = endpoint->version; + } + if (endpoint->version < min_version) { + min_version = endpoint->version; + } + if (endpoint->version > max_version) { + max_version = endpoint->version; + } + found_program = 1; + if (c.call.body.cbody.vers == endpoint->version) { + break; + } + } + } + if (endpoint == NULL) { + rpc_set_error(rpc, "No endpoint found for CALL " + "program:0x%08x version:%d\n", + (int)c.call.body.cbody.prog, + (int)c.call.body.cbody.vers); + if (!found_program) { + return rpc_send_error_reply(rpc, &c.call, PROG_UNAVAIL, + 0, 0); + } + return rpc_send_error_reply(rpc, &c.call, PROG_MISMATCH, + min_version, max_version); + } + for (i = 0; i < endpoint->num_procs; i++) { + if (endpoint->procs[i].proc == c.call.body.cbody.proc) { + if (endpoint->procs[i].decode_buf_size) { + c.call.body.cbody.args = zdr_malloc(zdr, endpoint->procs[i].decode_buf_size); + memset(c.call.body.cbody.args, 0, endpoint->procs[i].decode_buf_size); + } + if (!endpoint->procs[i].decode_fn(zdr, c.call.body.cbody.args)) { + rpc_set_error(rpc, "Failed to unmarshall " + "call payload"); + return rpc_send_error_reply(rpc, &c.call, GARBAGE_ARGS, 0 ,0); + } + return endpoint->procs[i].func(rpc, &c.call, endpoint->procs[i].opaque); + } + } + + return rpc_send_error_reply(rpc, &c.call, PROC_UNAVAIL, 0 ,0); +} + +struct rpc_pdu *rpc_find_pdu(struct rpc_context *rpc, uint32_t xid) +{ + struct rpc_pdu *pdu, *prev_pdu; + struct rpc_queue *q; + unsigned int hash; + +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_lock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ + + /* First check outqueue */ + q = &rpc->outqueue; + prev_pdu = NULL; + for (pdu=q->head; pdu; pdu=pdu->next) { + if (pdu->xid != xid) { + prev_pdu = pdu; + continue; + } + if (rpc->is_udp == 0 || rpc->is_broadcast == 0) { + /* Singly-linked but we track head and tail */ + if (pdu == q->head) + q->head = pdu->next; + if (pdu == q->tail) + q->tail = prev_pdu; + if (prev_pdu != NULL) + prev_pdu->next = pdu->next; + } + break; + } + if (pdu) { + goto finished; + } + + /* Look up the transaction in a hash table of our requests */ + hash = rpc_hash_xid(rpc, rpc->rm_xid[1]); + q = &rpc->waitpdu[hash]; + + /* Follow the hash chain. Linear traverse singly-linked list, + * but track previous entry for optimised removal */ + prev_pdu = NULL; + for (pdu=q->head; pdu; pdu=pdu->next) { + if (pdu->xid != xid) { + prev_pdu = pdu; + continue; + } + if (rpc->is_udp == 0 || rpc->is_broadcast == 0) { + /* Singly-linked but we track head and tail */ + if (pdu == q->head) + q->head = pdu->next; + if (pdu == q->tail) + q->tail = prev_pdu; + if (prev_pdu != NULL) + prev_pdu->next = pdu->next; + rpc->waitpdu_len--; + } + break; + } + + finished: + if (pdu) { + pdu->next = NULL; + } + +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_unlock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ + + return pdu; +} + +int rpc_cancel_pdu(struct rpc_context *rpc, struct rpc_pdu *pdu) +{ + /* + * Use rpc_find_pdu() to locate it and remove it from the input list. + */ + pdu = rpc_find_pdu(rpc, pdu->xid); + if (pdu) { + rpc_free_pdu(rpc, pdu); + return 0; + } + + return -ENOENT; +} + +int rpc_process_pdu(struct rpc_context *rpc, char *buf, int size) +{ + ZDR zdr; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + memset(&zdr, 0, sizeof(ZDR)); + + zdrmem_create(&zdr, buf, size, ZDR_DECODE); + if (rpc->is_server_context) { + int ret; + + ret = rpc_process_call(rpc, &zdr); + zdr_destroy(&zdr); + + return ret; + } + +#ifdef HAVE_LIBKRB5 + /* + * For KRB5P and iovectors, i.e. NFS[34]READ we + * need to use a ZDR that hangs off the PDU so we can + * access the ZDR and its buffers to manually copy + * data into the iovectors. + */ + if (rpc->pdu->zero_copy_iov && rpc->sec == RPC_SEC_KRB5P) { + zdr_destroy(&rpc->pdu->zdr); + zdrmem_create(&rpc->pdu->zdr, buf, size, ZDR_DECODE); + if (rpc_process_reply(rpc, &rpc->pdu->zdr) != 0) { + rpc_set_error(rpc, "rpc_procdess_reply failed (for krb5 read)"); + } + } else +#endif /* HAVE_LIBKRB5 */ + if (rpc_process_reply(rpc, &zdr) != 0) { + rpc_set_error(rpc, "rpc_procdess_reply failed"); + } + + if (rpc->fragments == NULL && rpc->pdu && rpc->pdu->in.base) { + memcpy(&rpc->pdu->zdr, &zdr, sizeof(zdr)); + rpc->pdu->free_zdr = 1; + } else { + zdr_destroy(&zdr); + } + return 0; +} + diff --git a/deps/libnfs/lib/socket.c b/deps/libnfs/lib/socket.c new file mode 100644 index 000000000000..417669d26172 --- /dev/null +++ b/deps/libnfs/lib/socket.c @@ -0,0 +1,2035 @@ +/* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */ +/* + 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 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef __linux__ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#endif + +#ifdef AROS +#include "aros_compat.h" +#endif + +#ifdef PS2_EE +#include "ps2_compat.h" +#endif + +#ifdef PS3_PPU +#include "ps3_compat.h" +#endif + +#ifdef WIN32 +#include +#endif + +#ifdef HAVE_ARPA_INET_H +#include +#endif + +#ifdef HAVE_POLL_H +#include +#endif + +#if defined(HAVE_SYS_UIO_H) || (defined(__APPLE__) && defined(__MACH__)) +#include +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_SYS_IOCTL_H +#include +#endif + +#ifdef HAVE_SYS_SOCKET_H +#include +#endif + +#ifdef HAVE_NETINET_IN_H +#include +#endif + +#ifdef HAVE_NETINET_TCP_H +#include +#endif + +#ifdef HAVE_NETDB_H +#include +#endif + +#ifdef HAVE_SYS_FILIO_H +#include +#endif + +#ifdef HAVE_SYS_SOCKIO_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include "libnfs-zdr.h" +#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 + +#ifndef MSG_NOSIGNAL +#if (defined(__APPLE__) && defined(__MACH__)) || defined(PS2_EE) +#define MSG_NOSIGNAL 0 +#endif +#endif + +static int +rpc_reconnect_requeue(struct rpc_context *rpc); + +static int +create_socket(int domain, int type, int protocol) +{ +#ifdef SOCK_CLOEXEC +#ifdef __linux__ + /* Linux-specific extension (since 2.6.27): set the + close-on-exec flag on all sockets to avoid leaking file + descriptors to child processes */ + int fd = socket(domain, type|SOCK_CLOEXEC, protocol); + if (fd >= 0 || errno != EINVAL) { + if (type == SOCK_DGRAM) { + int opt; + if (domain == AF_INET) { + opt = 1; + setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &opt, sizeof(opt)); + } else { + opt = 1; + setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, &opt, sizeof(opt)); + } + } + return fd; + } +#endif +#endif + + return socket(domain, type, protocol); +} + +static int +set_nonblocking(int fd) +{ + int v = 0; +#if defined(WIN32) + u_long nonblocking=1; + v = ioctl(fd, FIONBIO, &nonblocking); +#else + v = fcntl(fd, F_GETFL, 0); + v = fcntl(fd, F_SETFL, v | O_NONBLOCK); +#endif + return v; +} + +static void +set_nolinger(int fd) +{ +#if !defined(PS2_EE) + struct linger lng; + lng.l_onoff = 1; + lng.l_linger = 0; + setsockopt(fd, SOL_SOCKET, SO_LINGER, (char *)&lng, sizeof(lng)); +#endif +} + +static int +set_bind_device(int fd, char *ifname) +{ + int rc = 0; + +#ifdef HAVE_SO_BINDTODEVICE + if (*ifname) { + rc = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, ifname, + strlen(ifname)); + } + +#endif + return rc; +} + +#ifdef HAVE_NETINET_TCP_H +static int +set_tcp_sockopt(int sockfd, int optname, int value) +{ + int level; + + #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun) || (defined(__APPLE__) && defined(__MACH__)) + struct protoent *buf; + + if ((buf = getprotobyname("tcp")) != NULL) + level = buf->p_proto; + else + return -1; + #else + level = SOL_TCP; + #endif + + return setsockopt(sockfd, level, optname, (char *)&value, + sizeof(value)); +} + +static int +set_keepalive(struct rpc_context *rpc, int sockfd) +{ +#ifdef SO_KEEPALIVE + const int enable_keepalive = 1; + + if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, + &enable_keepalive, sizeof(enable_keepalive)) != 0) { + /* Keepalive is best-effort: sandboxed platforms (webOS, etc.) + * may deny these options. Do not abort the NFS connection. */ + RPC_LOG(rpc, 2, "setsockopt(SO_KEEPALIVE) failed: %s", strerror(errno)); + return 0; + } +#endif + + /* + * Following code uses Linux specific socket options to change keepalive + * settings for the socket. + * + * TODO: Add for non-Linux clients. + */ + +#if defined(TCP_KEEPIDLE) + { + /* First keepalive probe after 60 secs of inactivity */ + const int keepidle_secs = 60; + + if (set_tcp_sockopt(sockfd, TCP_KEEPIDLE, keepidle_secs) != 0) { + RPC_LOG(rpc, 2, "setsockopt(TCP_KEEPIDLE) failed: %s", strerror(errno)); + /* non-fatal */ + } + } +#endif + +#if defined(TCP_KEEPINTVL) + { + /* Send keepalive probe every 60 secs */ + const int keepinterval_secs = 60; + + if (set_tcp_sockopt(sockfd, TCP_KEEPINTVL, keepinterval_secs) != 0) { + RPC_LOG(rpc, 2, "setsockopt(TCP_KEEPINTVL) failed: %s", strerror(errno)); + /* non-fatal */ + } + } +#endif + +#if defined(TCP_KEEPCNT) + { + /* Terminate connection after 3 failed keepalives */ + const int keepcnt = 3; + + if (set_tcp_sockopt(sockfd, TCP_KEEPCNT, keepcnt) != 0) { + RPC_LOG(rpc, 2, "setsockopt(TCP_KEEPCNT) failed: %s", strerror(errno)); + /* non-fatal */ + } + } +#endif + + return 0; +} +#endif /* HAVE_NETINET_TCP_H */ + +int +rpc_get_fd(struct rpc_context *rpc) +{ + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (rpc->old_fd) { + return rpc->old_fd; + } + + return rpc->fd; +} + +static int +rpc_has_queue(struct rpc_queue *q) +{ + return q->head != NULL; +} + +int +rpc_which_events(struct rpc_context *rpc) +{ + int events; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + events = rpc->is_connected ? POLLIN : POLLOUT; + + if (rpc->is_udp != 0) { + /* for udp sockets we only wait for pollin */ + return POLLIN; + } + +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_lock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ + if (rpc_has_queue(&rpc->outqueue)) { + events |= POLLOUT; + } +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_unlock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ + return events; +} + +void +rpc_disable_socket(struct rpc_context *rpc, int val) +{ + rpc->socket_disabled = val; +} + +int +rpc_write_to_socket(struct rpc_context *rpc) +{ + struct rpc_pdu *pdu; + struct iovec fast_iov[RPC_FAST_VECTORS]; + struct iovec *iov = fast_iov; + int iovcnt = RPC_FAST_VECTORS; + int ret = 0; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + if (rpc->socket_disabled) { + return 0; + } + if (rpc->fd == -1) { + rpc_set_error(rpc, "trying to write but not connected"); + return -1; + } + +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_lock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ + + /* Write several pdus at once */ + while ((rpc->max_waitpdu_len == 0 || + rpc->max_waitpdu_len > rpc->waitpdu_len) && + (pdu = rpc->outqueue.head) != NULL) { + int niov = 0; + uint32_t num_pdus = 0; + char *last_buf = NULL; + ssize_t count; + + assert(pdu->out.niov <= pdu->out.iov_capacity); + assert(pdu->out.iov_capacity <= RPC_MAX_VECTORS); + + if (pdu->out.niov > iovcnt && iovcnt != RPC_MAX_VECTORS) { + assert(iov == fast_iov); + iov = (struct iovec *) calloc(RPC_MAX_VECTORS, + sizeof(struct iovec)); + /* + * If allocation fails, continue with smaller iov. + * It'll require more writev() calls to send out one + * pdu, but it'll work. + */ + if (iov != NULL) { + iovcnt = RPC_MAX_VECTORS; + } else { + iov = fast_iov; + iovcnt = RPC_FAST_VECTORS; + } + } + + do { + size_t num_done = pdu->out.num_done; + int pdu_niov = pdu->out.niov; + int i; + + /* Fully sent PDU should not be sitting in outqueue */ + assert(num_done < pdu->out.total_size); + + for (i = 0; i < pdu_niov; i++) { + char *buf = pdu->out.iov[i].buf; + size_t len = pdu->out.iov[i].len; + if (num_done >= len) { + num_done -= len; + continue; + } + buf += num_done; + len -= num_done; + num_done = 0; + + /* Concatenate continous blocks */ + if (last_buf != buf) { + iov[niov].iov_base = buf; + iov[niov].iov_len = len; + niov++; + if (niov >= iovcnt) + break; + last_buf = (buf + len); + } else { + iov[niov - 1].iov_len += len; + last_buf += len; + } + } + + num_pdus++; + pdu = pdu->next; + } while ((rpc->max_waitpdu_len == 0 || + rpc->max_waitpdu_len > (rpc->waitpdu_len + num_pdus)) && + pdu != NULL && niov < iovcnt); + + /* + * We must never be doing 0-byte writes as those can get into + * infinite loop. + */ + assert(niov > 0); + + count = writev(rpc->fd, iov, niov); + if (count == -1) { + if (errno == EAGAIN || errno == EWOULDBLOCK) { + ret = 0; + goto finished; + + } + rpc_set_error_locked(rpc, "Error when writing to " + "socket :%d %s", errno, + rpc_get_error(rpc)); + ret = -1; + goto finished; + } + + /* Check how many pdu we completed */ + while (count > 0 && (pdu = rpc->outqueue.head) != NULL) { + size_t remaining = (pdu->out.total_size - pdu->out.num_done); + if (remaining <= count) { + unsigned int hash; + + count -= remaining; + + pdu->out.num_done = pdu->out.total_size; + + rpc->outqueue.head = pdu->next; + if (rpc->outqueue.head == NULL) + rpc->outqueue.tail = NULL; + + /* RPC sent, original or retransmit */ + INC_STATS(rpc, num_req_sent); + + if (pdu->discard_after_sending) { + rpc_free_pdu(rpc, pdu); + ret = 0; + goto finished; + } + + hash = rpc_hash_xid(rpc, pdu->xid); + rpc_enqueue(&rpc->waitpdu[hash], pdu); + rpc->waitpdu_len++; + + pdu->pdu_stats.send_timestamp = rpc_current_time_us(); + if (rpc->stats_cb) { + rpc->stats_cb(rpc, &pdu->pdu_stats, rpc->stats_private_data); + } + } else { + pdu->out.num_done += count; + break; + } + } + } + + finished: +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_unlock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ + + /* Free iov if dynamically allocated */ + if (iov != fast_iov) { + assert(iovcnt > RPC_FAST_VECTORS); + free(iov); + } + + return ret; +} + +static int adjust_inbuf(struct rpc_context *rpc, uint32_t pdu_size) +{ + char *buf; + + if (rpc->inbuf_size < pdu_size) { + if (pdu_size > NFS_MAX_XFER_SIZE + 4096) { + rpc_set_error(rpc, "Incoming PDU exceeds limit of %d " + "bytes.", NFS_MAX_XFER_SIZE + 4096); + return -1; + } + buf = realloc(rpc->inbuf, pdu_size); + if (buf == NULL) { + rpc_set_error(rpc, "Failed to allocate buffer of %d " + "bytes for pdu, errno:%d. Closing " + "socket.", (int)pdu_size, errno); + return -1; + } + rpc->inbuf_size = pdu_size; + rpc->inbuf = buf; + } + return 0; +} + +static char *rpc_reassemble_pdu(struct rpc_context *rpc, uint32_t *pdu_size) +{ + struct rpc_fragment *fragment; + char *reasbuf = NULL, *ptr; + uint32_t size; + + size = rpc->inpos; + for (fragment = rpc->fragments; fragment; fragment = fragment->next) { + size += fragment->size; + if (size < fragment->size) { + rpc_set_error(rpc, "Fragments too large"); + rpc_free_all_fragments(rpc); + return NULL; + } + } + + reasbuf = malloc(size); + if (reasbuf == NULL) { + rpc_set_error(rpc, "Failed to reassemble PDU"); + rpc_free_all_fragments(rpc); + return NULL; + } + ptr = reasbuf; + for (fragment = rpc->fragments; fragment; fragment = fragment->next) { + memcpy(ptr, fragment->data, fragment->size); + ptr += fragment->size; + } + memcpy(ptr, rpc->inbuf, rpc->inpos); + + *pdu_size = size; + return reasbuf; +} + +static void rpc_finished_pdu(struct rpc_context *rpc) +{ + if (rpc->pdu && rpc->pdu->free_pdu) { + /* + * For zero-copy read, this is where we call the user callback. + */ + rpc->pdu->cb(rpc, RPC_STATUS_SUCCESS, rpc->pdu->zdr_decode_buf, rpc->pdu->private_data); + } + if (rpc->pdu && rpc->pdu->free_zdr) { + zdr_destroy(&rpc->pdu->zdr); + } + rpc->state = READ_RM; + rpc->inpos = 0; + if (rpc->pdu && (rpc->is_udp == 0 || rpc->is_broadcast == 0)) { + rpc_free_pdu(rpc, rpc->pdu); + rpc->pdu = NULL; + } +} + +/* + * ZeroCopyReadPreamble. The maximum amount of head data we read for a PDU + * assuming that all onc-rpc and protocol layer headers will fit inside this + * preamble and that all the remaining data will be READ3/4 payload. + */ +#define ZCRP 1024 + +#define MAX_UDP_SIZE 65536 +#define MAX_FRAGMENT_SIZE 8*1024*1024 +static int +rpc_read_from_socket(struct rpc_context *rpc) +{ + ssize_t count; + int pos; + uint32_t inbuf_size; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + if (rpc->socket_disabled) { + return 0; + } + if (rpc->is_udp) { + socklen_t socklen = sizeof(rpc->udp_src); + char *buf = NULL; + + buf = malloc(MAX_UDP_SIZE); + if (buf == NULL) { + rpc_set_error(rpc, "Failed to malloc buffer for " + "recvfrom"); + return -1; + } +#ifdef __linux__ + struct sockaddr_in *sin; + struct sockaddr_in6 *sin6; + char cmbuf[0x100]; + struct iovec iov = { buf, MAX_UDP_SIZE }; + struct msghdr mh = { + .msg_iov = &iov, + .msg_iovlen = 1, + .msg_name = &rpc->udp_src, + .msg_namelen = socklen, + .msg_control = cmbuf, + .msg_controllen = sizeof(cmbuf), + }; + count = recvmsg(rpc->fd, &mh, 0); + for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&mh); + cmsg != NULL; + cmsg = CMSG_NXTHDR(&mh, cmsg)) { + if (cmsg->cmsg_type != IP_PKTINFO) { + continue; + } + switch (cmsg->cmsg_level) { + case IPPROTO_IP: + sin = (struct sockaddr_in *)&rpc->udp_dst; + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = ((struct in_pktinfo *)CMSG_DATA(cmsg))->ipi_addr.s_addr; + break; + case IPPROTO_IPV6: + sin6 = (struct sockaddr_in6 *)&rpc->udp_dst; + sin6->sin6_family = AF_INET6; + memcpy(&sin6->sin6_addr.s6_addr[0], &((struct in6_pktinfo *)CMSG_DATA(cmsg))->ipi6_addr.s6_addr[0], 16); + break; + } + break; + } +#else /* __linux__ */ + count = recvfrom(rpc->fd, buf, MAX_UDP_SIZE, MSG_DONTWAIT, + (struct sockaddr *)&rpc->udp_src, &socklen); +#endif /* __linux__ */ + if (count == -1) { + free(buf); + if (errno == EINTR || errno == EAGAIN) { + return 0; + } + rpc_set_error(rpc, "Failed recvfrom: %s", + strerror(errno)); + return -1; + } + if (!rpc->is_server_context) { + rpc->rm_xid[0] = count; + rpc->rm_xid[1] = ntohl(*(uint32_t *)(void *)&buf[0]); + rpc->pdu = rpc_find_pdu(rpc, ntohl(*(uint32_t *)(void *)&buf[0])); + if (rpc->pdu == NULL) { + rpc_set_error(rpc, "Failed to match incoming PDU/XID." + " Ignoring PDU"); + free(buf); + return 0; + } + } + if (rpc_process_pdu(rpc, buf, count) != 0) { + rpc_set_error(rpc, "Invalid/garbage pdu received from " + "server. Ignoring PDU"); + free(buf); + return -1; + } + free(buf); + return 0; + } + + while (1){ + if (rpc->inpos == 0) { + switch (rpc->state) { + case READ_RM: + /* + * Read record marker, + * And if this is a cleint context read the next 4 bytes + * i.e. the XID on a client + */ + rpc->pdu_size = 8; + rpc->buf = (char *)&rpc->rm_xid[0]; + rpc->pdu = NULL; + break; + case READ_PAYLOAD: + /* we already read 4 bytes into the buffer */ + rpc->inpos = 4; + rpc->pdu_size = rpc->rm_xid[0]; + rpc->buf = rpc->inbuf + rpc->inpos; + + /* + * If it is a READ pdu, just read part of the data + * to the buffer and read the remainder directly into + * the application iovec. ZCRP is big enough to + * "guarantee" that we get the whole onc-rpc as well + * as the read3res header into the buffer. + * I don't want to have to deal with reading too + * little here and having to increase the limit and + * restart unmarshalling from scratch. + */ + /* We do not have rpc->pdu for server context */ +#ifdef HAVE_LIBKRB5 + /* + * KRB5P can not use zero-copy reads + */ + if (rpc->sec != RPC_SEC_KRB5P) +#endif /* HAVE_LIBKRB5 */ + if (rpc->pdu && rpc->pdu->in.base && rpc->pdu_size > ZCRP) { + rpc->pdu_size = ZCRP; + } + break; + case READ_UNKNOWN: + case READ_FRAGMENT: + /* we already read 4 bytes into the buffer */ + rpc->inpos = 4; + rpc->pdu_size = rpc->rm_xid[0]; + rpc->buf = rpc->inbuf + rpc->inpos; + assert(rpc->pdu_size <= rpc->inbuf_size); + break; + case READ_IOVEC: + /* + * Set rpc->buf to NULL to convey to the following + * code that data must be read into the vector buffer + * rpc->pdu->in.iov instead. + */ + rpc->buf = NULL; + rpc->pdu_size = rpc->pdu->read_count; + break; + case READ_PADDING: + /* rm_xid[0] is clamped to be the remaining + * amount of data after we have processed + * all payload and all iovecs + */ + rpc->pdu_size = rpc->rm_xid[0]; + rpc->buf = rpc->inbuf; + break; + } + } + + count = rpc->pdu_size - rpc->inpos; + /* + * When reading padding, clamp this so we do not overwrite + * rpc->inbuf/rpc->inbuf_size which we use as the garbage buffer + */ + if (rpc->state == READ_PADDING) { + rpc->buf = rpc->inbuf; + if (count > rpc->inbuf_size) { + count = rpc->inbuf_size; + } + } + + if (rpc->buf) { + count = recv(rpc->fd, rpc->buf, count, MSG_DONTWAIT); + } else { + assert(rpc->pdu->in.iovcnt > 0); + assert(count <= rpc->pdu->in.remaining_size); + count = readv(rpc->fd, rpc->pdu->in.iov, rpc->pdu->in.iovcnt); + } + + if (count < 0) { + /* + * No more data to read so we can break out of + * the loop and return. + */ + if (errno == EINTR || errno == EAGAIN) { + break; + } + rpc_set_error(rpc, "Read from socket(%d) failed, errno:%d (%s). " + "Closing socket.", rpc->fd, errno, strerror(errno)); + RPC_LOG(rpc, 2, "Read from socket(%d) failed, errno:%d (%s). " + "Closing socket.", rpc->fd, errno, strerror(errno)); + return -1; + } + if (count == 0) { + rpc_set_error(rpc, "Remote side closed connection for socket fd %d", + rpc->fd); + RPC_LOG(rpc, 2, "Remote side closed connection for socket fd %d", + rpc->fd); + /* remote side has closed the socket. Reconnect. */ + return -1; + } + rpc->inpos += count; + + if (rpc->buf) { + rpc->buf += count; + } else { + rpc_advance_cursor(rpc, &rpc->pdu->in, count); + } + + if (rpc->inpos == rpc->pdu_size) { + switch (rpc->state) { + case READ_RM: + /* We have just read the record marker */ + rpc->rm_xid[0] = ntohl(rpc->rm_xid[0]); + if (rpc->rm_xid[0] & 0x80000000) { + rpc->state = READ_PAYLOAD; + } else { + rpc_set_error(rpc, "Fragment support not yet working"); + rpc->state = READ_FRAGMENT; + return -1; + } + rpc->rm_xid[0] &= 0x7fffffff; + if (rpc->rm_xid[0] < 8 || rpc->rm_xid[0] > MAX_FRAGMENT_SIZE) { + rpc_set_error(rpc, "Invalid recordmarker size"); + return -1; + } + + /* + * When performing zero-copy read we read just ZCRP bytes + * into rpc->inbuf and read rest of the data directly into + * user provided buffers, so we just need to allocate + * inbuf large enough to hold ZCRP bytes of data, plus 4 + * bytes for the XID, i.e., ZCRP+4 bytes. + * RPC fragments are directly read into rpc->inbuf, no + * zero copy, so we need to allocate space equal to the + * fragment size. For non zero-copy reads also we need to + * allocate the entire PDU size. + */ + inbuf_size = rpc->rm_xid[0]; + + rpc->rm_xid[1] = ntohl(rpc->rm_xid[1]); + if (!rpc->is_server_context) { + rpc->pdu = rpc_find_pdu(rpc, rpc->rm_xid[1]); + +#ifdef HAVE_LIBKRB5 + if (rpc->sec != RPC_SEC_KRB5P) +#endif /* HAVE_LIBKRB5 */ + if (rpc->state != READ_FRAGMENT && rpc->pdu && rpc->pdu->in.base) { + inbuf_size = ZCRP; + } + } + + if (adjust_inbuf(rpc, inbuf_size) != 0) { + if (!rpc->is_server_context && rpc->pdu) { + #ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_lock(&rpc->rpc_mutex); + } + #endif /* HAVE_MULTITHREADING */ + + /* + * queue it back to outqueue for retransmit. + * Note that we don't need to queue it back to + * waitpdu[] queue as returning failure from + * here will force a reconnect, which will anyways + * re-queue everything from waitpdu[] to outqueue. + */ + rpc_return_to_outqueue(rpc, rpc->pdu); + rpc->pdu = NULL; + + #ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_unlock(&rpc->rpc_mutex); + } + #endif /* HAVE_MULTITHREADING */ + } + + rpc_set_error(rpc, "adjust_inbuf failed for socket fd %d", + rpc->fd); + RPC_LOG(rpc, 2, "adjust_inbuf failed for socket fd %d", + rpc->fd); + return -1; + } + + /* Copy the next 4 bytes into inbuf */ + *((uint32_t *)(void *)rpc->inbuf) = htonl(rpc->rm_xid[1]); + + /* but set inpos to 0, we will update it above + * that we have already read these 4 bytes in + * PAYLOAD and FRAGMENT + */ + rpc->inpos = 0; + + if (!rpc->is_server_context) { + /* Unknown xid, either unsolicited + * or an xid we have cancelled + */ + if (rpc->pdu == NULL) { + rpc->state = READ_UNKNOWN; + continue; + } + } + continue; + case READ_FRAGMENT: + if (rpc_add_fragment(rpc, rpc->inbuf, rpc->inpos) != 0) { + rpc_set_error(rpc, "Failed to queue fragment for reassembly."); + return -1; + } + rpc->state = READ_RM; + rpc->inpos = 0; + continue; + case READ_UNKNOWN: + rpc->state = READ_RM; + rpc->inpos = 0; + continue; + case READ_PAYLOAD: + if (rpc->fragments) { + rpc->buf = rpc_reassemble_pdu(rpc, &rpc->pdu_size); + if (rpc->buf == NULL) { + return -1; + } + } else { + rpc->buf = rpc->inbuf; + } + if (rpc_process_pdu(rpc, rpc->buf, rpc->pdu_size) != 0) { + rpc_set_error(rpc, "Invalid/garbage pdu" + " received from server. " + "Closing socket"); + return -1; + } +#ifdef HAVE_LIBKRB5 + /* + * Since we don't do zero-copy reads for + * KRB5P we are basically finished processing + * the reply at this point. + */ + if (rpc->sec == RPC_SEC_KRB5P) { + goto payload_finished; + } +#endif /* HAVE_LIBKRB5 */ + /* We do not have rpc->pdu for server context */ + if (rpc->pdu && rpc->pdu->free_zdr) { + if (rpc->program == NFS_PROGRAM && rpc->version == NFS_V3) { + /* + * If the READ failed, bail out here as there is no + * data. + */ + const READ3res *res = (READ3res *)(void *) rpc->pdu->zdr_decode_buf; + if (res->status != NFS3_OK) { + goto payload_finished; + } + } + + /* + * We are doing zero-copy read. + * pdu->read_count is the amount of read data returned by + * the server in this RPC response. + */ + if (!zdr_uint32_t(&rpc->pdu->zdr, &rpc->pdu->read_count)) + return -1; + + /* + * Now pos is pointing at the start of data, while rpc->inpos + * is the total bytes we have read for this RPC response, + * including the RPC header, so "rpc->inpos - pos" is the + * number of data bytes read. This will be less than ZCRP, + * since we clamped the read size to ZCRP above. + */ + pos = zdr_getpos(&rpc->pdu->zdr); + count = rpc->inpos - pos; + assert(count <= ZCRP); + /* + * No sane server will return more read data than we asked for. + * If the server is buggy and does send more, we discard the extra + * data. + */ + if (rpc->pdu->read_count > rpc->pdu->requested_read_count) { + rpc->pdu->read_count = rpc->pdu->requested_read_count; + } + + /* + * Clamp count to the actual data read, minus any padding. + */ + if (count > rpc->pdu->read_count) { + count = rpc->pdu->read_count; + } + if (rpc->pdu->in.remaining_size > rpc->pdu->read_count) { + /* we got a short read */ + rpc_shrink_cursor(rpc, &rpc->pdu->in, rpc->pdu->read_count); + assert(rpc->pdu->in.remaining_size == rpc->pdu->read_count); + } + + /* XXX With the above two clamps, can this still happen ? */ + if (rpc->pdu->in.remaining_size < count) { + count = rpc->pdu->in.remaining_size; + } + rpc_memcpy_cursor(rpc, &rpc->pdu->in, &rpc->inbuf[pos], count); + + if (rpc->pdu->in.remaining_size == 0) { + // handle padding? + } else { + rpc->pdu->read_count -= count; + rpc->state = READ_IOVEC; + rpc->inpos = 0; + rpc->rm_xid[0] -= pos + count; + continue; + } + } + payload_finished: + if (rpc->fragments) { + free(rpc->buf); + rpc->buf = NULL; + rpc_free_all_fragments(rpc); + } + rpc_finished_pdu(rpc); + break; + case READ_IOVEC: + rpc->pdu->read_count -= rpc->pdu_size; + if (rpc->rm_xid[0] < rpc->pdu_size) { + return -1; + } + rpc->rm_xid[0] -= rpc->pdu_size; + if (!rpc->rm_xid[0]) { + rpc_finished_pdu(rpc); + break; + } + rpc->state = READ_PADDING; + rpc->inpos = 0; + continue; + case READ_PADDING: + rpc_finished_pdu(rpc); + break; + } + } + } + + return 0; +} + +static void +maybe_call_connect_cb(struct rpc_context *rpc, int status) +{ + rpc_cb tmp_cb = rpc->connect_cb; + + if (rpc->connect_cb == NULL) { + return; + } + + rpc->connect_cb = NULL; + tmp_cb(rpc, status, rpc->error_string, rpc->connect_data); +} + +/* + * Return value of -1 indicates that the timeout scan discovered one or more + * RPCs with major timeout and caller MUST terminate the connection to try fix + * things. + */ +static int +rpc_timeout_scan(struct rpc_context *rpc) +{ + struct rpc_pdu *pdu; + struct rpc_pdu *next_pdu; + uint64_t t = rpc_current_time(); + unsigned int i; + /* Milliseconds since last successful RPC response on this transport */ + const int last_rpc_msecs = + ((rpc->last_successful_rpc_response == 0) ? -1 : + (t - rpc->last_successful_rpc_response)); + bool_t need_reconnect = FALSE; + + /* + * Only scan once per second. + */ + if (t <= rpc->last_timeout_scan + 1000) { + return 0; + } + rpc->last_timeout_scan = t; + +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_lock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ + + /* + * First check requests that have timed out while sitting in outqueue. + * These have not been sent to the server so do not indicate any issue + * with server or connection, hence we do not take any corrective + * action based on these request timeouts. + */ + for (pdu = rpc->outqueue.head; pdu; pdu = next_pdu) { + next_pdu = pdu->next; + + if (pdu->timeout == 0) { + /* no timeout for this pdu */ + continue; + } + if (t < pdu->timeout) { + /* not expired yet */ + continue; + } + + /* Timed out w/o being sent */ + INC_STATS(rpc, num_timedout_in_outqueue); + + /* + * rpc->retrans > 0 implies that user wants us to retransmit + * timed out RPCs. Note that we treat non-zero rpc->retrans + * as hard mount, so we just advance the timeout values for + * this RPC and leave it in the outqueue. + * Since these have not been sent to the server, they don't + * signify any issue with the server or the connection and + * hence major timeout has no special significance for such + * requests. + */ + if (!pdu->do_not_retry && rpc->retrans > 0) { + /* + * Ask pdu_set_timeout() to advance pdu->timeout and + * pdu->major_timeout. Note that major_timeout has no + * special significance for requests timing out in + * outqueue. + */ + pdu->timeout = 0; + pdu->major_timeout = 0; + pdu_set_timeout(rpc, pdu, t); + + RPC_LOG(rpc, 2, "[pdu %p] Request timed out in outqueue, " + "will send when connection allows!", pdu); + } else { + rpc_remove_pdu_from_queue(&rpc->outqueue, pdu); + rpc_set_error_locked(rpc, "command timed out"); + if (pdu->cb) { + pdu->cb(rpc, RPC_STATUS_TIMEOUT, + NULL, pdu->private_data); + } + rpc_free_pdu(rpc, pdu); + } + } + + /* + * Now look for requests in waitpdu. These are requests which have + * been sent to server and we are awaiting response from the server. + * These may indicate an unresponsive server and/or bad connection. + * We log a message on major_timeout and try recovery by dropping + * existing connection and creting a new one. + */ + for (i = 0; i < rpc->num_hashes; i++) { + struct rpc_queue *q; + + q = &rpc->waitpdu[i]; + for (pdu = q->head; pdu; pdu = next_pdu) { + next_pdu = pdu->next; + + if (pdu->timeout == 0) { + /* no timeout for this pdu */ + continue; + } + if (t < pdu->timeout && t < pdu->major_timeout) { + /* not expired yet */ + continue; + } + + /* Timed out waiting for response */ + if (t >= pdu->timeout) { + INC_STATS(rpc, num_timedout); + } + + rpc_remove_pdu_from_queue(q, pdu); + rpc->waitpdu_len--; + + /* + * rpc->retrans > 0 implies that user wants us to + * retransmit timed out RPCs. We update the timeout + * values for these RPCs and move them to outqueue for + * retransmit. + */ + if (!pdu->do_not_retry && rpc->retrans > 0) { + /* Ask pdu_set_timeout() to set pdu->timeout */ + pdu->timeout = 0; + + if (t >= pdu->major_timeout) { + /* Timed out waiting for response */ + INC_STATS(rpc, num_major_timedout); + + /* Ask pdu_set_timeout() to set pdu->major_timeout */ + pdu->major_timeout = 0; + if (!pdu->snr_logged) { + /* Log only once for an RPC */ + pdu->snr_logged = TRUE; + RPC_LOG(rpc, 1, "[pdu %p] Server %s " + "not responding, still trying", + pdu, rpc->server); + } + if (!need_reconnect) { + need_reconnect = (last_rpc_msecs > rpc->timeout); + } + } + /* Reset the RPC timeout values as appropriate */ + pdu_set_timeout(rpc, pdu, t); + + /* queue it back to outqueue for retransmit */ + rpc_return_to_outqueue(rpc, pdu); + } else { + // qqq move to a temporary queue and process after + // we drop the mutex + rpc_set_error_locked(rpc, "command timed out"); + if (pdu->cb) { + pdu->cb(rpc, RPC_STATUS_TIMEOUT, + NULL, pdu->private_data); + } + rpc_free_pdu(rpc, pdu); + } + } + } +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_unlock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ + + if (need_reconnect) { + RPC_LOG(rpc, 2, "rpc_timeout_scan: Recovery action needed for fd %d", + rpc->fd); + } + + return (need_reconnect ? -1 : 0); +} + +int +rpc_service(struct rpc_context *rpc, int revents) +{ + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + /* + * rpc_timeout_scan() will return -1 to indicate that we need to perform + * recovery action by reconnecting and queueing all RPCs on the new + * connection. Schedule reconnect and requeue and return. Once the new + * connection is ready, events will be processed for that. + */ + if (rpc_timeout_scan(rpc) != 0) { + return rpc_reconnect_requeue(rpc); + } + + if (revents == -1 || revents & (POLLERR|POLLHUP)) { + if (revents != -1 && 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, + (char *)&err, &err_size) != 0 || err != 0) { + if (err == 0) { + err = errno; + } + rpc_set_error(rpc, "rpc_service: socket error " + "%s(%d).", + strerror(err), err); + } else { + rpc_set_error(rpc, "rpc_service: POLLERR, " + "Unknown socket error."); + } + } else if (revents != -1 && revents & POLLHUP) { + rpc_set_error(rpc, "Socket failed with POLLHUP"); + } + if (rpc->auto_reconnect) { + return rpc_reconnect_requeue(rpc); + } + maybe_call_connect_cb(rpc, RPC_STATUS_ERROR); + return -1; + + } + + if (rpc->is_connected == 0 && rpc->fd != -1 && (revents & POLLOUT)) { + int err = 0; + socklen_t err_size = sizeof(err); + + if (getsockopt(rpc->fd, SOL_SOCKET, SO_ERROR, + (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); + maybe_call_connect_cb(rpc, RPC_STATUS_ERROR); + return -1; + } + + rpc->is_connected = 1; + RPC_LOG(rpc, 2, "connection established on fd %d", rpc->fd); + maybe_call_connect_cb(rpc, RPC_STATUS_SUCCESS); + return 0; + } + +#ifdef HAVE_TLS + /* + * We perform TLS handshake in a nonblocking fashion, i.e., we don't + * block on recv() and send(), so if we get a POLLIN or POLLOUT event + * during TLS handshake we must advance the TLS handshake process by + * calling do_tls_handshake() again. do_tls_handshake() will return + * TLS_HANDSHAKE_IN_PROGRESS if it needs to wait for network IO, o/w + * it'll complete the handshake process. + * Note that do_tls_handshake() can correctly handle multiple calls and + * it can advance the handshake process till it either completes successfully + * or fails. + */ + if (rpc->tls_context.state == TLS_HANDSHAKE_IN_PROGRESS && + (revents & (POLLOUT | POLLIN))) { + struct tls_cb_data *data = &rpc->tls_context.data; + + /* Should be only doing this for secure transport */ + assert(rpc->use_tls); + + rpc->tls_context.state = do_tls_handshake(rpc); + + switch (rpc->tls_context.state) { + case TLS_HANDSHAKE_IN_PROGRESS: + RPC_LOG(rpc, 2, "do_tls_handshake() returned " + "TLS_HANDSHAKE_IN_PROGRESS on fd %d", + rpc->fd); + break; + case TLS_HANDSHAKE_COMPLETED: + RPC_LOG(rpc, 2, "do_tls_handshake() returned " + "TLS_HANDSHAKE_COMPLETED on fd %d", + rpc->fd); + data->cb(rpc, RPC_STATUS_SUCCESS, NULL, data->private_data); + break; + case TLS_HANDSHAKE_FAILED: + RPC_LOG(rpc, 1, "do_tls_handshake() returned " + "TLS_HANDSHAKE_FAILED on fd %d", + rpc->fd); + data->cb(rpc, RPC_STATUS_ERROR, "TLS_HANDSHAKE_FAILED", + data->private_data); + break; + default: + /* Should not return any other status */ + assert(0); + } + + return 0; + } +#endif /* HAVE_TLS */ + + if (revents & POLLIN) { + if (rpc_read_from_socket(rpc) != 0) { + if (rpc->is_server_context) { + return -1; + } else { +#ifdef HAVE_TLS + /* + * TODO: read from ktls sockets will fail with EIO + * if TLS records of type other than data + * (e.g., alert or handshake) are received. + * We will need to issue a recvmsg() call + * with enough cmsg space to fetch the + * record type and data correctly. + * We can then log that here to help the + * user. In any case the only valid course + * of action is to terminate the connection + * and reconnect so that we can correctly + * re-auth. + */ +#endif /* HAVE_TLS */ + return rpc_reconnect_requeue(rpc); + } + } + } + +#ifdef HAVE_TLS + /* + * For secure NFS connections we should never write to the socket w/o + * properly completing the TLS handshake. Note that we do allow reads + * from the socket as we would want to read response to the AUTH_TLS + * NULL RPC. + */ + if (rpc->use_tls && (rpc->tls_context.state != TLS_HANDSHAKE_COMPLETED)) { + RPC_LOG(rpc, 2, "TLS handshake state %d on fd %d, skipping socket write!", + rpc->tls_context.state, rpc->fd); + return 0; + } +#endif + + if (revents & POLLOUT && rpc_has_queue(&rpc->outqueue)) { + if (rpc_write_to_socket(rpc) != 0) { + if (rpc->is_server_context) { + return -1; + } else { + return rpc_reconnect_requeue(rpc); + } + } + } + + return 0; +} + +/* + * Set resiliency related paramters for the RPC context. + * Following are the resiliency parameters for RPC transport: + * 1. num_tcp_reconnect: + * Number of times TCP reconnection is allowed before giving up. + * -1 indicates retry indefinitely. + * 2. timeout: + * How long we wait for an RPC response before retrying the RPC? + * 0 or -1 indicates infinite timeout. + * 3. retrans: + * Number of times an RPC is retried before we consider it a "major timeout" + * and take further recovery actions which might involve reconnection. + */ +void +rpc_set_resiliency(struct rpc_context *rpc, + int num_tcp_reconnect, + int timeout_msecs, + int retrans) +{ + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + /* we can not connect and not reconnect on a server context. */ + if (rpc->is_server_context) { + return; + } + + rpc->auto_reconnect = num_tcp_reconnect; + rpc->timeout = timeout_msecs; + rpc->retrans = retrans; +} + + +void +rpc_set_tcp_syncnt(struct rpc_context *rpc, int v) +{ + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + rpc->tcp_syncnt = v; +} + +#ifndef TCP_SYNCNT +#define TCP_SYNCNT 7 +#endif + +static int +rpc_connect_sockaddr_async(struct rpc_context *rpc) +{ + struct sockaddr_storage *s = &rpc->s; + socklen_t socksize; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + switch (s->ss_family) { + case AF_INET: + socksize = sizeof(struct sockaddr_in); + rpc->fd = create_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (set_bind_device(rpc->fd, rpc->ifname) != 0) { + rpc_set_error (rpc, "Failed to bind to interface"); + return -1; + } + +#ifdef HAVE_NETINET_TCP_H + if (rpc->tcp_syncnt != RPC_PARAM_UNDEFINED) { + set_tcp_sockopt(rpc->fd, TCP_SYNCNT, rpc->tcp_syncnt); + } +#endif + break; + case AF_INET6: + socksize = sizeof(struct sockaddr_in6); + rpc->fd = create_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); + if (set_bind_device(rpc->fd, rpc->ifname) != 0) { + rpc_set_error (rpc, "Failed to bind to interface"); + return -1; + } + +#ifdef HAVE_NETINET_TCP_H + if (rpc->tcp_syncnt != RPC_PARAM_UNDEFINED) { + set_tcp_sockopt(rpc->fd, TCP_SYNCNT, rpc->tcp_syncnt); + } +#endif + 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(HAVE_NETINET_TCP_H) && defined(TCP_NODELAY) + set_tcp_sockopt(rpc->fd, TCP_NODELAY, 1); +#endif + + if (rpc->old_fd) { +#if !defined(WIN32) && !defined(PS3_PPU) && !defined(PS2_EE) + if (dup2(rpc->fd, rpc->old_fd) == -1) { + rpc_set_error(rpc, "dup2() failed: %s", strerror(errno)); + return -1; + } + close(rpc->fd); + rpc->fd = rpc->old_fd; +#else + /* On Windows dup2 does not work on sockets + * instead just close the old socket */ + close(rpc->old_fd); + rpc->old_fd = 0; +#endif + } + + /* 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. + * + * On Windows, there is no concept of privileged ports. Thus + * binding will usually succeed. + */ + { + struct sockaddr_storage ss; + struct sockaddr_in *sin; +#if !defined(PS3_PPU) && !defined(PS2_EE) + struct sockaddr_in6 *sin6; +#endif + static int portOfs = 0; + const int firstPort = 512; /* >= 512 according to Sun docs */ + const int portCount = IPPORT_RESERVED - firstPort; + int startOfs, port, rc; + + sin = (struct sockaddr_in *)&ss; +#if !defined(PS3_PPU) && !defined(PS2_EE) + sin6 = (struct sockaddr_in6 *)&ss; +#endif + if (portOfs == 0) { + portOfs = rpc_current_time() % 400; + } + startOfs = portOfs; + do { + rc = -1; + port = htons(firstPort + portOfs); + portOfs = (portOfs + 1) % portCount; + + /* skip well-known ports */ + if (!getservbyport(port, "tcp")) { + memset(&ss, 0, sizeof(ss)); + + switch (s->ss_family) { + case AF_INET: + sin->sin_port = port; + sin->sin_family = AF_INET; +#ifdef HAVE_SOCKADDR_LEN + sin->sin_len = + sizeof(struct sockaddr_in); +#endif + break; +#if !defined(PS3_PPU) && !defined(PS2_EE) + case AF_INET6: + sin6->sin6_port = port; + sin6->sin6_family = AF_INET6; +#ifdef HAVE_SOCKADDR_LEN + sin6->sin6_len = + sizeof(struct sockaddr_in6); +#endif + break; +#endif + } + + rc = bind(rpc->fd, (struct sockaddr *)&ss, + socksize); +#if !defined(WIN32) + /* we got EACCES, so don't try again */ + if (rc != 0 && errno == EACCES) + break; +#endif + } + } while (rc != 0 && portOfs != startOfs); + } + + rpc->is_nonblocking = !set_nonblocking(rpc->fd); + set_nolinger(rpc->fd); + +#ifdef HAVE_NETINET_TCP_H + /* + * Enable keepalive to detect and terminate dead connections when server + * TCP stops responding. + */ + if (set_keepalive(rpc, rpc->fd) != 0) { + rpc_set_error(rpc, "Cannot enable keepalive for fd %d: %s", + rpc->fd, strerror(errno)); + return -1; + } +#endif + + if (connect(rpc->fd, (struct sockaddr *)s, socksize) != 0 && + errno != EINPROGRESS) { + rpc_set_error(rpc, "connect() to server failed. %s(%d)", + strerror(errno), errno); + return -1; + } + + return 0; +} + +static int +rpc_set_sockaddr(struct rpc_context *rpc, const char *server, int port) +{ + struct addrinfo *ai = NULL; + struct addrinfo hints; + + /* Prefer IPv4: NFSv3 portmap + IPv6 is unreliable, and many LAN + * NAS boxes only expose the share on IPv4. Fall back to any family. */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + if (getaddrinfo(server, NULL, &hints, &ai) != 0) { + if (getaddrinfo(server, NULL, NULL, &ai) != 0) { + rpc_set_error(rpc, "Invalid address:%s. " + "Can not resolv into IPv4/v6 structure.", server); + return -1; + } + } + + switch (ai->ai_family) { + case AF_INET: + ((struct sockaddr_in *)&rpc->s)->sin_family = ai->ai_family; + ((struct sockaddr_in *)&rpc->s)->sin_port = htons(port); + ((struct sockaddr_in *)&rpc->s)->sin_addr = + ((struct sockaddr_in *)(void *)(ai->ai_addr))->sin_addr; +#ifdef HAVE_SOCKADDR_LEN + ((struct sockaddr_in *)&rpc->s)->sin_len = + sizeof(struct sockaddr_in); +#endif + break; +#if !defined(PS3_PPU) && !defined(PS2_EE) + case AF_INET6: + ((struct sockaddr_in6 *)&rpc->s)->sin6_family = ai->ai_family; + ((struct sockaddr_in6 *)&rpc->s)->sin6_port = htons(port); + ((struct sockaddr_in6 *)&rpc->s)->sin6_addr = + ((struct sockaddr_in6 *)(void *)(ai->ai_addr))->sin6_addr; +#ifdef HAVE_SOCKADDR_LEN + ((struct sockaddr_in6 *)&rpc->s)->sin6_len = + sizeof(struct sockaddr_in6); +#endif + break; +#endif + } + freeaddrinfo(ai); + + return 0; +} + +int +rpc_connect_async(struct rpc_context *rpc, const char *server, int port, + rpc_cb cb, void *private_data) +{ + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (rpc->is_server_context) { + rpc_set_error(rpc, "Can not connect on a server context"); + return -1; + } + + if (rpc->fd != -1) { + rpc_set_error(rpc, "Trying to connect while already connected"); + return -1; + } + + if (rpc->is_udp != 0) { + rpc_set_error(rpc, "Trying to connect on UDP socket"); + return -1; + } + + rpc->auto_reconnect = 0; + + if (rpc_set_sockaddr(rpc, server, port) != 0) { + return -1; + } + + rpc->connect_cb = cb; + rpc->connect_data = private_data; + + if (rpc_connect_sockaddr_async(rpc) != 0) { + return -1; + } + + return 0; +} + +int +rpc_disconnect(struct rpc_context *rpc, const char *error) +{ + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (rpc->fd != -1) { + close(rpc->fd); + rpc->fd = -1; + } + + /* Do not re-disconnect if we are already disconnected */ + if (!rpc->is_connected) { + return 0; + } + + /* Turn off resiliency */ + rpc_set_resiliency(rpc, 0, rpc->timeout, 0); + + rpc->is_connected = 0; + + if (!rpc->is_server_context) { + rpc_error_all_pdus(rpc, error); + } + + maybe_call_connect_cb(rpc, RPC_STATUS_CANCEL); + return 0; +} + +#ifdef HAVE_TLS +/* + * During TCP reconnection (either server or client closes connection) for secure + * transport we need to perform the TLS handshake. This is the callback function + * called when a TLS handshake performed during reconnection completes. + */ +static void +reconnect_cb_tls(struct rpc_context *rpc, int status, + void *command_data, void *private_data) +{ + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + /* Must be called only for TLS transport */ + assert(rpc->use_tls); + + /* Must be called only after TLS handshake completes/fails */ + assert(rpc->tls_context.state == TLS_HANDSHAKE_COMPLETED || + rpc->tls_context.state == TLS_HANDSHAKE_FAILED); + + /* + * If handshake failed, restart the entire TCP connection not just the handshake. + * This will create a new connection and perform the handshake. + */ + if (rpc->tls_context.state == TLS_HANDSHAKE_FAILED) { + RPC_LOG(rpc, 1, "reconnect_cb_tls: TLS handshake failed, restarting connection!"); + + if (rpc->fd != -1) { + close(rpc->fd); + rpc->fd = -1; + } + rpc->is_connected = 0; + rpc_reconnect_requeue(rpc); + return; + } + + RPC_LOG(rpc, 2, "reconnect_cb_tls: TLS handshake completed successfully!"); +} +#endif + +static void +reconnect_cb(struct rpc_context *rpc, int status, void *data, + void *private_data) +{ + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (status != RPC_STATUS_SUCCESS) { + rpc_set_error(rpc, "Failed to reconnect async"); + rpc_reconnect_requeue(rpc); + return; + } + + rpc->is_connected = 1; + rpc->connect_cb = NULL; + rpc->old_fd = 0; + +#ifdef HAVE_TLS + /* + * For secure NFS connections, we need to setup TLS session now. + */ + RPC_LOG(rpc, 2, "reconnect_cb called with status %d", status); + if (rpc->use_tls) { + if (rpc_null_task_authtls(rpc, rpc->nfs_version, + reconnect_cb_tls, NULL) == NULL) { + RPC_LOG(rpc, 1, "reconnect_cb: rpc_null_task_authtls() failed, " + "restarting connection!"); + /* + * Force reconnect so that we can time the retries using + * the existing rpc->num_retries. Forcing reconnect also + * has the advantage that it sets up a fresh TCP connection + * in case the older connection had some issues preventing + * successful TLS handshake. + */ + if (rpc->fd != -1) { + close(rpc->fd); + rpc->fd = -1; + } + rpc->is_connected = 0; + rpc_reconnect_requeue(rpc); + return; + } + } +#endif /* HAVE_TLS */ +} + +/* 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, *next; + unsigned int i; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (rpc->auto_reconnect == 0) { + RPC_LOG(rpc, 1, "reconnect is disabled"); + rpc_error_all_pdus(rpc, "RPC ERROR: Failed to reconnect async"); + return -1; + } + + if (rpc->is_connected) { + rpc->num_retries = rpc->auto_reconnect; + } + + if (rpc->fd != -1) { + rpc->old_fd = rpc->fd; + } + rpc->fd = -1; + rpc->is_connected = 0; + + if (rpc->outqueue.head) { + rpc->outqueue.head->out.num_done = 0; + } + + rpc->inpos = 0; + rpc->state = READ_RM; + + /* + * Drop all fragments on reconnect + */ + rpc_free_all_fragments(rpc); + + /* 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. + */ +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_lock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ + for (i = 0; i < rpc->num_hashes; i++) { + struct rpc_queue *q = &rpc->waitpdu[i]; + for (pdu = q->head; pdu; pdu = next) { + next = pdu->next; + rpc_return_to_outqueue(rpc, pdu); + } + rpc_reset_queue(q); + } + rpc->waitpdu_len = 0; + + /* + * If there's any half-read PDU, that needs to be restarted too. + */ + if (rpc->pdu) { + rpc_return_to_outqueue(rpc, rpc->pdu); + rpc->pdu = NULL; + } + +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_unlock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ + + if (rpc->auto_reconnect < 0 || rpc->num_retries > 0) { + rpc->num_retries--; + rpc->connect_cb = reconnect_cb; + RPC_LOG(rpc, 1, "reconnect initiated"); + if (rpc_connect_sockaddr_async(rpc) != 0) { + rpc_error_all_pdus(rpc, "RPC ERROR: Failed to " + "reconnect async"); + return -1; + } + INC_STATS(rpc, num_reconnects); + return 0; + } + + RPC_LOG(rpc, 1, "reconnect: all attempts failed."); + rpc_error_all_pdus(rpc, "RPC ERROR: All attempts to reconnect failed."); + return -1; +} + + +int +rpc_bind_udp(struct rpc_context *rpc, char *addr, int port) +{ + struct addrinfo *ai = NULL; + char service[6]; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (rpc->is_udp == 0) { + rpc_set_error(rpc, "Cant not bind UDP. Not UDP context"); + return -1; + } + + 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.", addr); + return -1; + } + + switch(ai->ai_family) { + case AF_INET: + rpc->fd = create_socket(ai->ai_family, SOCK_DGRAM, 0); + if (rpc->fd == -1) { + rpc_set_error(rpc, "Failed to create UDP socket: %s", + strerror(errno)); + freeaddrinfo(ai); + return -1; + } + + if (bind(rpc->fd, (struct sockaddr *)ai->ai_addr, + sizeof(struct sockaddr_in)) != 0) { + rpc_set_error(rpc, "Failed to bind to UDP socket: %s", + strerror(errno)); + freeaddrinfo(ai); + return -1; + } + break; + default: + rpc_set_error(rpc, "Can not handle UPD sockets of family %d " + "yet", ai->ai_family); + freeaddrinfo(ai); + return -1; + } + + freeaddrinfo(ai); + + return 0; +} + +int +rpc_set_udp_destination(struct rpc_context *rpc, char *addr, int port, + int is_broadcast) +{ + struct addrinfo *ai = NULL; + char service[6]; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (rpc->is_udp == 0) { + rpc_set_error(rpc, "Can not set destination sockaddr. Not UDP " + "context"); + return -1; + } + + 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.", addr); + return -1; + } + + rpc->is_broadcast = is_broadcast; + setsockopt(rpc->fd, SOL_SOCKET, SO_BROADCAST, (char *)&is_broadcast, sizeof(is_broadcast)); + + memcpy(&rpc->udp_dest, ai->ai_addr, ai->ai_addrlen); + freeaddrinfo(ai); + + if (!is_broadcast) { + if (connect(rpc->fd, (struct sockaddr *)&rpc->udp_dest, sizeof(rpc->udp_dest)) != 0 && errno != EINPROGRESS) { + rpc_set_error(rpc, "connect() to UDP address failed. %s(%d)", strerror(errno), errno); + return -1; + } + } + + return 0; +} + +struct sockaddr * +rpc_get_udp_src_sockaddr(struct rpc_context *rpc) +{ + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + return (struct sockaddr *)&rpc->udp_src; +} + +#ifdef __linux__ +struct sockaddr * +rpc_get_udp_dst_sockaddr(struct rpc_context *rpc) +{ + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + return (struct sockaddr *)&rpc->udp_dst; +} +#endif + +int +rpc_queue_length(struct rpc_context *rpc) +{ + int i = 0; + struct rpc_pdu *pdu; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + for(pdu = rpc->outqueue.head; pdu; pdu = pdu->next) { + i++; + } + +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_lock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ + i += rpc->waitpdu_len; +#ifdef HAVE_MULTITHREADING + if (rpc->multithreading_enabled) { + nfs_mt_mutex_unlock(&rpc->rpc_mutex); + } +#endif /* HAVE_MULTITHREADING */ + + return i; +} + +int rpc_get_num_awaiting(struct rpc_context *rpc) +{ + return rpc->waitpdu_len; +} + +void rpc_set_awaiting_limit(struct rpc_context *rpc, int limit) +{ + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + rpc->max_waitpdu_len = limit; +} + +void +rpc_set_fd(struct rpc_context *rpc, int fd) +{ + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + rpc->fd = fd; +} + +int +rpc_is_udp_socket(struct rpc_context *rpc) +{ +#ifdef WIN32 + char type = 0; +#else + int type = 0; +#endif + socklen_t len = sizeof(type); + + getsockopt(rpc->fd, SOL_SOCKET, SO_TYPE, &type, &len); + return type == SOCK_DGRAM; +} diff --git a/deps/libnfs/libnfs.pc.in b/deps/libnfs/libnfs.pc.in new file mode 100644 index 000000000000..525da11c0131 --- /dev/null +++ b/deps/libnfs/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 @tls_library@ +Libs.private: @LIBS_PRIVATE@ +Cflags: -I${includedir} diff --git a/deps/libnfs/mount/CMakeLists.txt b/deps/libnfs/mount/CMakeLists.txt new file mode 100644 index 000000000000..af3e0c8d6c7e --- /dev/null +++ b/deps/libnfs/mount/CMakeLists.txt @@ -0,0 +1,5 @@ +set(SOURCES libnfs-raw-mount.c + mount.c) +set(HEADERS libnfs-raw-mount.h) + +core_add_library(mount) diff --git a/deps/libnfs/mount/Makefile.am b/deps/libnfs/mount/Makefile.am new file mode 100644 index 000000000000..97862401fc69 --- /dev/null +++ b/deps/libnfs/mount/Makefile.am @@ -0,0 +1,25 @@ +noinst_LTLIBRARIES = libmount.la + +mount_SOURCES_GENERATED = +mount_HEADERS_GENERATED = +mount_GENERATED = $(mount_SOURCES_GENERATED) $(mount_HEADERS_GENERATED) + +CLEANFILES = $(mount_GENERATED) mount-stamp + +libmount_la_CPPFLAGS = -I$(abs_top_srcdir)/include \ + -I$(abs_top_srcdir)/include/nfsc \ + -I$(abs_top_srcdir)/win32 +libmount_la_SOURCES = \ + $(mount_SOURCES_GENERATED) \ + mount.c libnfs-raw-mount.c libnfs-raw-mount.h + +$(mount_GENERATED) : mount-stamp +mount-stamp : mount.x + rm -f $(mount_GENERATED) + touch mount-stamp + +compile_rpc: + cat mount.x | head -29 >libnfs-raw-mount.h + rpcgen -h mount.x | sed -e "s/#include /#include /" | sed -e "s/xdr/zdr/g" -e "s/XDR/ZDR/g" -e "s/ CLIENT / void /g" -e "s/SVCXPRT /void /g" -e "s/bool_t/uint32_t/g" -e "s/u_int /uint32_t /g" >> libnfs-raw-mount.h + cat mount.x | head -29 >libnfs-raw-mount.c + rpcgen -c mount.x | sed -e "s/#include \".*mount.h\"/#include \"libnfs-xdr.h\"\n#include \"libnfs-raw-mount.h\"/" -e "s/xdr/zdr/g" -e "s/XDR/ZDR/g" -e "s/register int32_t \*buf;//" -e "s/bool_t/uint32_t/g" -e "s/u_int /uint32_t /g" >> libnfs-raw-mount.c diff --git a/deps/libnfs/mount/libnfs-raw-mount.c b/deps/libnfs/mount/libnfs-raw-mount.c new file mode 100644 index 000000000000..40911fcbc1f1 --- /dev/null +++ b/deps/libnfs/mount/libnfs-raw-mount.c @@ -0,0 +1,305 @@ +/* +Copyright (c) 2014, Ronnie Sahlberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +/* + * Please do not edit this file. + * It was generated using rpcgen. + */ + +#include "libnfs-zdr.h" +#include "libnfs-raw-mount.h" + +uint32_t +zdr_fhandle3 (ZDR *zdrs, fhandle3 *objp) +{ + if (!zdr_bytes (zdrs, (char **)&objp->fhandle3_val, (uint32_t *) &objp->fhandle3_len, FHSIZE3)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_dirpath (ZDR *zdrs, dirpath *objp) +{ + if (!zdr_string (zdrs, objp, MNTPATHLEN)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_name (ZDR *zdrs, name *objp) +{ + if (!zdr_string (zdrs, objp, MNTNAMLEN)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_mountstat3 (ZDR *zdrs, mountstat3 *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_mountlist (ZDR *zdrs, mountlist *objp) +{ + if (!zdr_pointer (zdrs, (char **)objp, sizeof (struct mountbody), (zdrproc_t) zdr_mountbody)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_mountbody (ZDR *zdrs, mountbody *objp) +{ + if (!zdr_name (zdrs, &objp->ml_hostname)) + return FALSE; + if (!zdr_dirpath (zdrs, &objp->ml_directory)) + return FALSE; + if (!zdr_mountlist (zdrs, &objp->ml_next)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_groups (ZDR *zdrs, groups *objp) +{ + if (!zdr_pointer (zdrs, (char **)objp, sizeof (struct groupnode), (zdrproc_t) zdr_groupnode)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_groupnode (ZDR *zdrs, groupnode *objp) +{ + if (!zdr_name (zdrs, &objp->gr_name)) + return FALSE; + if (!zdr_groups (zdrs, &objp->gr_next)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_exports (ZDR *zdrs, exports *objp) +{ + if (!zdr_pointer (zdrs, (char **)objp, sizeof (struct exportnode), (zdrproc_t) zdr_exportnode)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_exportnode (ZDR *zdrs, exportnode *objp) +{ + if (!zdr_dirpath (zdrs, &objp->ex_dir)) + return FALSE; + if (!zdr_groups (zdrs, &objp->ex_groups)) + return FALSE; + if (!zdr_exports (zdrs, &objp->ex_next)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_mountres3_ok (ZDR *zdrs, mountres3_ok *objp) +{ + if (!zdr_fhandle3 (zdrs, &objp->fhandle)) + return FALSE; + if (!zdr_array (zdrs, (char **)&objp->auth_flavors.auth_flavors_val, (uint32_t *) &objp->auth_flavors.auth_flavors_len, ~0, + sizeof (int), (zdrproc_t) zdr_int)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_mountres3 (ZDR *zdrs, mountres3 *objp) +{ + if (!zdr_mountstat3 (zdrs, &objp->fhs_status)) + return FALSE; + switch (objp->fhs_status) { + case MNT3_OK: + if (!zdr_mountres3_ok (zdrs, &objp->mountres3_u.mountinfo)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_mountstat1 (ZDR *zdrs, mountstat1 *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fhandle1 (ZDR *zdrs, fhandle1 objp) +{ + if (!zdr_opaque (zdrs, objp, FHSIZE)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_mountres1_ok (ZDR *zdrs, mountres1_ok *objp) +{ + if (!zdr_fhandle1 (zdrs, objp->fhandle)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_mountres1 (ZDR *zdrs, mountres1 *objp) +{ + if (!zdr_mountstat1 (zdrs, &objp->fhs_status)) + return FALSE; + switch (objp->fhs_status) { + case MNT1_OK: + if (!zdr_mountres1_ok (zdrs, &objp->mountres1_u.mountinfo)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_MOUNT1MNTargs (ZDR *zdrs, MOUNT1MNTargs *objp) +{ + if (!zdr_dirpath (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_MOUNT1MNTres (ZDR *zdrs, MOUNT1MNTres *objp) +{ + if (!zdr_mountres1 (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_MOUNT1DUMPres (ZDR *zdrs, MOUNT1DUMPres *objp) +{ + if (!zdr_mountbody (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_MOUNT1DUMPres_ptr (ZDR *zdrs, MOUNT1DUMPres_ptr *objp) +{ + if (!zdr_mountlist (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_MOUNT1UMNTargs (ZDR *zdrs, MOUNT1UMNTargs *objp) +{ + if (!zdr_dirpath (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_MOUNT1EXPORTres (ZDR *zdrs, MOUNT1EXPORTres *objp) +{ + if (!zdr_exportnode (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_MOUNT1EXPORTres_ptr (ZDR *zdrs, MOUNT1EXPORTres_ptr *objp) +{ + if (!zdr_pointer (zdrs, (char **)objp, sizeof (exportnode), (zdrproc_t) zdr_exportnode)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_MOUNT3MNTargs (ZDR *zdrs, MOUNT3MNTargs *objp) +{ + if (!zdr_dirpath (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_MOUNT3MNTres (ZDR *zdrs, MOUNT3MNTres *objp) +{ + if (!zdr_mountres3 (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_MOUNT3DUMPres (ZDR *zdrs, MOUNT3DUMPres *objp) +{ + if (!zdr_mountbody (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_MOUNT3DUMPres_ptr (ZDR *zdrs, MOUNT3DUMPres_ptr *objp) +{ + if (!zdr_mountlist (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_MOUNT3UMNTargs (ZDR *zdrs, MOUNT3UMNTargs *objp) +{ + if (!zdr_dirpath (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_MOUNT3EXPORTres (ZDR *zdrs, MOUNT3EXPORTres *objp) +{ + if (!zdr_exportnode (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_MOUNT3EXPORTres_ptr (ZDR *zdrs, MOUNT3EXPORTres_ptr *objp) +{ + if (!zdr_pointer (zdrs, (char **)objp, sizeof (exportnode), (zdrproc_t) zdr_exportnode)) + return FALSE; + return TRUE; +} diff --git a/deps/libnfs/mount/libnfs-raw-mount.h b/deps/libnfs/mount/libnfs-raw-mount.h new file mode 100644 index 000000000000..dba1a7d8603b --- /dev/null +++ b/deps/libnfs/mount/libnfs-raw-mount.h @@ -0,0 +1,335 @@ +/* +Copyright (c) 2014, Ronnie Sahlberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +/* + * Please do not edit this file. + * It was generated using rpcgen. + */ + +#ifndef _MOUNT_H_RPCGEN +#define _MOUNT_H_RPCGEN + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +#define MNTPATHLEN 1024 +#define MNTNAMLEN 255 +#define FHSIZE3 64 + +typedef struct { + uint32_t fhandle3_len; + char *fhandle3_val; +} fhandle3; + +typedef char *dirpath; + +typedef char *name; + +enum mountstat3 { + MNT3_OK = 0, + MNT3ERR_PERM = 1, + MNT3ERR_NOENT = 2, + MNT3ERR_IO = 5, + MNT3ERR_ACCES = 13, + MNT3ERR_NOTDIR = 20, + MNT3ERR_INVAL = 22, + MNT3ERR_NAMETOOLONG = 63, + MNT3ERR_NOTSUPP = 10004, + MNT3ERR_SERVERFAULT = 10006, +}; +typedef enum mountstat3 mountstat3; + +typedef struct mountbody *mountlist; + +struct mountbody { + name ml_hostname; + dirpath ml_directory; + mountlist ml_next; +}; +typedef struct mountbody mountbody; + +typedef struct groupnode *groups; + +struct groupnode { + name gr_name; + groups gr_next; +}; +typedef struct groupnode groupnode; + +typedef struct exportnode *exports; + +struct exportnode { + dirpath ex_dir; + groups ex_groups; + exports ex_next; +}; +typedef struct exportnode exportnode; + +struct mountres3_ok { + fhandle3 fhandle; + struct { + uint32_t auth_flavors_len; + int *auth_flavors_val; + } auth_flavors; +}; +typedef struct mountres3_ok mountres3_ok; + +struct mountres3 { + mountstat3 fhs_status; + union { + mountres3_ok mountinfo; + } mountres3_u; +}; +typedef struct mountres3 mountres3; + +enum mountstat1 { + MNT1_OK = 0, + MNT1ERR_PERM = 1, + MNT1ERR_NOENT = 2, + MNT1ERR_IO = 5, + MNT1ERR_ACCES = 13, + MNT1ERR_NOTDIR = 20, + MNT1ERR_INVAL = 22, + MNT1ERR_NAMETOOLONG = 63, + MNT1ERR_NOTSUPP = 10004, + MNT1ERR_SERVERFAULT = 10006, +}; +typedef enum mountstat1 mountstat1; +#define FHSIZE 32 + +typedef char fhandle1[FHSIZE]; + +struct mountres1_ok { + fhandle1 fhandle; +}; +typedef struct mountres1_ok mountres1_ok; + +struct mountres1 { + mountstat1 fhs_status; + union { + mountres1_ok mountinfo; + } mountres1_u; +}; +typedef struct mountres1 mountres1; + +typedef dirpath MOUNT1MNTargs; + +typedef mountres1 MOUNT1MNTres; + +typedef mountbody MOUNT1DUMPres; + +typedef mountlist MOUNT1DUMPres_ptr; + +typedef dirpath MOUNT1UMNTargs; + +typedef exportnode MOUNT1EXPORTres; + +typedef exportnode *MOUNT1EXPORTres_ptr; + +typedef dirpath MOUNT3MNTargs; + +typedef mountres3 MOUNT3MNTres; + +typedef mountbody MOUNT3DUMPres; + +typedef mountlist MOUNT3DUMPres_ptr; + +typedef dirpath MOUNT3UMNTargs; + +typedef exportnode MOUNT3EXPORTres; + +typedef exportnode *MOUNT3EXPORTres_ptr; + +#define MOUNT_PROGRAM 100005 +#define MOUNT_V1 1 + +#if defined(__STDC__) || defined(__cplusplus) +#define MOUNT1_NULL 0 +extern void * mount1_null_1(void *, void *); +extern void * mount1_null_1_svc(void *, struct svc_req *); +#define MOUNT1_MNT 1 +extern MOUNT1MNTres * mount1_mnt_1(MOUNT1MNTargs *, void *); +extern MOUNT1MNTres * mount1_mnt_1_svc(MOUNT1MNTargs *, struct svc_req *); +#define MOUNT1_DUMP 2 +extern MOUNT1DUMPres * mount1_dump_1(void *, void *); +extern MOUNT1DUMPres * mount1_dump_1_svc(void *, struct svc_req *); +#define MOUNT1_UMNT 3 +extern void * mount1_umnt_1(MOUNT1UMNTargs *, void *); +extern void * mount1_umnt_1_svc(MOUNT1UMNTargs *, struct svc_req *); +#define MOUNT1_UMNTALL 4 +extern void * mount1_umntall_1(void *, void *); +extern void * mount1_umntall_1_svc(void *, struct svc_req *); +#define MOUNT1_EXPORT 5 +extern MOUNT1EXPORTres * mount1_export_1(void *, void *); +extern MOUNT1EXPORTres * mount1_export_1_svc(void *, struct svc_req *); +extern int mount_program_1_freeresult (void *, zdrproc_t, caddr_t); + +#else /* K&R C */ +#define MOUNT1_NULL 0 +extern void * mount1_null_1(); +extern void * mount1_null_1_svc(); +#define MOUNT1_MNT 1 +extern MOUNT1MNTres * mount1_mnt_1(); +extern MOUNT1MNTres * mount1_mnt_1_svc(); +#define MOUNT1_DUMP 2 +extern MOUNT1DUMPres * mount1_dump_1(); +extern MOUNT1DUMPres * mount1_dump_1_svc(); +#define MOUNT1_UMNT 3 +extern void * mount1_umnt_1(); +extern void * mount1_umnt_1_svc(); +#define MOUNT1_UMNTALL 4 +extern void * mount1_umntall_1(); +extern void * mount1_umntall_1_svc(); +#define MOUNT1_EXPORT 5 +extern MOUNT1EXPORTres * mount1_export_1(); +extern MOUNT1EXPORTres * mount1_export_1_svc(); +extern int mount_program_1_freeresult (); +#endif /* K&R C */ +#define MOUNT_V3 3 + +#if defined(__STDC__) || defined(__cplusplus) +#define MOUNT3_NULL 0 +extern void * mount3_null_3(void *, void *); +extern void * mount3_null_3_svc(void *, struct svc_req *); +#define MOUNT3_MNT 1 +extern MOUNT3MNTres * mount3_mnt_3(MOUNT3MNTargs *, void *); +extern MOUNT3MNTres * mount3_mnt_3_svc(MOUNT3MNTargs *, struct svc_req *); +#define MOUNT3_DUMP 2 +extern MOUNT3DUMPres * mount3_dump_3(void *, void *); +extern MOUNT3DUMPres * mount3_dump_3_svc(void *, struct svc_req *); +#define MOUNT3_UMNT 3 +extern void * mount3_umnt_3(MOUNT3MNTargs *, void *); +extern void * mount3_umnt_3_svc(MOUNT3MNTargs *, struct svc_req *); +#define MOUNT3_UMNTALL 4 +extern void * mount3_umntall_3(void *, void *); +extern void * mount3_umntall_3_svc(void *, struct svc_req *); +#define MOUNT3_EXPORT 5 +extern MOUNT3EXPORTres * mount3_export_3(void *, void *); +extern MOUNT3EXPORTres * mount3_export_3_svc(void *, struct svc_req *); +extern int mount_program_3_freeresult (void *, zdrproc_t, caddr_t); + +#else /* K&R C */ +#define MOUNT3_NULL 0 +extern void * mount3_null_3(); +extern void * mount3_null_3_svc(); +#define MOUNT3_MNT 1 +extern MOUNT3MNTres * mount3_mnt_3(); +extern MOUNT3MNTres * mount3_mnt_3_svc(); +#define MOUNT3_DUMP 2 +extern MOUNT3DUMPres * mount3_dump_3(); +extern MOUNT3DUMPres * mount3_dump_3_svc(); +#define MOUNT3_UMNT 3 +extern void * mount3_umnt_3(); +extern void * mount3_umnt_3_svc(); +#define MOUNT3_UMNTALL 4 +extern void * mount3_umntall_3(); +extern void * mount3_umntall_3_svc(); +#define MOUNT3_EXPORT 5 +extern MOUNT3EXPORTres * mount3_export_3(); +extern MOUNT3EXPORTres * mount3_export_3_svc(); +extern int mount_program_3_freeresult (); +#endif /* K&R C */ + +/* the zdr functions */ + +#if defined(__STDC__) || defined(__cplusplus) +extern uint32_t zdr_fhandle3 (ZDR *, fhandle3*); +extern uint32_t zdr_dirpath (ZDR *, dirpath*); +extern uint32_t zdr_name (ZDR *, name*); +extern uint32_t zdr_mountstat3 (ZDR *, mountstat3*); +extern uint32_t zdr_mountlist (ZDR *, mountlist*); +extern uint32_t zdr_mountbody (ZDR *, mountbody*); +extern uint32_t zdr_groups (ZDR *, groups*); +extern uint32_t zdr_groupnode (ZDR *, groupnode*); +extern uint32_t zdr_exports (ZDR *, exports*); +extern uint32_t zdr_exportnode (ZDR *, exportnode*); +extern uint32_t zdr_mountres3_ok (ZDR *, mountres3_ok*); +extern uint32_t zdr_mountres3 (ZDR *, mountres3*); +extern uint32_t zdr_mountstat1 (ZDR *, mountstat1*); +extern uint32_t zdr_fhandle1 (ZDR *, fhandle1); +extern uint32_t zdr_mountres1_ok (ZDR *, mountres1_ok*); +extern uint32_t zdr_mountres1 (ZDR *, mountres1*); +extern uint32_t zdr_MOUNT1MNTargs (ZDR *, MOUNT1MNTargs*); +extern uint32_t zdr_MOUNT1MNTres (ZDR *, MOUNT1MNTres*); +extern uint32_t zdr_MOUNT1DUMPres (ZDR *, MOUNT1DUMPres*); +extern uint32_t zdr_MOUNT1DUMPres_ptr (ZDR *, MOUNT1DUMPres_ptr*); +extern uint32_t zdr_MOUNT1UMNTargs (ZDR *, MOUNT1UMNTargs*); +extern uint32_t zdr_MOUNT1EXPORTres (ZDR *, MOUNT1EXPORTres*); +extern uint32_t zdr_MOUNT1EXPORTres_ptr (ZDR *, MOUNT1EXPORTres_ptr*); +extern uint32_t zdr_MOUNT3MNTargs (ZDR *, MOUNT3MNTargs*); +extern uint32_t zdr_MOUNT3MNTres (ZDR *, MOUNT3MNTres*); +extern uint32_t zdr_MOUNT3DUMPres (ZDR *, MOUNT3DUMPres*); +extern uint32_t zdr_MOUNT3DUMPres_ptr (ZDR *, MOUNT3DUMPres_ptr*); +extern uint32_t zdr_MOUNT3UMNTargs (ZDR *, MOUNT3UMNTargs*); +extern uint32_t zdr_MOUNT3EXPORTres (ZDR *, MOUNT3EXPORTres*); +extern uint32_t zdr_MOUNT3EXPORTres_ptr (ZDR *, MOUNT3EXPORTres_ptr*); + +#else /* K&R C */ +extern uint32_t zdr_fhandle3 (); +extern uint32_t zdr_dirpath (); +extern uint32_t zdr_name (); +extern uint32_t zdr_mountstat3 (); +extern uint32_t zdr_mountlist (); +extern uint32_t zdr_mountbody (); +extern uint32_t zdr_groups (); +extern uint32_t zdr_groupnode (); +extern uint32_t zdr_exports (); +extern uint32_t zdr_exportnode (); +extern uint32_t zdr_mountres3_ok (); +extern uint32_t zdr_mountres3 (); +extern uint32_t zdr_mountstat1 (); +extern uint32_t zdr_fhandle1 (); +extern uint32_t zdr_mountres1_ok (); +extern uint32_t zdr_mountres1 (); +extern uint32_t zdr_MOUNT1MNTargs (); +extern uint32_t zdr_MOUNT1MNTres (); +extern uint32_t zdr_MOUNT1DUMPres (); +extern uint32_t zdr_MOUNT1DUMPres_ptr (); +extern uint32_t zdr_MOUNT1UMNTargs (); +extern uint32_t zdr_MOUNT1EXPORTres (); +extern uint32_t zdr_MOUNT1EXPORTres_ptr (); +extern uint32_t zdr_MOUNT3MNTargs (); +extern uint32_t zdr_MOUNT3MNTres (); +extern uint32_t zdr_MOUNT3DUMPres (); +extern uint32_t zdr_MOUNT3DUMPres_ptr (); +extern uint32_t zdr_MOUNT3UMNTargs (); +extern uint32_t zdr_MOUNT3EXPORTres (); +extern uint32_t zdr_MOUNT3EXPORTres_ptr (); + +#endif /* K&R C */ + +#ifdef __cplusplus +} +#endif + +#endif /* !_MOUNT_H_RPCGEN */ diff --git a/deps/libnfs/mount/mount.c b/deps/libnfs/mount/mount.c new file mode 100644 index 000000000000..bf55c38222d4 --- /dev/null +++ b/deps/libnfs/mount/mount.c @@ -0,0 +1,329 @@ +/* + 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 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef PS2_EE +#include "ps2_compat.h" +#endif + +#ifdef WIN32 +#include +#endif/*WIN32*/ + +#include +#include +#include "libnfs-zdr.h" +#include "libnfs.h" +#include "libnfs-raw.h" +#include "libnfs-private.h" +#include "libnfs-raw-mount.h" + +struct rpc_pdu * +rpc_mount3_null_task(struct rpc_context *rpc, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, MOUNT_PROGRAM, MOUNT_V3, MOUNT3_NULL, cb, private_data, (zdrproc_t)zdr_void, 0); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for mount/null call"); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for mount/null call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_mount3_mnt_task(struct rpc_context *rpc, rpc_cb cb, char *export, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, MOUNT_PROGRAM, MOUNT_V3, MOUNT3_MNT, cb, private_data, (zdrproc_t)zdr_mountres3, sizeof(mountres3)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for mount/mnt call"); + return NULL; + } + + if (zdr_dirpath(&pdu->zdr, &export) == 0) { + rpc_set_error(rpc, "ZDR error. Failed to encode mount/mnt call"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for mount/mnt call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_mount3_dump_task(struct rpc_context *rpc, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, MOUNT_PROGRAM, MOUNT_V3, MOUNT3_DUMP, cb, private_data, (zdrproc_t)zdr_mountlist, sizeof(mountlist)); + if (pdu == NULL) { + rpc_set_error(rpc, "Failed to allocate pdu for mount/dump"); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue mount/dump pdu"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_mount3_umnt_task(struct rpc_context *rpc, rpc_cb cb, char *export, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, MOUNT_PROGRAM, MOUNT_V3, MOUNT3_UMNT, cb, private_data, (zdrproc_t)zdr_void, 0); + if (pdu == NULL) { + rpc_set_error(rpc, "Failed to allocate pdu for mount/umnt"); + return NULL; + } + + if (zdr_dirpath(&pdu->zdr, &export) == 0) { + rpc_set_error(rpc, "failed to encode dirpath for mount/umnt"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue mount/umnt pdu"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_mount3_umntall_task(struct rpc_context *rpc, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, MOUNT_PROGRAM, MOUNT_V3, MOUNT3_UMNTALL, cb, private_data, (zdrproc_t)zdr_void, 0); + if (pdu == NULL) { + rpc_set_error(rpc, "Failed to allocate pdu for mount/umntall"); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue mount/umntall pdu"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_mount3_export_task(struct rpc_context *rpc, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, MOUNT_PROGRAM, MOUNT_V3, MOUNT3_EXPORT, cb, private_data, (zdrproc_t)zdr_exports, sizeof(exports)); + if (pdu == NULL) { + rpc_set_error(rpc, "Failed to allocate pdu for mount/export"); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue mount/export pdu"); + return NULL; + } + + return pdu; +} + +char *mountstat3_to_str(int st) +{ + enum mountstat3 stat = st; + + char *str = "unknown mount stat"; + switch (stat) { + case MNT3_OK: str="MNT3_OK"; break; + case MNT3ERR_PERM: str="MNT3ERR_PERM"; break; + case MNT3ERR_NOENT: str="MNT3ERR_NOENT"; break; + case MNT3ERR_IO: str="MNT3ERR_IO"; break; + case MNT3ERR_ACCES: str="MNT3ERR_ACCES"; break; + case MNT3ERR_NOTDIR: str="MNT3ERR_NOTDIR"; break; + case MNT3ERR_INVAL: str="MNT3ERR_INVAL"; break; + case MNT3ERR_NAMETOOLONG: str="MNT3ERR_NAMETOOLONG"; break; + case MNT3ERR_NOTSUPP: str="MNT3ERR_NOTSUPP"; break; + case MNT3ERR_SERVERFAULT: str="MNT3ERR_SERVERFAULT"; break; + } + return str; +} + + +int mountstat3_to_errno(int st) +{ + enum mountstat3 stat = st; + + switch (stat) { + case MNT3_OK: return 0; break; + case MNT3ERR_PERM: return -EPERM; break; + case MNT3ERR_NOENT: return -EPERM; break; + case MNT3ERR_IO: return -EIO; break; + case MNT3ERR_ACCES: return -EACCES; break; + case MNT3ERR_NOTDIR: return -ENOTDIR; break; + case MNT3ERR_INVAL: return -EINVAL; break; + case MNT3ERR_NAMETOOLONG: return -E2BIG; break; + case MNT3ERR_NOTSUPP: return -EINVAL; break; + case MNT3ERR_SERVERFAULT: return -EIO; break; + } + return -ERANGE; +} + +struct rpc_pdu * +rpc_mount1_null_task(struct rpc_context *rpc, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, MOUNT_PROGRAM, MOUNT_V1, MOUNT1_NULL, cb, private_data, (zdrproc_t)zdr_void, 0); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for MOUNT1/NULL call"); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for MOUNT1/NULL call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_mount1_mnt_task(struct rpc_context *rpc, rpc_cb cb, char *export, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, MOUNT_PROGRAM, MOUNT_V1, MOUNT1_MNT, cb, private_data, (zdrproc_t)zdr_mountres1, sizeof(mountres1)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for MOUNT1/MNT call"); + return NULL; + } + + if (zdr_dirpath(&pdu->zdr, &export) == 0) { + rpc_set_error(rpc, "ZDR error. Failed to encode MOUNT1/MNT call"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for MOUNT1/MNT call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_mount1_dump_task(struct rpc_context *rpc, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, MOUNT_PROGRAM, MOUNT_V1, MOUNT1_DUMP, cb, private_data, (zdrproc_t)zdr_mountlist, sizeof(mountlist)); + if (pdu == NULL) { + rpc_set_error(rpc, "Failed to allocate pdu for MOUNT1/DUMP"); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue MOUNT1/DUMP pdu"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_mount1_umnt_task(struct rpc_context *rpc, rpc_cb cb, char *export, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, MOUNT_PROGRAM, MOUNT_V1, MOUNT1_UMNT, cb, private_data, (zdrproc_t)zdr_void, 0); + if (pdu == NULL) { + rpc_set_error(rpc, "Failed to allocate pdu for MOUNT1/UMNT"); + return NULL; + } + + if (zdr_dirpath(&pdu->zdr, &export) == 0) { + rpc_set_error(rpc, "failed to encode dirpath for MOUNT1/UMNT"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue MOUNT1/UMNT pdu"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_mount1_umntall_task(struct rpc_context *rpc, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, MOUNT_PROGRAM, MOUNT_V1, MOUNT1_UMNTALL, cb, private_data, (zdrproc_t)zdr_void, 0); + if (pdu == NULL) { + rpc_set_error(rpc, "Failed to allocate pdu for MOUNT1/UMNTALL"); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue MOUNT1/UMNTALL pdu"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_mount1_export_task(struct rpc_context *rpc, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, MOUNT_PROGRAM, MOUNT_V1, MOUNT1_EXPORT, cb, private_data, (zdrproc_t)zdr_exports, sizeof(exports)); + if (pdu == NULL) { + rpc_set_error(rpc, "Failed to allocate pdu for MOUNT1/EXPORT"); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue MOUNT1/EXPORT pdu"); + return NULL; + } + + return pdu; +} + diff --git a/deps/libnfs/mount/mount.x b/deps/libnfs/mount/mount.x new file mode 100644 index 000000000000..79d9da16488a --- /dev/null +++ b/deps/libnfs/mount/mount.x @@ -0,0 +1,171 @@ +/* +Copyright (c) 2014, Ronnie Sahlberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +const MNTPATHLEN = 1024; /* Maximum bytes in a path name */ +const MNTNAMLEN = 255; /* Maximum bytes in a name */ +const FHSIZE3 = 64; /* Maximum bytes in a V3 file handle */ + + +typedef opaque fhandle3; +typedef string dirpath; +typedef string name; + +enum mountstat3 { + MNT3_OK = 0, /* no error */ + MNT3ERR_PERM = 1, /* Not owner */ + MNT3ERR_NOENT = 2, /* No such file or directory */ + MNT3ERR_IO = 5, /* I/O error */ + MNT3ERR_ACCES = 13, /* Permission denied */ + MNT3ERR_NOTDIR = 20, /* Not a directory */ + MNT3ERR_INVAL = 22, /* Invalid argument */ + MNT3ERR_NAMETOOLONG = 63, /* Filename too long */ + MNT3ERR_NOTSUPP = 10004, /* Operation not supported */ + MNT3ERR_SERVERFAULT = 10006 /* A failure on the server */ +}; + + +typedef struct mountbody *mountlist; + +struct mountbody { + name ml_hostname; + dirpath ml_directory; + mountlist ml_next; +}; + +typedef struct groupnode *groups; + +struct groupnode { + name gr_name; + groups gr_next; +}; + +typedef struct exportnode *exports; + +struct exportnode { + dirpath ex_dir; + groups ex_groups; + exports ex_next; +}; + +struct mountres3_ok { + fhandle3 fhandle; + int auth_flavors<>; +}; + +union mountres3 switch (mountstat3 fhs_status) { + case MNT3_OK: + mountres3_ok mountinfo; + default: + void; +}; + + +enum mountstat1 { + MNT1_OK = 0, /* no error */ + MNT1ERR_PERM = 1, /* Not owner */ + MNT1ERR_NOENT = 2, /* No such file or directory */ + MNT1ERR_IO = 5, /* I/O error */ + MNT1ERR_ACCES = 13, /* Permission denied */ + MNT1ERR_NOTDIR = 20, /* Not a directory */ + MNT1ERR_INVAL = 22, /* Invalid argument */ + MNT1ERR_NAMETOOLONG = 63, /* Filename too long */ + MNT1ERR_NOTSUPP = 10004, /* Operation not supported */ + MNT1ERR_SERVERFAULT = 10006 /* A failure on the server */ +}; + +const FHSIZE = 32; +typedef opaque fhandle1[FHSIZE]; + +struct mountres1_ok { + fhandle1 fhandle; +}; + +union mountres1 switch (mountstat1 fhs_status) { + case MNT1_OK: + mountres1_ok mountinfo; + default: + void; +}; + +typedef dirpath MOUNT1MNTargs; +typedef mountres1 MOUNT1MNTres; +typedef mountbody MOUNT1DUMPres; +typedef mountlist MOUNT1DUMPres_ptr; +typedef dirpath MOUNT1UMNTargs; +typedef struct exportnode MOUNT1EXPORTres; +typedef struct exportnode *MOUNT1EXPORTres_ptr; + +typedef dirpath MOUNT3MNTargs; +typedef mountres3 MOUNT3MNTres; +typedef mountbody MOUNT3DUMPres; +typedef mountlist MOUNT3DUMPres_ptr; +typedef dirpath MOUNT3UMNTargs; +typedef struct exportnode MOUNT3EXPORTres; +typedef struct exportnode *MOUNT3EXPORTres_ptr; + +program MOUNT_PROGRAM { + version MOUNT_V1 { + void + MOUNT1_NULL(void) = 0; + + MOUNT1MNTres + MOUNT1_MNT(MOUNT1MNTargs) = 1; + + MOUNT1DUMPres + MOUNT1_DUMP(void) = 2; + + void + MOUNT1_UMNT(MOUNT1UMNTargs) = 3; + + void + MOUNT1_UMNTALL(void) = 4; + + MOUNT1EXPORTres + MOUNT1_EXPORT(void) = 5; + } = 1; + version MOUNT_V3 { + void + MOUNT3_NULL(void) = 0; + + MOUNT3MNTres + MOUNT3_MNT(MOUNT3MNTargs) = 1; + + MOUNT3DUMPres + MOUNT3_DUMP(void) = 2; + + void + MOUNT3_UMNT(MOUNT3MNTargs) = 3; + + void + MOUNT3_UMNTALL(void) = 4; + + MOUNT3EXPORTres + MOUNT3_EXPORT(void) = 5; + } = 3; +} = 100005; diff --git a/deps/libnfs/nfs/CMakeLists.txt b/deps/libnfs/nfs/CMakeLists.txt new file mode 100644 index 000000000000..626eea2d1937 --- /dev/null +++ b/deps/libnfs/nfs/CMakeLists.txt @@ -0,0 +1,6 @@ +set(SOURCES libnfs-raw-nfs.c + nfs.c + nfsacl.c) +set(HEADERS libnfs-raw-nfs.h) + +core_add_library(nfs) diff --git a/deps/libnfs/nfs/Makefile.am b/deps/libnfs/nfs/Makefile.am new file mode 100644 index 000000000000..231707c7af6f --- /dev/null +++ b/deps/libnfs/nfs/Makefile.am @@ -0,0 +1,26 @@ +noinst_LTLIBRARIES = libnfs.la + +nfs_SOURCES_GENERATED = +nfs_HEADERS_GENERATED = +nfs_GENERATED = $(nfs_SOURCES_GENERATED) $(nfs_HEADERS_GENERATED) + +CLEANFILES = $(nfs_GENERATED) nfs-stamp + +libnfs_la_CPPFLAGS = -I$(abs_top_srcdir)/include \ + -I$(abs_top_srcdir)/include/nfsc \ + -I$(abs_top_srcdir)/win32 +libnfs_la_SOURCES = \ + $(nfs_SOURCES_GENERATED) \ + nfs.c nfsacl.c libnfs-raw-nfs.c libnfs-raw-nfs.h + +$(nfs_GENERATED) : nfs-stamp +nfs-stamp : nfs.x + rm -f $(nfs_GENERATED) + touch nfs-stamp + +compile_rpc: + cat nfs.x | head -29 >libnfs-raw-nfs.h + rpcgen -h nfs.x | sed -e "s/#include /#include /" -e "s/xdr/zdr/g" -e "s/XDR/ZDR/g" -e "s/#define _NFS_H_RPCGEN/#define _NFS_H_RPCGEN\n#include /g" -e "s/#define NFS3_COOKIEVERFSIZE 8/#define NFS3_COOKIEVERFSIZE 8\n\n/g" -e "s/ CLIENT / void /g" -e "s/SVCXPRT /void /g" -e "s/bool_t/uint32_t/g" | head -n -5 >> libnfs-raw-nfs.h + cat libnfs-raw-nfs.h.extra >>libnfs-raw-nfs.h + cat nfs.x | head -29 >libnfs-raw-nfs.c + rpcgen -c nfs.x | sed -e "s/#include \".*nfs.h\"/#include \"libnfs-xdr.h\"\n#include \"libnfs-raw-nfs.h\"/" -e "s/xdr/zdr/g" -e "s/XDR/ZDR/g" -e "s/register int32_t \*buf;/register int32_t *buf;\n buf = NULL;/" -e "s/bool_t/uint32_t/g" >> libnfs-raw-nfs.c diff --git a/deps/libnfs/nfs/libnfs-raw-nfs.c b/deps/libnfs/nfs/libnfs-raw-nfs.c new file mode 100644 index 000000000000..81dd7960ea4b --- /dev/null +++ b/deps/libnfs/nfs/libnfs-raw-nfs.c @@ -0,0 +1,2660 @@ +/* +Copyright (c) 2014, Ronnie Sahlberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +/* + * Please do not edit this file. + * It was generated using rpcgen. + */ + +#include "libnfs-zdr.h" +#include "libnfs-raw-nfs.h" + +uint32_t +zdr_cookieverf3 (ZDR *zdrs, cookieverf3 objp) +{ + if (!zdr_opaque (zdrs, objp, NFS3_COOKIEVERFSIZE)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_cookie3 (ZDR *zdrs, cookie3 *objp) +{ + if (!zdr_uint64_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_nfs_fh3 (ZDR *zdrs, nfs_fh3 *objp) +{ + if (!zdr_bytes (zdrs, (char **)&objp->data.data_val, &objp->data.data_len, NFS3_FHSIZE)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_filename3 (ZDR *zdrs, filename3 *objp) +{ + if (!zdr_string (zdrs, objp, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_diropargs3 (ZDR *zdrs, diropargs3 *objp) +{ + if (!zdr_nfs_fh3 (zdrs, &objp->dir)) + return FALSE; + if (!zdr_filename3 (zdrs, &objp->name)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_ftype3 (ZDR *zdrs, ftype3 *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_mode3 (ZDR *zdrs, mode3 *objp) +{ + if (!zdr_u_int (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_uid3 (ZDR *zdrs, uid3 *objp) +{ + if (!zdr_u_int (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_gid3 (ZDR *zdrs, gid3 *objp) +{ + if (!zdr_u_int (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_size3 (ZDR *zdrs, size3 *objp) +{ + if (!zdr_uint64_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fileid3 (ZDR *zdrs, fileid3 *objp) +{ + if (!zdr_uint64_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_specdata3 (ZDR *zdrs, specdata3 *objp) +{ + if (!zdr_u_int (zdrs, &objp->specdata1)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->specdata2)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_nfstime3 (ZDR *zdrs, nfstime3 *objp) +{ + if (!zdr_u_int (zdrs, &objp->seconds)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->nseconds)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr3 (ZDR *zdrs, fattr3 *objp) +{ + if (!zdr_ftype3 (zdrs, &objp->type)) + return FALSE; + if (!zdr_mode3 (zdrs, &objp->mode)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->nlink)) + return FALSE; + if (!zdr_uid3 (zdrs, &objp->uid)) + return FALSE; + if (!zdr_gid3 (zdrs, &objp->gid)) + return FALSE; + if (!zdr_size3 (zdrs, &objp->size)) + return FALSE; + if (!zdr_size3 (zdrs, &objp->used)) + return FALSE; + if (!zdr_specdata3 (zdrs, &objp->rdev)) + return FALSE; + if (!zdr_uint64_t (zdrs, &objp->fsid)) + return FALSE; + if (!zdr_fileid3 (zdrs, &objp->fileid)) + return FALSE; + if (!zdr_nfstime3 (zdrs, &objp->atime)) + return FALSE; + if (!zdr_nfstime3 (zdrs, &objp->mtime)) + return FALSE; + if (!zdr_nfstime3 (zdrs, &objp->ctime)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_post_op_attr (ZDR *zdrs, post_op_attr *objp) +{ + if (!zdr_bool (zdrs, &objp->attributes_follow)) + return FALSE; + switch (objp->attributes_follow) { + case TRUE: + if (!zdr_fattr3 (zdrs, &objp->post_op_attr_u.attributes)) + return FALSE; + break; + case FALSE: + break; + default: + return FALSE; + } + return TRUE; +} + +uint32_t +zdr_nfsstat3 (ZDR *zdrs, nfsstat3 *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_stable_how (ZDR *zdrs, stable_how *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_offset3 (ZDR *zdrs, offset3 *objp) +{ + if (!zdr_uint64_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_count3 (ZDR *zdrs, count3 *objp) +{ + if (!zdr_u_int (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_wcc_attr (ZDR *zdrs, wcc_attr *objp) +{ + if (!zdr_size3 (zdrs, &objp->size)) + return FALSE; + if (!zdr_nfstime3 (zdrs, &objp->mtime)) + return FALSE; + if (!zdr_nfstime3 (zdrs, &objp->ctime)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_pre_op_attr (ZDR *zdrs, pre_op_attr *objp) +{ + if (!zdr_bool (zdrs, &objp->attributes_follow)) + return FALSE; + switch (objp->attributes_follow) { + case TRUE: + if (!zdr_wcc_attr (zdrs, &objp->pre_op_attr_u.attributes)) + return FALSE; + break; + case FALSE: + break; + default: + return FALSE; + } + return TRUE; +} + +uint32_t +zdr_wcc_data (ZDR *zdrs, wcc_data *objp) +{ + if (!zdr_pre_op_attr (zdrs, &objp->before)) + return FALSE; + if (!zdr_post_op_attr (zdrs, &objp->after)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_WRITE3args (ZDR *zdrs, WRITE3args *objp) +{ + if (!zdr_nfs_fh3 (zdrs, &objp->file)) + return FALSE; + if (!zdr_offset3 (zdrs, &objp->offset)) + return FALSE; + if (!zdr_count3 (zdrs, &objp->count)) + return FALSE; + if (!zdr_stable_how (zdrs, &objp->stable)) + return FALSE; + if (!zdr_bytes (zdrs, (char **)&objp->data.data_val, &objp->data.data_len, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_writeverf3 (ZDR *zdrs, writeverf3 objp) +{ + if (!zdr_opaque (zdrs, objp, NFS3_WRITEVERFSIZE)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_WRITE3resok (ZDR *zdrs, WRITE3resok *objp) +{ + if (!zdr_wcc_data (zdrs, &objp->file_wcc)) + return FALSE; + if (!zdr_count3 (zdrs, &objp->count)) + return FALSE; + if (!zdr_stable_how (zdrs, &objp->committed)) + return FALSE; + if (!zdr_writeverf3 (zdrs, objp->verf)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_WRITE3resfail (ZDR *zdrs, WRITE3resfail *objp) +{ + if (!zdr_wcc_data (zdrs, &objp->file_wcc)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_WRITE3res (ZDR *zdrs, WRITE3res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_WRITE3resok (zdrs, &objp->WRITE3res_u.resok)) + return FALSE; + break; + default: + if (!zdr_WRITE3resfail (zdrs, &objp->WRITE3res_u.resfail)) + return FALSE; + break; + } + return TRUE; +} + +uint32_t +zdr_LOOKUP3args (ZDR *zdrs, LOOKUP3args *objp) +{ + if (!zdr_diropargs3 (zdrs, &objp->what)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_LOOKUP3resok (ZDR *zdrs, LOOKUP3resok *objp) +{ + if (!zdr_nfs_fh3 (zdrs, &objp->object)) + return FALSE; + if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) + return FALSE; + if (!zdr_post_op_attr (zdrs, &objp->dir_attributes)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_LOOKUP3resfail (ZDR *zdrs, LOOKUP3resfail *objp) +{ + if (!zdr_post_op_attr (zdrs, &objp->dir_attributes)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_LOOKUP3res (ZDR *zdrs, LOOKUP3res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_LOOKUP3resok (zdrs, &objp->LOOKUP3res_u.resok)) + return FALSE; + break; + default: + if (!zdr_LOOKUP3resfail (zdrs, &objp->LOOKUP3res_u.resfail)) + return FALSE; + break; + } + return TRUE; +} + +uint32_t +zdr_COMMIT3args (ZDR *zdrs, COMMIT3args *objp) +{ + if (!zdr_nfs_fh3 (zdrs, &objp->file)) + return FALSE; + if (!zdr_offset3 (zdrs, &objp->offset)) + return FALSE; + if (!zdr_count3 (zdrs, &objp->count)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_COMMIT3resok (ZDR *zdrs, COMMIT3resok *objp) +{ + if (!zdr_wcc_data (zdrs, &objp->file_wcc)) + return FALSE; + if (!zdr_writeverf3 (zdrs, objp->verf)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_COMMIT3resfail (ZDR *zdrs, COMMIT3resfail *objp) +{ + if (!zdr_wcc_data (zdrs, &objp->file_wcc)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_COMMIT3res (ZDR *zdrs, COMMIT3res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_COMMIT3resok (zdrs, &objp->COMMIT3res_u.resok)) + return FALSE; + break; + default: + if (!zdr_COMMIT3resfail (zdrs, &objp->COMMIT3res_u.resfail)) + return FALSE; + break; + } + return TRUE; +} + +uint32_t +zdr_ACCESS3args (ZDR *zdrs, ACCESS3args *objp) +{ + if (!zdr_nfs_fh3 (zdrs, &objp->object)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->access)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_ACCESS3resok (ZDR *zdrs, ACCESS3resok *objp) +{ + if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->access)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_ACCESS3resfail (ZDR *zdrs, ACCESS3resfail *objp) +{ + if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_ACCESS3res (ZDR *zdrs, ACCESS3res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_ACCESS3resok (zdrs, &objp->ACCESS3res_u.resok)) + return FALSE; + break; + default: + if (!zdr_ACCESS3resfail (zdrs, &objp->ACCESS3res_u.resfail)) + return FALSE; + break; + } + return TRUE; +} + +uint32_t +zdr_GETATTR3args (ZDR *zdrs, GETATTR3args *objp) +{ + if (!zdr_nfs_fh3 (zdrs, &objp->object)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_GETATTR3resok (ZDR *zdrs, GETATTR3resok *objp) +{ + if (!zdr_fattr3 (zdrs, &objp->obj_attributes)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_GETATTR3res (ZDR *zdrs, GETATTR3res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_GETATTR3resok (zdrs, &objp->GETATTR3res_u.resok)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_time_how (ZDR *zdrs, time_how *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_set_mode3 (ZDR *zdrs, set_mode3 *objp) +{ + if (!zdr_bool (zdrs, &objp->set_it)) + return FALSE; + switch (objp->set_it) { + case TRUE: + if (!zdr_mode3 (zdrs, &objp->set_mode3_u.mode)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_set_uid3 (ZDR *zdrs, set_uid3 *objp) +{ + if (!zdr_bool (zdrs, &objp->set_it)) + return FALSE; + switch (objp->set_it) { + case TRUE: + if (!zdr_uid3 (zdrs, &objp->set_uid3_u.uid)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_set_gid3 (ZDR *zdrs, set_gid3 *objp) +{ + if (!zdr_bool (zdrs, &objp->set_it)) + return FALSE; + switch (objp->set_it) { + case TRUE: + if (!zdr_gid3 (zdrs, &objp->set_gid3_u.gid)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_set_size3 (ZDR *zdrs, set_size3 *objp) +{ + if (!zdr_bool (zdrs, &objp->set_it)) + return FALSE; + switch (objp->set_it) { + case TRUE: + if (!zdr_size3 (zdrs, &objp->set_size3_u.size)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_set_atime (ZDR *zdrs, set_atime *objp) +{ + if (!zdr_time_how (zdrs, &objp->set_it)) + return FALSE; + switch (objp->set_it) { + case SET_TO_CLIENT_TIME: + if (!zdr_nfstime3 (zdrs, &objp->set_atime_u.atime)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_set_mtime (ZDR *zdrs, set_mtime *objp) +{ + if (!zdr_time_how (zdrs, &objp->set_it)) + return FALSE; + switch (objp->set_it) { + case SET_TO_CLIENT_TIME: + if (!zdr_nfstime3 (zdrs, &objp->set_mtime_u.mtime)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_sattr3 (ZDR *zdrs, sattr3 *objp) +{ + if (!zdr_set_mode3 (zdrs, &objp->mode)) + return FALSE; + if (!zdr_set_uid3 (zdrs, &objp->uid)) + return FALSE; + if (!zdr_set_gid3 (zdrs, &objp->gid)) + return FALSE; + if (!zdr_set_size3 (zdrs, &objp->size)) + return FALSE; + if (!zdr_set_atime (zdrs, &objp->atime)) + return FALSE; + if (!zdr_set_mtime (zdrs, &objp->mtime)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_createmode3 (ZDR *zdrs, createmode3 *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_createverf3 (ZDR *zdrs, createverf3 objp) +{ + if (!zdr_opaque (zdrs, objp, NFS3_CREATEVERFSIZE)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_createhow3 (ZDR *zdrs, createhow3 *objp) +{ + if (!zdr_createmode3 (zdrs, &objp->mode)) + return FALSE; + switch (objp->mode) { + case UNCHECKED: + if (!zdr_sattr3 (zdrs, &objp->createhow3_u.obj_attributes)) + return FALSE; + break; + case GUARDED: + if (!zdr_sattr3 (zdrs, &objp->createhow3_u.g_obj_attributes)) + return FALSE; + break; + case EXCLUSIVE: + if (!zdr_createverf3 (zdrs, objp->createhow3_u.verf)) + return FALSE; + break; + default: + return FALSE; + } + return TRUE; +} + +uint32_t +zdr_CREATE3args (ZDR *zdrs, CREATE3args *objp) +{ + if (!zdr_diropargs3 (zdrs, &objp->where)) + return FALSE; + if (!zdr_createhow3 (zdrs, &objp->how)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_post_op_fh3 (ZDR *zdrs, post_op_fh3 *objp) +{ + if (!zdr_bool (zdrs, &objp->handle_follows)) + return FALSE; + switch (objp->handle_follows) { + case TRUE: + if (!zdr_nfs_fh3 (zdrs, &objp->post_op_fh3_u.handle)) + return FALSE; + break; + case FALSE: + break; + default: + return FALSE; + } + return TRUE; +} + +uint32_t +zdr_CREATE3resok (ZDR *zdrs, CREATE3resok *objp) +{ + if (!zdr_post_op_fh3 (zdrs, &objp->obj)) + return FALSE; + if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) + return FALSE; + if (!zdr_wcc_data (zdrs, &objp->dir_wcc)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_CREATE3resfail (ZDR *zdrs, CREATE3resfail *objp) +{ + if (!zdr_wcc_data (zdrs, &objp->dir_wcc)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_CREATE3res (ZDR *zdrs, CREATE3res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_CREATE3resok (zdrs, &objp->CREATE3res_u.resok)) + return FALSE; + break; + default: + if (!zdr_CREATE3resfail (zdrs, &objp->CREATE3res_u.resfail)) + return FALSE; + break; + } + return TRUE; +} + +uint32_t +zdr_REMOVE3args (ZDR *zdrs, REMOVE3args *objp) +{ + if (!zdr_diropargs3 (zdrs, &objp->object)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_REMOVE3resok (ZDR *zdrs, REMOVE3resok *objp) +{ + if (!zdr_wcc_data (zdrs, &objp->dir_wcc)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_REMOVE3resfail (ZDR *zdrs, REMOVE3resfail *objp) +{ + if (!zdr_wcc_data (zdrs, &objp->dir_wcc)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_REMOVE3res (ZDR *zdrs, REMOVE3res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_REMOVE3resok (zdrs, &objp->REMOVE3res_u.resok)) + return FALSE; + break; + default: + if (!zdr_REMOVE3resfail (zdrs, &objp->REMOVE3res_u.resfail)) + return FALSE; + break; + } + return TRUE; +} + +uint32_t +zdr_READ3args (ZDR *zdrs, READ3args *objp) +{ + if (!zdr_nfs_fh3 (zdrs, &objp->file)) + return FALSE; + if (!zdr_offset3 (zdrs, &objp->offset)) + return FALSE; + if (!zdr_count3 (zdrs, &objp->count)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_READ3resok (ZDR *zdrs, READ3resok *objp) +{ + if (!zdr_post_op_attr (zdrs, &objp->file_attributes)) + return FALSE; + if (!zdr_count3 (zdrs, &objp->count)) + return FALSE; + if (!zdr_bool (zdrs, &objp->eof)) + return FALSE; + if (!zdr_bytes (zdrs, (char **)&objp->data.data_val, &objp->data.data_len, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_READ3resfail (ZDR *zdrs, READ3resfail *objp) +{ + if (!zdr_post_op_attr (zdrs, &objp->file_attributes)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_READ3res (ZDR *zdrs, READ3res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_READ3resok (zdrs, &objp->READ3res_u.resok)) + return FALSE; + break; + default: + if (!zdr_READ3resfail (zdrs, &objp->READ3res_u.resfail)) + return FALSE; + break; + } + return TRUE; +} + +uint32_t +zdr_FSINFO3args (ZDR *zdrs, FSINFO3args *objp) +{ + if (!zdr_nfs_fh3 (zdrs, &objp->fsroot)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_FSINFO3resok (ZDR *zdrs, FSINFO3resok *objp) +{ + register int32_t *buf; + + if (zdrs->x_op == ZDR_ENCODE) { + if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) + return FALSE; + buf = ZDR_INLINE (zdrs, 7 * BYTES_PER_ZDR_UNIT); + if (buf == NULL) { + if (!zdr_u_int (zdrs, &objp->rtmax)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->rtpref)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->rtmult)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->wtmax)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->wtpref)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->wtmult)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->dtpref)) + return FALSE; + + } else { + IZDR_PUT_U_LONG(buf, objp->rtmax); + IZDR_PUT_U_LONG(buf, objp->rtpref); + IZDR_PUT_U_LONG(buf, objp->rtmult); + IZDR_PUT_U_LONG(buf, objp->wtmax); + IZDR_PUT_U_LONG(buf, objp->wtpref); + IZDR_PUT_U_LONG(buf, objp->wtmult); + IZDR_PUT_U_LONG(buf, objp->dtpref); + } + if (!zdr_size3 (zdrs, &objp->maxfilesize)) + return FALSE; + if (!zdr_nfstime3 (zdrs, &objp->time_delta)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->properties)) + return FALSE; + return TRUE; + } else if (zdrs->x_op == ZDR_DECODE) { + if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) + return FALSE; + buf = ZDR_INLINE (zdrs, 7 * BYTES_PER_ZDR_UNIT); + if (buf == NULL) { + if (!zdr_u_int (zdrs, &objp->rtmax)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->rtpref)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->rtmult)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->wtmax)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->wtpref)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->wtmult)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->dtpref)) + return FALSE; + + } else { + objp->rtmax = IZDR_GET_U_LONG(buf); + objp->rtpref = IZDR_GET_U_LONG(buf); + objp->rtmult = IZDR_GET_U_LONG(buf); + objp->wtmax = IZDR_GET_U_LONG(buf); + objp->wtpref = IZDR_GET_U_LONG(buf); + objp->wtmult = IZDR_GET_U_LONG(buf); + objp->dtpref = IZDR_GET_U_LONG(buf); + } + if (!zdr_size3 (zdrs, &objp->maxfilesize)) + return FALSE; + if (!zdr_nfstime3 (zdrs, &objp->time_delta)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->properties)) + return FALSE; + return TRUE; + } + + if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->rtmax)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->rtpref)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->rtmult)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->wtmax)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->wtpref)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->wtmult)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->dtpref)) + return FALSE; + if (!zdr_size3 (zdrs, &objp->maxfilesize)) + return FALSE; + if (!zdr_nfstime3 (zdrs, &objp->time_delta)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->properties)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_FSINFO3resfail (ZDR *zdrs, FSINFO3resfail *objp) +{ + if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_FSINFO3res (ZDR *zdrs, FSINFO3res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_FSINFO3resok (zdrs, &objp->FSINFO3res_u.resok)) + return FALSE; + break; + default: + if (!zdr_FSINFO3resfail (zdrs, &objp->FSINFO3res_u.resfail)) + return FALSE; + break; + } + return TRUE; +} + +uint32_t +zdr_FSSTAT3args (ZDR *zdrs, FSSTAT3args *objp) +{ + if (!zdr_nfs_fh3 (zdrs, &objp->fsroot)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_FSSTAT3resok (ZDR *zdrs, FSSTAT3resok *objp) +{ + if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) + return FALSE; + if (!zdr_size3 (zdrs, &objp->tbytes)) + return FALSE; + if (!zdr_size3 (zdrs, &objp->fbytes)) + return FALSE; + if (!zdr_size3 (zdrs, &objp->abytes)) + return FALSE; + if (!zdr_size3 (zdrs, &objp->tfiles)) + return FALSE; + if (!zdr_size3 (zdrs, &objp->ffiles)) + return FALSE; + if (!zdr_size3 (zdrs, &objp->afiles)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->invarsec)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_FSSTAT3resfail (ZDR *zdrs, FSSTAT3resfail *objp) +{ + if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_FSSTAT3res (ZDR *zdrs, FSSTAT3res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_FSSTAT3resok (zdrs, &objp->FSSTAT3res_u.resok)) + return FALSE; + break; + default: + if (!zdr_FSSTAT3resfail (zdrs, &objp->FSSTAT3res_u.resfail)) + return FALSE; + break; + } + return TRUE; +} + +uint32_t +zdr_PATHCONF3args (ZDR *zdrs, PATHCONF3args *objp) +{ + if (!zdr_nfs_fh3 (zdrs, &objp->object)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PATHCONF3resok (ZDR *zdrs, PATHCONF3resok *objp) +{ + register int32_t *buf; + + if (zdrs->x_op == ZDR_ENCODE) { + if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) + return FALSE; + buf = ZDR_INLINE (zdrs, 6 * BYTES_PER_ZDR_UNIT); + if (buf == NULL) { + if (!zdr_u_int (zdrs, &objp->linkmax)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->name_max)) + return FALSE; + if (!zdr_bool (zdrs, &objp->no_trunc)) + return FALSE; + if (!zdr_bool (zdrs, &objp->chown_restricted)) + return FALSE; + if (!zdr_bool (zdrs, &objp->case_insensitive)) + return FALSE; + if (!zdr_bool (zdrs, &objp->case_preserving)) + return FALSE; + } else { + IZDR_PUT_U_LONG(buf, objp->linkmax); + IZDR_PUT_U_LONG(buf, objp->name_max); + IZDR_PUT_BOOL(buf, objp->no_trunc); + IZDR_PUT_BOOL(buf, objp->chown_restricted); + IZDR_PUT_BOOL(buf, objp->case_insensitive); + IZDR_PUT_BOOL(buf, objp->case_preserving); + } + return TRUE; + } else if (zdrs->x_op == ZDR_DECODE) { + if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) + return FALSE; + buf = ZDR_INLINE (zdrs, 6 * BYTES_PER_ZDR_UNIT); + if (buf == NULL) { + if (!zdr_u_int (zdrs, &objp->linkmax)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->name_max)) + return FALSE; + if (!zdr_bool (zdrs, &objp->no_trunc)) + return FALSE; + if (!zdr_bool (zdrs, &objp->chown_restricted)) + return FALSE; + if (!zdr_bool (zdrs, &objp->case_insensitive)) + return FALSE; + if (!zdr_bool (zdrs, &objp->case_preserving)) + return FALSE; + } else { + objp->linkmax = IZDR_GET_U_LONG(buf); + objp->name_max = IZDR_GET_U_LONG(buf); + objp->no_trunc = IZDR_GET_BOOL(buf); + objp->chown_restricted = IZDR_GET_BOOL(buf); + objp->case_insensitive = IZDR_GET_BOOL(buf); + objp->case_preserving = IZDR_GET_BOOL(buf); + } + return TRUE; + } + + if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->linkmax)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->name_max)) + return FALSE; + if (!zdr_bool (zdrs, &objp->no_trunc)) + return FALSE; + if (!zdr_bool (zdrs, &objp->chown_restricted)) + return FALSE; + if (!zdr_bool (zdrs, &objp->case_insensitive)) + return FALSE; + if (!zdr_bool (zdrs, &objp->case_preserving)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PATHCONF3resfail (ZDR *zdrs, PATHCONF3resfail *objp) +{ + if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PATHCONF3res (ZDR *zdrs, PATHCONF3res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_PATHCONF3resok (zdrs, &objp->PATHCONF3res_u.resok)) + return FALSE; + break; + default: + if (!zdr_PATHCONF3resfail (zdrs, &objp->PATHCONF3res_u.resfail)) + return FALSE; + break; + } + return TRUE; +} + +uint32_t +zdr_nfspath3 (ZDR *zdrs, nfspath3 *objp) +{ + if (!zdr_string (zdrs, objp, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_symlinkdata3 (ZDR *zdrs, symlinkdata3 *objp) +{ + if (!zdr_sattr3 (zdrs, &objp->symlink_attributes)) + return FALSE; + if (!zdr_nfspath3 (zdrs, &objp->symlink_data)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_SYMLINK3args (ZDR *zdrs, SYMLINK3args *objp) +{ + if (!zdr_diropargs3 (zdrs, &objp->where)) + return FALSE; + if (!zdr_symlinkdata3 (zdrs, &objp->symlink)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_SYMLINK3resok (ZDR *zdrs, SYMLINK3resok *objp) +{ + if (!zdr_post_op_fh3 (zdrs, &objp->obj)) + return FALSE; + if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) + return FALSE; + if (!zdr_wcc_data (zdrs, &objp->dir_wcc)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_SYMLINK3resfail (ZDR *zdrs, SYMLINK3resfail *objp) +{ + if (!zdr_wcc_data (zdrs, &objp->dir_wcc)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_SYMLINK3res (ZDR *zdrs, SYMLINK3res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_SYMLINK3resok (zdrs, &objp->SYMLINK3res_u.resok)) + return FALSE; + break; + default: + if (!zdr_SYMLINK3resfail (zdrs, &objp->SYMLINK3res_u.resfail)) + return FALSE; + break; + } + return TRUE; +} + +uint32_t +zdr_READLINK3args (ZDR *zdrs, READLINK3args *objp) +{ + if (!zdr_nfs_fh3 (zdrs, &objp->symlink)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_READLINK3resok (ZDR *zdrs, READLINK3resok *objp) +{ + if (!zdr_post_op_attr (zdrs, &objp->symlink_attributes)) + return FALSE; + if (!zdr_nfspath3 (zdrs, &objp->data)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_READLINK3resfail (ZDR *zdrs, READLINK3resfail *objp) +{ + if (!zdr_post_op_attr (zdrs, &objp->symlink_attributes)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_READLINK3res (ZDR *zdrs, READLINK3res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_READLINK3resok (zdrs, &objp->READLINK3res_u.resok)) + return FALSE; + break; + default: + if (!zdr_READLINK3resfail (zdrs, &objp->READLINK3res_u.resfail)) + return FALSE; + break; + } + return TRUE; +} + +uint32_t +zdr_devicedata3 (ZDR *zdrs, devicedata3 *objp) +{ + if (!zdr_sattr3 (zdrs, &objp->dev_attributes)) + return FALSE; + if (!zdr_specdata3 (zdrs, &objp->spec)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_mknoddata3 (ZDR *zdrs, mknoddata3 *objp) +{ + if (!zdr_ftype3 (zdrs, &objp->type)) + return FALSE; + switch (objp->type) { + case NF3CHR: + if (!zdr_devicedata3 (zdrs, &objp->mknoddata3_u.chr_device)) + return FALSE; + break; + case NF3BLK: + if (!zdr_devicedata3 (zdrs, &objp->mknoddata3_u.blk_device)) + return FALSE; + break; + case NF3SOCK: + if (!zdr_sattr3 (zdrs, &objp->mknoddata3_u.sock_attributes)) + return FALSE; + break; + case NF3FIFO: + if (!zdr_sattr3 (zdrs, &objp->mknoddata3_u.pipe_attributes)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_MKNOD3args (ZDR *zdrs, MKNOD3args *objp) +{ + if (!zdr_diropargs3 (zdrs, &objp->where)) + return FALSE; + if (!zdr_mknoddata3 (zdrs, &objp->what)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_MKNOD3resok (ZDR *zdrs, MKNOD3resok *objp) +{ + if (!zdr_post_op_fh3 (zdrs, &objp->obj)) + return FALSE; + if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) + return FALSE; + if (!zdr_wcc_data (zdrs, &objp->dir_wcc)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_MKNOD3resfail (ZDR *zdrs, MKNOD3resfail *objp) +{ + if (!zdr_wcc_data (zdrs, &objp->dir_wcc)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_MKNOD3res (ZDR *zdrs, MKNOD3res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_MKNOD3resok (zdrs, &objp->MKNOD3res_u.resok)) + return FALSE; + break; + default: + if (!zdr_MKNOD3resfail (zdrs, &objp->MKNOD3res_u.resfail)) + return FALSE; + break; + } + return TRUE; +} + +uint32_t +zdr_MKDIR3args (ZDR *zdrs, MKDIR3args *objp) +{ + if (!zdr_diropargs3 (zdrs, &objp->where)) + return FALSE; + if (!zdr_sattr3 (zdrs, &objp->attributes)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_MKDIR3resok (ZDR *zdrs, MKDIR3resok *objp) +{ + if (!zdr_post_op_fh3 (zdrs, &objp->obj)) + return FALSE; + if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) + return FALSE; + if (!zdr_wcc_data (zdrs, &objp->dir_wcc)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_MKDIR3resfail (ZDR *zdrs, MKDIR3resfail *objp) +{ + if (!zdr_wcc_data (zdrs, &objp->dir_wcc)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_MKDIR3res (ZDR *zdrs, MKDIR3res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_MKDIR3resok (zdrs, &objp->MKDIR3res_u.resok)) + return FALSE; + break; + default: + if (!zdr_MKDIR3resfail (zdrs, &objp->MKDIR3res_u.resfail)) + return FALSE; + break; + } + return TRUE; +} + +uint32_t +zdr_RMDIR3args (ZDR *zdrs, RMDIR3args *objp) +{ + if (!zdr_diropargs3 (zdrs, &objp->object)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_RMDIR3resok (ZDR *zdrs, RMDIR3resok *objp) +{ + if (!zdr_wcc_data (zdrs, &objp->dir_wcc)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_RMDIR3resfail (ZDR *zdrs, RMDIR3resfail *objp) +{ + if (!zdr_wcc_data (zdrs, &objp->dir_wcc)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_RMDIR3res (ZDR *zdrs, RMDIR3res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_RMDIR3resok (zdrs, &objp->RMDIR3res_u.resok)) + return FALSE; + break; + default: + if (!zdr_RMDIR3resfail (zdrs, &objp->RMDIR3res_u.resfail)) + return FALSE; + break; + } + return TRUE; +} + +uint32_t +zdr_RENAME3args (ZDR *zdrs, RENAME3args *objp) +{ + if (!zdr_diropargs3 (zdrs, &objp->from)) + return FALSE; + if (!zdr_diropargs3 (zdrs, &objp->to)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_RENAME3resok (ZDR *zdrs, RENAME3resok *objp) +{ + if (!zdr_wcc_data (zdrs, &objp->fromdir_wcc)) + return FALSE; + if (!zdr_wcc_data (zdrs, &objp->todir_wcc)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_RENAME3resfail (ZDR *zdrs, RENAME3resfail *objp) +{ + if (!zdr_wcc_data (zdrs, &objp->fromdir_wcc)) + return FALSE; + if (!zdr_wcc_data (zdrs, &objp->todir_wcc)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_RENAME3res (ZDR *zdrs, RENAME3res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_RENAME3resok (zdrs, &objp->RENAME3res_u.resok)) + return FALSE; + break; + default: + if (!zdr_RENAME3resfail (zdrs, &objp->RENAME3res_u.resfail)) + return FALSE; + break; + } + return TRUE; +} + +uint32_t +zdr_READDIRPLUS3args (ZDR *zdrs, READDIRPLUS3args *objp) +{ + if (!zdr_nfs_fh3 (zdrs, &objp->dir)) + return FALSE; + if (!zdr_cookie3 (zdrs, &objp->cookie)) + return FALSE; + if (!zdr_cookieverf3 (zdrs, objp->cookieverf)) + return FALSE; + if (!zdr_count3 (zdrs, &objp->dircount)) + return FALSE; + if (!zdr_count3 (zdrs, &objp->maxcount)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_entryplus3 (ZDR *zdrs, entryplus3 *objp) +{ + if (!zdr_fileid3 (zdrs, &objp->fileid)) + return FALSE; + if (!zdr_filename3 (zdrs, &objp->name)) + return FALSE; + if (!zdr_cookie3 (zdrs, &objp->cookie)) + return FALSE; + if (!zdr_post_op_attr (zdrs, &objp->name_attributes)) + return FALSE; + if (!zdr_post_op_fh3 (zdrs, &objp->name_handle)) + return FALSE; + if (!zdr_pointer (zdrs, (char **)&objp->nextentry, sizeof (entryplus3), (zdrproc_t) zdr_entryplus3)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_dirlistplus3 (ZDR *zdrs, dirlistplus3 *objp) +{ + if (!zdr_pointer (zdrs, (char **)&objp->entries, sizeof (entryplus3), (zdrproc_t) zdr_entryplus3)) + return FALSE; + if (!zdr_bool (zdrs, &objp->eof)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_READDIRPLUS3resok (ZDR *zdrs, READDIRPLUS3resok *objp) +{ + if (!zdr_post_op_attr (zdrs, &objp->dir_attributes)) + return FALSE; + if (!zdr_cookieverf3 (zdrs, objp->cookieverf)) + return FALSE; + if (!zdr_dirlistplus3 (zdrs, &objp->reply)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_READDIRPLUS3resfail (ZDR *zdrs, READDIRPLUS3resfail *objp) +{ + if (!zdr_post_op_attr (zdrs, &objp->dir_attributes)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_READDIRPLUS3res (ZDR *zdrs, READDIRPLUS3res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_READDIRPLUS3resok (zdrs, &objp->READDIRPLUS3res_u.resok)) + return FALSE; + break; + default: + if (!zdr_READDIRPLUS3resfail (zdrs, &objp->READDIRPLUS3res_u.resfail)) + return FALSE; + break; + } + return TRUE; +} + +uint32_t +zdr_READDIR3args (ZDR *zdrs, READDIR3args *objp) +{ + if (!zdr_nfs_fh3 (zdrs, &objp->dir)) + return FALSE; + if (!zdr_cookie3 (zdrs, &objp->cookie)) + return FALSE; + if (!zdr_cookieverf3 (zdrs, objp->cookieverf)) + return FALSE; + if (!zdr_count3 (zdrs, &objp->count)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_entry3 (ZDR *zdrs, entry3 *objp) +{ + bool_t more_data; + + one_more: + if (!zdr_fileid3 (zdrs, &objp->fileid)) + return FALSE; + if (!zdr_filename3 (zdrs, &objp->name)) + return FALSE; + if (!zdr_cookie3 (zdrs, &objp->cookie)) + return FALSE; + + if (!libnfs_zdr_bool(zdrs, &more_data)) { + return FALSE; + } + if (more_data) { + goto one_more; + } + return TRUE; +} + +uint32_t +zdr_dirlist3 (ZDR *zdrs, dirlist3 *objp) +{ + if (!zdr_pointer (zdrs, (char **)&objp->entries, sizeof (entry3), (zdrproc_t) zdr_entry3)) + return FALSE; + if (!zdr_bool (zdrs, &objp->eof)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_READDIR3resok (ZDR *zdrs, READDIR3resok *objp) +{ + if (!zdr_post_op_attr (zdrs, &objp->dir_attributes)) + return FALSE; + if (!zdr_cookieverf3 (zdrs, objp->cookieverf)) + return FALSE; + if (!zdr_dirlist3 (zdrs, &objp->reply)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_READDIR3resfail (ZDR *zdrs, READDIR3resfail *objp) +{ + if (!zdr_post_op_attr (zdrs, &objp->dir_attributes)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_READDIR3res (ZDR *zdrs, READDIR3res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_READDIR3resok (zdrs, &objp->READDIR3res_u.resok)) + return FALSE; + break; + default: + if (!zdr_READDIR3resfail (zdrs, &objp->READDIR3res_u.resfail)) + return FALSE; + break; + } + return TRUE; +} + +uint32_t +zdr_LINK3args (ZDR *zdrs, LINK3args *objp) +{ + if (!zdr_nfs_fh3 (zdrs, &objp->file)) + return FALSE; + if (!zdr_diropargs3 (zdrs, &objp->link)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_LINK3resok (ZDR *zdrs, LINK3resok *objp) +{ + if (!zdr_post_op_attr (zdrs, &objp->file_attributes)) + return FALSE; + if (!zdr_wcc_data (zdrs, &objp->linkdir_wcc)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_LINK3resfail (ZDR *zdrs, LINK3resfail *objp) +{ + if (!zdr_post_op_attr (zdrs, &objp->file_attributes)) + return FALSE; + if (!zdr_wcc_data (zdrs, &objp->linkdir_wcc)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_LINK3res (ZDR *zdrs, LINK3res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_LINK3resok (zdrs, &objp->LINK3res_u.resok)) + return FALSE; + break; + default: + if (!zdr_LINK3resfail (zdrs, &objp->LINK3res_u.resfail)) + return FALSE; + break; + } + return TRUE; +} + +uint32_t +zdr_sattrguard3 (ZDR *zdrs, sattrguard3 *objp) +{ + if (!zdr_bool (zdrs, &objp->check)) + return FALSE; + switch (objp->check) { + case TRUE: + if (!zdr_nfstime3 (zdrs, &objp->sattrguard3_u.obj_ctime)) + return FALSE; + break; + case FALSE: + break; + default: + return FALSE; + } + return TRUE; +} + +uint32_t +zdr_SETATTR3args (ZDR *zdrs, SETATTR3args *objp) +{ + if (!zdr_nfs_fh3 (zdrs, &objp->object)) + return FALSE; + if (!zdr_sattr3 (zdrs, &objp->new_attributes)) + return FALSE; + if (!zdr_sattrguard3 (zdrs, &objp->guard)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_SETATTR3resok (ZDR *zdrs, SETATTR3resok *objp) +{ + if (!zdr_wcc_data (zdrs, &objp->obj_wcc)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_SETATTR3resfail (ZDR *zdrs, SETATTR3resfail *objp) +{ + if (!zdr_wcc_data (zdrs, &objp->obj_wcc)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_SETATTR3res (ZDR *zdrs, SETATTR3res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_SETATTR3resok (zdrs, &objp->SETATTR3res_u.resok)) + return FALSE; + break; + default: + if (!zdr_SETATTR3resfail (zdrs, &objp->SETATTR3res_u.resfail)) + return FALSE; + break; + } + return TRUE; +} + +uint32_t +zdr_fhandle2 (ZDR *zdrs, fhandle2 objp) +{ + if (!zdr_opaque (zdrs, objp, FHSIZE2)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_ftype2 (ZDR *zdrs, ftype2 *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr2 (ZDR *zdrs, fattr2 *objp) +{ + register int32_t *buf; + + if (zdrs->x_op == ZDR_ENCODE) { + if (!zdr_ftype2 (zdrs, &objp->type)) + return FALSE; + buf = ZDR_INLINE (zdrs, 10 * BYTES_PER_ZDR_UNIT); + if (buf == NULL) { + if (!zdr_u_int (zdrs, &objp->mode)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->nlink)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->uid)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->gid)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->size)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->blocksize)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->rdev)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->blocks)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->fsid)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->fileid)) + return FALSE; + + } else { + IZDR_PUT_U_LONG(buf, objp->mode); + IZDR_PUT_U_LONG(buf, objp->nlink); + IZDR_PUT_U_LONG(buf, objp->uid); + IZDR_PUT_U_LONG(buf, objp->gid); + IZDR_PUT_U_LONG(buf, objp->size); + IZDR_PUT_U_LONG(buf, objp->blocksize); + IZDR_PUT_U_LONG(buf, objp->rdev); + IZDR_PUT_U_LONG(buf, objp->blocks); + IZDR_PUT_U_LONG(buf, objp->fsid); + IZDR_PUT_U_LONG(buf, objp->fileid); + } + if (!zdr_nfstime3 (zdrs, &objp->atime)) + return FALSE; + if (!zdr_nfstime3 (zdrs, &objp->mtime)) + return FALSE; + if (!zdr_nfstime3 (zdrs, &objp->ctime)) + return FALSE; + return TRUE; + } else if (zdrs->x_op == ZDR_DECODE) { + if (!zdr_ftype2 (zdrs, &objp->type)) + return FALSE; + buf = ZDR_INLINE (zdrs, 10 * BYTES_PER_ZDR_UNIT); + if (buf == NULL) { + if (!zdr_u_int (zdrs, &objp->mode)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->nlink)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->uid)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->gid)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->size)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->blocksize)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->rdev)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->blocks)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->fsid)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->fileid)) + return FALSE; + + } else { + objp->mode = IZDR_GET_U_LONG(buf); + objp->nlink = IZDR_GET_U_LONG(buf); + objp->uid = IZDR_GET_U_LONG(buf); + objp->gid = IZDR_GET_U_LONG(buf); + objp->size = IZDR_GET_U_LONG(buf); + objp->blocksize = IZDR_GET_U_LONG(buf); + objp->rdev = IZDR_GET_U_LONG(buf); + objp->blocks = IZDR_GET_U_LONG(buf); + objp->fsid = IZDR_GET_U_LONG(buf); + objp->fileid = IZDR_GET_U_LONG(buf); + } + if (!zdr_nfstime3 (zdrs, &objp->atime)) + return FALSE; + if (!zdr_nfstime3 (zdrs, &objp->mtime)) + return FALSE; + if (!zdr_nfstime3 (zdrs, &objp->ctime)) + return FALSE; + return TRUE; + } + + if (!zdr_ftype2 (zdrs, &objp->type)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->mode)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->nlink)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->uid)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->gid)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->size)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->blocksize)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->rdev)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->blocks)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->fsid)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->fileid)) + return FALSE; + if (!zdr_nfstime3 (zdrs, &objp->atime)) + return FALSE; + if (!zdr_nfstime3 (zdrs, &objp->mtime)) + return FALSE; + if (!zdr_nfstime3 (zdrs, &objp->ctime)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_sattr2 (ZDR *zdrs, sattr2 *objp) +{ + register int32_t *buf; + + if (zdrs->x_op == ZDR_ENCODE) { + buf = ZDR_INLINE (zdrs, 4 * BYTES_PER_ZDR_UNIT); + if (buf == NULL) { + if (!zdr_u_int (zdrs, &objp->mode)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->uid)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->gid)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->size)) + return FALSE; + + } else { + IZDR_PUT_U_LONG(buf, objp->mode); + IZDR_PUT_U_LONG(buf, objp->uid); + IZDR_PUT_U_LONG(buf, objp->gid); + IZDR_PUT_U_LONG(buf, objp->size); + } + if (!zdr_nfstime3 (zdrs, &objp->atime)) + return FALSE; + if (!zdr_nfstime3 (zdrs, &objp->mtime)) + return FALSE; + return TRUE; + } else if (zdrs->x_op == ZDR_DECODE) { + buf = ZDR_INLINE (zdrs, 4 * BYTES_PER_ZDR_UNIT); + if (buf == NULL) { + if (!zdr_u_int (zdrs, &objp->mode)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->uid)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->gid)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->size)) + return FALSE; + + } else { + objp->mode = IZDR_GET_U_LONG(buf); + objp->uid = IZDR_GET_U_LONG(buf); + objp->gid = IZDR_GET_U_LONG(buf); + objp->size = IZDR_GET_U_LONG(buf); + } + if (!zdr_nfstime3 (zdrs, &objp->atime)) + return FALSE; + if (!zdr_nfstime3 (zdrs, &objp->mtime)) + return FALSE; + return TRUE; + } + + if (!zdr_u_int (zdrs, &objp->mode)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->uid)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->gid)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->size)) + return FALSE; + if (!zdr_nfstime3 (zdrs, &objp->atime)) + return FALSE; + if (!zdr_nfstime3 (zdrs, &objp->mtime)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_filename2 (ZDR *zdrs, filename2 *objp) +{ + if (!zdr_string (zdrs, objp, MAXNAMLEN2)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_path2 (ZDR *zdrs, path2 *objp) +{ + if (!zdr_string (zdrs, objp, MAXPATHLEN2)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_nfsdata2 (ZDR *zdrs, nfsdata2 *objp) +{ + if (!zdr_bytes (zdrs, (char **)&objp->nfsdata2_val, &objp->nfsdata2_len, NFSMAXDATA2)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_nfscookie2 (ZDR *zdrs, nfscookie2 objp) +{ + if (!zdr_opaque (zdrs, objp, NFSCOOKIESIZE2)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_entry2 (ZDR *zdrs, entry2 *objp) +{ + if (!zdr_u_int (zdrs, &objp->fileid)) + return FALSE; + if (!zdr_filename2 (zdrs, &objp->name)) + return FALSE; + if (!zdr_nfscookie2 (zdrs, objp->cookie)) + return FALSE; + if (!zdr_pointer (zdrs, (char **)&objp->nextentry, sizeof (entry2), (zdrproc_t) zdr_entry2)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_diropargs2 (ZDR *zdrs, diropargs2 *objp) +{ + if (!zdr_fhandle2 (zdrs, objp->dir)) + return FALSE; + if (!zdr_filename2 (zdrs, &objp->name)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_GETATTR2args (ZDR *zdrs, GETATTR2args *objp) +{ + if (!zdr_fhandle2 (zdrs, objp->fhandle)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_GETATTR2resok (ZDR *zdrs, GETATTR2resok *objp) +{ + if (!zdr_fattr2 (zdrs, &objp->attributes)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_GETATTR2res (ZDR *zdrs, GETATTR2res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_GETATTR2resok (zdrs, &objp->GETATTR2res_u.resok)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_SETATTR2args (ZDR *zdrs, SETATTR2args *objp) +{ + if (!zdr_fhandle2 (zdrs, objp->fhandle)) + return FALSE; + if (!zdr_sattr2 (zdrs, &objp->attributes)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_SETATTR2resok (ZDR *zdrs, SETATTR2resok *objp) +{ + if (!zdr_fattr2 (zdrs, &objp->attributes)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_SETATTR2res (ZDR *zdrs, SETATTR2res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_SETATTR2resok (zdrs, &objp->SETATTR2res_u.resok)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_LOOKUP2args (ZDR *zdrs, LOOKUP2args *objp) +{ + if (!zdr_diropargs2 (zdrs, &objp->what)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_LOOKUP2resok (ZDR *zdrs, LOOKUP2resok *objp) +{ + if (!zdr_fhandle2 (zdrs, objp->file)) + return FALSE; + if (!zdr_fattr2 (zdrs, &objp->attributes)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_LOOKUP2res (ZDR *zdrs, LOOKUP2res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_LOOKUP2resok (zdrs, &objp->LOOKUP2res_u.resok)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_READLINK2args (ZDR *zdrs, READLINK2args *objp) +{ + if (!zdr_fhandle2 (zdrs, objp->file)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_READLINK2resok (ZDR *zdrs, READLINK2resok *objp) +{ + if (!zdr_path2 (zdrs, &objp->data)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_READLINK2res (ZDR *zdrs, READLINK2res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_READLINK2resok (zdrs, &objp->READLINK2res_u.resok)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_READ2args (ZDR *zdrs, READ2args *objp) +{ + if (!zdr_fhandle2 (zdrs, objp->file)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->offset)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->count)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->totalcount)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_READ2resok (ZDR *zdrs, READ2resok *objp) +{ + if (!zdr_fattr2 (zdrs, &objp->attributes)) + return FALSE; + if (!zdr_nfsdata2 (zdrs, &objp->data)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_READ2res (ZDR *zdrs, READ2res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_READ2resok (zdrs, &objp->READ2res_u.resok)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_WRITE2args (ZDR *zdrs, WRITE2args *objp) +{ + register int32_t *buf; + + if (zdrs->x_op == ZDR_ENCODE) { + if (!zdr_fhandle2 (zdrs, objp->file)) + return FALSE; + buf = ZDR_INLINE (zdrs, 3 * BYTES_PER_ZDR_UNIT); + if (buf == NULL) { + if (!zdr_u_int (zdrs, &objp->beginoffset)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->offset)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->totalcount)) + return FALSE; + + } else { + IZDR_PUT_U_LONG(buf, objp->beginoffset); + IZDR_PUT_U_LONG(buf, objp->offset); + IZDR_PUT_U_LONG(buf, objp->totalcount); + } + if (!zdr_nfsdata2 (zdrs, &objp->data)) + return FALSE; + return TRUE; + } else if (zdrs->x_op == ZDR_DECODE) { + if (!zdr_fhandle2 (zdrs, objp->file)) + return FALSE; + buf = ZDR_INLINE (zdrs, 3 * BYTES_PER_ZDR_UNIT); + if (buf == NULL) { + if (!zdr_u_int (zdrs, &objp->beginoffset)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->offset)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->totalcount)) + return FALSE; + + } else { + objp->beginoffset = IZDR_GET_U_LONG(buf); + objp->offset = IZDR_GET_U_LONG(buf); + objp->totalcount = IZDR_GET_U_LONG(buf); + } + if (!zdr_nfsdata2 (zdrs, &objp->data)) + return FALSE; + return TRUE; + } + + if (!zdr_fhandle2 (zdrs, objp->file)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->beginoffset)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->offset)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->totalcount)) + return FALSE; + if (!zdr_nfsdata2 (zdrs, &objp->data)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_WRITE2resok (ZDR *zdrs, WRITE2resok *objp) +{ + if (!zdr_fattr2 (zdrs, &objp->attributes)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_WRITE2res (ZDR *zdrs, WRITE2res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_WRITE2resok (zdrs, &objp->WRITE2res_u.resok)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_CREATE2args (ZDR *zdrs, CREATE2args *objp) +{ + if (!zdr_diropargs2 (zdrs, &objp->where)) + return FALSE; + if (!zdr_sattr2 (zdrs, &objp->attributes)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_CREATE2resok (ZDR *zdrs, CREATE2resok *objp) +{ + if (!zdr_fhandle2 (zdrs, objp->file)) + return FALSE; + if (!zdr_fattr2 (zdrs, &objp->attributes)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_CREATE2res (ZDR *zdrs, CREATE2res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_CREATE2resok (zdrs, &objp->CREATE2res_u.resok)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_REMOVE2args (ZDR *zdrs, REMOVE2args *objp) +{ + if (!zdr_diropargs2 (zdrs, &objp->what)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_REMOVE2res (ZDR *zdrs, REMOVE2res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_RENAME2args (ZDR *zdrs, RENAME2args *objp) +{ + if (!zdr_diropargs2 (zdrs, &objp->from)) + return FALSE; + if (!zdr_diropargs2 (zdrs, &objp->to)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_RENAME2res (ZDR *zdrs, RENAME2res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_LINK2args (ZDR *zdrs, LINK2args *objp) +{ + if (!zdr_fhandle2 (zdrs, objp->from)) + return FALSE; + if (!zdr_diropargs2 (zdrs, &objp->to)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_LINK2res (ZDR *zdrs, LINK2res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_SYMLINK2args (ZDR *zdrs, SYMLINK2args *objp) +{ + if (!zdr_diropargs2 (zdrs, &objp->from)) + return FALSE; + if (!zdr_path2 (zdrs, &objp->to)) + return FALSE; + if (!zdr_sattr2 (zdrs, &objp->attributes)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_SYMLINK2res (ZDR *zdrs, SYMLINK2res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_MKDIR2args (ZDR *zdrs, MKDIR2args *objp) +{ + if (!zdr_diropargs2 (zdrs, &objp->where)) + return FALSE; + if (!zdr_sattr2 (zdrs, &objp->attributes)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_MKDIR2resok (ZDR *zdrs, MKDIR2resok *objp) +{ + if (!zdr_fhandle2 (zdrs, objp->file)) + return FALSE; + if (!zdr_fattr2 (zdrs, &objp->attributes)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_MKDIR2res (ZDR *zdrs, MKDIR2res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_MKDIR2resok (zdrs, &objp->MKDIR2res_u.resok)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_RMDIR2args (ZDR *zdrs, RMDIR2args *objp) +{ + if (!zdr_diropargs2 (zdrs, &objp->what)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_RMDIR2res (ZDR *zdrs, RMDIR2res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_READDIR2args (ZDR *zdrs, READDIR2args *objp) +{ + if (!zdr_fhandle2 (zdrs, objp->dir)) + return FALSE; + if (!zdr_nfscookie2 (zdrs, objp->cookie)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->count)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_READDIR2resok (ZDR *zdrs, READDIR2resok *objp) +{ + if (!zdr_pointer (zdrs, (char **)&objp->entries, sizeof (entry2), (zdrproc_t) zdr_entry2)) + return FALSE; + if (!zdr_bool (zdrs, &objp->eof)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_READDIR2res (ZDR *zdrs, READDIR2res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_READDIR2resok (zdrs, &objp->READDIR2res_u.resok)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_STATFS2args (ZDR *zdrs, STATFS2args *objp) +{ + if (!zdr_fhandle2 (zdrs, objp->dir)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_STATFS2resok (ZDR *zdrs, STATFS2resok *objp) +{ + register int32_t *buf; + + if (zdrs->x_op == ZDR_ENCODE) { + buf = ZDR_INLINE (zdrs, 5 * BYTES_PER_ZDR_UNIT); + if (buf == NULL) { + if (!zdr_u_int (zdrs, &objp->tsize)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->bsize)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->blocks)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->bfree)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->bavail)) + return FALSE; + } else { + IZDR_PUT_U_LONG(buf, objp->tsize); + IZDR_PUT_U_LONG(buf, objp->bsize); + IZDR_PUT_U_LONG(buf, objp->blocks); + IZDR_PUT_U_LONG(buf, objp->bfree); + IZDR_PUT_U_LONG(buf, objp->bavail); + } + return TRUE; + } else if (zdrs->x_op == ZDR_DECODE) { + buf = ZDR_INLINE (zdrs, 5 * BYTES_PER_ZDR_UNIT); + if (buf == NULL) { + if (!zdr_u_int (zdrs, &objp->tsize)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->bsize)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->blocks)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->bfree)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->bavail)) + return FALSE; + } else { + objp->tsize = IZDR_GET_U_LONG(buf); + objp->bsize = IZDR_GET_U_LONG(buf); + objp->blocks = IZDR_GET_U_LONG(buf); + objp->bfree = IZDR_GET_U_LONG(buf); + objp->bavail = IZDR_GET_U_LONG(buf); + } + return TRUE; + } + + if (!zdr_u_int (zdrs, &objp->tsize)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->bsize)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->blocks)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->bfree)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->bavail)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_STATFS2res (ZDR *zdrs, STATFS2res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_STATFS2resok (zdrs, &objp->STATFS2res_u.resok)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_nfsacl_type (ZDR *zdrs, nfsacl_type *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_nfsacl_ace (ZDR *zdrs, nfsacl_ace *objp) +{ + if (!zdr_nfsacl_type (zdrs, &objp->type)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->id)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->perm)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_GETACL3args (ZDR *zdrs, GETACL3args *objp) +{ + if (!zdr_nfs_fh3 (zdrs, &objp->dir)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->mask)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_GETACL3resok (ZDR *zdrs, GETACL3resok *objp) +{ + if (!zdr_post_op_attr (zdrs, &objp->attr)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->mask)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->ace_count)) + return FALSE; + if (!zdr_array (zdrs, (char **)&objp->ace.ace_val, &objp->ace.ace_len, ~0, + sizeof (nfsacl_ace), (zdrproc_t) zdr_nfsacl_ace)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->default_ace_count)) + return FALSE; + if (!zdr_array (zdrs, (char **)&objp->default_ace.default_ace_val, &objp->default_ace.default_ace_len, ~0, + sizeof (nfsacl_ace), (zdrproc_t) zdr_nfsacl_ace)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_GETACL3res (ZDR *zdrs, GETACL3res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_GETACL3resok (zdrs, &objp->GETACL3res_u.resok)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_SETACL3args (ZDR *zdrs, SETACL3args *objp) +{ + if (!zdr_nfs_fh3 (zdrs, &objp->dir)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->mask)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->ace_count)) + return FALSE; + if (!zdr_array (zdrs, (char **)&objp->ace.ace_val, &objp->ace.ace_len, ~0, + sizeof (nfsacl_ace), (zdrproc_t) zdr_nfsacl_ace)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->default_ace_count)) + return FALSE; + if (!zdr_array (zdrs, (char **)&objp->default_ace.default_ace_val, &objp->default_ace.default_ace_len, ~0, + sizeof (nfsacl_ace), (zdrproc_t) zdr_nfsacl_ace)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_SETACL3resok (ZDR *zdrs, SETACL3resok *objp) +{ + if (!zdr_post_op_attr (zdrs, &objp->attr)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_SETACL3res (ZDR *zdrs, SETACL3res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_SETACL3resok (zdrs, &objp->SETACL3res_u.resok)) + return FALSE; + break; + default: + break; + } + return TRUE; +} diff --git a/deps/libnfs/nfs/libnfs-raw-nfs.h b/deps/libnfs/nfs/libnfs-raw-nfs.h new file mode 100644 index 000000000000..05a6fc4c8bf7 --- /dev/null +++ b/deps/libnfs/nfs/libnfs-raw-nfs.h @@ -0,0 +1,2063 @@ +/* +Copyright (c) 2014, Ronnie Sahlberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +/* + * Please do not edit this file. + * It was generated using rpcgen. + */ + +#ifndef _NFS_H_RPCGEN +#define _NFS_H_RPCGEN +#include + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +#define NFS3_FHSIZE 64 +#define NFS3_WRITEVERFSIZE 8 +#define NFS3_CREATEVERFSIZE 8 +#define NFS3_COOKIEVERFSIZE 8 + + + +typedef char cookieverf3[NFS3_COOKIEVERFSIZE]; + +typedef uint64_t cookie3; + +struct nfs_fh3 { + struct { + uint32_t data_len; + char *data_val; + } data; +}; +typedef struct nfs_fh3 nfs_fh3; + +typedef char *filename3; + +struct diropargs3 { + nfs_fh3 dir; + filename3 name; +}; +typedef struct diropargs3 diropargs3; + +enum ftype3 { + NF3REG = 1, + NF3DIR = 2, + NF3BLK = 3, + NF3CHR = 4, + NF3LNK = 5, + NF3SOCK = 6, + NF3FIFO = 7, +}; +typedef enum ftype3 ftype3; + +typedef uint32_t mode3; + +typedef uint32_t uid3; + +typedef uint32_t gid3; + +typedef uint64_t size3; + +typedef uint64_t fileid3; + +struct specdata3 { + uint32_t specdata1; + uint32_t specdata2; +}; +typedef struct specdata3 specdata3; + +struct nfstime3 { + uint32_t seconds; + uint32_t nseconds; +}; +typedef struct nfstime3 nfstime3; + +struct fattr3 { + ftype3 type; + mode3 mode; + uint32_t nlink; + uid3 uid; + gid3 gid; + size3 size; + size3 used; + specdata3 rdev; + uint64_t fsid; + fileid3 fileid; + nfstime3 atime; + nfstime3 mtime; + nfstime3 ctime; +}; +typedef struct fattr3 fattr3; + +struct post_op_attr { + uint32_t attributes_follow; + union { + fattr3 attributes; + } post_op_attr_u; +}; +typedef struct post_op_attr post_op_attr; + +enum nfsstat3 { + NFS3_OK = 0, + NFS3ERR_PERM = 1, + NFS3ERR_NOENT = 2, + NFS3ERR_IO = 5, + NFS3ERR_NXIO = 6, + NFS3ERR_ACCES = 13, + NFS3ERR_EXIST = 17, + NFS3ERR_XDEV = 18, + NFS3ERR_NODEV = 19, + NFS3ERR_NOTDIR = 20, + NFS3ERR_ISDIR = 21, + NFS3ERR_INVAL = 22, + NFS3ERR_FBIG = 27, + NFS3ERR_NOSPC = 28, + NFS3ERR_ROFS = 30, + NFS3ERR_MLINK = 31, + NFS3ERR_NAMETOOLONG = 63, + NFS3ERR_NOTEMPTY = 66, + NFS3ERR_DQUOT = 69, + NFS3ERR_STALE = 70, + NFS3ERR_REMOTE = 71, + NFS3ERR_BADHANDLE = 10001, + NFS3ERR_NOT_SYNC = 10002, + NFS3ERR_BAD_COOKIE = 10003, + NFS3ERR_NOTSUPP = 10004, + NFS3ERR_TOOSMALL = 10005, + NFS3ERR_SERVERFAULT = 10006, + NFS3ERR_BADTYPE = 10007, + NFS3ERR_JUKEBOX = 10008, +}; +typedef enum nfsstat3 nfsstat3; + +enum stable_how { + UNSTABLE = 0, + DATA_SYNC = 1, + FILE_SYNC = 2, +}; +typedef enum stable_how stable_how; + +typedef uint64_t offset3; + +typedef uint32_t count3; + +struct wcc_attr { + size3 size; + nfstime3 mtime; + nfstime3 ctime; +}; +typedef struct wcc_attr wcc_attr; + +struct pre_op_attr { + uint32_t attributes_follow; + union { + wcc_attr attributes; + } pre_op_attr_u; +}; +typedef struct pre_op_attr pre_op_attr; + +struct wcc_data { + pre_op_attr before; + post_op_attr after; +}; +typedef struct wcc_data wcc_data; + +struct WRITE3args { + nfs_fh3 file; + offset3 offset; + count3 count; + stable_how stable; + struct { + uint32_t data_len; + char *data_val; + } data; +}; +typedef struct WRITE3args WRITE3args; + +typedef char writeverf3[NFS3_WRITEVERFSIZE]; + +struct WRITE3resok { + wcc_data file_wcc; + count3 count; + stable_how committed; + writeverf3 verf; +}; +typedef struct WRITE3resok WRITE3resok; + +struct WRITE3resfail { + wcc_data file_wcc; +}; +typedef struct WRITE3resfail WRITE3resfail; + +struct WRITE3res { + nfsstat3 status; + union { + WRITE3resok resok; + WRITE3resfail resfail; + } WRITE3res_u; +}; +typedef struct WRITE3res WRITE3res; + +struct LOOKUP3args { + diropargs3 what; +}; +typedef struct LOOKUP3args LOOKUP3args; + +struct LOOKUP3resok { + nfs_fh3 object; + post_op_attr obj_attributes; + post_op_attr dir_attributes; +}; +typedef struct LOOKUP3resok LOOKUP3resok; + +struct LOOKUP3resfail { + post_op_attr dir_attributes; +}; +typedef struct LOOKUP3resfail LOOKUP3resfail; + +struct LOOKUP3res { + nfsstat3 status; + union { + LOOKUP3resok resok; + LOOKUP3resfail resfail; + } LOOKUP3res_u; +}; +typedef struct LOOKUP3res LOOKUP3res; + +struct COMMIT3args { + nfs_fh3 file; + offset3 offset; + count3 count; +}; +typedef struct COMMIT3args COMMIT3args; + +struct COMMIT3resok { + wcc_data file_wcc; + writeverf3 verf; +}; +typedef struct COMMIT3resok COMMIT3resok; + +struct COMMIT3resfail { + wcc_data file_wcc; +}; +typedef struct COMMIT3resfail COMMIT3resfail; + +struct COMMIT3res { + nfsstat3 status; + union { + COMMIT3resok resok; + COMMIT3resfail resfail; + } COMMIT3res_u; +}; +typedef struct COMMIT3res COMMIT3res; +#define ACCESS3_READ 0x0001 +#define ACCESS3_LOOKUP 0x0002 +#define ACCESS3_MODIFY 0x0004 +#define ACCESS3_EXTEND 0x0008 +#define ACCESS3_DELETE 0x0010 +#define ACCESS3_EXECUTE 0x0020 + +struct ACCESS3args { + nfs_fh3 object; + uint32_t access; +}; +typedef struct ACCESS3args ACCESS3args; + +struct ACCESS3resok { + post_op_attr obj_attributes; + uint32_t access; +}; +typedef struct ACCESS3resok ACCESS3resok; + +struct ACCESS3resfail { + post_op_attr obj_attributes; +}; +typedef struct ACCESS3resfail ACCESS3resfail; + +struct ACCESS3res { + nfsstat3 status; + union { + ACCESS3resok resok; + ACCESS3resfail resfail; + } ACCESS3res_u; +}; +typedef struct ACCESS3res ACCESS3res; + +struct GETATTR3args { + nfs_fh3 object; +}; +typedef struct GETATTR3args GETATTR3args; + +struct GETATTR3resok { + fattr3 obj_attributes; +}; +typedef struct GETATTR3resok GETATTR3resok; + +struct GETATTR3res { + nfsstat3 status; + union { + GETATTR3resok resok; + } GETATTR3res_u; +}; +typedef struct GETATTR3res GETATTR3res; + +enum time_how { + DONT_CHANGE = 0, + SET_TO_SERVER_TIME = 1, + SET_TO_CLIENT_TIME = 2, +}; +typedef enum time_how time_how; + +struct set_mode3 { + uint32_t set_it; + union { + mode3 mode; + } set_mode3_u; +}; +typedef struct set_mode3 set_mode3; + +struct set_uid3 { + uint32_t set_it; + union { + uid3 uid; + } set_uid3_u; +}; +typedef struct set_uid3 set_uid3; + +struct set_gid3 { + uint32_t set_it; + union { + gid3 gid; + } set_gid3_u; +}; +typedef struct set_gid3 set_gid3; + +struct set_size3 { + uint32_t set_it; + union { + size3 size; + } set_size3_u; +}; +typedef struct set_size3 set_size3; + +struct set_atime { + time_how set_it; + union { + nfstime3 atime; + } set_atime_u; +}; +typedef struct set_atime set_atime; + +struct set_mtime { + time_how set_it; + union { + nfstime3 mtime; + } set_mtime_u; +}; +typedef struct set_mtime set_mtime; + +struct sattr3 { + set_mode3 mode; + set_uid3 uid; + set_gid3 gid; + set_size3 size; + set_atime atime; + set_mtime mtime; +}; +typedef struct sattr3 sattr3; + +enum createmode3 { + UNCHECKED = 0, + GUARDED = 1, + EXCLUSIVE = 2, +}; +typedef enum createmode3 createmode3; + +typedef char createverf3[NFS3_CREATEVERFSIZE]; + +struct createhow3 { + createmode3 mode; + union { + sattr3 obj_attributes; + sattr3 g_obj_attributes; + createverf3 verf; + } createhow3_u; +}; +typedef struct createhow3 createhow3; + +struct CREATE3args { + diropargs3 where; + createhow3 how; +}; +typedef struct CREATE3args CREATE3args; + +struct post_op_fh3 { + uint32_t handle_follows; + union { + nfs_fh3 handle; + } post_op_fh3_u; +}; +typedef struct post_op_fh3 post_op_fh3; + +struct CREATE3resok { + post_op_fh3 obj; + post_op_attr obj_attributes; + wcc_data dir_wcc; +}; +typedef struct CREATE3resok CREATE3resok; + +struct CREATE3resfail { + wcc_data dir_wcc; +}; +typedef struct CREATE3resfail CREATE3resfail; + +struct CREATE3res { + nfsstat3 status; + union { + CREATE3resok resok; + CREATE3resfail resfail; + } CREATE3res_u; +}; +typedef struct CREATE3res CREATE3res; + +struct REMOVE3args { + diropargs3 object; +}; +typedef struct REMOVE3args REMOVE3args; + +struct REMOVE3resok { + wcc_data dir_wcc; +}; +typedef struct REMOVE3resok REMOVE3resok; + +struct REMOVE3resfail { + wcc_data dir_wcc; +}; +typedef struct REMOVE3resfail REMOVE3resfail; + +struct REMOVE3res { + nfsstat3 status; + union { + REMOVE3resok resok; + REMOVE3resfail resfail; + } REMOVE3res_u; +}; +typedef struct REMOVE3res REMOVE3res; + +struct READ3args { + nfs_fh3 file; + offset3 offset; + count3 count; +}; +typedef struct READ3args READ3args; + +struct READ3resok { + post_op_attr file_attributes; + count3 count; + uint32_t eof; + struct { + uint32_t data_len; + char *data_val; + } data; +}; +typedef struct READ3resok READ3resok; + +struct READ3resfail { + post_op_attr file_attributes; +}; +typedef struct READ3resfail READ3resfail; + +struct READ3res { + nfsstat3 status; + union { + READ3resok resok; + READ3resfail resfail; + } READ3res_u; +}; +typedef struct READ3res READ3res; +#define FSF3_LINK 0x0001 +#define FSF3_SYMLINK 0x0002 +#define FSF3_HOMOGENEOUS 0x0008 +#define FSF3_CANSETTIME 0x0010 + +struct FSINFO3args { + nfs_fh3 fsroot; +}; +typedef struct FSINFO3args FSINFO3args; + +struct FSINFO3resok { + post_op_attr obj_attributes; + uint32_t rtmax; + uint32_t rtpref; + uint32_t rtmult; + uint32_t wtmax; + uint32_t wtpref; + uint32_t wtmult; + uint32_t dtpref; + size3 maxfilesize; + nfstime3 time_delta; + uint32_t properties; +}; +typedef struct FSINFO3resok FSINFO3resok; + +struct FSINFO3resfail { + post_op_attr obj_attributes; +}; +typedef struct FSINFO3resfail FSINFO3resfail; + +struct FSINFO3res { + nfsstat3 status; + union { + FSINFO3resok resok; + FSINFO3resfail resfail; + } FSINFO3res_u; +}; +typedef struct FSINFO3res FSINFO3res; + +struct FSSTAT3args { + nfs_fh3 fsroot; +}; +typedef struct FSSTAT3args FSSTAT3args; + +struct FSSTAT3resok { + post_op_attr obj_attributes; + size3 tbytes; + size3 fbytes; + size3 abytes; + size3 tfiles; + size3 ffiles; + size3 afiles; + uint32_t invarsec; +}; +typedef struct FSSTAT3resok FSSTAT3resok; + +struct FSSTAT3resfail { + post_op_attr obj_attributes; +}; +typedef struct FSSTAT3resfail FSSTAT3resfail; + +struct FSSTAT3res { + nfsstat3 status; + union { + FSSTAT3resok resok; + FSSTAT3resfail resfail; + } FSSTAT3res_u; +}; +typedef struct FSSTAT3res FSSTAT3res; + +struct PATHCONF3args { + nfs_fh3 object; +}; +typedef struct PATHCONF3args PATHCONF3args; + +struct PATHCONF3resok { + post_op_attr obj_attributes; + uint32_t linkmax; + uint32_t name_max; + uint32_t no_trunc; + uint32_t chown_restricted; + uint32_t case_insensitive; + uint32_t case_preserving; +}; +typedef struct PATHCONF3resok PATHCONF3resok; + +struct PATHCONF3resfail { + post_op_attr obj_attributes; +}; +typedef struct PATHCONF3resfail PATHCONF3resfail; + +struct PATHCONF3res { + nfsstat3 status; + union { + PATHCONF3resok resok; + PATHCONF3resfail resfail; + } PATHCONF3res_u; +}; +typedef struct PATHCONF3res PATHCONF3res; + +typedef char *nfspath3; + +struct symlinkdata3 { + sattr3 symlink_attributes; + nfspath3 symlink_data; +}; +typedef struct symlinkdata3 symlinkdata3; + +struct SYMLINK3args { + diropargs3 where; + symlinkdata3 symlink; +}; +typedef struct SYMLINK3args SYMLINK3args; + +struct SYMLINK3resok { + post_op_fh3 obj; + post_op_attr obj_attributes; + wcc_data dir_wcc; +}; +typedef struct SYMLINK3resok SYMLINK3resok; + +struct SYMLINK3resfail { + wcc_data dir_wcc; +}; +typedef struct SYMLINK3resfail SYMLINK3resfail; + +struct SYMLINK3res { + nfsstat3 status; + union { + SYMLINK3resok resok; + SYMLINK3resfail resfail; + } SYMLINK3res_u; +}; +typedef struct SYMLINK3res SYMLINK3res; + +struct READLINK3args { + nfs_fh3 symlink; +}; +typedef struct READLINK3args READLINK3args; + +struct READLINK3resok { + post_op_attr symlink_attributes; + nfspath3 data; +}; +typedef struct READLINK3resok READLINK3resok; + +struct READLINK3resfail { + post_op_attr symlink_attributes; +}; +typedef struct READLINK3resfail READLINK3resfail; + +struct READLINK3res { + nfsstat3 status; + union { + READLINK3resok resok; + READLINK3resfail resfail; + } READLINK3res_u; +}; +typedef struct READLINK3res READLINK3res; + +struct devicedata3 { + sattr3 dev_attributes; + specdata3 spec; +}; +typedef struct devicedata3 devicedata3; + +struct mknoddata3 { + ftype3 type; + union { + devicedata3 chr_device; + devicedata3 blk_device; + sattr3 sock_attributes; + sattr3 pipe_attributes; + } mknoddata3_u; +}; +typedef struct mknoddata3 mknoddata3; + +struct MKNOD3args { + diropargs3 where; + mknoddata3 what; +}; +typedef struct MKNOD3args MKNOD3args; + +struct MKNOD3resok { + post_op_fh3 obj; + post_op_attr obj_attributes; + wcc_data dir_wcc; +}; +typedef struct MKNOD3resok MKNOD3resok; + +struct MKNOD3resfail { + wcc_data dir_wcc; +}; +typedef struct MKNOD3resfail MKNOD3resfail; + +struct MKNOD3res { + nfsstat3 status; + union { + MKNOD3resok resok; + MKNOD3resfail resfail; + } MKNOD3res_u; +}; +typedef struct MKNOD3res MKNOD3res; + +struct MKDIR3args { + diropargs3 where; + sattr3 attributes; +}; +typedef struct MKDIR3args MKDIR3args; + +struct MKDIR3resok { + post_op_fh3 obj; + post_op_attr obj_attributes; + wcc_data dir_wcc; +}; +typedef struct MKDIR3resok MKDIR3resok; + +struct MKDIR3resfail { + wcc_data dir_wcc; +}; +typedef struct MKDIR3resfail MKDIR3resfail; + +struct MKDIR3res { + nfsstat3 status; + union { + MKDIR3resok resok; + MKDIR3resfail resfail; + } MKDIR3res_u; +}; +typedef struct MKDIR3res MKDIR3res; + +struct RMDIR3args { + diropargs3 object; +}; +typedef struct RMDIR3args RMDIR3args; + +struct RMDIR3resok { + wcc_data dir_wcc; +}; +typedef struct RMDIR3resok RMDIR3resok; + +struct RMDIR3resfail { + wcc_data dir_wcc; +}; +typedef struct RMDIR3resfail RMDIR3resfail; + +struct RMDIR3res { + nfsstat3 status; + union { + RMDIR3resok resok; + RMDIR3resfail resfail; + } RMDIR3res_u; +}; +typedef struct RMDIR3res RMDIR3res; + +struct RENAME3args { + diropargs3 from; + diropargs3 to; +}; +typedef struct RENAME3args RENAME3args; + +struct RENAME3resok { + wcc_data fromdir_wcc; + wcc_data todir_wcc; +}; +typedef struct RENAME3resok RENAME3resok; + +struct RENAME3resfail { + wcc_data fromdir_wcc; + wcc_data todir_wcc; +}; +typedef struct RENAME3resfail RENAME3resfail; + +struct RENAME3res { + nfsstat3 status; + union { + RENAME3resok resok; + RENAME3resfail resfail; + } RENAME3res_u; +}; +typedef struct RENAME3res RENAME3res; + +struct READDIRPLUS3args { + nfs_fh3 dir; + cookie3 cookie; + cookieverf3 cookieverf; + count3 dircount; + count3 maxcount; +}; +typedef struct READDIRPLUS3args READDIRPLUS3args; + +struct entryplus3 { + fileid3 fileid; + filename3 name; + cookie3 cookie; + post_op_attr name_attributes; + post_op_fh3 name_handle; + struct entryplus3 *nextentry; +}; +typedef struct entryplus3 entryplus3; + +struct dirlistplus3 { + entryplus3 *entries; + uint32_t eof; +}; +typedef struct dirlistplus3 dirlistplus3; + +struct READDIRPLUS3resok { + post_op_attr dir_attributes; + cookieverf3 cookieverf; + dirlistplus3 reply; +}; +typedef struct READDIRPLUS3resok READDIRPLUS3resok; + +struct READDIRPLUS3resfail { + post_op_attr dir_attributes; +}; +typedef struct READDIRPLUS3resfail READDIRPLUS3resfail; + +struct READDIRPLUS3res { + nfsstat3 status; + union { + READDIRPLUS3resok resok; + READDIRPLUS3resfail resfail; + } READDIRPLUS3res_u; +}; +typedef struct READDIRPLUS3res READDIRPLUS3res; + +struct READDIR3args { + nfs_fh3 dir; + cookie3 cookie; + cookieverf3 cookieverf; + count3 count; +}; +typedef struct READDIR3args READDIR3args; + +struct entry3 { + fileid3 fileid; + filename3 name; + cookie3 cookie; + struct entry3 *nextentry; +}; +typedef struct entry3 entry3; + +struct dirlist3 { + entry3 *entries; + uint32_t eof; +}; +typedef struct dirlist3 dirlist3; + +struct READDIR3resok { + post_op_attr dir_attributes; + cookieverf3 cookieverf; + dirlist3 reply; +}; +typedef struct READDIR3resok READDIR3resok; + +struct READDIR3resfail { + post_op_attr dir_attributes; +}; +typedef struct READDIR3resfail READDIR3resfail; + +struct READDIR3res { + nfsstat3 status; + union { + READDIR3resok resok; + READDIR3resfail resfail; + } READDIR3res_u; +}; +typedef struct READDIR3res READDIR3res; + +struct LINK3args { + nfs_fh3 file; + diropargs3 link; +}; +typedef struct LINK3args LINK3args; + +struct LINK3resok { + post_op_attr file_attributes; + wcc_data linkdir_wcc; +}; +typedef struct LINK3resok LINK3resok; + +struct LINK3resfail { + post_op_attr file_attributes; + wcc_data linkdir_wcc; +}; +typedef struct LINK3resfail LINK3resfail; + +struct LINK3res { + nfsstat3 status; + union { + LINK3resok resok; + LINK3resfail resfail; + } LINK3res_u; +}; +typedef struct LINK3res LINK3res; + +struct sattrguard3 { + uint32_t check; + union { + nfstime3 obj_ctime; + } sattrguard3_u; +}; +typedef struct sattrguard3 sattrguard3; + +struct SETATTR3args { + nfs_fh3 object; + sattr3 new_attributes; + sattrguard3 guard; +}; +typedef struct SETATTR3args SETATTR3args; + +struct SETATTR3resok { + wcc_data obj_wcc; +}; +typedef struct SETATTR3resok SETATTR3resok; + +struct SETATTR3resfail { + wcc_data obj_wcc; +}; +typedef struct SETATTR3resfail SETATTR3resfail; + +struct SETATTR3res { + nfsstat3 status; + union { + SETATTR3resok resok; + SETATTR3resfail resfail; + } SETATTR3res_u; +}; +typedef struct SETATTR3res SETATTR3res; +#define FHSIZE2 32 + +typedef char fhandle2[FHSIZE2]; + +enum ftype2 { + NF2NON = 0, + NF2REG = 1, + NF2DIR = 2, + NF2BLK = 3, + NF2CHR = 4, + NF2LNK = 5, +}; +typedef enum ftype2 ftype2; + +struct fattr2 { + ftype2 type; + uint32_t mode; + uint32_t nlink; + uint32_t uid; + uint32_t gid; + uint32_t size; + uint32_t blocksize; + uint32_t rdev; + uint32_t blocks; + uint32_t fsid; + uint32_t fileid; + nfstime3 atime; + nfstime3 mtime; + nfstime3 ctime; +}; +typedef struct fattr2 fattr2; + +struct sattr2 { + uint32_t mode; + uint32_t uid; + uint32_t gid; + uint32_t size; + nfstime3 atime; + nfstime3 mtime; +}; +typedef struct sattr2 sattr2; +#define MAXNAMLEN2 255 + +typedef char *filename2; +#define MAXPATHLEN2 1024 + +typedef char *path2; +#define NFSMAXDATA2 8192 + +typedef struct { + uint32_t nfsdata2_len; + char *nfsdata2_val; +} nfsdata2; +#define NFSCOOKIESIZE2 4 + +typedef char nfscookie2[NFSCOOKIESIZE2]; + +struct entry2 { + uint32_t fileid; + filename2 name; + nfscookie2 cookie; + struct entry2 *nextentry; +}; +typedef struct entry2 entry2; + +struct diropargs2 { + fhandle2 dir; + filename2 name; +}; +typedef struct diropargs2 diropargs2; + +struct GETATTR2args { + fhandle2 fhandle; +}; +typedef struct GETATTR2args GETATTR2args; + +struct GETATTR2resok { + fattr2 attributes; +}; +typedef struct GETATTR2resok GETATTR2resok; + +struct GETATTR2res { + nfsstat3 status; + union { + GETATTR2resok resok; + } GETATTR2res_u; +}; +typedef struct GETATTR2res GETATTR2res; + +struct SETATTR2args { + fhandle2 fhandle; + sattr2 attributes; +}; +typedef struct SETATTR2args SETATTR2args; + +struct SETATTR2resok { + fattr2 attributes; +}; +typedef struct SETATTR2resok SETATTR2resok; + +struct SETATTR2res { + nfsstat3 status; + union { + SETATTR2resok resok; + } SETATTR2res_u; +}; +typedef struct SETATTR2res SETATTR2res; + +struct LOOKUP2args { + diropargs2 what; +}; +typedef struct LOOKUP2args LOOKUP2args; + +struct LOOKUP2resok { + fhandle2 file; + fattr2 attributes; +}; +typedef struct LOOKUP2resok LOOKUP2resok; + +struct LOOKUP2res { + nfsstat3 status; + union { + LOOKUP2resok resok; + } LOOKUP2res_u; +}; +typedef struct LOOKUP2res LOOKUP2res; + +struct READLINK2args { + fhandle2 file; +}; +typedef struct READLINK2args READLINK2args; + +struct READLINK2resok { + path2 data; +}; +typedef struct READLINK2resok READLINK2resok; + +struct READLINK2res { + nfsstat3 status; + union { + READLINK2resok resok; + } READLINK2res_u; +}; +typedef struct READLINK2res READLINK2res; + +struct READ2args { + fhandle2 file; + uint32_t offset; + uint32_t count; + uint32_t totalcount; +}; +typedef struct READ2args READ2args; + +struct READ2resok { + fattr2 attributes; + nfsdata2 data; +}; +typedef struct READ2resok READ2resok; + +struct READ2res { + nfsstat3 status; + union { + READ2resok resok; + } READ2res_u; +}; +typedef struct READ2res READ2res; + +struct WRITE2args { + fhandle2 file; + uint32_t beginoffset; + uint32_t offset; + uint32_t totalcount; + nfsdata2 data; +}; +typedef struct WRITE2args WRITE2args; + +struct WRITE2resok { + fattr2 attributes; +}; +typedef struct WRITE2resok WRITE2resok; + +struct WRITE2res { + nfsstat3 status; + union { + WRITE2resok resok; + } WRITE2res_u; +}; +typedef struct WRITE2res WRITE2res; + +struct CREATE2args { + diropargs2 where; + sattr2 attributes; +}; +typedef struct CREATE2args CREATE2args; + +struct CREATE2resok { + fhandle2 file; + fattr2 attributes; +}; +typedef struct CREATE2resok CREATE2resok; + +struct CREATE2res { + nfsstat3 status; + union { + CREATE2resok resok; + } CREATE2res_u; +}; +typedef struct CREATE2res CREATE2res; + +struct REMOVE2args { + diropargs2 what; +}; +typedef struct REMOVE2args REMOVE2args; + +struct REMOVE2res { + nfsstat3 status; +}; +typedef struct REMOVE2res REMOVE2res; + +struct RENAME2args { + diropargs2 from; + diropargs2 to; +}; +typedef struct RENAME2args RENAME2args; + +struct RENAME2res { + nfsstat3 status; +}; +typedef struct RENAME2res RENAME2res; + +struct LINK2args { + fhandle2 from; + diropargs2 to; +}; +typedef struct LINK2args LINK2args; + +struct LINK2res { + nfsstat3 status; +}; +typedef struct LINK2res LINK2res; + +struct SYMLINK2args { + diropargs2 from; + path2 to; + sattr2 attributes; +}; +typedef struct SYMLINK2args SYMLINK2args; + +struct SYMLINK2res { + nfsstat3 status; +}; +typedef struct SYMLINK2res SYMLINK2res; + +struct MKDIR2args { + diropargs2 where; + sattr2 attributes; +}; +typedef struct MKDIR2args MKDIR2args; + +struct MKDIR2resok { + fhandle2 file; + fattr2 attributes; +}; +typedef struct MKDIR2resok MKDIR2resok; + +struct MKDIR2res { + nfsstat3 status; + union { + MKDIR2resok resok; + } MKDIR2res_u; +}; +typedef struct MKDIR2res MKDIR2res; + +struct RMDIR2args { + diropargs2 what; +}; +typedef struct RMDIR2args RMDIR2args; + +struct RMDIR2res { + nfsstat3 status; +}; +typedef struct RMDIR2res RMDIR2res; + +struct READDIR2args { + fhandle2 dir; + nfscookie2 cookie; + uint32_t count; +}; +typedef struct READDIR2args READDIR2args; + +struct READDIR2resok { + entry2 *entries; + uint32_t eof; +}; +typedef struct READDIR2resok READDIR2resok; + +struct READDIR2res { + nfsstat3 status; + union { + READDIR2resok resok; + } READDIR2res_u; +}; +typedef struct READDIR2res READDIR2res; + +struct STATFS2args { + fhandle2 dir; +}; +typedef struct STATFS2args STATFS2args; + +struct STATFS2resok { + uint32_t tsize; + uint32_t bsize; + uint32_t blocks; + uint32_t bfree; + uint32_t bavail; +}; +typedef struct STATFS2resok STATFS2resok; + +struct STATFS2res { + nfsstat3 status; + union { + STATFS2resok resok; + } STATFS2res_u; +}; +typedef struct STATFS2res STATFS2res; + +enum nfsacl_type { + NFSACL_TYPE_USER_OBJ = 0x0001, + NFSACL_TYPE_USER = 0x0002, + NFSACL_TYPE_GROUP_OBJ = 0x0004, + NFSACL_TYPE_GROUP = 0x0008, + NFSACL_TYPE_CLASS_OBJ = 0x0010, + NFSACL_TYPE_CLASS = 0x0020, + NFSACL_TYPE_DEFAULT = 0x1000, + NFSACL_TYPE_DEFAULT_USER_OBJ = 0x1001, + NFSACL_TYPE_DEFAULT_USER = 0x1002, + NFSACL_TYPE_DEFAULT_GROUP_OBJ = 0x1004, + NFSACL_TYPE_DEFAULT_GROUP = 0x1008, + NFSACL_TYPE_DEFAULT_CLASS_OBJ = 0x1010, + NFSACL_TYPE_DEFAULT_OTHER_OBJ = 0x1020, +}; +typedef enum nfsacl_type nfsacl_type; +#define NFSACL_PERM_READ 0x04 +#define NFSACL_PERM_WRITE 0x02 +#define NFSACL_PERM_EXEC 0x01 + +struct nfsacl_ace { + enum nfsacl_type type; + uint32_t id; + uint32_t perm; +}; +typedef struct nfsacl_ace nfsacl_ace; +#define NFSACL_MASK_ACL_ENTRY 0x0001 +#define NFSACL_MASK_ACL_COUNT 0x0002 +#define NFSACL_MASK_ACL_DEFAULT_ENTRY 0x0004 +#define NFSACL_MASK_ACL_DEFAULT_COUNT 0x0008 + +struct GETACL3args { + nfs_fh3 dir; + uint32_t mask; +}; +typedef struct GETACL3args GETACL3args; + +struct GETACL3resok { + post_op_attr attr; + uint32_t mask; + uint32_t ace_count; + struct { + uint32_t ace_len; + struct nfsacl_ace *ace_val; + } ace; + uint32_t default_ace_count; + struct { + uint32_t default_ace_len; + struct nfsacl_ace *default_ace_val; + } default_ace; +}; +typedef struct GETACL3resok GETACL3resok; + +struct GETACL3res { + nfsstat3 status; + union { + GETACL3resok resok; + } GETACL3res_u; +}; +typedef struct GETACL3res GETACL3res; + +struct SETACL3args { + nfs_fh3 dir; + uint32_t mask; + uint32_t ace_count; + struct { + uint32_t ace_len; + struct nfsacl_ace *ace_val; + } ace; + uint32_t default_ace_count; + struct { + uint32_t default_ace_len; + struct nfsacl_ace *default_ace_val; + } default_ace; +}; +typedef struct SETACL3args SETACL3args; + +struct SETACL3resok { + post_op_attr attr; +}; +typedef struct SETACL3resok SETACL3resok; + +struct SETACL3res { + nfsstat3 status; + union { + SETACL3resok resok; + } SETACL3res_u; +}; +typedef struct SETACL3res SETACL3res; + +#define NFS_PROGRAM 100003 +#define NFS_V2 2 + +#if defined(__STDC__) || defined(__cplusplus) +#define NFS2_NULL 0 +extern void * nfs2_null_2(void *, void *); +extern void * nfs2_null_2_svc(void *, struct svc_req *); +#define NFS2_GETATTR 1 +extern GETATTR2res * nfs2_getattr_2(GETATTR2args *, void *); +extern GETATTR2res * nfs2_getattr_2_svc(GETATTR2args *, struct svc_req *); +#define NFS2_SETATTR 2 +extern SETATTR2res * nfs2_setattr_2(SETATTR2args *, void *); +extern SETATTR2res * nfs2_setattr_2_svc(SETATTR2args *, struct svc_req *); +#define NFS2_LOOKUP 4 +extern LOOKUP2res * nfs2_lookup_2(LOOKUP2args *, void *); +extern LOOKUP2res * nfs2_lookup_2_svc(LOOKUP2args *, struct svc_req *); +#define NFS2_READLINK 5 +extern READLINK2res * nfs2_readlink_2(READLINK2args *, void *); +extern READLINK2res * nfs2_readlink_2_svc(READLINK2args *, struct svc_req *); +#define NFS2_READ 6 +extern READ2res * nfs2_read_2(READ2args *, void *); +extern READ2res * nfs2_read_2_svc(READ2args *, struct svc_req *); +#define NFS2_WRITE 8 +extern WRITE2res * nfs2_write_2(WRITE2args *, void *); +extern WRITE2res * nfs2_write_2_svc(WRITE2args *, struct svc_req *); +#define NFS2_CREATE 9 +extern CREATE2res * nfs2_create_2(CREATE2args *, void *); +extern CREATE2res * nfs2_create_2_svc(CREATE2args *, struct svc_req *); +#define NFS2_REMOVE 10 +extern REMOVE2res * nfs2_remove_2(REMOVE2args *, void *); +extern REMOVE2res * nfs2_remove_2_svc(REMOVE2args *, struct svc_req *); +#define NFS2_RENAME 11 +extern RENAME2res * nfs2_rename_2(RENAME2args *, void *); +extern RENAME2res * nfs2_rename_2_svc(RENAME2args *, struct svc_req *); +#define NFS2_LINK 12 +extern LINK2res * nfs2_link_2(LINK2args *, void *); +extern LINK2res * nfs2_link_2_svc(LINK2args *, struct svc_req *); +#define NFS2_SYMLINK 13 +extern SYMLINK2res * nfs2_symlink_2(SYMLINK2args *, void *); +extern SYMLINK2res * nfs2_symlink_2_svc(SYMLINK2args *, struct svc_req *); +#define NFS2_MKDIR 14 +extern MKDIR2res * nfs2_mkdir_2(MKDIR2args *, void *); +extern MKDIR2res * nfs2_mkdir_2_svc(MKDIR2args *, struct svc_req *); +#define NFS2_RMDIR 15 +extern RMDIR2res * nfs2_rmdir_2(RMDIR2args *, void *); +extern RMDIR2res * nfs2_rmdir_2_svc(RMDIR2args *, struct svc_req *); +#define NFS2_READDIR 16 +extern READDIR2res * nfs2_readdir_2(READDIR2args *, void *); +extern READDIR2res * nfs2_readdir_2_svc(READDIR2args *, struct svc_req *); +#define NFS2_STATFS 17 +extern STATFS2res * nfs2_statfs_2(STATFS2args *, void *); +extern STATFS2res * nfs2_statfs_2_svc(STATFS2args *, struct svc_req *); +extern int nfs_program_2_freeresult (void *, zdrproc_t, caddr_t); + +#else /* K&R C */ +#define NFS2_NULL 0 +extern void * nfs2_null_2(); +extern void * nfs2_null_2_svc(); +#define NFS2_GETATTR 1 +extern GETATTR2res * nfs2_getattr_2(); +extern GETATTR2res * nfs2_getattr_2_svc(); +#define NFS2_SETATTR 2 +extern SETATTR2res * nfs2_setattr_2(); +extern SETATTR2res * nfs2_setattr_2_svc(); +#define NFS2_LOOKUP 4 +extern LOOKUP2res * nfs2_lookup_2(); +extern LOOKUP2res * nfs2_lookup_2_svc(); +#define NFS2_READLINK 5 +extern READLINK2res * nfs2_readlink_2(); +extern READLINK2res * nfs2_readlink_2_svc(); +#define NFS2_READ 6 +extern READ2res * nfs2_read_2(); +extern READ2res * nfs2_read_2_svc(); +#define NFS2_WRITE 8 +extern WRITE2res * nfs2_write_2(); +extern WRITE2res * nfs2_write_2_svc(); +#define NFS2_CREATE 9 +extern CREATE2res * nfs2_create_2(); +extern CREATE2res * nfs2_create_2_svc(); +#define NFS2_REMOVE 10 +extern REMOVE2res * nfs2_remove_2(); +extern REMOVE2res * nfs2_remove_2_svc(); +#define NFS2_RENAME 11 +extern RENAME2res * nfs2_rename_2(); +extern RENAME2res * nfs2_rename_2_svc(); +#define NFS2_LINK 12 +extern LINK2res * nfs2_link_2(); +extern LINK2res * nfs2_link_2_svc(); +#define NFS2_SYMLINK 13 +extern SYMLINK2res * nfs2_symlink_2(); +extern SYMLINK2res * nfs2_symlink_2_svc(); +#define NFS2_MKDIR 14 +extern MKDIR2res * nfs2_mkdir_2(); +extern MKDIR2res * nfs2_mkdir_2_svc(); +#define NFS2_RMDIR 15 +extern RMDIR2res * nfs2_rmdir_2(); +extern RMDIR2res * nfs2_rmdir_2_svc(); +#define NFS2_READDIR 16 +extern READDIR2res * nfs2_readdir_2(); +extern READDIR2res * nfs2_readdir_2_svc(); +#define NFS2_STATFS 17 +extern STATFS2res * nfs2_statfs_2(); +extern STATFS2res * nfs2_statfs_2_svc(); +extern int nfs_program_2_freeresult (); +#endif /* K&R C */ +#define NFS_V3 3 + +#if defined(__STDC__) || defined(__cplusplus) +#define NFS3_NULL 0 +extern void * nfs3_null_3(void *, void *); +extern void * nfs3_null_3_svc(void *, struct svc_req *); +#define NFS3_GETATTR 1 +extern GETATTR3res * nfs3_getattr_3(GETATTR3args *, void *); +extern GETATTR3res * nfs3_getattr_3_svc(GETATTR3args *, struct svc_req *); +#define NFS3_SETATTR 2 +extern SETATTR3res * nfs3_setattr_3(SETATTR3args *, void *); +extern SETATTR3res * nfs3_setattr_3_svc(SETATTR3args *, struct svc_req *); +#define NFS3_LOOKUP 3 +extern LOOKUP3res * nfs3_lookup_3(LOOKUP3args *, void *); +extern LOOKUP3res * nfs3_lookup_3_svc(LOOKUP3args *, struct svc_req *); +#define NFS3_ACCESS 4 +extern ACCESS3res * nfs3_access_3(ACCESS3args *, void *); +extern ACCESS3res * nfs3_access_3_svc(ACCESS3args *, struct svc_req *); +#define NFS3_READLINK 5 +extern READLINK3res * nfs3_readlink_3(READLINK3args *, void *); +extern READLINK3res * nfs3_readlink_3_svc(READLINK3args *, struct svc_req *); +#define NFS3_READ 6 +extern READ3res * nfs3_read_3(READ3args *, void *); +extern READ3res * nfs3_read_3_svc(READ3args *, struct svc_req *); +#define NFS3_WRITE 7 +extern WRITE3res * nfs3_write_3(WRITE3args *, void *); +extern WRITE3res * nfs3_write_3_svc(WRITE3args *, struct svc_req *); +#define NFS3_CREATE 8 +extern CREATE3res * nfs3_create_3(CREATE3args *, void *); +extern CREATE3res * nfs3_create_3_svc(CREATE3args *, struct svc_req *); +#define NFS3_MKDIR 9 +extern MKDIR3res * nfs3_mkdir_3(MKDIR3args *, void *); +extern MKDIR3res * nfs3_mkdir_3_svc(MKDIR3args *, struct svc_req *); +#define NFS3_SYMLINK 10 +extern SYMLINK3res * nfs3_symlink_3(SYMLINK3args *, void *); +extern SYMLINK3res * nfs3_symlink_3_svc(SYMLINK3args *, struct svc_req *); +#define NFS3_MKNOD 11 +extern MKNOD3res * nfs3_mknod_3(MKNOD3args *, void *); +extern MKNOD3res * nfs3_mknod_3_svc(MKNOD3args *, struct svc_req *); +#define NFS3_REMOVE 12 +extern REMOVE3res * nfs3_remove_3(REMOVE3args *, void *); +extern REMOVE3res * nfs3_remove_3_svc(REMOVE3args *, struct svc_req *); +#define NFS3_RMDIR 13 +extern RMDIR3res * nfs3_rmdir_3(RMDIR3args *, void *); +extern RMDIR3res * nfs3_rmdir_3_svc(RMDIR3args *, struct svc_req *); +#define NFS3_RENAME 14 +extern RENAME3res * nfs3_rename_3(RENAME3args *, void *); +extern RENAME3res * nfs3_rename_3_svc(RENAME3args *, struct svc_req *); +#define NFS3_LINK 15 +extern LINK3res * nfs3_link_3(LINK3args *, void *); +extern LINK3res * nfs3_link_3_svc(LINK3args *, struct svc_req *); +#define NFS3_READDIR 16 +extern READDIR3res * nfs3_readdir_3(READDIR3args *, void *); +extern READDIR3res * nfs3_readdir_3_svc(READDIR3args *, struct svc_req *); +#define NFS3_READDIRPLUS 17 +extern READDIRPLUS3res * nfs3_readdirplus_3(READDIRPLUS3args *, void *); +extern READDIRPLUS3res * nfs3_readdirplus_3_svc(READDIRPLUS3args *, struct svc_req *); +#define NFS3_FSSTAT 18 +extern FSSTAT3res * nfs3_fsstat_3(FSSTAT3args *, void *); +extern FSSTAT3res * nfs3_fsstat_3_svc(FSSTAT3args *, struct svc_req *); +#define NFS3_FSINFO 19 +extern FSINFO3res * nfs3_fsinfo_3(FSINFO3args *, void *); +extern FSINFO3res * nfs3_fsinfo_3_svc(FSINFO3args *, struct svc_req *); +#define NFS3_PATHCONF 20 +extern PATHCONF3res * nfs3_pathconf_3(PATHCONF3args *, void *); +extern PATHCONF3res * nfs3_pathconf_3_svc(PATHCONF3args *, struct svc_req *); +#define NFS3_COMMIT 21 +extern COMMIT3res * nfs3_commit_3(COMMIT3args *, void *); +extern COMMIT3res * nfs3_commit_3_svc(COMMIT3args *, struct svc_req *); +extern int nfs_program_3_freeresult (void *, zdrproc_t, caddr_t); + +#else /* K&R C */ +#define NFS3_NULL 0 +extern void * nfs3_null_3(); +extern void * nfs3_null_3_svc(); +#define NFS3_GETATTR 1 +extern GETATTR3res * nfs3_getattr_3(); +extern GETATTR3res * nfs3_getattr_3_svc(); +#define NFS3_SETATTR 2 +extern SETATTR3res * nfs3_setattr_3(); +extern SETATTR3res * nfs3_setattr_3_svc(); +#define NFS3_LOOKUP 3 +extern LOOKUP3res * nfs3_lookup_3(); +extern LOOKUP3res * nfs3_lookup_3_svc(); +#define NFS3_ACCESS 4 +extern ACCESS3res * nfs3_access_3(); +extern ACCESS3res * nfs3_access_3_svc(); +#define NFS3_READLINK 5 +extern READLINK3res * nfs3_readlink_3(); +extern READLINK3res * nfs3_readlink_3_svc(); +#define NFS3_READ 6 +extern READ3res * nfs3_read_3(); +extern READ3res * nfs3_read_3_svc(); +#define NFS3_WRITE 7 +extern WRITE3res * nfs3_write_3(); +extern WRITE3res * nfs3_write_3_svc(); +#define NFS3_CREATE 8 +extern CREATE3res * nfs3_create_3(); +extern CREATE3res * nfs3_create_3_svc(); +#define NFS3_MKDIR 9 +extern MKDIR3res * nfs3_mkdir_3(); +extern MKDIR3res * nfs3_mkdir_3_svc(); +#define NFS3_SYMLINK 10 +extern SYMLINK3res * nfs3_symlink_3(); +extern SYMLINK3res * nfs3_symlink_3_svc(); +#define NFS3_MKNOD 11 +extern MKNOD3res * nfs3_mknod_3(); +extern MKNOD3res * nfs3_mknod_3_svc(); +#define NFS3_REMOVE 12 +extern REMOVE3res * nfs3_remove_3(); +extern REMOVE3res * nfs3_remove_3_svc(); +#define NFS3_RMDIR 13 +extern RMDIR3res * nfs3_rmdir_3(); +extern RMDIR3res * nfs3_rmdir_3_svc(); +#define NFS3_RENAME 14 +extern RENAME3res * nfs3_rename_3(); +extern RENAME3res * nfs3_rename_3_svc(); +#define NFS3_LINK 15 +extern LINK3res * nfs3_link_3(); +extern LINK3res * nfs3_link_3_svc(); +#define NFS3_READDIR 16 +extern READDIR3res * nfs3_readdir_3(); +extern READDIR3res * nfs3_readdir_3_svc(); +#define NFS3_READDIRPLUS 17 +extern READDIRPLUS3res * nfs3_readdirplus_3(); +extern READDIRPLUS3res * nfs3_readdirplus_3_svc(); +#define NFS3_FSSTAT 18 +extern FSSTAT3res * nfs3_fsstat_3(); +extern FSSTAT3res * nfs3_fsstat_3_svc(); +#define NFS3_FSINFO 19 +extern FSINFO3res * nfs3_fsinfo_3(); +extern FSINFO3res * nfs3_fsinfo_3_svc(); +#define NFS3_PATHCONF 20 +extern PATHCONF3res * nfs3_pathconf_3(); +extern PATHCONF3res * nfs3_pathconf_3_svc(); +#define NFS3_COMMIT 21 +extern COMMIT3res * nfs3_commit_3(); +extern COMMIT3res * nfs3_commit_3_svc(); +extern int nfs_program_3_freeresult (); +#endif /* K&R C */ + +#define NFSACL_PROGRAM 100227 +#define NFSACL_V3 3 + +#if defined(__STDC__) || defined(__cplusplus) +#define NFSACL3_NULL 0 +extern void * nfsacl3_null_3(void *, void *); +extern void * nfsacl3_null_3_svc(void *, struct svc_req *); +#define NFSACL3_GETACL 1 +extern GETACL3res * nfsacl3_getacl_3(GETACL3args *, void *); +extern GETACL3res * nfsacl3_getacl_3_svc(GETACL3args *, struct svc_req *); +#define NFSACL3_SETACL 2 +extern SETACL3res * nfsacl3_setacl_3(SETACL3args *, void *); +extern SETACL3res * nfsacl3_setacl_3_svc(SETACL3args *, struct svc_req *); +extern int nfsacl_program_3_freeresult (void *, zdrproc_t, caddr_t); + +#else /* K&R C */ +#define NFSACL3_NULL 0 +extern void * nfsacl3_null_3(); +extern void * nfsacl3_null_3_svc(); +#define NFSACL3_GETACL 1 +extern GETACL3res * nfsacl3_getacl_3(); +extern GETACL3res * nfsacl3_getacl_3_svc(); +#define NFSACL3_SETACL 2 +extern SETACL3res * nfsacl3_setacl_3(); +extern SETACL3res * nfsacl3_setacl_3_svc(); +extern int nfsacl_program_3_freeresult (); +#endif /* K&R C */ + +/* the zdr functions */ + +#if defined(__STDC__) || defined(__cplusplus) +extern uint32_t zdr_cookieverf3 (ZDR *, cookieverf3); +extern uint32_t zdr_cookie3 (ZDR *, cookie3*); +extern uint32_t zdr_nfs_fh3 (ZDR *, nfs_fh3*); +extern uint32_t zdr_filename3 (ZDR *, filename3*); +extern uint32_t zdr_diropargs3 (ZDR *, diropargs3*); +extern uint32_t zdr_ftype3 (ZDR *, ftype3*); +extern uint32_t zdr_mode3 (ZDR *, mode3*); +extern uint32_t zdr_uid3 (ZDR *, uid3*); +extern uint32_t zdr_gid3 (ZDR *, gid3*); +extern uint32_t zdr_size3 (ZDR *, size3*); +extern uint32_t zdr_fileid3 (ZDR *, fileid3*); +extern uint32_t zdr_specdata3 (ZDR *, specdata3*); +extern uint32_t zdr_nfstime3 (ZDR *, nfstime3*); +extern uint32_t zdr_fattr3 (ZDR *, fattr3*); +extern uint32_t zdr_post_op_attr (ZDR *, post_op_attr*); +extern uint32_t zdr_nfsstat3 (ZDR *, nfsstat3*); +extern uint32_t zdr_stable_how (ZDR *, stable_how*); +extern uint32_t zdr_offset3 (ZDR *, offset3*); +extern uint32_t zdr_count3 (ZDR *, count3*); +extern uint32_t zdr_wcc_attr (ZDR *, wcc_attr*); +extern uint32_t zdr_pre_op_attr (ZDR *, pre_op_attr*); +extern uint32_t zdr_wcc_data (ZDR *, wcc_data*); +extern uint32_t zdr_WRITE3args (ZDR *, WRITE3args*); +extern uint32_t zdr_writeverf3 (ZDR *, writeverf3); +extern uint32_t zdr_WRITE3resok (ZDR *, WRITE3resok*); +extern uint32_t zdr_WRITE3resfail (ZDR *, WRITE3resfail*); +extern uint32_t zdr_WRITE3res (ZDR *, WRITE3res*); +extern uint32_t zdr_LOOKUP3args (ZDR *, LOOKUP3args*); +extern uint32_t zdr_LOOKUP3resok (ZDR *, LOOKUP3resok*); +extern uint32_t zdr_LOOKUP3resfail (ZDR *, LOOKUP3resfail*); +extern uint32_t zdr_LOOKUP3res (ZDR *, LOOKUP3res*); +extern uint32_t zdr_COMMIT3args (ZDR *, COMMIT3args*); +extern uint32_t zdr_COMMIT3resok (ZDR *, COMMIT3resok*); +extern uint32_t zdr_COMMIT3resfail (ZDR *, COMMIT3resfail*); +extern uint32_t zdr_COMMIT3res (ZDR *, COMMIT3res*); +extern uint32_t zdr_ACCESS3args (ZDR *, ACCESS3args*); +extern uint32_t zdr_ACCESS3resok (ZDR *, ACCESS3resok*); +extern uint32_t zdr_ACCESS3resfail (ZDR *, ACCESS3resfail*); +extern uint32_t zdr_ACCESS3res (ZDR *, ACCESS3res*); +extern uint32_t zdr_GETATTR3args (ZDR *, GETATTR3args*); +extern uint32_t zdr_GETATTR3resok (ZDR *, GETATTR3resok*); +extern uint32_t zdr_GETATTR3res (ZDR *, GETATTR3res*); +extern uint32_t zdr_time_how (ZDR *, time_how*); +extern uint32_t zdr_set_mode3 (ZDR *, set_mode3*); +extern uint32_t zdr_set_uid3 (ZDR *, set_uid3*); +extern uint32_t zdr_set_gid3 (ZDR *, set_gid3*); +extern uint32_t zdr_set_size3 (ZDR *, set_size3*); +extern uint32_t zdr_set_atime (ZDR *, set_atime*); +extern uint32_t zdr_set_mtime (ZDR *, set_mtime*); +extern uint32_t zdr_sattr3 (ZDR *, sattr3*); +extern uint32_t zdr_createmode3 (ZDR *, createmode3*); +extern uint32_t zdr_createverf3 (ZDR *, createverf3); +extern uint32_t zdr_createhow3 (ZDR *, createhow3*); +extern uint32_t zdr_CREATE3args (ZDR *, CREATE3args*); +extern uint32_t zdr_post_op_fh3 (ZDR *, post_op_fh3*); +extern uint32_t zdr_CREATE3resok (ZDR *, CREATE3resok*); +extern uint32_t zdr_CREATE3resfail (ZDR *, CREATE3resfail*); +extern uint32_t zdr_CREATE3res (ZDR *, CREATE3res*); +extern uint32_t zdr_REMOVE3args (ZDR *, REMOVE3args*); +extern uint32_t zdr_REMOVE3resok (ZDR *, REMOVE3resok*); +extern uint32_t zdr_REMOVE3resfail (ZDR *, REMOVE3resfail*); +extern uint32_t zdr_REMOVE3res (ZDR *, REMOVE3res*); +extern uint32_t zdr_READ3args (ZDR *, READ3args*); +extern uint32_t zdr_READ3resok (ZDR *, READ3resok*); +extern uint32_t zdr_READ3resfail (ZDR *, READ3resfail*); +extern uint32_t zdr_READ3res (ZDR *, READ3res*); +extern uint32_t zdr_FSINFO3args (ZDR *, FSINFO3args*); +extern uint32_t zdr_FSINFO3resok (ZDR *, FSINFO3resok*); +extern uint32_t zdr_FSINFO3resfail (ZDR *, FSINFO3resfail*); +extern uint32_t zdr_FSINFO3res (ZDR *, FSINFO3res*); +extern uint32_t zdr_FSSTAT3args (ZDR *, FSSTAT3args*); +extern uint32_t zdr_FSSTAT3resok (ZDR *, FSSTAT3resok*); +extern uint32_t zdr_FSSTAT3resfail (ZDR *, FSSTAT3resfail*); +extern uint32_t zdr_FSSTAT3res (ZDR *, FSSTAT3res*); +extern uint32_t zdr_PATHCONF3args (ZDR *, PATHCONF3args*); +extern uint32_t zdr_PATHCONF3resok (ZDR *, PATHCONF3resok*); +extern uint32_t zdr_PATHCONF3resfail (ZDR *, PATHCONF3resfail*); +extern uint32_t zdr_PATHCONF3res (ZDR *, PATHCONF3res*); +extern uint32_t zdr_nfspath3 (ZDR *, nfspath3*); +extern uint32_t zdr_symlinkdata3 (ZDR *, symlinkdata3*); +extern uint32_t zdr_SYMLINK3args (ZDR *, SYMLINK3args*); +extern uint32_t zdr_SYMLINK3resok (ZDR *, SYMLINK3resok*); +extern uint32_t zdr_SYMLINK3resfail (ZDR *, SYMLINK3resfail*); +extern uint32_t zdr_SYMLINK3res (ZDR *, SYMLINK3res*); +extern uint32_t zdr_READLINK3args (ZDR *, READLINK3args*); +extern uint32_t zdr_READLINK3resok (ZDR *, READLINK3resok*); +extern uint32_t zdr_READLINK3resfail (ZDR *, READLINK3resfail*); +extern uint32_t zdr_READLINK3res (ZDR *, READLINK3res*); +extern uint32_t zdr_devicedata3 (ZDR *, devicedata3*); +extern uint32_t zdr_mknoddata3 (ZDR *, mknoddata3*); +extern uint32_t zdr_MKNOD3args (ZDR *, MKNOD3args*); +extern uint32_t zdr_MKNOD3resok (ZDR *, MKNOD3resok*); +extern uint32_t zdr_MKNOD3resfail (ZDR *, MKNOD3resfail*); +extern uint32_t zdr_MKNOD3res (ZDR *, MKNOD3res*); +extern uint32_t zdr_MKDIR3args (ZDR *, MKDIR3args*); +extern uint32_t zdr_MKDIR3resok (ZDR *, MKDIR3resok*); +extern uint32_t zdr_MKDIR3resfail (ZDR *, MKDIR3resfail*); +extern uint32_t zdr_MKDIR3res (ZDR *, MKDIR3res*); +extern uint32_t zdr_RMDIR3args (ZDR *, RMDIR3args*); +extern uint32_t zdr_RMDIR3resok (ZDR *, RMDIR3resok*); +extern uint32_t zdr_RMDIR3resfail (ZDR *, RMDIR3resfail*); +extern uint32_t zdr_RMDIR3res (ZDR *, RMDIR3res*); +extern uint32_t zdr_RENAME3args (ZDR *, RENAME3args*); +extern uint32_t zdr_RENAME3resok (ZDR *, RENAME3resok*); +extern uint32_t zdr_RENAME3resfail (ZDR *, RENAME3resfail*); +extern uint32_t zdr_RENAME3res (ZDR *, RENAME3res*); +extern uint32_t zdr_READDIRPLUS3args (ZDR *, READDIRPLUS3args*); +extern uint32_t zdr_entryplus3 (ZDR *, entryplus3*); +extern uint32_t zdr_dirlistplus3 (ZDR *, dirlistplus3*); +extern uint32_t zdr_READDIRPLUS3resok (ZDR *, READDIRPLUS3resok*); +extern uint32_t zdr_READDIRPLUS3resfail (ZDR *, READDIRPLUS3resfail*); +extern uint32_t zdr_READDIRPLUS3res (ZDR *, READDIRPLUS3res*); +extern uint32_t zdr_READDIR3args (ZDR *, READDIR3args*); +extern uint32_t zdr_entry3 (ZDR *, entry3*); +extern uint32_t zdr_dirlist3 (ZDR *, dirlist3*); +extern uint32_t zdr_READDIR3resok (ZDR *, READDIR3resok*); +extern uint32_t zdr_READDIR3resfail (ZDR *, READDIR3resfail*); +extern uint32_t zdr_READDIR3res (ZDR *, READDIR3res*); +extern uint32_t zdr_LINK3args (ZDR *, LINK3args*); +extern uint32_t zdr_LINK3resok (ZDR *, LINK3resok*); +extern uint32_t zdr_LINK3resfail (ZDR *, LINK3resfail*); +extern uint32_t zdr_LINK3res (ZDR *, LINK3res*); +extern uint32_t zdr_sattrguard3 (ZDR *, sattrguard3*); +extern uint32_t zdr_SETATTR3args (ZDR *, SETATTR3args*); +extern uint32_t zdr_SETATTR3resok (ZDR *, SETATTR3resok*); +extern uint32_t zdr_SETATTR3resfail (ZDR *, SETATTR3resfail*); +extern uint32_t zdr_SETATTR3res (ZDR *, SETATTR3res*); +extern uint32_t zdr_fhandle2 (ZDR *, fhandle2); +extern uint32_t zdr_ftype2 (ZDR *, ftype2*); +extern uint32_t zdr_fattr2 (ZDR *, fattr2*); +extern uint32_t zdr_sattr2 (ZDR *, sattr2*); +extern uint32_t zdr_filename2 (ZDR *, filename2*); +extern uint32_t zdr_path2 (ZDR *, path2*); +extern uint32_t zdr_nfsdata2 (ZDR *, nfsdata2*); +extern uint32_t zdr_nfscookie2 (ZDR *, nfscookie2); +extern uint32_t zdr_entry2 (ZDR *, entry2*); +extern uint32_t zdr_diropargs2 (ZDR *, diropargs2*); +extern uint32_t zdr_GETATTR2args (ZDR *, GETATTR2args*); +extern uint32_t zdr_GETATTR2resok (ZDR *, GETATTR2resok*); +extern uint32_t zdr_GETATTR2res (ZDR *, GETATTR2res*); +extern uint32_t zdr_SETATTR2args (ZDR *, SETATTR2args*); +extern uint32_t zdr_SETATTR2resok (ZDR *, SETATTR2resok*); +extern uint32_t zdr_SETATTR2res (ZDR *, SETATTR2res*); +extern uint32_t zdr_LOOKUP2args (ZDR *, LOOKUP2args*); +extern uint32_t zdr_LOOKUP2resok (ZDR *, LOOKUP2resok*); +extern uint32_t zdr_LOOKUP2res (ZDR *, LOOKUP2res*); +extern uint32_t zdr_READLINK2args (ZDR *, READLINK2args*); +extern uint32_t zdr_READLINK2resok (ZDR *, READLINK2resok*); +extern uint32_t zdr_READLINK2res (ZDR *, READLINK2res*); +extern uint32_t zdr_READ2args (ZDR *, READ2args*); +extern uint32_t zdr_READ2resok (ZDR *, READ2resok*); +extern uint32_t zdr_READ2res (ZDR *, READ2res*); +extern uint32_t zdr_WRITE2args (ZDR *, WRITE2args*); +extern uint32_t zdr_WRITE2resok (ZDR *, WRITE2resok*); +extern uint32_t zdr_WRITE2res (ZDR *, WRITE2res*); +extern uint32_t zdr_CREATE2args (ZDR *, CREATE2args*); +extern uint32_t zdr_CREATE2resok (ZDR *, CREATE2resok*); +extern uint32_t zdr_CREATE2res (ZDR *, CREATE2res*); +extern uint32_t zdr_REMOVE2args (ZDR *, REMOVE2args*); +extern uint32_t zdr_REMOVE2res (ZDR *, REMOVE2res*); +extern uint32_t zdr_RENAME2args (ZDR *, RENAME2args*); +extern uint32_t zdr_RENAME2res (ZDR *, RENAME2res*); +extern uint32_t zdr_LINK2args (ZDR *, LINK2args*); +extern uint32_t zdr_LINK2res (ZDR *, LINK2res*); +extern uint32_t zdr_SYMLINK2args (ZDR *, SYMLINK2args*); +extern uint32_t zdr_SYMLINK2res (ZDR *, SYMLINK2res*); +extern uint32_t zdr_MKDIR2args (ZDR *, MKDIR2args*); +extern uint32_t zdr_MKDIR2resok (ZDR *, MKDIR2resok*); +extern uint32_t zdr_MKDIR2res (ZDR *, MKDIR2res*); +extern uint32_t zdr_RMDIR2args (ZDR *, RMDIR2args*); +extern uint32_t zdr_RMDIR2res (ZDR *, RMDIR2res*); +extern uint32_t zdr_READDIR2args (ZDR *, READDIR2args*); +extern uint32_t zdr_READDIR2resok (ZDR *, READDIR2resok*); +extern uint32_t zdr_READDIR2res (ZDR *, READDIR2res*); +extern uint32_t zdr_STATFS2args (ZDR *, STATFS2args*); +extern uint32_t zdr_STATFS2resok (ZDR *, STATFS2resok*); +extern uint32_t zdr_STATFS2res (ZDR *, STATFS2res*); +extern uint32_t zdr_nfsacl_type (ZDR *, nfsacl_type*); +extern uint32_t zdr_nfsacl_ace (ZDR *, nfsacl_ace*); +extern uint32_t zdr_GETACL3args (ZDR *, GETACL3args*); +extern uint32_t zdr_GETACL3resok (ZDR *, GETACL3resok*); +extern uint32_t zdr_GETACL3res (ZDR *, GETACL3res*); +extern uint32_t zdr_SETACL3args (ZDR *, SETACL3args*); +extern uint32_t zdr_SETACL3resok (ZDR *, SETACL3resok*); +extern uint32_t zdr_SETACL3res (ZDR *, SETACL3res*); + +#else /* K&R C */ +extern uint32_t zdr_cookieverf3 (); +extern uint32_t zdr_cookie3 (); +extern uint32_t zdr_nfs_fh3 (); +extern uint32_t zdr_filename3 (); +extern uint32_t zdr_diropargs3 (); +extern uint32_t zdr_ftype3 (); +extern uint32_t zdr_mode3 (); +extern uint32_t zdr_uid3 (); +extern uint32_t zdr_gid3 (); +extern uint32_t zdr_size3 (); +extern uint32_t zdr_fileid3 (); +extern uint32_t zdr_specdata3 (); +extern uint32_t zdr_nfstime3 (); +extern uint32_t zdr_fattr3 (); +extern uint32_t zdr_post_op_attr (); +extern uint32_t zdr_nfsstat3 (); +extern uint32_t zdr_stable_how (); +extern uint32_t zdr_offset3 (); +extern uint32_t zdr_count3 (); +extern uint32_t zdr_wcc_attr (); +extern uint32_t zdr_pre_op_attr (); +extern uint32_t zdr_wcc_data (); +extern uint32_t zdr_WRITE3args (); +extern uint32_t zdr_writeverf3 (); +extern uint32_t zdr_WRITE3resok (); +extern uint32_t zdr_WRITE3resfail (); +extern uint32_t zdr_WRITE3res (); +extern uint32_t zdr_LOOKUP3args (); +extern uint32_t zdr_LOOKUP3resok (); +extern uint32_t zdr_LOOKUP3resfail (); +extern uint32_t zdr_LOOKUP3res (); +extern uint32_t zdr_COMMIT3args (); +extern uint32_t zdr_COMMIT3resok (); +extern uint32_t zdr_COMMIT3resfail (); +extern uint32_t zdr_COMMIT3res (); +extern uint32_t zdr_ACCESS3args (); +extern uint32_t zdr_ACCESS3resok (); +extern uint32_t zdr_ACCESS3resfail (); +extern uint32_t zdr_ACCESS3res (); +extern uint32_t zdr_GETATTR3args (); +extern uint32_t zdr_GETATTR3resok (); +extern uint32_t zdr_GETATTR3res (); +extern uint32_t zdr_time_how (); +extern uint32_t zdr_set_mode3 (); +extern uint32_t zdr_set_uid3 (); +extern uint32_t zdr_set_gid3 (); +extern uint32_t zdr_set_size3 (); +extern uint32_t zdr_set_atime (); +extern uint32_t zdr_set_mtime (); +extern uint32_t zdr_sattr3 (); +extern uint32_t zdr_createmode3 (); +extern uint32_t zdr_createverf3 (); +extern uint32_t zdr_createhow3 (); +extern uint32_t zdr_CREATE3args (); +extern uint32_t zdr_post_op_fh3 (); +extern uint32_t zdr_CREATE3resok (); +extern uint32_t zdr_CREATE3resfail (); +extern uint32_t zdr_CREATE3res (); +extern uint32_t zdr_REMOVE3args (); +extern uint32_t zdr_REMOVE3resok (); +extern uint32_t zdr_REMOVE3resfail (); +extern uint32_t zdr_REMOVE3res (); +extern uint32_t zdr_READ3args (); +extern uint32_t zdr_READ3resok (); +extern uint32_t zdr_READ3resfail (); +extern uint32_t zdr_READ3res (); +extern uint32_t zdr_FSINFO3args (); +extern uint32_t zdr_FSINFO3resok (); +extern uint32_t zdr_FSINFO3resfail (); +extern uint32_t zdr_FSINFO3res (); +extern uint32_t zdr_FSSTAT3args (); +extern uint32_t zdr_FSSTAT3resok (); +extern uint32_t zdr_FSSTAT3resfail (); +extern uint32_t zdr_FSSTAT3res (); +extern uint32_t zdr_PATHCONF3args (); +extern uint32_t zdr_PATHCONF3resok (); +extern uint32_t zdr_PATHCONF3resfail (); +extern uint32_t zdr_PATHCONF3res (); +extern uint32_t zdr_nfspath3 (); +extern uint32_t zdr_symlinkdata3 (); +extern uint32_t zdr_SYMLINK3args (); +extern uint32_t zdr_SYMLINK3resok (); +extern uint32_t zdr_SYMLINK3resfail (); +extern uint32_t zdr_SYMLINK3res (); +extern uint32_t zdr_READLINK3args (); +extern uint32_t zdr_READLINK3resok (); +extern uint32_t zdr_READLINK3resfail (); +extern uint32_t zdr_READLINK3res (); +extern uint32_t zdr_devicedata3 (); +extern uint32_t zdr_mknoddata3 (); +extern uint32_t zdr_MKNOD3args (); +extern uint32_t zdr_MKNOD3resok (); +extern uint32_t zdr_MKNOD3resfail (); +extern uint32_t zdr_MKNOD3res (); +extern uint32_t zdr_MKDIR3args (); +extern uint32_t zdr_MKDIR3resok (); +extern uint32_t zdr_MKDIR3resfail (); +extern uint32_t zdr_MKDIR3res (); +extern uint32_t zdr_RMDIR3args (); +extern uint32_t zdr_RMDIR3resok (); +extern uint32_t zdr_RMDIR3resfail (); +extern uint32_t zdr_RMDIR3res (); +extern uint32_t zdr_RENAME3args (); +extern uint32_t zdr_RENAME3resok (); +extern uint32_t zdr_RENAME3resfail (); +extern uint32_t zdr_RENAME3res (); +extern uint32_t zdr_READDIRPLUS3args (); +extern uint32_t zdr_entryplus3 (); +extern uint32_t zdr_dirlistplus3 (); +extern uint32_t zdr_READDIRPLUS3resok (); +extern uint32_t zdr_READDIRPLUS3resfail (); +extern uint32_t zdr_READDIRPLUS3res (); +extern uint32_t zdr_READDIR3args (); +extern uint32_t zdr_entry3 (); +extern uint32_t zdr_dirlist3 (); +extern uint32_t zdr_READDIR3resok (); +extern uint32_t zdr_READDIR3resfail (); +extern uint32_t zdr_READDIR3res (); +extern uint32_t zdr_LINK3args (); +extern uint32_t zdr_LINK3resok (); +extern uint32_t zdr_LINK3resfail (); +extern uint32_t zdr_LINK3res (); +extern uint32_t zdr_sattrguard3 (); +extern uint32_t zdr_SETATTR3args (); +extern uint32_t zdr_SETATTR3resok (); +extern uint32_t zdr_SETATTR3resfail (); +extern uint32_t zdr_SETATTR3res (); +extern uint32_t zdr_fhandle2 (); +extern uint32_t zdr_ftype2 (); +extern uint32_t zdr_fattr2 (); +extern uint32_t zdr_sattr2 (); +extern uint32_t zdr_filename2 (); +extern uint32_t zdr_path2 (); +extern uint32_t zdr_nfsdata2 (); +extern uint32_t zdr_nfscookie2 (); +extern uint32_t zdr_entry2 (); +extern uint32_t zdr_diropargs2 (); +extern uint32_t zdr_GETATTR2args (); +extern uint32_t zdr_GETATTR2resok (); +extern uint32_t zdr_GETATTR2res (); +extern uint32_t zdr_SETATTR2args (); +extern uint32_t zdr_SETATTR2resok (); +extern uint32_t zdr_SETATTR2res (); +extern uint32_t zdr_LOOKUP2args (); +extern uint32_t zdr_LOOKUP2resok (); +extern uint32_t zdr_LOOKUP2res (); +extern uint32_t zdr_READLINK2args (); +extern uint32_t zdr_READLINK2resok (); +extern uint32_t zdr_READLINK2res (); +extern uint32_t zdr_READ2args (); +extern uint32_t zdr_READ2resok (); +extern uint32_t zdr_READ2res (); +extern uint32_t zdr_WRITE2args (); +extern uint32_t zdr_WRITE2resok (); +extern uint32_t zdr_WRITE2res (); +extern uint32_t zdr_CREATE2args (); +extern uint32_t zdr_CREATE2resok (); +extern uint32_t zdr_CREATE2res (); +extern uint32_t zdr_REMOVE2args (); +extern uint32_t zdr_REMOVE2res (); +extern uint32_t zdr_RENAME2args (); +extern uint32_t zdr_RENAME2res (); +extern uint32_t zdr_LINK2args (); +extern uint32_t zdr_LINK2res (); +extern uint32_t zdr_SYMLINK2args (); +extern uint32_t zdr_SYMLINK2res (); +extern uint32_t zdr_MKDIR2args (); +extern uint32_t zdr_MKDIR2resok (); +extern uint32_t zdr_MKDIR2res (); +extern uint32_t zdr_RMDIR2args (); +extern uint32_t zdr_RMDIR2res (); +extern uint32_t zdr_READDIR2args (); +extern uint32_t zdr_READDIR2resok (); +extern uint32_t zdr_READDIR2res (); +extern uint32_t zdr_STATFS2args (); +extern uint32_t zdr_STATFS2resok (); +extern uint32_t zdr_STATFS2res (); +extern uint32_t zdr_nfsacl_type (); +extern uint32_t zdr_nfsacl_ace (); +extern uint32_t zdr_GETACL3args (); +extern uint32_t zdr_GETACL3resok (); +extern uint32_t zdr_GETACL3res (); +extern uint32_t zdr_SETACL3args (); +extern uint32_t zdr_SETACL3resok (); +extern uint32_t zdr_SETACL3res (); + +#endif /* K&R C */ + +#include + +#if defined(WIN32) && defined(libnfs_EXPORTS) +#define EXTERN __declspec( dllexport ) +#else +#ifndef EXTERN +#define EXTERN +#endif +#endif + +typedef struct { + uint32_t ace_count; + struct nfsacl_ace *ace; + uint32_t default_ace_count; + struct nfsacl_ace *default_ace; +} fattr3_acl; + +/* + * NFSv3 ACL + */ +/* + * Async nfs3 get acl + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is fattr3_acl * + * -errno : An error occured. + * data is the error string. + */ +EXTERN int nfs3_getacl_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + nfs_cb cb, void *private_data); + +/* + * Sync nfs3 get acl + * Function returns + * 0 : The operation was successful. + * -errno : The command failed. + * + * If the command was successful, the returned data in nfs3acl must be freed + * by calling nfs3_acl_free() + */ +EXTERN int nfs3_getacl(struct nfs_context *nfs, struct nfsfh *nfsfh, + fattr3_acl *nfs3acl); + +EXTERN void nfs3_acl_free(fattr3_acl *nfs3acl); + +#ifdef __cplusplus +} +#endif + +#endif /* !_NFS_H_RPCGEN */ diff --git a/deps/libnfs/nfs/libnfs-raw-nfs.h.extra b/deps/libnfs/nfs/libnfs-raw-nfs.h.extra new file mode 100644 index 000000000000..c8f55b866593 --- /dev/null +++ b/deps/libnfs/nfs/libnfs-raw-nfs.h.extra @@ -0,0 +1,56 @@ +#include + +#if defined(WIN32) && defined(libnfs_EXPORTS) +#define EXTERN __declspec( dllexport ) +#else +#ifndef EXTERN +#define EXTERN +#endif +#endif + +typedef struct { + u_int ace_count; + struct nfsacl_ace *ace; + u_int default_ace_count; + struct nfsacl_ace *default_ace; +} fattr3_acl; + +/* + * NFSv3 ACL + */ +/* + * Async nfs3 get acl + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is fattr3_acl * + * -errno : An error occured. + * data is the error string. + */ +EXTERN int nfs3_getacl_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + nfs_cb cb, void *private_data); + +/* + * Sync nfs3 get acl + * Function returns + * 0 : The operation was successful. + * -errno : The command failed. + * + * If the command was successful, the returned data in nfs3acl must be freed + * by calling nfs3_acl_free() + */ +EXTERN int nfs3_getacl(struct nfs_context *nfs, struct nfsfh *nfsfh, + fattr3_acl *nfs3acl); + +EXTERN void nfs3_acl_free(fattr3_acl *nfs3acl); + +#ifdef __cplusplus +} +#endif + +#endif /* !_NFS_H_RPCGEN */ diff --git a/deps/libnfs/nfs/nfs.c b/deps/libnfs/nfs/nfs.c new file mode 100644 index 000000000000..d9cae41b7b9e --- /dev/null +++ b/deps/libnfs/nfs/nfs.c @@ -0,0 +1,1293 @@ +/* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */ +/* + 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 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef PS2_EE +#include "ps2_compat.h" +#endif + +#ifdef WIN32 +#include +#else +#include +#endif/*WIN32*/ + +#include +#include +#include +#include +#include "libnfs-zdr.h" +#include "libnfs.h" +#include "libnfs-raw.h" +#include "libnfs-private.h" +#include "libnfs-raw-nfs.h" + +char *nfsstat3_to_str(int error) +{ + switch (error) { + case NFS3_OK: return "NFS3_OK"; break; + case NFS3ERR_PERM: return "NFS3ERR_PERM"; break; + case NFS3ERR_NOENT: return "NFS3ERR_NOENT"; break; + case NFS3ERR_IO: return "NFS3ERR_IO"; break; + case NFS3ERR_NXIO: return "NFS3ERR_NXIO"; break; + case NFS3ERR_ACCES: return "NFS3ERR_ACCES"; break; + case NFS3ERR_EXIST: return "NFS3ERR_EXIST"; break; + case NFS3ERR_XDEV: return "NFS3ERR_XDEV"; break; + case NFS3ERR_NODEV: return "NFS3ERR_NODEV"; break; + case NFS3ERR_NOTDIR: return "NFS3ERR_NOTDIR"; break; + case NFS3ERR_ISDIR: return "NFS3ERR_ISDIR"; break; + case NFS3ERR_INVAL: return "NFS3ERR_INVAL"; break; + case NFS3ERR_FBIG: return "NFS3ERR_FBIG"; break; + case NFS3ERR_NOSPC: return "NFS3ERR_NOSPC"; break; + case NFS3ERR_ROFS: return "NFS3ERR_ROFS"; break; + case NFS3ERR_MLINK: return "NFS3ERR_MLINK"; break; + case NFS3ERR_NAMETOOLONG: return "NFS3ERR_NAMETOOLONG"; break; + case NFS3ERR_NOTEMPTY: return "NFS3ERR_NOTEMPTY"; break; + case NFS3ERR_DQUOT: return "NFS3ERR_DQUOT"; break; + case NFS3ERR_STALE: return "NFS3ERR_STALE"; break; + case NFS3ERR_REMOTE: return "NFS3ERR_REMOTE"; break; + case NFS3ERR_BADHANDLE: return "NFS3ERR_BADHANDLE"; break; + case NFS3ERR_NOT_SYNC: return "NFS3ERR_NOT_SYNC"; break; + case NFS3ERR_BAD_COOKIE: return "NFS3ERR_BAD_COOKIE"; break; + case NFS3ERR_NOTSUPP: return "NFS3ERR_NOTSUPP"; break; + case NFS3ERR_TOOSMALL: return "NFS3ERR_TOOSMALL"; break; + case NFS3ERR_SERVERFAULT: return "NFS3ERR_SERVERFAULT"; break; + case NFS3ERR_BADTYPE: return "NFS3ERR_BADTYPE"; break; + case NFS3ERR_JUKEBOX: return "NFS3ERR_JUKEBOX"; break; + }; + return "unknown nfs error"; +} + +int nfsstat3_to_errno(int error) +{ + switch (error) { + case NFS3_OK: return 0; break; + case NFS3ERR_PERM: return -EPERM; break; + case NFS3ERR_NOENT: return -ENOENT; break; + case NFS3ERR_IO: return -EIO; break; + case NFS3ERR_NXIO: return -ENXIO; break; + case NFS3ERR_ACCES: return -EACCES; break; + case NFS3ERR_EXIST: return -EEXIST; break; + case NFS3ERR_XDEV: return -EXDEV; break; + case NFS3ERR_NODEV: return -ENODEV; break; + case NFS3ERR_NOTDIR: return -ENOTDIR; break; + case NFS3ERR_ISDIR: return -EISDIR; break; + case NFS3ERR_INVAL: return -EINVAL; break; + case NFS3ERR_FBIG: return -EFBIG; break; + case NFS3ERR_NOSPC: return -ENOSPC; break; + case NFS3ERR_ROFS: return -EROFS; break; + case NFS3ERR_MLINK: return -EMLINK; break; + case NFS3ERR_NAMETOOLONG: return -ENAMETOOLONG; break; + case NFS3ERR_NOTEMPTY: return -ENOTEMPTY; break; + case NFS3ERR_DQUOT: return -ERANGE; break; + case NFS3ERR_STALE: return -ESTALE; break; + case NFS3ERR_REMOTE: return -EIO; break; + case NFS3ERR_BADHANDLE: return -EIO; break; + case NFS3ERR_NOT_SYNC: return -EIO; break; + case NFS3ERR_BAD_COOKIE: return -EIO; break; + case NFS3ERR_NOTSUPP: return -EINVAL; break; + case NFS3ERR_TOOSMALL: return -EIO; break; + case NFS3ERR_SERVERFAULT: return -EIO; break; + case NFS3ERR_BADTYPE: return -EINVAL; break; + case NFS3ERR_JUKEBOX: return -EAGAIN; break; + }; + return -ERANGE; +} + + +/* + * NFSv3 + */ +struct rpc_pdu *rpc_nfs3_null_task(struct rpc_context *rpc, rpc_cb cb, + void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_NULL, cb, private_data, (zdrproc_t)zdr_void, 0); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/NULL call"); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/NULL call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs3_getattr_task(struct rpc_context *rpc, rpc_cb cb, + struct GETATTR3args *args, + void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_GETATTR, cb, private_data, (zdrproc_t)zdr_GETATTR3res, sizeof(GETATTR3res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/GETATTR call"); + return NULL; + } + + if (zdr_GETATTR3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode GETATTR3args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/GETATTR call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs3_pathconf_task(struct rpc_context *rpc, rpc_cb cb, + struct PATHCONF3args *args, + void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_PATHCONF, cb, private_data, (zdrproc_t)zdr_PATHCONF3res, sizeof(PATHCONF3res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/PATHCONF call"); + return NULL; + } + + if (zdr_PATHCONF3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode PATHCONF3args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/PATHCONF call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs3_lookup_task(struct rpc_context *rpc, rpc_cb cb, + struct LOOKUP3args *args, + void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_LOOKUP, cb, private_data, (zdrproc_t)zdr_LOOKUP3res, sizeof(LOOKUP3res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/LOOKUP call"); + return NULL; + } + + if (zdr_LOOKUP3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode LOOKUP3args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/LOOKUP call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs3_access_task(struct rpc_context *rpc, rpc_cb cb, + struct ACCESS3args *args, + void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_ACCESS, cb, private_data, (zdrproc_t)zdr_ACCESS3res, sizeof(ACCESS3res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/ACCESS call"); + return NULL; + } + + if (zdr_ACCESS3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode ACCESS3args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/ACCESS call"); + return NULL; + } + + return pdu; +} + +uint32_t +zdr_READ3resok_zero_copy (ZDR *zdrs, READ3resok *objp) +{ + if (!zdr_post_op_attr (zdrs, &objp->file_attributes)) + return FALSE; + if (!zdr_count3 (zdrs, &objp->count)) + return FALSE; + if (!zdr_bool (zdrs, &objp->eof)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_READ3res_zero_copy (ZDR *zdrs, READ3res *objp) +{ + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS3_OK: + if (!zdr_READ3resok_zero_copy (zdrs, &objp->READ3res_u.resok)) + return FALSE; + break; + default: + if (!zdr_READ3resfail (zdrs, &objp->READ3res_u.resfail)) + return FALSE; + break; + } + return TRUE; +} + +struct rpc_pdu * +rpc_nfs3_readv_task(struct rpc_context *rpc, rpc_cb cb, + const struct iovec *iov, int iovcnt, + struct READ3args *args, void *private_data) +{ + struct rpc_pdu *pdu; + int i; + + if (iovcnt == 0 || iov == NULL) { + rpc_set_error(rpc, "Invalid arguments: iov and iovcnt must be specified"); + return NULL; + } + + /* + * It's disallowed since it's not tested. It may work. + */ + if (iovcnt > 1 && rpc->is_udp) { + rpc_set_error(rpc, "Invalid arguments: Vectored read not supported for UDP transport"); + return NULL; + } + + /* + * Don't accept more iovecs than what readv() can handle. + */ + if (iovcnt > RPC_MAX_VECTORS) { + rpc_set_error(rpc, "Invalid arguments: iovcnt must be <= %d", RPC_MAX_VECTORS); + return NULL; + } + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_READ, cb, private_data, (zdrproc_t)zdr_READ3res_zero_copy, sizeof(READ3res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/READ call"); + return NULL; + } + if (zdr_READ3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode READ3args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + /* + * Allocate twice the iovec space, first half will be used for iov[]. + * This will be updated as data is read into user buffers. + * Second half is for iov_ref[]. This is not used in happy path. Only + * if we need to resend the request we need it to reset the cursor to + * the original iovec. + * See rpc_reset_cursor(). + */ + pdu->in.base = (struct iovec *) malloc(sizeof(struct iovec) * iovcnt * 2); + if (!pdu->in.base) { + rpc_set_error(rpc, "error: Failed to allocate memory"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + pdu->in.iov = pdu->in.base; + pdu->in.iov_ref = pdu->in.base + iovcnt; + pdu->in.iovcnt = pdu->in.iovcnt_ref = iovcnt; + + for (i = 0; i < iovcnt; i++) { + pdu->in.iov[i] = pdu->in.iov_ref[i] = iov[i]; + pdu->in.remaining_size += iov[i].iov_len; + } + + pdu->requested_read_count = pdu->in.remaining_size; + pdu->zero_copy_iov = 1; + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/READ call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_nfs3_read_task(struct rpc_context *rpc, rpc_cb cb, + void *buf, size_t count, + struct READ3args *args, void *private_data) +{ + struct iovec iov; + + iov.iov_base = buf; + iov.iov_len = count; + + return rpc_nfs3_readv_task(rpc, cb, &iov, 1, args, private_data); +} + +/* + * Replacement WRITE3args so that we can add the data as an iovector + * instead of marshalling it in the out buffer. + * This will marshall the WRITE3args structure except for the final + * byte/array for the actual data. + */ +uint32_t +zdr_WRITE3args_zerocopy(ZDR *zdrs, WRITE3args *objp) +{ + if (!zdr_nfs_fh3 (zdrs, &objp->file)) + return FALSE; + if (!zdr_offset3 (zdrs, &objp->offset)) + return FALSE; + if (!zdr_count3 (zdrs, &objp->count)) + return FALSE; + if (!zdr_stable_how (zdrs, &objp->stable)) + return FALSE; + return TRUE; +} + +struct rpc_pdu *rpc_nfs3_writev_task(struct rpc_context *rpc, rpc_cb cb, + struct WRITE3args *args, + const struct iovec *iov, + int iovcnt, + void *private_data) +{ + struct rpc_pdu *pdu; + int start; + static uint32_t zero_padding; + uint32_t data_len; + + /* + * If caller has a single contiguous buffer they can convey it + * using args.data, and if they have an io vector they can convey + * that using iov. + */ + if ((iovcnt == 0) != (iov == NULL)) { + rpc_set_error(rpc, "Invalid arguments: iov and iovcnt must both be specified together"); + return NULL; + } + + if (iovcnt && args->data.data_len) { + /* Warn bad callers */ + rpc_set_error(rpc, "Invalid arguments: args->data.data_len not 0 when iovcnt is non-zero"); + return NULL; + } + + if (iov && rpc->is_udp) { + rpc_set_error(rpc, "Invalid arguments: Vectored write not supported for UDP transport"); + return NULL; + } + + /* + * We add 4 to the user provided iovcnt to account for one each for + * the following: + * - Record marker + * - RPC header + * - NFS header + * - Padding (optional) + */ + pdu = rpc_allocate_pdu2(rpc, NFS_PROGRAM, NFS_V3, NFS3_WRITE, cb, private_data, (zdrproc_t)zdr_WRITE3res, sizeof(WRITE3res), 0, iovcnt + 4); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/WRITE call"); + return NULL; + } + + start = zdr_getpos(&pdu->zdr); + + if (zdr_WRITE3args_zerocopy(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode WRITE3args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + /* Add an iovector for the WRITE3 header */ + if (rpc_add_iovector(rpc, &pdu->out, &pdu->outdata.data[start + 4], + zdr_getpos(&pdu->zdr) - start, NULL) < 0) { + rpc_free_pdu(rpc, pdu); + return NULL; + } + + /* Calculate data length to encode in the RPC request */ + if (iov) { + int i; + data_len = 0; + for (i = 0; i < iovcnt; i++) { + data_len += iov[i].iov_len; + } + } else { + data_len = args->data.data_len; + } + + /* Add an iovector for the length of the byte/array blob */ + start = zdr_getpos(&pdu->zdr); + zdr_u_int(&pdu->zdr, &data_len); + if (rpc_add_iovector(rpc, &pdu->out, &pdu->outdata.data[start + 4], + 4, NULL) < 0) { + rpc_free_pdu(rpc, pdu); + return NULL; + } + + /* Add an iovector for the data itself */ + if (!iov) { + if (rpc_add_iovector(rpc, &pdu->out, args->data.data_val, + args->data.data_len, NULL) < 0) { + rpc_free_pdu(rpc, pdu); + return NULL; + } + } else { + int i; + for (i = 0; i < iovcnt; i++) { + if (rpc_add_iovector(rpc, &pdu->out, + iov[i].iov_base, + iov[i].iov_len, NULL) < 0) { + rpc_free_pdu(rpc, pdu); + return NULL; + } + } + } + + /* We may need to pad this to 4 byte boundary */ + if (data_len & 0x03) { + if (rpc_add_iovector(rpc, &pdu->out, (char *)&zero_padding, + 4 - (data_len & 0x03), NULL) < 0) { + rpc_free_pdu(rpc, pdu); + return NULL; + } + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/WRITE call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs3_write_task(struct rpc_context *rpc, rpc_cb cb, + struct WRITE3args *args, + void *private_data) +{ + return rpc_nfs3_writev_task(rpc, cb, args, NULL, 0, private_data); +} + +struct rpc_pdu *rpc_nfs3_commit_task(struct rpc_context *rpc, rpc_cb cb, + struct COMMIT3args *args, + void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_COMMIT, cb, private_data, (zdrproc_t)zdr_COMMIT3res, sizeof(COMMIT3res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/COMMIT call"); + return NULL; + } + + if (zdr_COMMIT3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode COMMIT3args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/COMMIT call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_nfs3_setattr_task(struct rpc_context *rpc, rpc_cb cb, SETATTR3args *args, + void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_SETATTR, cb, private_data, (zdrproc_t)zdr_SETATTR3res, sizeof(SETATTR3res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/SETATTR call"); + return NULL; + } + + if (zdr_SETATTR3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode SETATTR3args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/SETATTR call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs3_mkdir_task(struct rpc_context *rpc, rpc_cb cb, + MKDIR3args *args, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_MKDIR, cb, private_data, (zdrproc_t)zdr_MKDIR3res, sizeof(MKDIR3res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/MKDIR call"); + return NULL; + } + + if (zdr_MKDIR3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode MKDIR3args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/MKDIR call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs3_rmdir_task(struct rpc_context *rpc, rpc_cb cb, + struct RMDIR3args *args, + void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_RMDIR, cb, private_data, (zdrproc_t)zdr_RMDIR3res, sizeof(RMDIR3res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/RMDIR call"); + return NULL; + } + + if (zdr_RMDIR3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode RMDIR3args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/RMDIR call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs3_create_task(struct rpc_context *rpc, rpc_cb cb, + CREATE3args *args, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_CREATE, cb, private_data, (zdrproc_t)zdr_CREATE3res, sizeof(CREATE3res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/CREATE call"); + return NULL; + } + + if (zdr_CREATE3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode CREATE3args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/CREATE call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs3_mknod_task(struct rpc_context *rpc, rpc_cb cb, + struct MKNOD3args *args, + void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_MKNOD, cb, private_data, (zdrproc_t)zdr_MKNOD3res, sizeof(MKNOD3res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/MKNOD call"); + return NULL; + } + + if (zdr_MKNOD3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode MKNOD3args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/MKNOD call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs3_remove_task(struct rpc_context *rpc, rpc_cb cb, + struct REMOVE3args *args, + void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_REMOVE, cb, private_data, (zdrproc_t)zdr_REMOVE3res, sizeof(REMOVE3res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/REMOVE call"); + return NULL; + } + + if (zdr_REMOVE3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode REMOVE3args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/REMOVE call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs3_readdir_task(struct rpc_context *rpc, rpc_cb cb, + struct READDIR3args *args, + void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_READDIR, cb, private_data, (zdrproc_t)zdr_READDIR3res, sizeof(READDIR3res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/READDIR call"); + return NULL; + } + + if (zdr_READDIR3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode READDIR3args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/READDIR call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs3_readdirplus_task(struct rpc_context *rpc, rpc_cb cb, + struct READDIRPLUS3args *args, + void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_READDIRPLUS, cb, private_data, (zdrproc_t)zdr_READDIRPLUS3res, sizeof(READDIRPLUS3res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/READDIRPLUS call"); + return NULL; + } + + if (zdr_READDIRPLUS3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode READDIRPLUS3args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/READDIRPLUS call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs3_fsstat_task(struct rpc_context *rpc, rpc_cb cb, + struct FSSTAT3args *args, + void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_FSSTAT, cb, private_data, (zdrproc_t)zdr_FSSTAT3res, sizeof(FSSTAT3res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/FSSTAT call"); + return NULL; + } + + if (zdr_FSSTAT3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode FSSTAT3args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/FSSTAT call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs3_fsinfo_task(struct rpc_context *rpc, rpc_cb cb, + struct FSINFO3args *args, + void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_FSINFO, cb, private_data, (zdrproc_t)zdr_FSINFO3res, sizeof(FSINFO3res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/FSINFO call"); + return NULL; + } + + if (zdr_FSINFO3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode FSINFO3args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/FSINFO call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_nfs3_readlink_task(struct rpc_context *rpc, rpc_cb cb, + READLINK3args *args, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_READLINK, cb, private_data, (zdrproc_t)zdr_READLINK3res, sizeof(READLINK3res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/READLINK call"); + return NULL; + } + + if (zdr_READLINK3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode READLINK3args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/READLINK call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs3_symlink_task(struct rpc_context *rpc, rpc_cb cb, + SYMLINK3args *args, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_SYMLINK, cb, private_data, (zdrproc_t)zdr_SYMLINK3res, sizeof(SYMLINK3res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/SYMLINK call"); + return NULL; + } + + if (zdr_SYMLINK3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode SYMLINK3args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/SYMLINK call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs3_rename_task(struct rpc_context *rpc, rpc_cb cb, + struct RENAME3args *args, + void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_RENAME, cb, private_data, (zdrproc_t)zdr_RENAME3res, sizeof(RENAME3res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/RENAME call"); + return NULL; + } + + if (zdr_RENAME3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode RENAME3args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/RENAME call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs3_link_task(struct rpc_context *rpc, rpc_cb cb, + struct LINK3args *args, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_LINK, cb, private_data, (zdrproc_t)zdr_LINK3res, sizeof(LINK3res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/LINK call"); + return NULL; + } + + if (zdr_LINK3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode LINK3args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/LINK call"); + return NULL; + } + + return pdu; +} + +/* + * NFSv2 + */ +struct rpc_pdu *rpc_nfs2_null_task(struct rpc_context *rpc, rpc_cb cb, + void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_NULL, cb, private_data, (zdrproc_t)zdr_void, 0); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/NULL call"); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/NULL call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs2_getattr_task(struct rpc_context *rpc, rpc_cb cb, + struct GETATTR2args *args, + void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_GETATTR, cb, private_data, (zdrproc_t)zdr_GETATTR2res, sizeof(GETATTR2res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/GETATTR call"); + return NULL; + } + + if (zdr_GETATTR2args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode GETATTR2args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/GETATTR call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs2_setattr_task(struct rpc_context *rpc, rpc_cb cb, + SETATTR2args *args, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_SETATTR, cb, private_data, (zdrproc_t)zdr_SETATTR2res, sizeof(SETATTR2res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/SETATTR call"); + return NULL; + } + + if (zdr_SETATTR2args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode SETATTR2args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/SETATTR call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs2_lookup_task(struct rpc_context *rpc, rpc_cb cb, + struct LOOKUP2args *args, + void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_LOOKUP, cb, private_data, (zdrproc_t)zdr_LOOKUP2res, sizeof(LOOKUP2res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/LOOKUP call"); + return NULL; + } + + if (zdr_LOOKUP2args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode LOOKUP2args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/LOOKUP call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs2_readlink_task(struct rpc_context *rpc, rpc_cb cb, + READLINK2args *args, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_READLINK, cb, private_data, (zdrproc_t)zdr_READLINK2res, sizeof(READLINK2res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/READLINK call"); + return NULL; + } + + if (zdr_READLINK2args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode READLINK2args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/READLINK call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs2_read_task(struct rpc_context *rpc, rpc_cb cb, + struct READ2args *args, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_READ, cb, private_data, (zdrproc_t)zdr_READ2res, sizeof(READ2res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/READ call"); + return NULL; + } + + if (zdr_READ2args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode READ2args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/READ call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs2_write_task(struct rpc_context *rpc, rpc_cb cb, + struct WRITE2args *args, + void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu2(rpc, NFS_PROGRAM, NFS_V2, NFS2_WRITE, cb, private_data, (zdrproc_t)zdr_WRITE2res, sizeof(WRITE2res), args->totalcount, 0); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/WRITE call"); + return NULL; + } + + if (zdr_WRITE2args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode WRITE2args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/WRITE call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs2_create_task(struct rpc_context *rpc, rpc_cb cb, + CREATE2args *args, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_CREATE, cb, private_data, (zdrproc_t)zdr_CREATE2res, sizeof(CREATE2res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/CREATE call"); + return NULL; + } + + if (zdr_CREATE2args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode CREATE2args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/CREATE call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs2_remove_task(struct rpc_context *rpc, rpc_cb cb, + struct REMOVE2args *args, + void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_REMOVE, cb, private_data, (zdrproc_t)zdr_REMOVE2res, sizeof(REMOVE2res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/REMOVE call"); + return NULL; + } + + if (zdr_REMOVE2args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode REMOVE2args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/REMOVE call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs2_rename_task(struct rpc_context *rpc, rpc_cb cb, + struct RENAME2args *args, + void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_RENAME, cb, private_data, (zdrproc_t)zdr_RENAME2res, sizeof(RENAME2res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/RENAME call"); + return NULL; + } + + if (zdr_RENAME2args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode RENAME2args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/RENAME call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs2_link_task(struct rpc_context *rpc, rpc_cb cb, + LINK2args *args, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_LINK, cb, private_data, (zdrproc_t)zdr_LINK2res, sizeof(LINK2res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/LINK call"); + return NULL; + } + + if (zdr_LINK2args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode LINK2args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/LINK call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs2_symlink_task(struct rpc_context *rpc, rpc_cb cb, + SYMLINK2args *args, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_SYMLINK, cb, private_data, (zdrproc_t)zdr_SYMLINK2res, sizeof(SYMLINK2res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/SYMLINK call"); + return NULL; + } + + if (zdr_SYMLINK2args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode SYMLINK2args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/SYMLINK call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs2_mkdir_task(struct rpc_context *rpc, rpc_cb cb, + MKDIR2args *args, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_MKDIR, cb, private_data, (zdrproc_t)zdr_MKDIR2res, sizeof(MKDIR2res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/MKDIR call"); + return NULL; + } + + if (zdr_MKDIR2args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode MKDIR2args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/MKDIR call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs2_rmdir_task(struct rpc_context *rpc, rpc_cb cb, + struct RMDIR2args *args, + void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_RMDIR, cb, private_data, (zdrproc_t)zdr_RMDIR2res, sizeof(RMDIR2res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/RMDIR call"); + return NULL; + } + + if (zdr_RMDIR2args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode RMDIR2args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/RMDIR call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs2_readdir_task(struct rpc_context *rpc, rpc_cb cb, + struct READDIR2args *args, + void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_READDIR, cb, private_data, (zdrproc_t)zdr_READDIR2res, sizeof(READDIR2res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/READDIR call"); + return NULL; + } + + if (zdr_READDIR2args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode READDIR2args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/READDIR call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs2_statfs_task(struct rpc_context *rpc, rpc_cb cb, + struct STATFS2args *args, + void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_STATFS, cb, private_data, (zdrproc_t)zdr_STATFS2res, sizeof(STATFS2res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/STATFS call"); + return NULL; + } + + if (zdr_STATFS2args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode STATFS2args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/STATFS call"); + return NULL; + } + + return pdu; +} diff --git a/deps/libnfs/nfs/nfs.x b/deps/libnfs/nfs/nfs.x new file mode 100644 index 000000000000..5f7afe579223 --- /dev/null +++ b/deps/libnfs/nfs/nfs.x @@ -0,0 +1,1291 @@ +/* +Copyright (c) 2014, Ronnie Sahlberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +/* + * NFS v3 Definitions + */ +const NFS3_FHSIZE = 64; /* Maximum bytes in a V3 file handle */ +const NFS3_WRITEVERFSIZE = 8; +const NFS3_CREATEVERFSIZE = 8; +const NFS3_COOKIEVERFSIZE = 8; + +typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE]; + +typedef uint64_t cookie3; + +struct nfs_fh3 { + opaque data; +}; + +typedef string filename3<>; + +struct diropargs3 { + nfs_fh3 dir; + filename3 name; +}; + +enum ftype3 { + NF3REG = 1, + NF3DIR = 2, + NF3BLK = 3, + NF3CHR = 4, + NF3LNK = 5, + NF3SOCK = 6, + NF3FIFO = 7 +}; + +typedef unsigned int mode3; + +typedef unsigned int uid3; + +typedef unsigned int gid3; + +typedef uint64_t size3; + +typedef uint64_t fileid3; + +struct specdata3 { + unsigned int specdata1; + unsigned int specdata2; +}; + +struct nfstime3 { + unsigned int seconds; + unsigned int nseconds; +}; + +struct fattr3 { + ftype3 type; + mode3 mode; + unsigned int nlink; + uid3 uid; + gid3 gid; + size3 size; + size3 used; + specdata3 rdev; + uint64_t fsid; + fileid3 fileid; + nfstime3 atime; + nfstime3 mtime; + nfstime3 ctime; +}; + +union post_op_attr switch (bool attributes_follow) { + case TRUE: + fattr3 attributes; + case FALSE: + void; +}; + + +enum nfsstat3 { + NFS3_OK = 0, + NFS3ERR_PERM = 1, + NFS3ERR_NOENT = 2, + NFS3ERR_IO = 5, + NFS3ERR_NXIO = 6, + NFS3ERR_ACCES = 13, + NFS3ERR_EXIST = 17, + NFS3ERR_XDEV = 18, + NFS3ERR_NODEV = 19, + NFS3ERR_NOTDIR = 20, + NFS3ERR_ISDIR = 21, + NFS3ERR_INVAL = 22, + NFS3ERR_FBIG = 27, + NFS3ERR_NOSPC = 28, + NFS3ERR_ROFS = 30, + NFS3ERR_MLINK = 31, + NFS3ERR_NAMETOOLONG = 63, + NFS3ERR_NOTEMPTY = 66, + NFS3ERR_DQUOT = 69, + NFS3ERR_STALE = 70, + NFS3ERR_REMOTE = 71, + NFS3ERR_BADHANDLE = 10001, + NFS3ERR_NOT_SYNC = 10002, + NFS3ERR_BAD_COOKIE = 10003, + NFS3ERR_NOTSUPP = 10004, + NFS3ERR_TOOSMALL = 10005, + NFS3ERR_SERVERFAULT = 10006, + NFS3ERR_BADTYPE = 10007, + NFS3ERR_JUKEBOX = 10008 +}; + +enum stable_how { + UNSTABLE = 0, + DATA_SYNC = 1, + FILE_SYNC = 2 +}; + +typedef uint64_t offset3; + +typedef unsigned int count3; + +struct wcc_attr { + size3 size; + nfstime3 mtime; + nfstime3 ctime; +}; + +union pre_op_attr switch (bool attributes_follow) { + case TRUE: + wcc_attr attributes; + case FALSE: + void; +}; + +struct wcc_data { + pre_op_attr before; + post_op_attr after; +}; + +struct WRITE3args { + nfs_fh3 file; + offset3 offset; + count3 count; + stable_how stable; + opaque data<>; +}; + +typedef opaque writeverf3[NFS3_WRITEVERFSIZE]; + +struct WRITE3resok { + wcc_data file_wcc; + count3 count; + stable_how committed; + writeverf3 verf; +}; + +struct WRITE3resfail { + wcc_data file_wcc; +}; + +union WRITE3res switch (nfsstat3 status) { + case NFS3_OK: + WRITE3resok resok; + default: + WRITE3resfail resfail; +}; + +struct LOOKUP3args { + diropargs3 what; +}; + +struct LOOKUP3resok { + nfs_fh3 object; + post_op_attr obj_attributes; + post_op_attr dir_attributes; +}; + +struct LOOKUP3resfail { + post_op_attr dir_attributes; +}; + + + +union LOOKUP3res switch (nfsstat3 status) { + case NFS3_OK: + LOOKUP3resok resok; + default: + LOOKUP3resfail resfail; +}; + +struct COMMIT3args { + nfs_fh3 file; + offset3 offset; + count3 count; +}; + +struct COMMIT3resok { + wcc_data file_wcc; + writeverf3 verf; +}; + +struct COMMIT3resfail { + wcc_data file_wcc; +}; + +union COMMIT3res switch (nfsstat3 status) { + case NFS3_OK: + COMMIT3resok resok; + default: + COMMIT3resfail resfail; +}; + +const ACCESS3_READ = 0x0001; +const ACCESS3_LOOKUP = 0x0002; +const ACCESS3_MODIFY = 0x0004; +const ACCESS3_EXTEND = 0x0008; +const ACCESS3_DELETE = 0x0010; +const ACCESS3_EXECUTE = 0x0020; + +struct ACCESS3args { + nfs_fh3 object; + unsigned int access; +}; + +struct ACCESS3resok { + post_op_attr obj_attributes; + unsigned int access; +}; + +struct ACCESS3resfail { + post_op_attr obj_attributes; +}; + +union ACCESS3res switch (nfsstat3 status) { +case NFS3_OK: + ACCESS3resok resok; +default: + ACCESS3resfail resfail; +}; + +struct GETATTR3args { + nfs_fh3 object; +}; + +struct GETATTR3resok { + fattr3 obj_attributes; +}; + +union GETATTR3res switch (nfsstat3 status) { + case NFS3_OK: + GETATTR3resok resok; + default: + void; +}; + + + +enum time_how { + DONT_CHANGE = 0, + SET_TO_SERVER_TIME = 1, + SET_TO_CLIENT_TIME = 2 +}; + +union set_mode3 switch (bool set_it) { + case TRUE: + mode3 mode; + default: + void; +}; + +union set_uid3 switch (bool set_it) { + case TRUE: + uid3 uid; + default: + void; +}; + +union set_gid3 switch (bool set_it) { + case TRUE: + gid3 gid; + default: + void; +}; + +union set_size3 switch (bool set_it) { + case TRUE: + size3 size; + default: + void; +}; + +union set_atime switch (time_how set_it) { + case SET_TO_CLIENT_TIME: + nfstime3 atime; + default: + void; +}; + +union set_mtime switch (time_how set_it) { + case SET_TO_CLIENT_TIME: + nfstime3 mtime; + default: + void; +}; + +struct sattr3 { + set_mode3 mode; + set_uid3 uid; + set_gid3 gid; + set_size3 size; + set_atime atime; + set_mtime mtime; +}; + +enum createmode3 { + UNCHECKED = 0, + GUARDED = 1, + EXCLUSIVE = 2 +}; + + +typedef opaque createverf3[NFS3_CREATEVERFSIZE]; + +union createhow3 switch (createmode3 mode) { + case UNCHECKED: + sattr3 obj_attributes; + case GUARDED: + sattr3 g_obj_attributes; + case EXCLUSIVE: + createverf3 verf; +}; + +struct CREATE3args { + diropargs3 where; + createhow3 how; +}; + +union post_op_fh3 switch (bool handle_follows) { + case TRUE: + nfs_fh3 handle; + case FALSE: + void; +}; + +struct CREATE3resok { + post_op_fh3 obj; + post_op_attr obj_attributes; + wcc_data dir_wcc; +}; + +struct CREATE3resfail { + wcc_data dir_wcc; + }; + +union CREATE3res switch (nfsstat3 status) { + case NFS3_OK: + CREATE3resok resok; + default: + CREATE3resfail resfail; +}; + +struct REMOVE3args { + diropargs3 object; +}; + +struct REMOVE3resok { + wcc_data dir_wcc; +}; + +struct REMOVE3resfail { + wcc_data dir_wcc; +}; + +union REMOVE3res switch (nfsstat3 status) { + case NFS3_OK: + REMOVE3resok resok; + default: + REMOVE3resfail resfail; +}; + +struct READ3args { + nfs_fh3 file; + offset3 offset; + count3 count; +}; + +struct READ3resok { + post_op_attr file_attributes; + count3 count; + bool eof; + opaque data<>; +}; + +struct READ3resfail { + post_op_attr file_attributes; +}; + +union READ3res switch (nfsstat3 status) { + case NFS3_OK: + READ3resok resok; + default: + READ3resfail resfail; +}; + + +const FSF3_LINK = 0x0001; +const FSF3_SYMLINK = 0x0002; +const FSF3_HOMOGENEOUS = 0x0008; +const FSF3_CANSETTIME = 0x0010; + +struct FSINFO3args { + nfs_fh3 fsroot; +}; + +struct FSINFO3resok { + post_op_attr obj_attributes; + unsigned int rtmax; + unsigned int rtpref; + unsigned int rtmult; + unsigned int wtmax; + unsigned int wtpref; + unsigned int wtmult; + unsigned int dtpref; + size3 maxfilesize; + nfstime3 time_delta; + unsigned int properties; +}; + +struct FSINFO3resfail { + post_op_attr obj_attributes; +}; + +union FSINFO3res switch (nfsstat3 status) { + case NFS3_OK: + FSINFO3resok resok; + default: + FSINFO3resfail resfail; +}; + + +struct FSSTAT3args { + nfs_fh3 fsroot; +}; + +struct FSSTAT3resok { + post_op_attr obj_attributes; + size3 tbytes; + size3 fbytes; + size3 abytes; + size3 tfiles; + size3 ffiles; + size3 afiles; + unsigned int invarsec; +}; + +struct FSSTAT3resfail { + post_op_attr obj_attributes; +}; + +union FSSTAT3res switch (nfsstat3 status) { + case NFS3_OK: + FSSTAT3resok resok; + default: + FSSTAT3resfail resfail; +}; + +struct PATHCONF3args { + nfs_fh3 object; +}; + +struct PATHCONF3resok { + post_op_attr obj_attributes; + unsigned int linkmax; + unsigned int name_max; + bool no_trunc; + bool chown_restricted; + bool case_insensitive; + bool case_preserving; +}; + +struct PATHCONF3resfail { + post_op_attr obj_attributes; +}; + +union PATHCONF3res switch (nfsstat3 status) { + case NFS3_OK: + PATHCONF3resok resok; + default: + PATHCONF3resfail resfail; +}; + +typedef string nfspath3<>; + +struct symlinkdata3 { + sattr3 symlink_attributes; + nfspath3 symlink_data; +}; + +struct SYMLINK3args { + diropargs3 where; + symlinkdata3 symlink; +}; + +struct SYMLINK3resok { + post_op_fh3 obj; + post_op_attr obj_attributes; + wcc_data dir_wcc; +}; + +struct SYMLINK3resfail { + wcc_data dir_wcc; +}; + +union SYMLINK3res switch (nfsstat3 status) { + case NFS3_OK: + SYMLINK3resok resok; + default: + SYMLINK3resfail resfail; +}; + + +struct READLINK3args { + nfs_fh3 symlink; +}; + +struct READLINK3resok { + post_op_attr symlink_attributes; + nfspath3 data; +}; + +struct READLINK3resfail { + post_op_attr symlink_attributes; +}; + +union READLINK3res switch (nfsstat3 status) { + case NFS3_OK: + READLINK3resok resok; + default: + READLINK3resfail resfail; +}; + + +struct devicedata3 { + sattr3 dev_attributes; + specdata3 spec; +}; + +union mknoddata3 switch (ftype3 type) { + case NF3CHR: + devicedata3 chr_device; + case NF3BLK: + devicedata3 blk_device; + case NF3SOCK: + sattr3 sock_attributes; + case NF3FIFO: + sattr3 pipe_attributes; + default: + void; +}; + +struct MKNOD3args { + diropargs3 where; + mknoddata3 what; +}; + +struct MKNOD3resok { + post_op_fh3 obj; + post_op_attr obj_attributes; + wcc_data dir_wcc; +}; + +struct MKNOD3resfail { + wcc_data dir_wcc; +}; + +union MKNOD3res switch (nfsstat3 status) { + case NFS3_OK: + MKNOD3resok resok; + default: + MKNOD3resfail resfail; +}; + + +struct MKDIR3args { + diropargs3 where; + sattr3 attributes; +}; + +struct MKDIR3resok { + post_op_fh3 obj; + post_op_attr obj_attributes; + wcc_data dir_wcc; +}; + +struct MKDIR3resfail { + wcc_data dir_wcc; +}; + +union MKDIR3res switch (nfsstat3 status) { + case NFS3_OK: + MKDIR3resok resok; + default: + MKDIR3resfail resfail; +}; + +struct RMDIR3args { + diropargs3 object; +}; + +struct RMDIR3resok { + wcc_data dir_wcc; +}; + +struct RMDIR3resfail { + wcc_data dir_wcc; +}; + +union RMDIR3res switch (nfsstat3 status) { + case NFS3_OK: + RMDIR3resok resok; + default: + RMDIR3resfail resfail; +}; + +struct RENAME3args { + diropargs3 from; + diropargs3 to; +}; + +struct RENAME3resok { + wcc_data fromdir_wcc; + wcc_data todir_wcc; +}; + +struct RENAME3resfail { + wcc_data fromdir_wcc; + wcc_data todir_wcc; +}; + +union RENAME3res switch (nfsstat3 status) { + case NFS3_OK: + RENAME3resok resok; + default: + RENAME3resfail resfail; +}; + +struct READDIRPLUS3args { + nfs_fh3 dir; + cookie3 cookie; + cookieverf3 cookieverf; + count3 dircount; + count3 maxcount; +}; + +struct entryplus3 { + fileid3 fileid; + filename3 name; + cookie3 cookie; + post_op_attr name_attributes; + post_op_fh3 name_handle; + entryplus3 *nextentry; +}; + +struct dirlistplus3 { + entryplus3 *entries; + bool eof; +}; + +struct READDIRPLUS3resok { + post_op_attr dir_attributes; + cookieverf3 cookieverf; + dirlistplus3 reply; +}; + + +struct READDIRPLUS3resfail { + post_op_attr dir_attributes; +}; + +union READDIRPLUS3res switch (nfsstat3 status) { + case NFS3_OK: + READDIRPLUS3resok resok; + default: + READDIRPLUS3resfail resfail; +}; + +struct READDIR3args { + nfs_fh3 dir; + cookie3 cookie; + cookieverf3 cookieverf; + count3 count; +}; + + +struct entry3 { + fileid3 fileid; + filename3 name; + cookie3 cookie; + entry3 *nextentry; +}; + +struct dirlist3 { + entry3 *entries; + bool eof; +}; + +struct READDIR3resok { + post_op_attr dir_attributes; + cookieverf3 cookieverf; + dirlist3 reply; +}; + +struct READDIR3resfail { + post_op_attr dir_attributes; +}; + +union READDIR3res switch (nfsstat3 status) { + case NFS3_OK: + READDIR3resok resok; + default: + READDIR3resfail resfail; +}; + +struct LINK3args { + nfs_fh3 file; + diropargs3 link; +}; + +struct LINK3resok { + post_op_attr file_attributes; + wcc_data linkdir_wcc; +}; + +struct LINK3resfail { + post_op_attr file_attributes; + wcc_data linkdir_wcc; +}; + +union LINK3res switch (nfsstat3 status) { + case NFS3_OK: + LINK3resok resok; + default: + LINK3resfail resfail; +}; + +union sattrguard3 switch (bool check) { + case TRUE: + nfstime3 obj_ctime; + case FALSE: + void; +}; + +struct SETATTR3args { + nfs_fh3 object; + sattr3 new_attributes; + sattrguard3 guard; +}; + +struct SETATTR3resok { + wcc_data obj_wcc; +}; + +struct SETATTR3resfail { + wcc_data obj_wcc; +}; + +union SETATTR3res switch (nfsstat3 status) { + case NFS3_OK: + SETATTR3resok resok; + default: + SETATTR3resfail resfail; +}; + +/* + * NFS v2 Definitions + * We share many definitions from v3 + */ +const FHSIZE2 = 32; +typedef opaque fhandle2[FHSIZE2]; + +enum ftype2 { + NF2NON = 0, + NF2REG = 1, + NF2DIR = 2, + NF2BLK = 3, + NF2CHR = 4, + NF2LNK = 5 +}; + +struct fattr2 { + ftype2 type; + unsigned int mode; + unsigned int nlink; + unsigned int uid; + unsigned int gid; + unsigned int size; + unsigned int blocksize; + unsigned int rdev; + unsigned int blocks; + unsigned int fsid; + unsigned int fileid; + nfstime3 atime; + nfstime3 mtime; + nfstime3 ctime; +}; + +struct sattr2 { + unsigned int mode; + unsigned int uid; + unsigned int gid; + unsigned int size; + nfstime3 atime; + nfstime3 mtime; +}; + +const MAXNAMLEN2 = 255; +typedef string filename2; + +const MAXPATHLEN2 = 1024; +typedef string path2; + +const NFSMAXDATA2 = 8192; +typedef opaque nfsdata2; + +const NFSCOOKIESIZE2 = 4; +typedef opaque nfscookie2[NFSCOOKIESIZE2]; + +struct entry2 { + unsigned int fileid; + filename2 name; + nfscookie2 cookie; + entry2 *nextentry; +}; + +struct diropargs2 { + fhandle2 dir; + filename2 name; +}; + +struct GETATTR2args { + fhandle2 fhandle; +}; + +struct GETATTR2resok { + fattr2 attributes; +}; + +union GETATTR2res switch (nfsstat3 status) { + case NFS3_OK: + GETATTR2resok resok; + default: + void; +}; + +struct SETATTR2args { + fhandle2 fhandle; + sattr2 attributes; +}; + +struct SETATTR2resok { + fattr2 attributes; +}; + +union SETATTR2res switch (nfsstat3 status) { + case NFS3_OK: + SETATTR2resok resok; + default: + void; +}; + +struct LOOKUP2args { + diropargs2 what; +}; + +struct LOOKUP2resok { + fhandle2 file; + fattr2 attributes; +}; + +union LOOKUP2res switch (nfsstat3 status) { + case NFS3_OK: + LOOKUP2resok resok; + default: + void; +}; + +struct READLINK2args { + fhandle2 file; +}; + +struct READLINK2resok { + path2 data; +}; + +union READLINK2res switch (nfsstat3 status) { + case NFS3_OK: + READLINK2resok resok; + default: + void; +}; + +struct READ2args { + fhandle2 file; + unsigned int offset; + unsigned int count; + unsigned int totalcount; +}; + +struct READ2resok { + fattr2 attributes; + nfsdata2 data; +}; + +union READ2res switch (nfsstat3 status) { + case NFS3_OK: + READ2resok resok; + default: + void; +}; + +struct WRITE2args { + fhandle2 file; + unsigned int beginoffset; + unsigned int offset; + unsigned int totalcount; + nfsdata2 data; +}; + +struct WRITE2resok { + fattr2 attributes; +}; + +union WRITE2res switch (nfsstat3 status) { + case NFS3_OK: + WRITE2resok resok; + default: + void; +}; + +struct CREATE2args { + diropargs2 where; + sattr2 attributes; +}; + +struct CREATE2resok { + fhandle2 file; + fattr2 attributes; +}; + +union CREATE2res switch (nfsstat3 status) { + case NFS3_OK: + CREATE2resok resok; + default: + void; +}; + +struct REMOVE2args { + diropargs2 what; +}; + +struct REMOVE2res { + nfsstat3 status; +}; + +struct RENAME2args { + diropargs2 from; + diropargs2 to; +}; + +struct RENAME2res { + nfsstat3 status; +}; + +struct LINK2args { + fhandle2 from; + diropargs2 to; +}; + +struct LINK2res { + nfsstat3 status; +}; + +struct SYMLINK2args { + diropargs2 from; + path2 to; + sattr2 attributes; +}; + +struct SYMLINK2res { + nfsstat3 status; +}; + +struct MKDIR2args { + diropargs2 where; + sattr2 attributes; +}; + +struct MKDIR2resok { + fhandle2 file; + fattr2 attributes; +}; + +union MKDIR2res switch (nfsstat3 status) { + case NFS3_OK: + MKDIR2resok resok; + default: + void; +}; + +struct RMDIR2args { + diropargs2 what; +}; + +struct RMDIR2res { + nfsstat3 status; +}; + +struct READDIR2args { + fhandle2 dir; + nfscookie2 cookie; + unsigned int count; +}; + +struct READDIR2resok { + entry2 *entries; + bool eof; +}; + +union READDIR2res switch (nfsstat3 status) { + case NFS3_OK: + READDIR2resok resok; + default: + void; +}; + +struct STATFS2args { + fhandle2 dir; +}; + +struct STATFS2resok { + unsigned int tsize; + unsigned int bsize; + unsigned int blocks; + unsigned int bfree; + unsigned int bavail; +}; + +union STATFS2res switch (nfsstat3 status) { + case NFS3_OK: + STATFS2resok resok; + default: + void; +}; + +program NFS_PROGRAM { + version NFS_V2 { + void + NFS2_NULL(void) = 0; + + GETATTR2res + NFS2_GETATTR(GETATTR2args) = 1; + + SETATTR2res + NFS2_SETATTR(SETATTR2args) = 2; + + LOOKUP2res + NFS2_LOOKUP(LOOKUP2args) = 4; + + READLINK2res + NFS2_READLINK(READLINK2args) = 5; + + READ2res + NFS2_READ(READ2args) = 6; + + WRITE2res + NFS2_WRITE(WRITE2args) = 8; + + CREATE2res + NFS2_CREATE(CREATE2args) = 9; + + REMOVE2res + NFS2_REMOVE(REMOVE2args) = 10; + + RENAME2res + NFS2_RENAME(RENAME2args) = 11; + + LINK2res + NFS2_LINK(LINK2args) = 12; + + SYMLINK2res + NFS2_SYMLINK(SYMLINK2args) = 13; + + MKDIR2res + NFS2_MKDIR(MKDIR2args) = 14; + + RMDIR2res + NFS2_RMDIR(RMDIR2args) = 15; + + READDIR2res + NFS2_READDIR(READDIR2args) = 16; + + STATFS2res + NFS2_STATFS(STATFS2args) = 17; + } = 2; + + version NFS_V3 { + void + NFS3_NULL(void) = 0; + + GETATTR3res + NFS3_GETATTR(GETATTR3args) = 1; + + SETATTR3res + NFS3_SETATTR(SETATTR3args) = 2; + + LOOKUP3res + NFS3_LOOKUP(LOOKUP3args) = 3; + + ACCESS3res + NFS3_ACCESS(ACCESS3args) = 4; + + READLINK3res + NFS3_READLINK(READLINK3args) = 5; + + READ3res + NFS3_READ(READ3args) = 6; + + WRITE3res + NFS3_WRITE(WRITE3args) = 7; + + CREATE3res + NFS3_CREATE(CREATE3args) = 8; + + MKDIR3res + NFS3_MKDIR(MKDIR3args) = 9; + + SYMLINK3res + NFS3_SYMLINK(SYMLINK3args) = 10; + + MKNOD3res + NFS3_MKNOD(MKNOD3args) = 11; + + REMOVE3res + NFS3_REMOVE(REMOVE3args) = 12; + + RMDIR3res + NFS3_RMDIR(RMDIR3args) = 13; + + RENAME3res + NFS3_RENAME(RENAME3args) = 14; + + LINK3res + NFS3_LINK(LINK3args) = 15; + + READDIR3res + NFS3_READDIR(READDIR3args) = 16; + + READDIRPLUS3res + NFS3_READDIRPLUS(READDIRPLUS3args) = 17; + + FSSTAT3res + NFS3_FSSTAT(FSSTAT3args) = 18; + + FSINFO3res + NFS3_FSINFO(FSINFO3args) = 19; + + PATHCONF3res + NFS3_PATHCONF(PATHCONF3args) = 20; + + COMMIT3res + NFS3_COMMIT(COMMIT3args) = 21; + } = 3; +} = 100003; + + + +/* NFS ACL definitions based on wireshark souces and network traces */ +/* NFSACL interface. Uses same port/process as NFS */ + +enum nfsacl_type { + NFSACL_TYPE_USER_OBJ = 0x0001, + NFSACL_TYPE_USER = 0x0002, + NFSACL_TYPE_GROUP_OBJ = 0x0004, + NFSACL_TYPE_GROUP = 0x0008, + NFSACL_TYPE_CLASS_OBJ = 0x0010, + NFSACL_TYPE_CLASS = 0x0020, + NFSACL_TYPE_DEFAULT = 0x1000, + NFSACL_TYPE_DEFAULT_USER_OBJ = 0x1001, + NFSACL_TYPE_DEFAULT_USER = 0x1002, + NFSACL_TYPE_DEFAULT_GROUP_OBJ = 0x1004, + NFSACL_TYPE_DEFAULT_GROUP = 0x1008, + NFSACL_TYPE_DEFAULT_CLASS_OBJ = 0x1010, + NFSACL_TYPE_DEFAULT_OTHER_OBJ = 0x1020 +}; + +const NFSACL_PERM_READ = 0x04; +const NFSACL_PERM_WRITE = 0x02; +const NFSACL_PERM_EXEC = 0x01; + +struct nfsacl_ace { + enum nfsacl_type type; + unsigned int id; + unsigned int perm; +}; + +const NFSACL_MASK_ACL_ENTRY = 0x0001; +const NFSACL_MASK_ACL_COUNT = 0x0002; +const NFSACL_MASK_ACL_DEFAULT_ENTRY = 0x0004; +const NFSACL_MASK_ACL_DEFAULT_COUNT = 0x0008; + +struct GETACL3args { + nfs_fh3 dir; + unsigned int mask; +}; + +struct GETACL3resok { + post_op_attr attr; + unsigned int mask; + unsigned int ace_count; + struct nfsacl_ace ace<>; + unsigned int default_ace_count; + struct nfsacl_ace default_ace<>; +}; + +union GETACL3res switch (nfsstat3 status) { +case NFS3_OK: + GETACL3resok resok; +default: + void; +}; + +struct SETACL3args { + nfs_fh3 dir; + unsigned int mask; + unsigned int ace_count; + struct nfsacl_ace ace<>; + unsigned int default_ace_count; + struct nfsacl_ace default_ace<>; +}; + +struct SETACL3resok { + post_op_attr attr; +}; + +union SETACL3res switch (nfsstat3 status) { +case NFS3_OK: + SETACL3resok resok; +default: + void; +}; + +program NFSACL_PROGRAM { + version NFSACL_V3 { + void + NFSACL3_NULL(void) = 0; + + GETACL3res + NFSACL3_GETACL(GETACL3args) = 1; + + SETACL3res + NFSACL3_SETACL(SETACL3args) = 2; + } = 3; +} = 100227; + diff --git a/deps/libnfs/nfs/nfsacl.c b/deps/libnfs/nfs/nfsacl.c new file mode 100644 index 000000000000..dcff3cee9105 --- /dev/null +++ b/deps/libnfs/nfs/nfsacl.c @@ -0,0 +1,106 @@ +/* + 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 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef WIN32 +#include +#else +#include +#endif/*WIN32*/ + +#include +#include +#include +#include "libnfs-zdr.h" +#include "libnfs.h" +#include "libnfs-raw.h" +#include "libnfs-private.h" +#include "libnfs-raw-nfs.h" + + +struct rpc_pdu * +rpc_nfsacl3_null_task(struct rpc_context *rpc, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFSACL_PROGRAM, NFSACL_V3, NFSACL3_NULL, cb, private_data, (zdrproc_t)zdr_void, 0); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nfsacl/null call"); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nfsacl/null call"); + return NULL; + } + + return pdu; +} + + +struct rpc_pdu * +rpc_nfsacl3_getacl_task(struct rpc_context *rpc, rpc_cb cb, struct GETACL3args *args, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFSACL_PROGRAM, NFSACL_V3, NFSACL3_GETACL, cb, private_data, (zdrproc_t)zdr_GETACL3res, sizeof(GETACL3res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nfsacl/getacl call"); + return NULL; + } + + if (zdr_GETACL3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode GETACL3args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nfsacl/getacl call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_nfsacl3_setacl_task(struct rpc_context *rpc, rpc_cb cb, struct SETACL3args *args, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFSACL_PROGRAM, NFSACL_V3, NFSACL3_SETACL, cb, private_data, (zdrproc_t)zdr_SETACL3res, sizeof(SETACL3res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nfsacl/setacl call"); + return NULL; + } + + if (zdr_SETACL3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode SETACL3args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nfsacl/setacl call"); + return NULL; + } + + return pdu; +} + diff --git a/deps/libnfs/nfs4/CMakeLists.txt b/deps/libnfs/nfs4/CMakeLists.txt new file mode 100644 index 000000000000..8e342d687870 --- /dev/null +++ b/deps/libnfs/nfs4/CMakeLists.txt @@ -0,0 +1,5 @@ +set(SOURCES libnfs-raw-nfs4.c + nfs4.c) +set(HEADERS libnfs-raw-nfs4.h) + +core_add_library(nfs4) diff --git a/deps/libnfs/nfs4/Makefile.am b/deps/libnfs/nfs4/Makefile.am new file mode 100644 index 000000000000..e4122dc49457 --- /dev/null +++ b/deps/libnfs/nfs4/Makefile.am @@ -0,0 +1,43 @@ +noinst_LTLIBRARIES = libnfs4.la + +nfs4_SOURCES_GENERATED = +nfs4_HEADERS_GENERATED = +nfs4_GENERATED = $(nfs4_SOURCES_GENERATED) $(nfs4_HEADERS_GENERATED) + +CLEANFILES = $(nfs_GENERATED) nfs4-stamp + +libnfs4_la_CPPFLAGS = -I$(abs_top_srcdir)/include \ + -I$(abs_top_srcdir)/include/nfsc \ + -I$(abs_top_srcdir)/win32 +libnfs4_la_SOURCES = \ + $(nfs4_SOURCES_GENERATED) \ + nfs4.c libnfs-raw-nfs4.c libnfs-raw-nfs4.h + +$(nfs4_GENERATED) : nfs4-stamp +nfs4-stamp : nfs4.x + rm -f $(nfs_GENERATED) + touch nfs4-stamp + +compile_rpc: + cat nfs4.x | head -16 >libnfs-raw-nfs4.h + rpcgen -h nfs4.x | sed \ +-e "s/#include /#include /" \ +-e "s/xdr/zdr/g" \ +-e "s/XDR/ZDR/g" \ +-e "s/#define _NFS_H_RPCGEN/#define _NFS_H_RPCGEN\n#include /g" \ +-e "s/#define NFS3_COOKIEVERFSIZE 8/#define NFS3_COOKIEVERFSIZE 8\n\n/g" \ +-e "s/ CLIENT / void /g" \ +-e "s/SVCXPRT /void /g" \ +-e "s/bool_t/uint32_t/g" | head --lines=-5 >>libnfs-raw-nfs4.h + cat libnfs-raw-nfs4.h.extra >>libnfs-raw-nfs4.h + cat nfs4.x | head -16 >libnfs-raw-nfs4.c + rpcgen -c nfs4.x | sed \ +-e "s/#include \".*nfs4.h\"/#include \"libnfs-xdr.h\"\n#include \"libnfs-raw-nfs4.h\"/" \ +-e "s/xdr/zdr/g" \ +-e "s/XDR/ZDR/g" \ +-e "s/bool_t/uint32_t/g" \ +-e "s/register int32_t \*buf;/register int32_t *buf;\n buf = NULL;/" \ +-e "s/int i;//" >> libnfs-raw-nfs4.c + sed -z -i -e "s/zdr_READ4resok/zzdr_READ4resok/" libnfs-raw-nfs4.c + sed -z -i -e "s/zdr_WRITE4args/zzdr_WRITE4args/" libnfs-raw-nfs4.c + cat libnfs-raw-nfs4.c.fragment >>libnfs-raw-nfs4.c diff --git a/deps/libnfs/nfs4/libnfs-raw-nfs4.c b/deps/libnfs/nfs4/libnfs-raw-nfs4.c new file mode 100644 index 000000000000..741a4cfa02ce --- /dev/null +++ b/deps/libnfs/nfs4/libnfs-raw-nfs4.c @@ -0,0 +1,4098 @@ +/* This is based on RFC3530 */ + +/* + * NFS v4 Definitions + */ + + +/* + * Copyright (C) The Internet Society (1998,1999,2000,2001,2002). + * All Rights Reserved. + */ + +/* + * nfs4_prot.x + * + */ +/* + * Please do not edit this file. + * It was generated using rpcgen. + */ + +#include "libnfs-zdr.h" +#include "libnfs-raw-nfs4.h" + +uint32_t +zdr_nfs_ftype4 (ZDR *zdrs, nfs_ftype4 *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_nfsstat4 (ZDR *zdrs, nfsstat4 *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_bitmap4 (ZDR *zdrs, bitmap4 *objp) +{ + if (!zdr_array (zdrs, (char **)&objp->bitmap4_val, &objp->bitmap4_len, ~0, + sizeof (uint32_t), (zdrproc_t) zdr_uint32_t)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_offset4 (ZDR *zdrs, offset4 *objp) +{ + if (!zdr_uint64_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_count4 (ZDR *zdrs, count4 *objp) +{ + if (!zdr_uint32_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_length4 (ZDR *zdrs, length4 *objp) +{ + if (!zdr_uint64_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_clientid4 (ZDR *zdrs, clientid4 *objp) +{ + if (!zdr_uint64_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_sequenceid4 (ZDR *zdrs, sequenceid4 *objp) +{ + if (!zdr_uint32_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_seqid4 (ZDR *zdrs, seqid4 *objp) +{ + if (!zdr_uint32_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_slotid4 (ZDR *zdrs, slotid4 *objp) +{ + if (!zdr_uint32_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_utf8string (ZDR *zdrs, utf8string *objp) +{ + if (!zdr_bytes (zdrs, (char **)&objp->utf8string_val, &objp->utf8string_len, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_utf8str_cis (ZDR *zdrs, utf8str_cis *objp) +{ + if (!zdr_utf8string (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_utf8str_cs (ZDR *zdrs, utf8str_cs *objp) +{ + if (!zdr_utf8string (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_utf8str_mixed (ZDR *zdrs, utf8str_mixed *objp) +{ + if (!zdr_utf8string (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_component4 (ZDR *zdrs, component4 *objp) +{ + if (!zdr_utf8str_cs (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_pathname4 (ZDR *zdrs, pathname4 *objp) +{ + if (!zdr_array (zdrs, (char **)&objp->pathname4_val, &objp->pathname4_len, ~0, + sizeof (component4), (zdrproc_t) zdr_component4)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_nfs_lockid4 (ZDR *zdrs, nfs_lockid4 *objp) +{ + if (!zdr_uint64_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_nfs_cookie4 (ZDR *zdrs, nfs_cookie4 *objp) +{ + if (!zdr_uint64_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_linktext4 (ZDR *zdrs, linktext4 *objp) +{ + if (!zdr_utf8str_cs (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_sec_oid4 (ZDR *zdrs, sec_oid4 *objp) +{ + if (!zdr_bytes (zdrs, (char **)&objp->sec_oid4_val, &objp->sec_oid4_len, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_qop4 (ZDR *zdrs, qop4 *objp) +{ + if (!zdr_uint32_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_mode4 (ZDR *zdrs, mode4 *objp) +{ + if (!zdr_uint32_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_changeid4 (ZDR *zdrs, changeid4 *objp) +{ + if (!zdr_uint64_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_verifier4 (ZDR *zdrs, verifier4 objp) +{ + if (!zdr_opaque (zdrs, objp, NFS4_VERIFIER_SIZE)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_sessionid4 (ZDR *zdrs, sessionid4 objp) +{ + if (!zdr_opaque (zdrs, objp, NFS4_SESSIONID_SIZE)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_authsys_parms (ZDR *zdrs, authsys_parms *objp) +{ + if (!zdr_u_int (zdrs, &objp->stamp)) + return FALSE; + if (!zdr_string (zdrs, &objp->machinename, 255)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->uid)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->gid)) + return FALSE; + if (!zdr_array (zdrs, (char **)&objp->gids.gids_val, &objp->gids.gids_len, 16, + sizeof (uint32_t), (zdrproc_t) zdr_u_int)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_deviceid4 (ZDR *zdrs, deviceid4 objp) +{ + if (!zdr_opaque (zdrs, objp, NFS4_DEVICEID4_SIZE)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_layouttype4 (ZDR *zdrs, layouttype4 *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_layoutupdate4 (ZDR *zdrs, layoutupdate4 *objp) +{ + if (!zdr_layouttype4 (zdrs, &objp->lou_type)) + return FALSE; + if (!zdr_bytes (zdrs, (char **)&objp->lou_body.lou_body_val, &objp->lou_body.lou_body_len, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_device_addr4 (ZDR *zdrs, device_addr4 *objp) +{ + if (!zdr_layouttype4 (zdrs, &objp->da_layout_type)) + return FALSE; + if (!zdr_bytes (zdrs, (char **)&objp->da_addr_body.da_addr_body_val, &objp->da_addr_body.da_addr_body_len, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_nfstime4 (ZDR *zdrs, nfstime4 *objp) +{ + if (!zdr_int64_t (zdrs, &objp->seconds)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->nseconds)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_time_how4 (ZDR *zdrs, time_how4 *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_layoutiomode4 (ZDR *zdrs, layoutiomode4 *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_layout_content4 (ZDR *zdrs, layout_content4 *objp) +{ + if (!zdr_layouttype4 (zdrs, &objp->loc_type)) + return FALSE; + if (!zdr_bytes (zdrs, (char **)&objp->loc_body.loc_body_val, &objp->loc_body.loc_body_len, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_layout4 (ZDR *zdrs, layout4 *objp) +{ + if (!zdr_offset4 (zdrs, &objp->lo_offset)) + return FALSE; + if (!zdr_length4 (zdrs, &objp->lo_length)) + return FALSE; + if (!zdr_layoutiomode4 (zdrs, &objp->lo_iomode)) + return FALSE; + if (!zdr_layout_content4 (zdrs, &objp->lo_content)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_settime4 (ZDR *zdrs, settime4 *objp) +{ + if (!zdr_time_how4 (zdrs, &objp->set_it)) + return FALSE; + switch (objp->set_it) { + case SET_TO_CLIENT_TIME4: + if (!zdr_nfstime4 (zdrs, &objp->settime4_u.time)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_nfs_fh4 (ZDR *zdrs, nfs_fh4 *objp) +{ + if (!zdr_bytes (zdrs, (char **)&objp->nfs_fh4_val, &objp->nfs_fh4_len, NFS4_FHSIZE)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fsid4 (ZDR *zdrs, fsid4 *objp) +{ + if (!zdr_uint64_t (zdrs, &objp->major)) + return FALSE; + if (!zdr_uint64_t (zdrs, &objp->minor)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fs_location4 (ZDR *zdrs, fs_location4 *objp) +{ + if (!zdr_array (zdrs, (char **)&objp->server.server_val, &objp->server.server_len, ~0, + sizeof (utf8str_cis), (zdrproc_t) zdr_utf8str_cis)) + return FALSE; + if (!zdr_pathname4 (zdrs, &objp->rootpath)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fs_locations4 (ZDR *zdrs, fs_locations4 *objp) +{ + if (!zdr_pathname4 (zdrs, &objp->fs_root)) + return FALSE; + if (!zdr_array (zdrs, (char **)&objp->locations.locations_val, &objp->locations.locations_len, ~0, + sizeof (fs_location4), (zdrproc_t) zdr_fs_location4)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_acetype4 (ZDR *zdrs, acetype4 *objp) +{ + if (!zdr_uint32_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_aceflag4 (ZDR *zdrs, aceflag4 *objp) +{ + if (!zdr_uint32_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_acemask4 (ZDR *zdrs, acemask4 *objp) +{ + if (!zdr_uint32_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_nfsace4 (ZDR *zdrs, nfsace4 *objp) +{ + if (!zdr_acetype4 (zdrs, &objp->type)) + return FALSE; + if (!zdr_aceflag4 (zdrs, &objp->flag)) + return FALSE; + if (!zdr_acemask4 (zdrs, &objp->access_mask)) + return FALSE; + if (!zdr_utf8str_mixed (zdrs, &objp->who)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_specdata4 (ZDR *zdrs, specdata4 *objp) +{ + if (!zdr_uint32_t (zdrs, &objp->specdata1)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->specdata2)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_supported_attrs (ZDR *zdrs, fattr4_supported_attrs *objp) +{ + if (!zdr_bitmap4 (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_type (ZDR *zdrs, fattr4_type *objp) +{ + if (!zdr_nfs_ftype4 (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_fh_expire_type (ZDR *zdrs, fattr4_fh_expire_type *objp) +{ + if (!zdr_uint32_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_change (ZDR *zdrs, fattr4_change *objp) +{ + if (!zdr_changeid4 (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_size (ZDR *zdrs, fattr4_size *objp) +{ + if (!zdr_uint64_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_link_support (ZDR *zdrs, fattr4_link_support *objp) +{ + if (!zdr_bool (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_symlink_support (ZDR *zdrs, fattr4_symlink_support *objp) +{ + if (!zdr_bool (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_named_attr (ZDR *zdrs, fattr4_named_attr *objp) +{ + if (!zdr_bool (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_fsid (ZDR *zdrs, fattr4_fsid *objp) +{ + if (!zdr_fsid4 (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_unique_handles (ZDR *zdrs, fattr4_unique_handles *objp) +{ + if (!zdr_bool (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_lease_time (ZDR *zdrs, fattr4_lease_time *objp) +{ + if (!zdr_uint32_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_rdattr_error (ZDR *zdrs, fattr4_rdattr_error *objp) +{ + if (!zdr_nfsstat4 (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_acl (ZDR *zdrs, fattr4_acl *objp) +{ + if (!zdr_array (zdrs, (char **)&objp->fattr4_acl_val, &objp->fattr4_acl_len, ~0, + sizeof (nfsace4), (zdrproc_t) zdr_nfsace4)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_aclsupport (ZDR *zdrs, fattr4_aclsupport *objp) +{ + if (!zdr_uint32_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_archive (ZDR *zdrs, fattr4_archive *objp) +{ + if (!zdr_bool (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_cansettime (ZDR *zdrs, fattr4_cansettime *objp) +{ + if (!zdr_bool (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_case_insensitive (ZDR *zdrs, fattr4_case_insensitive *objp) +{ + if (!zdr_bool (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_case_preserving (ZDR *zdrs, fattr4_case_preserving *objp) +{ + if (!zdr_bool (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_chown_restricted (ZDR *zdrs, fattr4_chown_restricted *objp) +{ + if (!zdr_bool (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_fileid (ZDR *zdrs, fattr4_fileid *objp) +{ + if (!zdr_uint64_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_files_avail (ZDR *zdrs, fattr4_files_avail *objp) +{ + if (!zdr_uint64_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_filehandle (ZDR *zdrs, fattr4_filehandle *objp) +{ + if (!zdr_nfs_fh4 (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_files_free (ZDR *zdrs, fattr4_files_free *objp) +{ + if (!zdr_uint64_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_files_total (ZDR *zdrs, fattr4_files_total *objp) +{ + if (!zdr_uint64_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_fs_locations (ZDR *zdrs, fattr4_fs_locations *objp) +{ + if (!zdr_fs_locations4 (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_hidden (ZDR *zdrs, fattr4_hidden *objp) +{ + if (!zdr_bool (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_homogeneous (ZDR *zdrs, fattr4_homogeneous *objp) +{ + if (!zdr_bool (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_maxfilesize (ZDR *zdrs, fattr4_maxfilesize *objp) +{ + if (!zdr_uint64_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_maxlink (ZDR *zdrs, fattr4_maxlink *objp) +{ + if (!zdr_uint32_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_maxname (ZDR *zdrs, fattr4_maxname *objp) +{ + if (!zdr_uint32_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_maxread (ZDR *zdrs, fattr4_maxread *objp) +{ + if (!zdr_uint64_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_maxwrite (ZDR *zdrs, fattr4_maxwrite *objp) +{ + if (!zdr_uint64_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_mimetype (ZDR *zdrs, fattr4_mimetype *objp) +{ + if (!zdr_utf8str_cs (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_mode (ZDR *zdrs, fattr4_mode *objp) +{ + if (!zdr_mode4 (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_mounted_on_fileid (ZDR *zdrs, fattr4_mounted_on_fileid *objp) +{ + if (!zdr_uint64_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_no_trunc (ZDR *zdrs, fattr4_no_trunc *objp) +{ + if (!zdr_bool (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_numlinks (ZDR *zdrs, fattr4_numlinks *objp) +{ + if (!zdr_uint32_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_owner (ZDR *zdrs, fattr4_owner *objp) +{ + if (!zdr_utf8str_mixed (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_owner_group (ZDR *zdrs, fattr4_owner_group *objp) +{ + if (!zdr_utf8str_mixed (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_quota_avail_hard (ZDR *zdrs, fattr4_quota_avail_hard *objp) +{ + if (!zdr_uint64_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_quota_avail_soft (ZDR *zdrs, fattr4_quota_avail_soft *objp) +{ + if (!zdr_uint64_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_quota_used (ZDR *zdrs, fattr4_quota_used *objp) +{ + if (!zdr_uint64_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_rawdev (ZDR *zdrs, fattr4_rawdev *objp) +{ + if (!zdr_specdata4 (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_space_avail (ZDR *zdrs, fattr4_space_avail *objp) +{ + if (!zdr_uint64_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_space_free (ZDR *zdrs, fattr4_space_free *objp) +{ + if (!zdr_uint64_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_space_total (ZDR *zdrs, fattr4_space_total *objp) +{ + if (!zdr_uint64_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_space_used (ZDR *zdrs, fattr4_space_used *objp) +{ + if (!zdr_uint64_t (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_system (ZDR *zdrs, fattr4_system *objp) +{ + if (!zdr_bool (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_time_access (ZDR *zdrs, fattr4_time_access *objp) +{ + if (!zdr_nfstime4 (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_time_access_set (ZDR *zdrs, fattr4_time_access_set *objp) +{ + if (!zdr_settime4 (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_time_backup (ZDR *zdrs, fattr4_time_backup *objp) +{ + if (!zdr_nfstime4 (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_time_create (ZDR *zdrs, fattr4_time_create *objp) +{ + if (!zdr_nfstime4 (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_time_delta (ZDR *zdrs, fattr4_time_delta *objp) +{ + if (!zdr_nfstime4 (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_time_metadata (ZDR *zdrs, fattr4_time_metadata *objp) +{ + if (!zdr_nfstime4 (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_time_modify (ZDR *zdrs, fattr4_time_modify *objp) +{ + if (!zdr_nfstime4 (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4_time_modify_set (ZDR *zdrs, fattr4_time_modify_set *objp) +{ + if (!zdr_settime4 (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_attrlist4 (ZDR *zdrs, attrlist4 *objp) +{ + if (!zdr_bytes (zdrs, (char **)&objp->attrlist4_val, &objp->attrlist4_len, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_fattr4 (ZDR *zdrs, fattr4 *objp) +{ + if (!zdr_bitmap4 (zdrs, &objp->attrmask)) + return FALSE; + if (!zdr_attrlist4 (zdrs, &objp->attr_vals)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_change_info4 (ZDR *zdrs, change_info4 *objp) +{ + if (!zdr_bool (zdrs, &objp->atomic)) + return FALSE; + if (!zdr_changeid4 (zdrs, &objp->before)) + return FALSE; + if (!zdr_changeid4 (zdrs, &objp->after)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_clientaddr4 (ZDR *zdrs, clientaddr4 *objp) +{ + if (!zdr_string (zdrs, &objp->r_netid, ~0)) + return FALSE; + if (!zdr_string (zdrs, &objp->r_addr, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_cb_client4 (ZDR *zdrs, cb_client4 *objp) +{ + if (!zdr_uint32_t (zdrs, &objp->cb_program)) + return FALSE; + if (!zdr_clientaddr4 (zdrs, &objp->cb_location)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_stateid4 (ZDR *zdrs, stateid4 *objp) +{ + + if (!zdr_uint32_t (zdrs, &objp->seqid)) + return FALSE; + if (!zdr_opaque (zdrs, objp->other, 12)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_nfs_client_id4 (ZDR *zdrs, nfs_client_id4 *objp) +{ + if (!zdr_verifier4 (zdrs, objp->verifier)) + return FALSE; + if (!zdr_bytes (zdrs, (char **)&objp->id.id_val, &objp->id.id_len, NFS4_OPAQUE_LIMIT)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_open_owner4 (ZDR *zdrs, open_owner4 *objp) +{ + if (!zdr_clientid4 (zdrs, &objp->clientid)) + return FALSE; + if (!zdr_bytes (zdrs, (char **)&objp->owner.owner_val, &objp->owner.owner_len, NFS4_OPAQUE_LIMIT)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_lock_owner4 (ZDR *zdrs, lock_owner4 *objp) +{ + if (!zdr_clientid4 (zdrs, &objp->clientid)) + return FALSE; + if (!zdr_bytes (zdrs, (char **)&objp->owner.owner_val, &objp->owner.owner_len, NFS4_OPAQUE_LIMIT)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_nfs_lock_type4 (ZDR *zdrs, nfs_lock_type4 *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_client_owner4 (ZDR *zdrs, client_owner4 *objp) +{ + if (!zdr_verifier4 (zdrs, objp->co_verifier)) + return FALSE; + if (!zdr_bytes (zdrs, (char **)&objp->co_ownerid.co_ownerid_val, &objp->co_ownerid.co_ownerid_len, NFS4_OPAQUE_LIMIT)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_server_owner4 (ZDR *zdrs, server_owner4 *objp) +{ + if (!zdr_uint64_t (zdrs, &objp->so_minor_id)) + return FALSE; + if (!zdr_bytes (zdrs, (char **)&objp->so_major_id.so_major_id_val, &objp->so_major_id.so_major_id_len, NFS4_OPAQUE_LIMIT)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_nfs_impl_id4 (ZDR *zdrs, nfs_impl_id4 *objp) +{ + if (!zdr_utf8str_cis (zdrs, &objp->nii_domain)) + return FALSE; + if (!zdr_utf8str_cs (zdrs, &objp->nii_name)) + return FALSE; + if (!zdr_nfstime4 (zdrs, &objp->nii_date)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_ACCESS4args (ZDR *zdrs, ACCESS4args *objp) +{ + if (!zdr_uint32_t (zdrs, &objp->access)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_ACCESS4resok (ZDR *zdrs, ACCESS4resok *objp) +{ + if (!zdr_uint32_t (zdrs, &objp->supported)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->access)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_ACCESS4res (ZDR *zdrs, ACCESS4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS4_OK: + if (!zdr_ACCESS4resok (zdrs, &objp->ACCESS4res_u.resok4)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_CLOSE4args (ZDR *zdrs, CLOSE4args *objp) +{ + if (!zdr_seqid4 (zdrs, &objp->seqid)) + return FALSE; + if (!zdr_stateid4 (zdrs, &objp->open_stateid)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_CLOSE4res (ZDR *zdrs, CLOSE4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS4_OK: + if (!zdr_stateid4 (zdrs, &objp->CLOSE4res_u.open_stateid)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_COMMIT4args (ZDR *zdrs, COMMIT4args *objp) +{ + if (!zdr_offset4 (zdrs, &objp->offset)) + return FALSE; + if (!zdr_count4 (zdrs, &objp->count)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_COMMIT4resok (ZDR *zdrs, COMMIT4resok *objp) +{ + if (!zdr_verifier4 (zdrs, objp->writeverf)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_COMMIT4res (ZDR *zdrs, COMMIT4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS4_OK: + if (!zdr_COMMIT4resok (zdrs, &objp->COMMIT4res_u.resok4)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_createtype4 (ZDR *zdrs, createtype4 *objp) +{ + if (!zdr_nfs_ftype4 (zdrs, &objp->type)) + return FALSE; + switch (objp->type) { + case NF4LNK: + if (!zdr_linktext4 (zdrs, &objp->createtype4_u.linkdata)) + return FALSE; + break; + case NF4BLK: + case NF4CHR: + if (!zdr_specdata4 (zdrs, &objp->createtype4_u.devdata)) + return FALSE; + break; + case NF4SOCK: + case NF4FIFO: + case NF4DIR: + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_CREATE4args (ZDR *zdrs, CREATE4args *objp) +{ + if (!zdr_createtype4 (zdrs, &objp->objtype)) + return FALSE; + if (!zdr_component4 (zdrs, &objp->objname)) + return FALSE; + if (!zdr_fattr4 (zdrs, &objp->createattrs)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_CREATE4resok (ZDR *zdrs, CREATE4resok *objp) +{ + if (!zdr_change_info4 (zdrs, &objp->cinfo)) + return FALSE; + if (!zdr_bitmap4 (zdrs, &objp->attrset)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_CREATE4res (ZDR *zdrs, CREATE4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS4_OK: + if (!zdr_CREATE4resok (zdrs, &objp->CREATE4res_u.resok4)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_DELEGPURGE4args (ZDR *zdrs, DELEGPURGE4args *objp) +{ + if (!zdr_clientid4 (zdrs, &objp->clientid)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_DELEGPURGE4res (ZDR *zdrs, DELEGPURGE4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_DELEGRETURN4args (ZDR *zdrs, DELEGRETURN4args *objp) +{ + if (!zdr_stateid4 (zdrs, &objp->deleg_stateid)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_DELEGRETURN4res (ZDR *zdrs, DELEGRETURN4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_GETATTR4args (ZDR *zdrs, GETATTR4args *objp) +{ + if (!zdr_bitmap4 (zdrs, &objp->attr_request)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_GETATTR4resok (ZDR *zdrs, GETATTR4resok *objp) +{ + if (!zdr_fattr4 (zdrs, &objp->obj_attributes)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_GETATTR4res (ZDR *zdrs, GETATTR4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS4_OK: + if (!zdr_GETATTR4resok (zdrs, &objp->GETATTR4res_u.resok4)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_GETFH4resok (ZDR *zdrs, GETFH4resok *objp) +{ + if (!zdr_nfs_fh4 (zdrs, &objp->object)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_GETFH4res (ZDR *zdrs, GETFH4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS4_OK: + if (!zdr_GETFH4resok (zdrs, &objp->GETFH4res_u.resok4)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_LINK4args (ZDR *zdrs, LINK4args *objp) +{ + if (!zdr_component4 (zdrs, &objp->newname)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_LINK4resok (ZDR *zdrs, LINK4resok *objp) +{ + if (!zdr_change_info4 (zdrs, &objp->cinfo)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_LINK4res (ZDR *zdrs, LINK4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS4_OK: + if (!zdr_LINK4resok (zdrs, &objp->LINK4res_u.resok4)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_open_to_lock_owner4 (ZDR *zdrs, open_to_lock_owner4 *objp) +{ + if (!zdr_seqid4 (zdrs, &objp->open_seqid)) + return FALSE; + if (!zdr_stateid4 (zdrs, &objp->open_stateid)) + return FALSE; + if (!zdr_seqid4 (zdrs, &objp->lock_seqid)) + return FALSE; + if (!zdr_lock_owner4 (zdrs, &objp->lock_owner)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_exist_lock_owner4 (ZDR *zdrs, exist_lock_owner4 *objp) +{ + if (!zdr_stateid4 (zdrs, &objp->lock_stateid)) + return FALSE; + if (!zdr_seqid4 (zdrs, &objp->lock_seqid)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_locker4 (ZDR *zdrs, locker4 *objp) +{ + if (!zdr_bool (zdrs, &objp->new_lock_owner)) + return FALSE; + switch (objp->new_lock_owner) { + case TRUE: + if (!zdr_open_to_lock_owner4 (zdrs, &objp->locker4_u.open_owner)) + return FALSE; + break; + case FALSE: + if (!zdr_exist_lock_owner4 (zdrs, &objp->locker4_u.lock_owner)) + return FALSE; + break; + default: + return FALSE; + } + return TRUE; +} + +uint32_t +zdr_LOCK4args (ZDR *zdrs, LOCK4args *objp) +{ + if (!zdr_nfs_lock_type4 (zdrs, &objp->locktype)) + return FALSE; + if (!zdr_bool (zdrs, &objp->reclaim)) + return FALSE; + if (!zdr_offset4 (zdrs, &objp->offset)) + return FALSE; + if (!zdr_length4 (zdrs, &objp->length)) + return FALSE; + if (!zdr_locker4 (zdrs, &objp->locker)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_LOCK4denied (ZDR *zdrs, LOCK4denied *objp) +{ + if (!zdr_offset4 (zdrs, &objp->offset)) + return FALSE; + if (!zdr_length4 (zdrs, &objp->length)) + return FALSE; + if (!zdr_nfs_lock_type4 (zdrs, &objp->locktype)) + return FALSE; + if (!zdr_lock_owner4 (zdrs, &objp->owner)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_LOCK4resok (ZDR *zdrs, LOCK4resok *objp) +{ + if (!zdr_stateid4 (zdrs, &objp->lock_stateid)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_LOCK4res (ZDR *zdrs, LOCK4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS4_OK: + if (!zdr_LOCK4resok (zdrs, &objp->LOCK4res_u.resok4)) + return FALSE; + break; + case NFS4ERR_DENIED: + if (!zdr_LOCK4denied (zdrs, &objp->LOCK4res_u.denied)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_LOCKT4args (ZDR *zdrs, LOCKT4args *objp) +{ + if (!zdr_nfs_lock_type4 (zdrs, &objp->locktype)) + return FALSE; + if (!zdr_offset4 (zdrs, &objp->offset)) + return FALSE; + if (!zdr_length4 (zdrs, &objp->length)) + return FALSE; + if (!zdr_lock_owner4 (zdrs, &objp->owner)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_LOCKT4res (ZDR *zdrs, LOCKT4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS4ERR_DENIED: + if (!zdr_LOCK4denied (zdrs, &objp->LOCKT4res_u.denied)) + return FALSE; + break; + case NFS4_OK: + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_LOCKU4args (ZDR *zdrs, LOCKU4args *objp) +{ + if (!zdr_nfs_lock_type4 (zdrs, &objp->locktype)) + return FALSE; + if (!zdr_seqid4 (zdrs, &objp->seqid)) + return FALSE; + if (!zdr_stateid4 (zdrs, &objp->lock_stateid)) + return FALSE; + if (!zdr_offset4 (zdrs, &objp->offset)) + return FALSE; + if (!zdr_length4 (zdrs, &objp->length)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_LOCKU4res (ZDR *zdrs, LOCKU4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS4_OK: + if (!zdr_stateid4 (zdrs, &objp->LOCKU4res_u.lock_stateid)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_LOOKUP4args (ZDR *zdrs, LOOKUP4args *objp) +{ + if (!zdr_component4 (zdrs, &objp->objname)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_LOOKUP4res (ZDR *zdrs, LOOKUP4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_LOOKUPP4res (ZDR *zdrs, LOOKUPP4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_NVERIFY4args (ZDR *zdrs, NVERIFY4args *objp) +{ + if (!zdr_fattr4 (zdrs, &objp->obj_attributes)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_NVERIFY4res (ZDR *zdrs, NVERIFY4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_createmode4 (ZDR *zdrs, createmode4 *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_createhow4 (ZDR *zdrs, createhow4 *objp) +{ + if (!zdr_createmode4 (zdrs, &objp->mode)) + return FALSE; + switch (objp->mode) { + case UNCHECKED4: + case GUARDED4: + if (!zdr_fattr4 (zdrs, &objp->createhow4_u.createattrs)) + return FALSE; + break; + case EXCLUSIVE4: + if (!zdr_verifier4 (zdrs, objp->createhow4_u.createverf)) + return FALSE; + break; + default: + return FALSE; + } + return TRUE; +} + +uint32_t +zdr_opentype4 (ZDR *zdrs, opentype4 *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_openflag4 (ZDR *zdrs, openflag4 *objp) +{ + if (!zdr_opentype4 (zdrs, &objp->opentype)) + return FALSE; + switch (objp->opentype) { + case OPEN4_CREATE: + if (!zdr_createhow4 (zdrs, &objp->openflag4_u.how)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_limit_by4 (ZDR *zdrs, limit_by4 *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_nfs_modified_limit4 (ZDR *zdrs, nfs_modified_limit4 *objp) +{ + if (!zdr_uint32_t (zdrs, &objp->num_blocks)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->bytes_per_block)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_nfs_space_limit4 (ZDR *zdrs, nfs_space_limit4 *objp) +{ + if (!zdr_limit_by4 (zdrs, &objp->limitby)) + return FALSE; + switch (objp->limitby) { + case NFS_LIMIT_SIZE: + if (!zdr_uint64_t (zdrs, &objp->nfs_space_limit4_u.filesize)) + return FALSE; + break; + case NFS_LIMIT_BLOCKS: + if (!zdr_nfs_modified_limit4 (zdrs, &objp->nfs_space_limit4_u.mod_blocks)) + return FALSE; + break; + default: + return FALSE; + } + return TRUE; +} + +uint32_t +zdr_open_delegation_type4 (ZDR *zdrs, open_delegation_type4 *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_open_claim_type4 (ZDR *zdrs, open_claim_type4 *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_open_claim_delegate_cur4 (ZDR *zdrs, open_claim_delegate_cur4 *objp) +{ + if (!zdr_stateid4 (zdrs, &objp->delegate_stateid)) + return FALSE; + if (!zdr_component4 (zdrs, &objp->file)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_open_claim4 (ZDR *zdrs, open_claim4 *objp) +{ + if (!zdr_open_claim_type4 (zdrs, &objp->claim)) + return FALSE; + switch (objp->claim) { + case CLAIM_NULL: + if (!zdr_component4 (zdrs, &objp->open_claim4_u.file)) + return FALSE; + break; + case CLAIM_PREVIOUS: + if (!zdr_open_delegation_type4 (zdrs, &objp->open_claim4_u.delegate_type)) + return FALSE; + break; + case CLAIM_DELEGATE_CUR: + if (!zdr_open_claim_delegate_cur4 (zdrs, &objp->open_claim4_u.delegate_cur_info)) + return FALSE; + break; + case CLAIM_DELEGATE_PREV: + if (!zdr_component4 (zdrs, &objp->open_claim4_u.file_delegate_prev)) + return FALSE; + break; + case CLAIM_FH: + break; + case CLAIM_DELEG_PREV_FH: + break; + case CLAIM_DELEG_CUR_FH: + if (!zdr_stateid4 (zdrs, &objp->open_claim4_u.oc_delegate_stateid)) + return FALSE; + break; + default: + return FALSE; + } + return TRUE; +} + +uint32_t +zdr_OPEN4args (ZDR *zdrs, OPEN4args *objp) +{ + if (!zdr_seqid4 (zdrs, &objp->seqid)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->share_access)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->share_deny)) + return FALSE; + if (!zdr_open_owner4 (zdrs, &objp->owner)) + return FALSE; + if (!zdr_openflag4 (zdrs, &objp->openhow)) + return FALSE; + if (!zdr_open_claim4 (zdrs, &objp->claim)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_open_read_delegation4 (ZDR *zdrs, open_read_delegation4 *objp) +{ + if (!zdr_stateid4 (zdrs, &objp->stateid)) + return FALSE; + if (!zdr_bool (zdrs, &objp->recall)) + return FALSE; + if (!zdr_nfsace4 (zdrs, &objp->permissions)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_open_write_delegation4 (ZDR *zdrs, open_write_delegation4 *objp) +{ + if (!zdr_stateid4 (zdrs, &objp->stateid)) + return FALSE; + if (!zdr_bool (zdrs, &objp->recall)) + return FALSE; + if (!zdr_nfs_space_limit4 (zdrs, &objp->space_limit)) + return FALSE; + if (!zdr_nfsace4 (zdrs, &objp->permissions)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_open_delegation4 (ZDR *zdrs, open_delegation4 *objp) +{ + if (!zdr_open_delegation_type4 (zdrs, &objp->delegation_type)) + return FALSE; + switch (objp->delegation_type) { + case OPEN_DELEGATE_NONE: + break; + case OPEN_DELEGATE_READ: + if (!zdr_open_read_delegation4 (zdrs, &objp->open_delegation4_u.read)) + return FALSE; + break; + case OPEN_DELEGATE_WRITE: + if (!zdr_open_write_delegation4 (zdrs, &objp->open_delegation4_u.write)) + return FALSE; + break; + default: + return FALSE; + } + return TRUE; +} + +uint32_t +zdr_OPEN4resok (ZDR *zdrs, OPEN4resok *objp) +{ + if (!zdr_stateid4 (zdrs, &objp->stateid)) + return FALSE; + if (!zdr_change_info4 (zdrs, &objp->cinfo)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->rflags)) + return FALSE; + if (!zdr_bitmap4 (zdrs, &objp->attrset)) + return FALSE; + if (!zdr_open_delegation4 (zdrs, &objp->delegation)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_OPEN4res (ZDR *zdrs, OPEN4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS4_OK: + if (!zdr_OPEN4resok (zdrs, &objp->OPEN4res_u.resok4)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_OPENATTR4args (ZDR *zdrs, OPENATTR4args *objp) +{ + if (!zdr_bool (zdrs, &objp->createdir)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_OPENATTR4res (ZDR *zdrs, OPENATTR4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_OPEN_CONFIRM4args (ZDR *zdrs, OPEN_CONFIRM4args *objp) +{ + if (!zdr_stateid4 (zdrs, &objp->open_stateid)) + return FALSE; + if (!zdr_seqid4 (zdrs, &objp->seqid)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_OPEN_CONFIRM4resok (ZDR *zdrs, OPEN_CONFIRM4resok *objp) +{ + if (!zdr_stateid4 (zdrs, &objp->open_stateid)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_OPEN_CONFIRM4res (ZDR *zdrs, OPEN_CONFIRM4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS4_OK: + if (!zdr_OPEN_CONFIRM4resok (zdrs, &objp->OPEN_CONFIRM4res_u.resok4)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_OPEN_DOWNGRADE4args (ZDR *zdrs, OPEN_DOWNGRADE4args *objp) +{ + if (!zdr_stateid4 (zdrs, &objp->open_stateid)) + return FALSE; + if (!zdr_seqid4 (zdrs, &objp->seqid)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->share_access)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->share_deny)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_OPEN_DOWNGRADE4resok (ZDR *zdrs, OPEN_DOWNGRADE4resok *objp) +{ + if (!zdr_stateid4 (zdrs, &objp->open_stateid)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_OPEN_DOWNGRADE4res (ZDR *zdrs, OPEN_DOWNGRADE4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS4_OK: + if (!zdr_OPEN_DOWNGRADE4resok (zdrs, &objp->OPEN_DOWNGRADE4res_u.resok4)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_PUTFH4args (ZDR *zdrs, PUTFH4args *objp) +{ + if (!zdr_nfs_fh4 (zdrs, &objp->object)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PUTFH4res (ZDR *zdrs, PUTFH4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PUTPUBFH4res (ZDR *zdrs, PUTPUBFH4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PUTROOTFH4res (ZDR *zdrs, PUTROOTFH4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_READ4args (ZDR *zdrs, READ4args *objp) +{ + if (!zdr_stateid4 (zdrs, &objp->stateid)) + return FALSE; + if (!zdr_offset4 (zdrs, &objp->offset)) + return FALSE; + if (!zdr_count4 (zdrs, &objp->count)) + return FALSE; + return TRUE; +} + +uint32_t +zzdr_READ4resok (ZDR *zdrs, READ4resok *objp) +{ + if (!zdr_bool (zdrs, &objp->eof)) + return FALSE; + if (!zdr_bytes (zdrs, (char **)&objp->data.data_val, &objp->data.data_len, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_READ4res (ZDR *zdrs, READ4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS4_OK: + if (!zdr_READ4resok (zdrs, &objp->READ4res_u.resok4)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_READDIR4args (ZDR *zdrs, READDIR4args *objp) +{ + if (!zdr_nfs_cookie4 (zdrs, &objp->cookie)) + return FALSE; + if (!zdr_verifier4 (zdrs, objp->cookieverf)) + return FALSE; + if (!zdr_count4 (zdrs, &objp->dircount)) + return FALSE; + if (!zdr_count4 (zdrs, &objp->maxcount)) + return FALSE; + if (!zdr_bitmap4 (zdrs, &objp->attr_request)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_entry4 (ZDR *zdrs, entry4 *objp) +{ + if (!zdr_nfs_cookie4 (zdrs, &objp->cookie)) + return FALSE; + if (!zdr_component4 (zdrs, &objp->name)) + return FALSE; + if (!zdr_fattr4 (zdrs, &objp->attrs)) + return FALSE; + if (!zdr_pointer (zdrs, (char **)&objp->nextentry, sizeof (entry4), (zdrproc_t) zdr_entry4)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_dirlist4 (ZDR *zdrs, dirlist4 *objp) +{ + if (!zdr_pointer (zdrs, (char **)&objp->entries, sizeof (entry4), (zdrproc_t) zdr_entry4)) + return FALSE; + if (!zdr_bool (zdrs, &objp->eof)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_READDIR4resok (ZDR *zdrs, READDIR4resok *objp) +{ + if (!zdr_verifier4 (zdrs, objp->cookieverf)) + return FALSE; + if (!zdr_dirlist4 (zdrs, &objp->reply)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_READDIR4res (ZDR *zdrs, READDIR4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS4_OK: + if (!zdr_READDIR4resok (zdrs, &objp->READDIR4res_u.resok4)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_READLINK4resok (ZDR *zdrs, READLINK4resok *objp) +{ + if (!zdr_linktext4 (zdrs, &objp->link)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_READLINK4res (ZDR *zdrs, READLINK4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS4_OK: + if (!zdr_READLINK4resok (zdrs, &objp->READLINK4res_u.resok4)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_REMOVE4args (ZDR *zdrs, REMOVE4args *objp) +{ + if (!zdr_component4 (zdrs, &objp->target)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_REMOVE4resok (ZDR *zdrs, REMOVE4resok *objp) +{ + if (!zdr_change_info4 (zdrs, &objp->cinfo)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_REMOVE4res (ZDR *zdrs, REMOVE4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS4_OK: + if (!zdr_REMOVE4resok (zdrs, &objp->REMOVE4res_u.resok4)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_RENAME4args (ZDR *zdrs, RENAME4args *objp) +{ + if (!zdr_component4 (zdrs, &objp->oldname)) + return FALSE; + if (!zdr_component4 (zdrs, &objp->newname)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_RENAME4resok (ZDR *zdrs, RENAME4resok *objp) +{ + if (!zdr_change_info4 (zdrs, &objp->source_cinfo)) + return FALSE; + if (!zdr_change_info4 (zdrs, &objp->target_cinfo)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_RENAME4res (ZDR *zdrs, RENAME4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS4_OK: + if (!zdr_RENAME4resok (zdrs, &objp->RENAME4res_u.resok4)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_RENEW4args (ZDR *zdrs, RENEW4args *objp) +{ + if (!zdr_clientid4 (zdrs, &objp->clientid)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_RENEW4res (ZDR *zdrs, RENEW4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_RESTOREFH4res (ZDR *zdrs, RESTOREFH4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_SAVEFH4res (ZDR *zdrs, SAVEFH4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_SECINFO4args (ZDR *zdrs, SECINFO4args *objp) +{ + if (!zdr_component4 (zdrs, &objp->name)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_rpc_gss_svc_t (ZDR *zdrs, rpc_gss_svc_t *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_rpcsec_gss_info (ZDR *zdrs, rpcsec_gss_info *objp) +{ + if (!zdr_sec_oid4 (zdrs, &objp->oid)) + return FALSE; + if (!zdr_qop4 (zdrs, &objp->qop)) + return FALSE; + if (!zdr_rpc_gss_svc_t (zdrs, &objp->service)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_secinfo4 (ZDR *zdrs, secinfo4 *objp) +{ + if (!zdr_uint32_t (zdrs, &objp->flavor)) + return FALSE; + switch (objp->flavor) { + case RPCSEC_GSS: + if (!zdr_rpcsec_gss_info (zdrs, &objp->secinfo4_u.flavor_info)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_SECINFO4resok (ZDR *zdrs, SECINFO4resok *objp) +{ + if (!zdr_array (zdrs, (char **)&objp->SECINFO4resok_val, &objp->SECINFO4resok_len, ~0, + sizeof (secinfo4), (zdrproc_t) zdr_secinfo4)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_SECINFO4res (ZDR *zdrs, SECINFO4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS4_OK: + if (!zdr_SECINFO4resok (zdrs, &objp->SECINFO4res_u.resok4)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_SETATTR4args (ZDR *zdrs, SETATTR4args *objp) +{ + if (!zdr_stateid4 (zdrs, &objp->stateid)) + return FALSE; + if (!zdr_fattr4 (zdrs, &objp->obj_attributes)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_SETATTR4res (ZDR *zdrs, SETATTR4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + if (!zdr_bitmap4 (zdrs, &objp->attrsset)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_SETCLIENTID4args (ZDR *zdrs, SETCLIENTID4args *objp) +{ + if (!zdr_nfs_client_id4 (zdrs, &objp->client)) + return FALSE; + if (!zdr_cb_client4 (zdrs, &objp->callback)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->callback_ident)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_SETCLIENTID4resok (ZDR *zdrs, SETCLIENTID4resok *objp) +{ + if (!zdr_clientid4 (zdrs, &objp->clientid)) + return FALSE; + if (!zdr_verifier4 (zdrs, objp->setclientid_confirm)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_SETCLIENTID4res (ZDR *zdrs, SETCLIENTID4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS4_OK: + if (!zdr_SETCLIENTID4resok (zdrs, &objp->SETCLIENTID4res_u.resok4)) + return FALSE; + break; + case NFS4ERR_CLID_INUSE: + if (!zdr_clientaddr4 (zdrs, &objp->SETCLIENTID4res_u.client_using)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_SETCLIENTID_CONFIRM4args (ZDR *zdrs, SETCLIENTID_CONFIRM4args *objp) +{ + if (!zdr_clientid4 (zdrs, &objp->clientid)) + return FALSE; + if (!zdr_verifier4 (zdrs, objp->setclientid_confirm)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_SETCLIENTID_CONFIRM4res (ZDR *zdrs, SETCLIENTID_CONFIRM4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_VERIFY4args (ZDR *zdrs, VERIFY4args *objp) +{ + if (!zdr_fattr4 (zdrs, &objp->obj_attributes)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_VERIFY4res (ZDR *zdrs, VERIFY4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_stable_how4 (ZDR *zdrs, stable_how4 *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zzdr_WRITE4args (ZDR *zdrs, WRITE4args *objp) +{ + if (!zdr_stateid4 (zdrs, &objp->stateid)) + return FALSE; + if (!zdr_offset4 (zdrs, &objp->offset)) + return FALSE; + if (!zdr_stable_how4 (zdrs, &objp->stable)) + return FALSE; + if (!zdr_bytes (zdrs, (char **)&objp->data.data_val, &objp->data.data_len, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_WRITE4resok (ZDR *zdrs, WRITE4resok *objp) +{ + if (!zdr_count4 (zdrs, &objp->count)) + return FALSE; + if (!zdr_stable_how4 (zdrs, &objp->committed)) + return FALSE; + if (!zdr_verifier4 (zdrs, objp->writeverf)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_WRITE4res (ZDR *zdrs, WRITE4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS4_OK: + if (!zdr_WRITE4resok (zdrs, &objp->WRITE4res_u.resok4)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_RELEASE_LOCKOWNER4args (ZDR *zdrs, RELEASE_LOCKOWNER4args *objp) +{ + if (!zdr_lock_owner4 (zdrs, &objp->lock_owner)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_RELEASE_LOCKOWNER4res (ZDR *zdrs, RELEASE_LOCKOWNER4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_gsshandle4_t (ZDR *zdrs, gsshandle4_t *objp) +{ + if (!zdr_bytes (zdrs, (char **)&objp->gsshandle4_t_val, &objp->gsshandle4_t_len, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_callback_sec_parms4 (ZDR *zdrs, callback_sec_parms4 *objp) +{ + if (!zdr_uint32_t (zdrs, &objp->cb_secflavor)) + return FALSE; + switch (objp->cb_secflavor) { + case AUTH_NONE: + break; + case AUTH_SYS: + if (!zdr_authsys_parms (zdrs, &objp->callback_sec_parms4_u.cbsp_sys_cred)) + return FALSE; + break; + default: + return FALSE; + } + return TRUE; +} + +uint32_t +zdr_channel_dir_from_client4 (ZDR *zdrs, channel_dir_from_client4 *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_BIND_CONN_TO_SESSION4args (ZDR *zdrs, BIND_CONN_TO_SESSION4args *objp) +{ + if (!zdr_sessionid4 (zdrs, objp->bctsa_sessid)) + return FALSE; + if (!zdr_channel_dir_from_client4 (zdrs, &objp->bctsa_dir)) + return FALSE; + if (!zdr_bool (zdrs, &objp->bctsa_use_conn_in_rdma_mode)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_channel_dir_from_server4 (ZDR *zdrs, channel_dir_from_server4 *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_BIND_CONN_TO_SESSION4resok (ZDR *zdrs, BIND_CONN_TO_SESSION4resok *objp) +{ + if (!zdr_sessionid4 (zdrs, objp->bctsr_sessid)) + return FALSE; + if (!zdr_channel_dir_from_server4 (zdrs, &objp->bctsr_dir)) + return FALSE; + if (!zdr_bool (zdrs, &objp->bctsr_use_conn_in_rdma_mode)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_BIND_CONN_TO_SESSION4res (ZDR *zdrs, BIND_CONN_TO_SESSION4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->bctsr_status)) + return FALSE; + switch (objp->bctsr_status) { + case NFS4_OK: + if (!zdr_BIND_CONN_TO_SESSION4resok (zdrs, &objp->BIND_CONN_TO_SESSION4res_u.bctsr_resok4)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_state_protect_ops4 (ZDR *zdrs, state_protect_ops4 *objp) +{ + if (!zdr_bitmap4 (zdrs, &objp->spo_must_enforce)) + return FALSE; + if (!zdr_bitmap4 (zdrs, &objp->spo_must_allow)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_ssv_sp_parms4 (ZDR *zdrs, ssv_sp_parms4 *objp) +{ + if (!zdr_state_protect_ops4 (zdrs, &objp->ssp_ops)) + return FALSE; + if (!zdr_array (zdrs, (char **)&objp->ssp_hash_algs.ssp_hash_algs_val, &objp->ssp_hash_algs.ssp_hash_algs_len, ~0, + sizeof (sec_oid4), (zdrproc_t) zdr_sec_oid4)) + return FALSE; + if (!zdr_array (zdrs, (char **)&objp->ssp_encr_algs.ssp_encr_algs_val, &objp->ssp_encr_algs.ssp_encr_algs_len, ~0, + sizeof (sec_oid4), (zdrproc_t) zdr_sec_oid4)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->ssp_window)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->ssp_num_gss_handles)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_state_protect_how4 (ZDR *zdrs, state_protect_how4 *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_state_protect4_a (ZDR *zdrs, state_protect4_a *objp) +{ + if (!zdr_state_protect_how4 (zdrs, &objp->spa_how)) + return FALSE; + switch (objp->spa_how) { + case SP4_NONE: + break; + case SP4_MACH_CRED: + if (!zdr_state_protect_ops4 (zdrs, &objp->state_protect4_a_u.spa_mach_ops)) + return FALSE; + break; + case SP4_SSV: + if (!zdr_ssv_sp_parms4 (zdrs, &objp->state_protect4_a_u.spa_ssv_parms)) + return FALSE; + break; + default: + return FALSE; + } + return TRUE; +} + +uint32_t +zdr_EXCHANGE_ID4args (ZDR *zdrs, EXCHANGE_ID4args *objp) +{ + if (!zdr_client_owner4 (zdrs, &objp->eia_clientowner)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->eia_flags)) + return FALSE; + if (!zdr_state_protect4_a (zdrs, &objp->eia_state_protect)) + return FALSE; + if (!zdr_array (zdrs, (char **)&objp->eia_client_impl_id.eia_client_impl_id_val, &objp->eia_client_impl_id.eia_client_impl_id_len, 1, + sizeof (nfs_impl_id4), (zdrproc_t) zdr_nfs_impl_id4)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_ssv_prot_info4 (ZDR *zdrs, ssv_prot_info4 *objp) +{ + if (!zdr_state_protect_ops4 (zdrs, &objp->spi_ops)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->spi_hash_alg)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->spi_encr_alg)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->spi_ssv_len)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->spi_window)) + return FALSE; + if (!zdr_array (zdrs, (char **)&objp->spi_handles.spi_handles_val, &objp->spi_handles.spi_handles_len, ~0, + sizeof (gsshandle4_t), (zdrproc_t) zdr_gsshandle4_t)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_state_protect4_r (ZDR *zdrs, state_protect4_r *objp) +{ + if (!zdr_state_protect_how4 (zdrs, &objp->spr_how)) + return FALSE; + switch (objp->spr_how) { + case SP4_NONE: + break; + case SP4_MACH_CRED: + if (!zdr_state_protect_ops4 (zdrs, &objp->state_protect4_r_u.spr_mach_ops)) + return FALSE; + break; + case SP4_SSV: + if (!zdr_ssv_prot_info4 (zdrs, &objp->state_protect4_r_u.spr_ssv_info)) + return FALSE; + break; + default: + return FALSE; + } + return TRUE; +} + +uint32_t +zdr_EXCHANGE_ID4resok (ZDR *zdrs, EXCHANGE_ID4resok *objp) +{ + if (!zdr_clientid4 (zdrs, &objp->eir_clientid)) + return FALSE; + if (!zdr_sequenceid4 (zdrs, &objp->eir_sequenceid)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->eir_flags)) + return FALSE; + if (!zdr_state_protect4_r (zdrs, &objp->eir_state_protect)) + return FALSE; + if (!zdr_server_owner4 (zdrs, &objp->eir_server_owner)) + return FALSE; + if (!zdr_bytes (zdrs, (char **)&objp->eir_server_scope.eir_server_scope_val, &objp->eir_server_scope.eir_server_scope_len, NFS4_OPAQUE_LIMIT)) + return FALSE; + if (!zdr_array (zdrs, (char **)&objp->eir_server_impl_id.eir_server_impl_id_val, &objp->eir_server_impl_id.eir_server_impl_id_len, 1, + sizeof (nfs_impl_id4), (zdrproc_t) zdr_nfs_impl_id4)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_EXCHANGE_ID4res (ZDR *zdrs, EXCHANGE_ID4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->eir_status)) + return FALSE; + switch (objp->eir_status) { + case NFS4_OK: + if (!zdr_EXCHANGE_ID4resok (zdrs, &objp->EXCHANGE_ID4res_u.eir_resok4)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_channel_attrs4 (ZDR *zdrs, channel_attrs4 *objp) +{ + if (!zdr_count4 (zdrs, &objp->ca_headerpadsize)) + return FALSE; + if (!zdr_count4 (zdrs, &objp->ca_maxrequestsize)) + return FALSE; + if (!zdr_count4 (zdrs, &objp->ca_maxresponsesize)) + return FALSE; + if (!zdr_count4 (zdrs, &objp->ca_maxresponsesize_cached)) + return FALSE; + if (!zdr_count4 (zdrs, &objp->ca_maxoperations)) + return FALSE; + if (!zdr_count4 (zdrs, &objp->ca_maxrequests)) + return FALSE; + if (!zdr_array (zdrs, (char **)&objp->ca_rdma_ird.ca_rdma_ird_val, &objp->ca_rdma_ird.ca_rdma_ird_len, 1, + sizeof (uint32_t), (zdrproc_t) zdr_uint32_t)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_CREATE_SESSION4args (ZDR *zdrs, CREATE_SESSION4args *objp) +{ + if (!zdr_clientid4 (zdrs, &objp->csa_clientid)) + return FALSE; + if (!zdr_sequenceid4 (zdrs, &objp->csa_sequence)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->csa_flags)) + return FALSE; + if (!zdr_channel_attrs4 (zdrs, &objp->csa_fore_chan_attrs)) + return FALSE; + if (!zdr_channel_attrs4 (zdrs, &objp->csa_back_chan_attrs)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->csa_cb_program)) + return FALSE; + if (!zdr_array (zdrs, (char **)&objp->csa_sec_parms.csa_sec_parms_val, &objp->csa_sec_parms.csa_sec_parms_len, ~0, + sizeof (callback_sec_parms4), (zdrproc_t) zdr_callback_sec_parms4)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_CREATE_SESSION4resok (ZDR *zdrs, CREATE_SESSION4resok *objp) +{ + if (!zdr_sessionid4 (zdrs, objp->csr_sessionid)) + return FALSE; + if (!zdr_sequenceid4 (zdrs, &objp->csr_sequence)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->csr_flags)) + return FALSE; + if (!zdr_channel_attrs4 (zdrs, &objp->csr_fore_chan_attrs)) + return FALSE; + if (!zdr_channel_attrs4 (zdrs, &objp->csr_back_chan_attrs)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_CREATE_SESSION4res (ZDR *zdrs, CREATE_SESSION4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->csr_status)) + return FALSE; + switch (objp->csr_status) { + case NFS4_OK: + if (!zdr_CREATE_SESSION4resok (zdrs, &objp->CREATE_SESSION4res_u.csr_resok4)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_DESTROY_SESSION4args (ZDR *zdrs, DESTROY_SESSION4args *objp) +{ + if (!zdr_sessionid4 (zdrs, objp->dsa_sessionid)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_DESTROY_SESSION4res (ZDR *zdrs, DESTROY_SESSION4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->dsr_status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_FREE_STATEID4args (ZDR *zdrs, FREE_STATEID4args *objp) +{ + if (!zdr_stateid4 (zdrs, &objp->fsa_stateid)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_FREE_STATEID4res (ZDR *zdrs, FREE_STATEID4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->fsr_status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_attr_notice4 (ZDR *zdrs, attr_notice4 *objp) +{ + if (!zdr_nfstime4 (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_GET_DIR_DELEGATION4args (ZDR *zdrs, GET_DIR_DELEGATION4args *objp) +{ + if (!zdr_bool (zdrs, &objp->gdda_signal_deleg_avail)) + return FALSE; + if (!zdr_bitmap4 (zdrs, &objp->gdda_notification_types)) + return FALSE; + if (!zdr_attr_notice4 (zdrs, &objp->gdda_child_attr_delay)) + return FALSE; + if (!zdr_attr_notice4 (zdrs, &objp->gdda_dir_attr_delay)) + return FALSE; + if (!zdr_bitmap4 (zdrs, &objp->gdda_child_attributes)) + return FALSE; + if (!zdr_bitmap4 (zdrs, &objp->gdda_dir_attributes)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_GET_DIR_DELEGATION4resok (ZDR *zdrs, GET_DIR_DELEGATION4resok *objp) +{ + if (!zdr_verifier4 (zdrs, objp->gddr_cookieverf)) + return FALSE; + if (!zdr_stateid4 (zdrs, &objp->gddr_stateid)) + return FALSE; + if (!zdr_bitmap4 (zdrs, &objp->gddr_notification)) + return FALSE; + if (!zdr_bitmap4 (zdrs, &objp->gddr_child_attributes)) + return FALSE; + if (!zdr_bitmap4 (zdrs, &objp->gddr_dir_attributes)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_gddrnf4_status (ZDR *zdrs, gddrnf4_status *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_GET_DIR_DELEGATION4res_non_fatal (ZDR *zdrs, GET_DIR_DELEGATION4res_non_fatal *objp) +{ + if (!zdr_gddrnf4_status (zdrs, &objp->gddrnf_status)) + return FALSE; + switch (objp->gddrnf_status) { + case GDD4_OK: + if (!zdr_GET_DIR_DELEGATION4resok (zdrs, &objp->GET_DIR_DELEGATION4res_non_fatal_u.gddrnf_resok4)) + return FALSE; + break; + case GDD4_UNAVAIL: + if (!zdr_bool (zdrs, &objp->GET_DIR_DELEGATION4res_non_fatal_u.gddrnf_will_signal_deleg_avail)) + return FALSE; + break; + default: + return FALSE; + } + return TRUE; +} + +uint32_t +zdr_GET_DIR_DELEGATION4res (ZDR *zdrs, GET_DIR_DELEGATION4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->gddr_status)) + return FALSE; + switch (objp->gddr_status) { + case NFS4_OK: + if (!zdr_GET_DIR_DELEGATION4res_non_fatal (zdrs, &objp->GET_DIR_DELEGATION4res_u.gddr_res_non_fatal4)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_GETDEVICEINFO4args (ZDR *zdrs, GETDEVICEINFO4args *objp) +{ + if (!zdr_deviceid4 (zdrs, objp->gdia_device_id)) + return FALSE; + if (!zdr_layouttype4 (zdrs, &objp->gdia_layout_type)) + return FALSE; + if (!zdr_count4 (zdrs, &objp->gdia_maxcount)) + return FALSE; + if (!zdr_bitmap4 (zdrs, &objp->gdia_notify_types)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_GETDEVICEINFO4resok (ZDR *zdrs, GETDEVICEINFO4resok *objp) +{ + if (!zdr_device_addr4 (zdrs, &objp->gdir_device_addr)) + return FALSE; + if (!zdr_bitmap4 (zdrs, &objp->gdir_notification)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_GETDEVICEINFO4res (ZDR *zdrs, GETDEVICEINFO4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->gdir_status)) + return FALSE; + switch (objp->gdir_status) { + case NFS4_OK: + if (!zdr_GETDEVICEINFO4resok (zdrs, &objp->GETDEVICEINFO4res_u.gdir_resok4)) + return FALSE; + break; + case NFS4ERR_TOOSMALL: + if (!zdr_count4 (zdrs, &objp->GETDEVICEINFO4res_u.gdir_mincount)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_GETDEVICELIST4args (ZDR *zdrs, GETDEVICELIST4args *objp) +{ + if (!zdr_layouttype4 (zdrs, &objp->gdla_layout_type)) + return FALSE; + if (!zdr_count4 (zdrs, &objp->gdla_maxdevices)) + return FALSE; + if (!zdr_nfs_cookie4 (zdrs, &objp->gdla_cookie)) + return FALSE; + if (!zdr_verifier4 (zdrs, objp->gdla_cookieverf)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_GETDEVICELIST4resok (ZDR *zdrs, GETDEVICELIST4resok *objp) +{ + if (!zdr_nfs_cookie4 (zdrs, &objp->gdlr_cookie)) + return FALSE; + if (!zdr_verifier4 (zdrs, objp->gdlr_cookieverf)) + return FALSE; + if (!zdr_array (zdrs, (char **)&objp->gdlr_deviceid_list.gdlr_deviceid_list_val, &objp->gdlr_deviceid_list.gdlr_deviceid_list_len, ~0, + sizeof (deviceid4), (zdrproc_t) zdr_deviceid4)) + return FALSE; + if (!zdr_bool (zdrs, &objp->gdlr_eof)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_GETDEVICELIST4res (ZDR *zdrs, GETDEVICELIST4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->gdlr_status)) + return FALSE; + switch (objp->gdlr_status) { + case NFS4_OK: + if (!zdr_GETDEVICELIST4resok (zdrs, &objp->GETDEVICELIST4res_u.gdlr_resok4)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_newtime4 (ZDR *zdrs, newtime4 *objp) +{ + if (!zdr_bool (zdrs, &objp->nt_timechanged)) + return FALSE; + switch (objp->nt_timechanged) { + case TRUE: + if (!zdr_nfstime4 (zdrs, &objp->newtime4_u.nt_time)) + return FALSE; + break; + case FALSE: + break; + default: + return FALSE; + } + return TRUE; +} + +uint32_t +zdr_newoffset4 (ZDR *zdrs, newoffset4 *objp) +{ + if (!zdr_bool (zdrs, &objp->no_newoffset)) + return FALSE; + switch (objp->no_newoffset) { + case TRUE: + if (!zdr_offset4 (zdrs, &objp->newoffset4_u.no_offset)) + return FALSE; + break; + case FALSE: + break; + default: + return FALSE; + } + return TRUE; +} + +uint32_t +zdr_LAYOUTCOMMIT4args (ZDR *zdrs, LAYOUTCOMMIT4args *objp) +{ + if (!zdr_offset4 (zdrs, &objp->loca_offset)) + return FALSE; + if (!zdr_length4 (zdrs, &objp->loca_length)) + return FALSE; + if (!zdr_bool (zdrs, &objp->loca_reclaim)) + return FALSE; + if (!zdr_stateid4 (zdrs, &objp->loca_stateid)) + return FALSE; + if (!zdr_newoffset4 (zdrs, &objp->loca_last_write_offset)) + return FALSE; + if (!zdr_newtime4 (zdrs, &objp->loca_time_modify)) + return FALSE; + if (!zdr_layoutupdate4 (zdrs, &objp->loca_layoutupdate)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_newsize4 (ZDR *zdrs, newsize4 *objp) +{ + if (!zdr_bool (zdrs, &objp->ns_sizechanged)) + return FALSE; + switch (objp->ns_sizechanged) { + case TRUE: + if (!zdr_length4 (zdrs, &objp->newsize4_u.ns_size)) + return FALSE; + break; + case FALSE: + break; + default: + return FALSE; + } + return TRUE; +} + +uint32_t +zdr_LAYOUTCOMMIT4resok (ZDR *zdrs, LAYOUTCOMMIT4resok *objp) +{ + if (!zdr_newsize4 (zdrs, &objp->locr_newsize)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_LAYOUTCOMMIT4res (ZDR *zdrs, LAYOUTCOMMIT4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->locr_status)) + return FALSE; + switch (objp->locr_status) { + case NFS4_OK: + if (!zdr_LAYOUTCOMMIT4resok (zdrs, &objp->LAYOUTCOMMIT4res_u.locr_resok4)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_LAYOUTGET4args (ZDR *zdrs, LAYOUTGET4args *objp) +{ + if (!zdr_bool (zdrs, &objp->loga_signal_layout_avail)) + return FALSE; + if (!zdr_layouttype4 (zdrs, &objp->loga_layout_type)) + return FALSE; + if (!zdr_layoutiomode4 (zdrs, &objp->loga_iomode)) + return FALSE; + if (!zdr_offset4 (zdrs, &objp->loga_offset)) + return FALSE; + if (!zdr_length4 (zdrs, &objp->loga_length)) + return FALSE; + if (!zdr_length4 (zdrs, &objp->loga_minlength)) + return FALSE; + if (!zdr_stateid4 (zdrs, &objp->loga_stateid)) + return FALSE; + if (!zdr_count4 (zdrs, &objp->loga_maxcount)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_LAYOUTGET4resok (ZDR *zdrs, LAYOUTGET4resok *objp) +{ + if (!zdr_bool (zdrs, &objp->logr_return_on_close)) + return FALSE; + if (!zdr_stateid4 (zdrs, &objp->logr_stateid)) + return FALSE; + if (!zdr_array (zdrs, (char **)&objp->logr_layout.logr_layout_val, &objp->logr_layout.logr_layout_len, ~0, + sizeof (layout4), (zdrproc_t) zdr_layout4)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_LAYOUTGET4res (ZDR *zdrs, LAYOUTGET4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->logr_status)) + return FALSE; + switch (objp->logr_status) { + case NFS4_OK: + if (!zdr_LAYOUTGET4resok (zdrs, &objp->LAYOUTGET4res_u.logr_resok4)) + return FALSE; + break; + case NFS4ERR_LAYOUTTRYLATER: + if (!zdr_bool (zdrs, &objp->LAYOUTGET4res_u.logr_will_signal_layout_avail)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_layoutreturn_type4 (ZDR *zdrs, layoutreturn_type4 *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_layoutreturn_file4 (ZDR *zdrs, layoutreturn_file4 *objp) +{ + if (!zdr_offset4 (zdrs, &objp->lrf_offset)) + return FALSE; + if (!zdr_length4 (zdrs, &objp->lrf_length)) + return FALSE; + if (!zdr_stateid4 (zdrs, &objp->lrf_stateid)) + return FALSE; + if (!zdr_bytes (zdrs, (char **)&objp->lrf_body.lrf_body_val, &objp->lrf_body.lrf_body_len, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_layoutreturn4 (ZDR *zdrs, layoutreturn4 *objp) +{ + if (!zdr_layoutreturn_type4 (zdrs, &objp->lr_returntype)) + return FALSE; + switch (objp->lr_returntype) { + case LAYOUTRETURN4_FILE: + if (!zdr_layoutreturn_file4 (zdrs, &objp->layoutreturn4_u.lr_layout)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_LAYOUTRETURN4args (ZDR *zdrs, LAYOUTRETURN4args *objp) +{ + if (!zdr_bool (zdrs, &objp->lora_reclaim)) + return FALSE; + if (!zdr_layouttype4 (zdrs, &objp->lora_layout_type)) + return FALSE; + if (!zdr_layoutiomode4 (zdrs, &objp->lora_iomode)) + return FALSE; + if (!zdr_layoutreturn4 (zdrs, &objp->lora_layoutreturn)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_layoutreturn_stateid (ZDR *zdrs, layoutreturn_stateid *objp) +{ + if (!zdr_bool (zdrs, &objp->lrs_present)) + return FALSE; + switch (objp->lrs_present) { + case TRUE: + if (!zdr_stateid4 (zdrs, &objp->layoutreturn_stateid_u.lrs_stateid)) + return FALSE; + break; + case FALSE: + break; + default: + return FALSE; + } + return TRUE; +} + +uint32_t +zdr_LAYOUTRETURN4res (ZDR *zdrs, LAYOUTRETURN4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->lorr_status)) + return FALSE; + switch (objp->lorr_status) { + case NFS4_OK: + if (!zdr_layoutreturn_stateid (zdrs, &objp->LAYOUTRETURN4res_u.lorr_stateid)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_secinfo_style4 (ZDR *zdrs, secinfo_style4 *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_SECINFO_NO_NAME4args (ZDR *zdrs, SECINFO_NO_NAME4args *objp) +{ + if (!zdr_secinfo_style4 (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_SECINFO_NO_NAME4res (ZDR *zdrs, SECINFO_NO_NAME4res *objp) +{ + if (!zdr_SECINFO4res (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_SEQUENCE4args (ZDR *zdrs, SEQUENCE4args *objp) +{ + if (!zdr_sessionid4 (zdrs, objp->sa_sessionid)) + return FALSE; + if (!zdr_sequenceid4 (zdrs, &objp->sa_sequenceid)) + return FALSE; + if (!zdr_slotid4 (zdrs, &objp->sa_slotid)) + return FALSE; + if (!zdr_slotid4 (zdrs, &objp->sa_highest_slotid)) + return FALSE; + if (!zdr_bool (zdrs, &objp->sa_cachethis)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_SEQUENCE4resok (ZDR *zdrs, SEQUENCE4resok *objp) +{ + if (!zdr_sessionid4 (zdrs, objp->sr_sessionid)) + return FALSE; + if (!zdr_sequenceid4 (zdrs, &objp->sr_sequenceid)) + return FALSE; + if (!zdr_slotid4 (zdrs, &objp->sr_slotid)) + return FALSE; + if (!zdr_slotid4 (zdrs, &objp->sr_highest_slotid)) + return FALSE; + if (!zdr_slotid4 (zdrs, &objp->sr_target_highest_slotid)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->sr_status_flags)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_SEQUENCE4res (ZDR *zdrs, SEQUENCE4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->sr_status)) + return FALSE; + switch (objp->sr_status) { + case NFS4_OK: + if (!zdr_SEQUENCE4resok (zdrs, &objp->SEQUENCE4res_u.sr_resok4)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_ssa_digest_input4 (ZDR *zdrs, ssa_digest_input4 *objp) +{ + if (!zdr_SEQUENCE4args (zdrs, &objp->sdi_seqargs)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_SET_SSV4args (ZDR *zdrs, SET_SSV4args *objp) +{ + if (!zdr_bytes (zdrs, (char **)&objp->ssa_ssv.ssa_ssv_val, &objp->ssa_ssv.ssa_ssv_len, ~0)) + return FALSE; + if (!zdr_bytes (zdrs, (char **)&objp->ssa_digest.ssa_digest_val, &objp->ssa_digest.ssa_digest_len, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_ssr_digest_input4 (ZDR *zdrs, ssr_digest_input4 *objp) +{ + if (!zdr_SEQUENCE4res (zdrs, &objp->sdi_seqres)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_SET_SSV4resok (ZDR *zdrs, SET_SSV4resok *objp) +{ + if (!zdr_bytes (zdrs, (char **)&objp->ssr_digest.ssr_digest_val, &objp->ssr_digest.ssr_digest_len, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_SET_SSV4res (ZDR *zdrs, SET_SSV4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->ssr_status)) + return FALSE; + switch (objp->ssr_status) { + case NFS4_OK: + if (!zdr_SET_SSV4resok (zdrs, &objp->SET_SSV4res_u.ssr_resok4)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_TEST_STATEID4args (ZDR *zdrs, TEST_STATEID4args *objp) +{ + if (!zdr_array (zdrs, (char **)&objp->ts_stateids.ts_stateids_val, &objp->ts_stateids.ts_stateids_len, ~0, + sizeof (stateid4), (zdrproc_t) zdr_stateid4)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_TEST_STATEID4resok (ZDR *zdrs, TEST_STATEID4resok *objp) +{ + if (!zdr_array (zdrs, (char **)&objp->tsr_status_codes.tsr_status_codes_val, &objp->tsr_status_codes.tsr_status_codes_len, ~0, + sizeof (nfsstat4), (zdrproc_t) zdr_nfsstat4)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_TEST_STATEID4res (ZDR *zdrs, TEST_STATEID4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->tsr_status)) + return FALSE; + switch (objp->tsr_status) { + case NFS4_OK: + if (!zdr_TEST_STATEID4resok (zdrs, &objp->TEST_STATEID4res_u.tsr_resok4)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_deleg_claim4 (ZDR *zdrs, deleg_claim4 *objp) +{ + if (!zdr_open_claim_type4 (zdrs, &objp->dc_claim)) + return FALSE; + switch (objp->dc_claim) { + case CLAIM_FH: + break; + case CLAIM_DELEG_PREV_FH: + break; + case CLAIM_PREVIOUS: + if (!zdr_open_delegation_type4 (zdrs, &objp->deleg_claim4_u.dc_delegate_type)) + return FALSE; + break; + default: + return FALSE; + } + return TRUE; +} + +uint32_t +zdr_WANT_DELEGATION4args (ZDR *zdrs, WANT_DELEGATION4args *objp) +{ + if (!zdr_uint32_t (zdrs, &objp->wda_want)) + return FALSE; + if (!zdr_deleg_claim4 (zdrs, &objp->wda_claim)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_WANT_DELEGATION4res (ZDR *zdrs, WANT_DELEGATION4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->wdr_status)) + return FALSE; + switch (objp->wdr_status) { + case NFS4_OK: + if (!zdr_open_delegation4 (zdrs, &objp->WANT_DELEGATION4res_u.wdr_resok4)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_DESTROY_CLIENTID4args (ZDR *zdrs, DESTROY_CLIENTID4args *objp) +{ + if (!zdr_clientid4 (zdrs, &objp->dca_clientid)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_DESTROY_CLIENTID4res (ZDR *zdrs, DESTROY_CLIENTID4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->dcr_status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_RECLAIM_COMPLETE4args (ZDR *zdrs, RECLAIM_COMPLETE4args *objp) +{ + if (!zdr_bool (zdrs, &objp->rca_one_fs)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_RECLAIM_COMPLETE4res (ZDR *zdrs, RECLAIM_COMPLETE4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->rcr_status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_ILLEGAL4res (ZDR *zdrs, ILLEGAL4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_nfs_opnum4 (ZDR *zdrs, nfs_opnum4 *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_nfs_argop4 (ZDR *zdrs, nfs_argop4 *objp) +{ + if (!zdr_nfs_opnum4 (zdrs, &objp->argop)) + return FALSE; + switch (objp->argop) { + case OP_ACCESS: + if (!zdr_ACCESS4args (zdrs, &objp->nfs_argop4_u.opaccess)) + return FALSE; + break; + case OP_CLOSE: + if (!zdr_CLOSE4args (zdrs, &objp->nfs_argop4_u.opclose)) + return FALSE; + break; + case OP_COMMIT: + if (!zdr_COMMIT4args (zdrs, &objp->nfs_argop4_u.opcommit)) + return FALSE; + break; + case OP_CREATE: + if (!zdr_CREATE4args (zdrs, &objp->nfs_argop4_u.opcreate)) + return FALSE; + break; + case OP_DELEGPURGE: + if (!zdr_DELEGPURGE4args (zdrs, &objp->nfs_argop4_u.opdelegpurge)) + return FALSE; + break; + case OP_DELEGRETURN: + if (!zdr_DELEGRETURN4args (zdrs, &objp->nfs_argop4_u.opdelegreturn)) + return FALSE; + break; + case OP_GETATTR: + if (!zdr_GETATTR4args (zdrs, &objp->nfs_argop4_u.opgetattr)) + return FALSE; + break; + case OP_GETFH: + break; + case OP_LINK: + if (!zdr_LINK4args (zdrs, &objp->nfs_argop4_u.oplink)) + return FALSE; + break; + case OP_LOCK: + if (!zdr_LOCK4args (zdrs, &objp->nfs_argop4_u.oplock)) + return FALSE; + break; + case OP_LOCKT: + if (!zdr_LOCKT4args (zdrs, &objp->nfs_argop4_u.oplockt)) + return FALSE; + break; + case OP_LOCKU: + if (!zdr_LOCKU4args (zdrs, &objp->nfs_argop4_u.oplocku)) + return FALSE; + break; + case OP_LOOKUP: + if (!zdr_LOOKUP4args (zdrs, &objp->nfs_argop4_u.oplookup)) + return FALSE; + break; + case OP_LOOKUPP: + break; + case OP_NVERIFY: + if (!zdr_NVERIFY4args (zdrs, &objp->nfs_argop4_u.opnverify)) + return FALSE; + break; + case OP_OPEN: + if (!zdr_OPEN4args (zdrs, &objp->nfs_argop4_u.opopen)) + return FALSE; + break; + case OP_OPENATTR: + if (!zdr_OPENATTR4args (zdrs, &objp->nfs_argop4_u.opopenattr)) + return FALSE; + break; + case OP_OPEN_CONFIRM: + if (!zdr_OPEN_CONFIRM4args (zdrs, &objp->nfs_argop4_u.opopen_confirm)) + return FALSE; + break; + case OP_OPEN_DOWNGRADE: + if (!zdr_OPEN_DOWNGRADE4args (zdrs, &objp->nfs_argop4_u.opopen_downgrade)) + return FALSE; + break; + case OP_PUTFH: + if (!zdr_PUTFH4args (zdrs, &objp->nfs_argop4_u.opputfh)) + return FALSE; + break; + case OP_PUTPUBFH: + break; + case OP_PUTROOTFH: + break; + case OP_READ: + if (!zdr_READ4args (zdrs, &objp->nfs_argop4_u.opread)) + return FALSE; + break; + case OP_READDIR: + if (!zdr_READDIR4args (zdrs, &objp->nfs_argop4_u.opreaddir)) + return FALSE; + break; + case OP_READLINK: + break; + case OP_REMOVE: + if (!zdr_REMOVE4args (zdrs, &objp->nfs_argop4_u.opremove)) + return FALSE; + break; + case OP_RENAME: + if (!zdr_RENAME4args (zdrs, &objp->nfs_argop4_u.oprename)) + return FALSE; + break; + case OP_RENEW: + if (!zdr_RENEW4args (zdrs, &objp->nfs_argop4_u.oprenew)) + return FALSE; + break; + case OP_RESTOREFH: + break; + case OP_SAVEFH: + break; + case OP_SECINFO: + if (!zdr_SECINFO4args (zdrs, &objp->nfs_argop4_u.opsecinfo)) + return FALSE; + break; + case OP_SETATTR: + if (!zdr_SETATTR4args (zdrs, &objp->nfs_argop4_u.opsetattr)) + return FALSE; + break; + case OP_SETCLIENTID: + if (!zdr_SETCLIENTID4args (zdrs, &objp->nfs_argop4_u.opsetclientid)) + return FALSE; + break; + case OP_SETCLIENTID_CONFIRM: + if (!zdr_SETCLIENTID_CONFIRM4args (zdrs, &objp->nfs_argop4_u.opsetclientid_confirm)) + return FALSE; + break; + case OP_VERIFY: + if (!zdr_VERIFY4args (zdrs, &objp->nfs_argop4_u.opverify)) + return FALSE; + break; + case OP_WRITE: + if (!zdr_WRITE4args (zdrs, &objp->nfs_argop4_u.opwrite)) + return FALSE; + break; + case OP_RELEASE_LOCKOWNER: + if (!zdr_RELEASE_LOCKOWNER4args (zdrs, &objp->nfs_argop4_u.oprelease_lockowner)) + return FALSE; + break; + case OP_BIND_CONN_TO_SESSION: + if (!zdr_BIND_CONN_TO_SESSION4args (zdrs, &objp->nfs_argop4_u.opbindconntosession)) + return FALSE; + break; + case OP_EXCHANGE_ID: + if (!zdr_EXCHANGE_ID4args (zdrs, &objp->nfs_argop4_u.opexchangeid)) + return FALSE; + break; + case OP_CREATE_SESSION: + if (!zdr_CREATE_SESSION4args (zdrs, &objp->nfs_argop4_u.opcreatesession)) + return FALSE; + break; + case OP_DESTROY_SESSION: + if (!zdr_DESTROY_SESSION4args (zdrs, &objp->nfs_argop4_u.opdestroysession)) + return FALSE; + break; + case OP_FREE_STATEID: + if (!zdr_FREE_STATEID4args (zdrs, &objp->nfs_argop4_u.opfreestateid)) + return FALSE; + break; + case OP_GET_DIR_DELEGATION: + if (!zdr_GET_DIR_DELEGATION4args (zdrs, &objp->nfs_argop4_u.opgetdirdelegation)) + return FALSE; + break; + case OP_GETDEVICEINFO: + if (!zdr_GETDEVICEINFO4args (zdrs, &objp->nfs_argop4_u.opgetdeviceinfo)) + return FALSE; + break; + case OP_GETDEVICELIST: + if (!zdr_GETDEVICELIST4args (zdrs, &objp->nfs_argop4_u.opgetdevicelist)) + return FALSE; + break; + case OP_LAYOUTCOMMIT: + if (!zdr_LAYOUTCOMMIT4args (zdrs, &objp->nfs_argop4_u.oplayoutcommit)) + return FALSE; + break; + case OP_LAYOUTGET: + if (!zdr_LAYOUTGET4args (zdrs, &objp->nfs_argop4_u.oplayoutget)) + return FALSE; + break; + case OP_LAYOUTRETURN: + if (!zdr_LAYOUTRETURN4args (zdrs, &objp->nfs_argop4_u.oplayoutreturn)) + return FALSE; + break; + case OP_SECINFO_NO_NAME: + if (!zdr_SECINFO_NO_NAME4args (zdrs, &objp->nfs_argop4_u.opsecinfononame)) + return FALSE; + break; + case OP_SEQUENCE: + if (!zdr_SEQUENCE4args (zdrs, &objp->nfs_argop4_u.opsequence)) + return FALSE; + break; + case OP_SET_SSV: + if (!zdr_SET_SSV4args (zdrs, &objp->nfs_argop4_u.opsetssv)) + return FALSE; + break; + case OP_TEST_STATEID: + if (!zdr_TEST_STATEID4args (zdrs, &objp->nfs_argop4_u.opteststateid)) + return FALSE; + break; + case OP_WANT_DELEGATION: + if (!zdr_WANT_DELEGATION4args (zdrs, &objp->nfs_argop4_u.opwantdelegation)) + return FALSE; + break; + case OP_DESTROY_CLIENTID: + if (!zdr_DESTROY_CLIENTID4args (zdrs, &objp->nfs_argop4_u.opdestroyclientid)) + return FALSE; + break; + case OP_RECLAIM_COMPLETE: + if (!zdr_RECLAIM_COMPLETE4args (zdrs, &objp->nfs_argop4_u.opreclaimcomplete)) + return FALSE; + break; + case OP_ILLEGAL: + break; + default: + return FALSE; + } + return TRUE; +} + +uint32_t +zdr_nfs_resop4 (ZDR *zdrs, nfs_resop4 *objp) +{ + if (!zdr_nfs_opnum4 (zdrs, &objp->resop)) + return FALSE; + switch (objp->resop) { + case OP_ACCESS: + if (!zdr_ACCESS4res (zdrs, &objp->nfs_resop4_u.opaccess)) + return FALSE; + break; + case OP_CLOSE: + if (!zdr_CLOSE4res (zdrs, &objp->nfs_resop4_u.opclose)) + return FALSE; + break; + case OP_COMMIT: + if (!zdr_COMMIT4res (zdrs, &objp->nfs_resop4_u.opcommit)) + return FALSE; + break; + case OP_CREATE: + if (!zdr_CREATE4res (zdrs, &objp->nfs_resop4_u.opcreate)) + return FALSE; + break; + case OP_DELEGPURGE: + if (!zdr_DELEGPURGE4res (zdrs, &objp->nfs_resop4_u.opdelegpurge)) + return FALSE; + break; + case OP_DELEGRETURN: + if (!zdr_DELEGRETURN4res (zdrs, &objp->nfs_resop4_u.opdelegreturn)) + return FALSE; + break; + case OP_GETATTR: + if (!zdr_GETATTR4res (zdrs, &objp->nfs_resop4_u.opgetattr)) + return FALSE; + break; + case OP_GETFH: + if (!zdr_GETFH4res (zdrs, &objp->nfs_resop4_u.opgetfh)) + return FALSE; + break; + case OP_LINK: + if (!zdr_LINK4res (zdrs, &objp->nfs_resop4_u.oplink)) + return FALSE; + break; + case OP_LOCK: + if (!zdr_LOCK4res (zdrs, &objp->nfs_resop4_u.oplock)) + return FALSE; + break; + case OP_LOCKT: + if (!zdr_LOCKT4res (zdrs, &objp->nfs_resop4_u.oplockt)) + return FALSE; + break; + case OP_LOCKU: + if (!zdr_LOCKU4res (zdrs, &objp->nfs_resop4_u.oplocku)) + return FALSE; + break; + case OP_LOOKUP: + if (!zdr_LOOKUP4res (zdrs, &objp->nfs_resop4_u.oplookup)) + return FALSE; + break; + case OP_LOOKUPP: + if (!zdr_LOOKUPP4res (zdrs, &objp->nfs_resop4_u.oplookupp)) + return FALSE; + break; + case OP_NVERIFY: + if (!zdr_NVERIFY4res (zdrs, &objp->nfs_resop4_u.opnverify)) + return FALSE; + break; + case OP_OPEN: + if (!zdr_OPEN4res (zdrs, &objp->nfs_resop4_u.opopen)) + return FALSE; + break; + case OP_OPENATTR: + if (!zdr_OPENATTR4res (zdrs, &objp->nfs_resop4_u.opopenattr)) + return FALSE; + break; + case OP_OPEN_CONFIRM: + if (!zdr_OPEN_CONFIRM4res (zdrs, &objp->nfs_resop4_u.opopen_confirm)) + return FALSE; + break; + case OP_OPEN_DOWNGRADE: + if (!zdr_OPEN_DOWNGRADE4res (zdrs, &objp->nfs_resop4_u.opopen_downgrade)) + return FALSE; + break; + case OP_PUTFH: + if (!zdr_PUTFH4res (zdrs, &objp->nfs_resop4_u.opputfh)) + return FALSE; + break; + case OP_PUTPUBFH: + if (!zdr_PUTPUBFH4res (zdrs, &objp->nfs_resop4_u.opputpubfh)) + return FALSE; + break; + case OP_PUTROOTFH: + if (!zdr_PUTROOTFH4res (zdrs, &objp->nfs_resop4_u.opputrootfh)) + return FALSE; + break; + case OP_READ: + if (!zdr_READ4res (zdrs, &objp->nfs_resop4_u.opread)) + return FALSE; + break; + case OP_READDIR: + if (!zdr_READDIR4res (zdrs, &objp->nfs_resop4_u.opreaddir)) + return FALSE; + break; + case OP_READLINK: + if (!zdr_READLINK4res (zdrs, &objp->nfs_resop4_u.opreadlink)) + return FALSE; + break; + case OP_REMOVE: + if (!zdr_REMOVE4res (zdrs, &objp->nfs_resop4_u.opremove)) + return FALSE; + break; + case OP_RENAME: + if (!zdr_RENAME4res (zdrs, &objp->nfs_resop4_u.oprename)) + return FALSE; + break; + case OP_RENEW: + if (!zdr_RENEW4res (zdrs, &objp->nfs_resop4_u.oprenew)) + return FALSE; + break; + case OP_RESTOREFH: + if (!zdr_RESTOREFH4res (zdrs, &objp->nfs_resop4_u.oprestorefh)) + return FALSE; + break; + case OP_SAVEFH: + if (!zdr_SAVEFH4res (zdrs, &objp->nfs_resop4_u.opsavefh)) + return FALSE; + break; + case OP_SECINFO: + if (!zdr_SECINFO4res (zdrs, &objp->nfs_resop4_u.opsecinfo)) + return FALSE; + break; + case OP_SETATTR: + if (!zdr_SETATTR4res (zdrs, &objp->nfs_resop4_u.opsetattr)) + return FALSE; + break; + case OP_SETCLIENTID: + if (!zdr_SETCLIENTID4res (zdrs, &objp->nfs_resop4_u.opsetclientid)) + return FALSE; + break; + case OP_SETCLIENTID_CONFIRM: + if (!zdr_SETCLIENTID_CONFIRM4res (zdrs, &objp->nfs_resop4_u.opsetclientid_confirm)) + return FALSE; + break; + case OP_VERIFY: + if (!zdr_VERIFY4res (zdrs, &objp->nfs_resop4_u.opverify)) + return FALSE; + break; + case OP_WRITE: + if (!zdr_WRITE4res (zdrs, &objp->nfs_resop4_u.opwrite)) + return FALSE; + break; + case OP_RELEASE_LOCKOWNER: + if (!zdr_RELEASE_LOCKOWNER4res (zdrs, &objp->nfs_resop4_u.oprelease_lockowner)) + return FALSE; + break; + case OP_BIND_CONN_TO_SESSION: + if (!zdr_BIND_CONN_TO_SESSION4res (zdrs, &objp->nfs_resop4_u.opbindconntosession)) + return FALSE; + break; + case OP_EXCHANGE_ID: + if (!zdr_EXCHANGE_ID4res (zdrs, &objp->nfs_resop4_u.opexchangeid)) + return FALSE; + break; + case OP_CREATE_SESSION: + if (!zdr_CREATE_SESSION4res (zdrs, &objp->nfs_resop4_u.opcreatesession)) + return FALSE; + break; + case OP_DESTROY_SESSION: + if (!zdr_DESTROY_SESSION4res (zdrs, &objp->nfs_resop4_u.opdestroysession)) + return FALSE; + break; + case OP_FREE_STATEID: + if (!zdr_FREE_STATEID4res (zdrs, &objp->nfs_resop4_u.opfreestateid)) + return FALSE; + break; + case OP_GET_DIR_DELEGATION: + if (!zdr_GET_DIR_DELEGATION4res (zdrs, &objp->nfs_resop4_u.opgetdirdelegation)) + return FALSE; + break; + case OP_GETDEVICEINFO: + if (!zdr_GETDEVICEINFO4res (zdrs, &objp->nfs_resop4_u.opgetdeviceinfo)) + return FALSE; + break; + case OP_GETDEVICELIST: + if (!zdr_GETDEVICELIST4res (zdrs, &objp->nfs_resop4_u.opgetdevicelist)) + return FALSE; + break; + case OP_LAYOUTCOMMIT: + if (!zdr_LAYOUTCOMMIT4res (zdrs, &objp->nfs_resop4_u.oplayoutcommit)) + return FALSE; + break; + case OP_LAYOUTGET: + if (!zdr_LAYOUTGET4res (zdrs, &objp->nfs_resop4_u.oplayoutget)) + return FALSE; + break; + case OP_LAYOUTRETURN: + if (!zdr_LAYOUTRETURN4res (zdrs, &objp->nfs_resop4_u.oplayoutreturn)) + return FALSE; + break; + case OP_SECINFO_NO_NAME: + if (!zdr_SECINFO_NO_NAME4res (zdrs, &objp->nfs_resop4_u.opsecinfononame)) + return FALSE; + break; + case OP_SEQUENCE: + if (!zdr_SEQUENCE4res (zdrs, &objp->nfs_resop4_u.opsequence)) + return FALSE; + break; + case OP_SET_SSV: + if (!zdr_SET_SSV4res (zdrs, &objp->nfs_resop4_u.opsetssv)) + return FALSE; + break; + case OP_TEST_STATEID: + if (!zdr_TEST_STATEID4res (zdrs, &objp->nfs_resop4_u.opteststateid)) + return FALSE; + break; + case OP_WANT_DELEGATION: + if (!zdr_WANT_DELEGATION4res (zdrs, &objp->nfs_resop4_u.opwantdelegation)) + return FALSE; + break; + case OP_DESTROY_CLIENTID: + if (!zdr_DESTROY_CLIENTID4res (zdrs, &objp->nfs_resop4_u.opdestroyclientid)) + return FALSE; + break; + case OP_RECLAIM_COMPLETE: + if (!zdr_RECLAIM_COMPLETE4res (zdrs, &objp->nfs_resop4_u.opreclaimcomplete)) + return FALSE; + break; + case OP_ILLEGAL: + if (!zdr_ILLEGAL4res (zdrs, &objp->nfs_resop4_u.opillegal)) + return FALSE; + break; + default: + return FALSE; + } + return TRUE; +} + +uint32_t +zdr_COMPOUND4args (ZDR *zdrs, COMPOUND4args *objp) +{ + if (!zdr_utf8str_cs (zdrs, &objp->tag)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->minorversion)) + return FALSE; + if (!zdr_array (zdrs, (char **)&objp->argarray.argarray_val, &objp->argarray.argarray_len, ~0, + sizeof (nfs_argop4), (zdrproc_t) zdr_nfs_argop4)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_COMPOUND4res (ZDR *zdrs, COMPOUND4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + if (!zdr_utf8str_cs (zdrs, &objp->tag)) + return FALSE; + if (!zdr_array (zdrs, (char **)&objp->resarray.resarray_val, &objp->resarray.resarray_len, ~0, + sizeof (nfs_resop4), (zdrproc_t) zdr_nfs_resop4)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_CB_GETATTR4args (ZDR *zdrs, CB_GETATTR4args *objp) +{ + if (!zdr_nfs_fh4 (zdrs, &objp->fh)) + return FALSE; + if (!zdr_bitmap4 (zdrs, &objp->attr_request)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_CB_GETATTR4resok (ZDR *zdrs, CB_GETATTR4resok *objp) +{ + if (!zdr_fattr4 (zdrs, &objp->obj_attributes)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_CB_GETATTR4res (ZDR *zdrs, CB_GETATTR4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NFS4_OK: + if (!zdr_CB_GETATTR4resok (zdrs, &objp->CB_GETATTR4res_u.resok4)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_CB_RECALL4args (ZDR *zdrs, CB_RECALL4args *objp) +{ + if (!zdr_stateid4 (zdrs, &objp->stateid)) + return FALSE; + if (!zdr_bool (zdrs, &objp->truncate)) + return FALSE; + if (!zdr_nfs_fh4 (zdrs, &objp->fh)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_CB_RECALL4res (ZDR *zdrs, CB_RECALL4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_CB_ILLEGAL4res (ZDR *zdrs, CB_ILLEGAL4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_nfs_cb_opnum4 (ZDR *zdrs, nfs_cb_opnum4 *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_nfs_cb_argop4 (ZDR *zdrs, nfs_cb_argop4 *objp) +{ + if (!zdr_u_int (zdrs, &objp->argop)) + return FALSE; + switch (objp->argop) { + case OP_CB_GETATTR: + if (!zdr_CB_GETATTR4args (zdrs, &objp->nfs_cb_argop4_u.opcbgetattr)) + return FALSE; + break; + case OP_CB_RECALL: + if (!zdr_CB_RECALL4args (zdrs, &objp->nfs_cb_argop4_u.opcbrecall)) + return FALSE; + break; + case OP_CB_ILLEGAL: + break; + default: + return FALSE; + } + return TRUE; +} + +uint32_t +zdr_nfs_cb_resop4 (ZDR *zdrs, nfs_cb_resop4 *objp) +{ + if (!zdr_u_int (zdrs, &objp->resop)) + return FALSE; + switch (objp->resop) { + case OP_CB_GETATTR: + if (!zdr_CB_GETATTR4res (zdrs, &objp->nfs_cb_resop4_u.opcbgetattr)) + return FALSE; + break; + case OP_CB_RECALL: + if (!zdr_CB_RECALL4res (zdrs, &objp->nfs_cb_resop4_u.opcbrecall)) + return FALSE; + break; + case OP_CB_ILLEGAL: + if (!zdr_CB_ILLEGAL4res (zdrs, &objp->nfs_cb_resop4_u.opcbillegal)) + return FALSE; + break; + default: + return FALSE; + } + return TRUE; +} + +uint32_t +zdr_CB_COMPOUND4args (ZDR *zdrs, CB_COMPOUND4args *objp) +{ + if (!zdr_utf8str_cs (zdrs, &objp->tag)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->minorversion)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->callback_ident)) + return FALSE; + if (!zdr_array (zdrs, (char **)&objp->argarray.argarray_val, &objp->argarray.argarray_len, ~0, + sizeof (nfs_cb_argop4), (zdrproc_t) zdr_nfs_cb_argop4)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_CB_COMPOUND4res (ZDR *zdrs, CB_COMPOUND4res *objp) +{ + if (!zdr_nfsstat4 (zdrs, &objp->status)) + return FALSE; + if (!zdr_utf8str_cs (zdrs, &objp->tag)) + return FALSE; + if (!zdr_array (zdrs, (char **)&objp->resarray.resarray_val, &objp->resarray.resarray_len, ~0, + sizeof (nfs_cb_resop4), (zdrproc_t) zdr_nfs_cb_resop4)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_rpc_gss_proc_t (ZDR *zdrs, rpc_gss_proc_t *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_rpc_gss_cred_vers_1_t (ZDR *zdrs, rpc_gss_cred_vers_1_t *objp) +{ + if (!zdr_rpc_gss_proc_t (zdrs, &objp->gss_proc)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->seq_num)) + return FALSE; + if (!zdr_rpc_gss_svc_t (zdrs, &objp->service)) + return FALSE; + if (!zdr_bytes (zdrs, (char **)&objp->handle.handle_val, &objp->handle.handle_len, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_rpc_gss_cred_t (ZDR *zdrs, rpc_gss_cred_t *objp) +{ + if (!zdr_u_int (zdrs, &objp->vers)) + return FALSE; + switch (objp->vers) { + case RPCSEC_GSS_VERS_1: + if (!zdr_rpc_gss_cred_vers_1_t (zdrs, &objp->rpc_gss_cred_t_u.rpc_gss_cred_vers_1_t)) + return FALSE; + break; + default: + return FALSE; + } + return TRUE; +} + +uint32_t +zdr_rpc_gss_init_arg (ZDR *zdrs, rpc_gss_init_arg *objp) +{ + if (!zdr_bytes (zdrs, (char **)&objp->gss_token.gss_token_val, &objp->gss_token.gss_token_len, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_rpc_gss_init_res (ZDR *zdrs, rpc_gss_init_res *objp) +{ + register int32_t *buf; + + if (zdrs->x_op == ZDR_ENCODE) { + if (!zdr_bytes (zdrs, (char **)&objp->handle.handle_val, &objp->handle.handle_len, ~0)) + return FALSE; + buf = ZDR_INLINE (zdrs, 3 * BYTES_PER_ZDR_UNIT); + if (buf == NULL) { + if (!zdr_u_int (zdrs, &objp->gss_major)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->gss_minor)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->seq_window)) + return FALSE; + + } else { + IZDR_PUT_U_LONG(buf, objp->gss_major); + IZDR_PUT_U_LONG(buf, objp->gss_minor); + IZDR_PUT_U_LONG(buf, objp->seq_window); + } + if (!zdr_bytes (zdrs, (char **)&objp->gss_token.gss_token_val, &objp->gss_token.gss_token_len, ~0)) + return FALSE; + return TRUE; + } else if (zdrs->x_op == ZDR_DECODE) { + if (!zdr_bytes (zdrs, (char **)&objp->handle.handle_val, &objp->handle.handle_len, ~0)) + return FALSE; + buf = ZDR_INLINE (zdrs, 3 * BYTES_PER_ZDR_UNIT); + if (buf == NULL) { + if (!zdr_u_int (zdrs, &objp->gss_major)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->gss_minor)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->seq_window)) + return FALSE; + + } else { + objp->gss_major = IZDR_GET_U_LONG(buf); + objp->gss_minor = IZDR_GET_U_LONG(buf); + objp->seq_window = IZDR_GET_U_LONG(buf); + } + if (!zdr_bytes (zdrs, (char **)&objp->gss_token.gss_token_val, &objp->gss_token.gss_token_len, ~0)) + return FALSE; + return TRUE; + } + + if (!zdr_bytes (zdrs, (char **)&objp->handle.handle_val, &objp->handle.handle_len, ~0)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->gss_major)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->gss_minor)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->seq_window)) + return FALSE; + if (!zdr_bytes (zdrs, (char **)&objp->gss_token.gss_token_val, &objp->gss_token.gss_token_len, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_rpc_gss_integ_data (ZDR *zdrs, rpc_gss_integ_data *objp) +{ + if (!zdr_bytes (zdrs, (char **)&objp->databody_integ.databody_integ_val, &objp->databody_integ.databody_integ_len, ~0)) + return FALSE; + if (!zdr_bytes (zdrs, (char **)&objp->checksum.checksum_val, &objp->checksum.checksum_len, ~0)) + return FALSE; + return TRUE; +} +uint32_t +zdr_READ4resok (ZDR *zdrs, READ4resok *objp) +{ + uint32_t pos; + + if (!zdr_bool (zdrs, &objp->eof)) + return FALSE; + pos = zdr_getpos(zdrs); + if (!zdr_uint32_t (zdrs, &objp->data.data_len)) + return FALSE; + zdr_setpos(zdrs, pos); + + return TRUE; +} + +uint32_t +zdr_WRITE4args (ZDR *zdrs, WRITE4args *objp) +{ + if (!zdr_stateid4 (zdrs, &objp->stateid)) + return FALSE; + if (!zdr_offset4 (zdrs, &objp->offset)) + return FALSE; + if (!zdr_stable_how4 (zdrs, &objp->stable)) + return FALSE; + return TRUE; +} diff --git a/deps/libnfs/nfs4/libnfs-raw-nfs4.c.fragment b/deps/libnfs/nfs4/libnfs-raw-nfs4.c.fragment new file mode 100644 index 000000000000..6893e592423c --- /dev/null +++ b/deps/libnfs/nfs4/libnfs-raw-nfs4.c.fragment @@ -0,0 +1,26 @@ +uint32_t +zdr_READ4resok (ZDR *zdrs, READ4resok *objp) +{ + uint32_t pos; + + if (!zdr_bool (zdrs, &objp->eof)) + return FALSE; + pos = zdr_getpos(zdrs); + if (!zdr_uint32_t (zdrs, &objp->data.data_len)) + return FALSE; + zdr_setpos(zdrs, pos); + + return TRUE; +} + +uint32_t +zdr_WRITE4args (ZDR *zdrs, WRITE4args *objp) +{ + if (!zdr_stateid4 (zdrs, &objp->stateid)) + return FALSE; + if (!zdr_offset4 (zdrs, &objp->offset)) + return FALSE; + if (!zdr_stable_how4 (zdrs, &objp->stable)) + return FALSE; + return TRUE; +} diff --git a/deps/libnfs/nfs4/libnfs-raw-nfs4.h b/deps/libnfs/nfs4/libnfs-raw-nfs4.h new file mode 100644 index 000000000000..e725561f737a --- /dev/null +++ b/deps/libnfs/nfs4/libnfs-raw-nfs4.h @@ -0,0 +1,3089 @@ +/* This is based on RFC3530 */ + +/* + * NFS v4 Definitions + */ + + +/* + * Copyright (C) The Internet Society (1998,1999,2000,2001,2002). + * All Rights Reserved. + */ + +/* + * nfs4_prot.x + * + */ +/* + * Please do not edit this file. + * It was generated using rpcgen. + */ + +#ifndef _NFS4_H_RPCGEN +#define _NFS4_H_RPCGEN + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +#define NFS4_FHSIZE 128 +#define NFS4_VERIFIER_SIZE 8 +#define NFS4_OPAQUE_LIMIT 1024 +#define NFS4_SESSIONID_SIZE 16 + +enum nfs_ftype4 { + NF4REG = 1, + NF4DIR = 2, + NF4BLK = 3, + NF4CHR = 4, + NF4LNK = 5, + NF4SOCK = 6, + NF4FIFO = 7, + NF4ATTRDIR = 8, + NF4NAMEDATTR = 9, +}; +typedef enum nfs_ftype4 nfs_ftype4; + +enum nfsstat4 { + NFS4_OK = 0, + NFS4ERR_PERM = 1, + NFS4ERR_NOENT = 2, + NFS4ERR_IO = 5, + NFS4ERR_NXIO = 6, + NFS4ERR_ACCESS = 13, + NFS4ERR_EXIST = 17, + NFS4ERR_XDEV = 18, + NFS4ERR_NOTDIR = 20, + NFS4ERR_ISDIR = 21, + NFS4ERR_INVAL = 22, + NFS4ERR_FBIG = 27, + NFS4ERR_NOSPC = 28, + NFS4ERR_ROFS = 30, + NFS4ERR_MLINK = 31, + NFS4ERR_NAMETOOLONG = 63, + NFS4ERR_NOTEMPTY = 66, + NFS4ERR_DQUOT = 69, + NFS4ERR_STALE = 70, + NFS4ERR_BADHANDLE = 10001, + NFS4ERR_BAD_COOKIE = 10003, + NFS4ERR_NOTSUPP = 10004, + NFS4ERR_TOOSMALL = 10005, + NFS4ERR_SERVERFAULT = 10006, + NFS4ERR_BADTYPE = 10007, + NFS4ERR_DELAY = 10008, + NFS4ERR_SAME = 10009, + NFS4ERR_DENIED = 10010, + NFS4ERR_EXPIRED = 10011, + NFS4ERR_LOCKED = 10012, + NFS4ERR_GRACE = 10013, + NFS4ERR_FHEXPIRED = 10014, + NFS4ERR_SHARE_DENIED = 10015, + NFS4ERR_WRONGSEC = 10016, + NFS4ERR_CLID_INUSE = 10017, + NFS4ERR_RESOURCE = 10018, + NFS4ERR_MOVED = 10019, + NFS4ERR_NOFILEHANDLE = 10020, + NFS4ERR_MINOR_VERS_MISMATCH = 10021, + NFS4ERR_STALE_CLIENTID = 10022, + NFS4ERR_STALE_STATEID = 10023, + NFS4ERR_OLD_STATEID = 10024, + NFS4ERR_BAD_STATEID = 10025, + NFS4ERR_BAD_SEQID = 10026, + NFS4ERR_NOT_SAME = 10027, + NFS4ERR_LOCK_RANGE = 10028, + NFS4ERR_SYMLINK = 10029, + NFS4ERR_RESTOREFH = 10030, + NFS4ERR_LEASE_MOVED = 10031, + NFS4ERR_ATTRNOTSUPP = 10032, + NFS4ERR_NO_GRACE = 10033, + NFS4ERR_RECLAIM_BAD = 10034, + NFS4ERR_RECLAIM_CONFLICT = 10035, + NFS4ERR_BADZDR = 10036, + NFS4ERR_LOCKS_HELD = 10037, + NFS4ERR_OPENMODE = 10038, + NFS4ERR_BADOWNER = 10039, + NFS4ERR_BADCHAR = 10040, + NFS4ERR_BADNAME = 10041, + NFS4ERR_BAD_RANGE = 10042, + NFS4ERR_LOCK_NOTSUPP = 10043, + NFS4ERR_OP_ILLEGAL = 10044, + NFS4ERR_DEADLOCK = 10045, + NFS4ERR_FILE_OPEN = 10046, + NFS4ERR_ADMIN_REVOKED = 10047, + NFS4ERR_CB_PATH_DOWN = 10048, + NFS4ERR_BADIOMODE = 10049, + NFS4ERR_BADLAYOUT = 10050, + NFS4ERR_BAD_SESSION_DIGEST = 10051, + NFS4ERR_BADSESSION = 10052, + NFS4ERR_BADSLOT = 10053, + NFS4ERR_COMPLETE_ALREADY = 10054, + NFS4ERR_CONN_NOT_BOUND_TO_SESSION = 10055, + NFS4ERR_DELEG_ALREADY_WANTED = 10056, + NFS4ERR_BACK_CHAN_BUSY = 10057, + NFS4ERR_LAYOUTTRYLATER = 10058, + NFS4ERR_LAYOUTUNAVAILABLE = 10059, + NFS4ERR_NOMATCHING_LAYOUT = 10060, + NFS4ERR_RECALLCONFLICT = 10061, +}; +typedef enum nfsstat4 nfsstat4; + +typedef struct { + uint32_t bitmap4_len; + uint32_t *bitmap4_val; +} bitmap4; + +typedef uint64_t offset4; + +typedef uint32_t count4; + +typedef uint64_t length4; + +typedef uint64_t clientid4; + +typedef uint32_t sequenceid4; + +typedef uint32_t seqid4; + +typedef uint32_t slotid4; + +typedef struct { + uint32_t utf8string_len; + char *utf8string_val; +} utf8string; + +typedef utf8string utf8str_cis; + +typedef utf8string utf8str_cs; + +typedef utf8string utf8str_mixed; + +typedef utf8str_cs component4; + +typedef struct { + uint32_t pathname4_len; + component4 *pathname4_val; +} pathname4; + +typedef uint64_t nfs_lockid4; + +typedef uint64_t nfs_cookie4; + +typedef utf8str_cs linktext4; + +typedef struct { + uint32_t sec_oid4_len; + char *sec_oid4_val; +} sec_oid4; + +typedef uint32_t qop4; + +typedef uint32_t mode4; + +typedef uint64_t changeid4; + +typedef char verifier4[NFS4_VERIFIER_SIZE]; + +typedef char sessionid4[NFS4_SESSIONID_SIZE]; + +struct authsys_parms { + uint32_t stamp; + char *machinename; + uint32_t uid; + uint32_t gid; + struct { + uint32_t gids_len; + uint32_t *gids_val; + } gids; +}; +typedef struct authsys_parms authsys_parms; +#define NFS4_DEVICEID4_SIZE 16 + +typedef char deviceid4[NFS4_DEVICEID4_SIZE]; + +enum layouttype4 { + LAYOUT4_NFSV4_1_FILES = 0x1, + LAYOUT4_OSD2_OBJECTS = 0x2, + LAYOUT4_BLOCK_VOLUME = 0x3, +}; +typedef enum layouttype4 layouttype4; + +struct layoutupdate4 { + layouttype4 lou_type; + struct { + uint32_t lou_body_len; + char *lou_body_val; + } lou_body; +}; +typedef struct layoutupdate4 layoutupdate4; + +struct device_addr4 { + layouttype4 da_layout_type; + struct { + uint32_t da_addr_body_len; + char *da_addr_body_val; + } da_addr_body; +}; +typedef struct device_addr4 device_addr4; + +struct nfstime4 { + int64_t seconds; + uint32_t nseconds; +}; +typedef struct nfstime4 nfstime4; + +enum time_how4 { + SET_TO_SERVER_TIME4 = 0, + SET_TO_CLIENT_TIME4 = 1, +}; +typedef enum time_how4 time_how4; + +enum layoutiomode4 { + LAYOUTIOMODE4_READ = 1, + LAYOUTIOMODE4_RW = 2, + LAYOUTIOMODE4_ANY = 3, +}; +typedef enum layoutiomode4 layoutiomode4; + +struct layout_content4 { + layouttype4 loc_type; + struct { + uint32_t loc_body_len; + char *loc_body_val; + } loc_body; +}; +typedef struct layout_content4 layout_content4; + +struct layout4 { + offset4 lo_offset; + length4 lo_length; + layoutiomode4 lo_iomode; + layout_content4 lo_content; +}; +typedef struct layout4 layout4; + +struct settime4 { + time_how4 set_it; + union { + nfstime4 time; + } settime4_u; +}; +typedef struct settime4 settime4; + +typedef struct { + uint32_t nfs_fh4_len; + char *nfs_fh4_val; +} nfs_fh4; + +struct fsid4 { + uint64_t major; + uint64_t minor; +}; +typedef struct fsid4 fsid4; + +struct fs_location4 { + struct { + uint32_t server_len; + utf8str_cis *server_val; + } server; + pathname4 rootpath; +}; +typedef struct fs_location4 fs_location4; + +struct fs_locations4 { + pathname4 fs_root; + struct { + uint32_t locations_len; + fs_location4 *locations_val; + } locations; +}; +typedef struct fs_locations4 fs_locations4; +#define ACL4_SUPPORT_ALLOW_ACL 0x00000001 +#define ACL4_SUPPORT_DENY_ACL 0x00000002 +#define ACL4_SUPPORT_AUDIT_ACL 0x00000004 +#define ACL4_SUPPORT_ALARM_ACL 0x00000008 + +typedef uint32_t acetype4; +#define ACE4_ACCESS_ALLOWED_ACE_TYPE 0x00000000 +#define ACE4_ACCESS_DENIED_ACE_TYPE 0x00000001 +#define ACE4_SYSTEM_AUDIT_ACE_TYPE 0x00000002 +#define ACE4_SYSTEM_ALARM_ACE_TYPE 0x00000003 + +typedef uint32_t aceflag4; +#define ACE4_FILE_INHERIT_ACE 0x00000001 +#define ACE4_DIRECTORY_INHERIT_ACE 0x00000002 +#define ACE4_NO_PROPAGATE_INHERIT_ACE 0x00000004 +#define ACE4_INHERIT_ONLY_ACE 0x00000008 +#define ACE4_SUCCESSFUL_ACCESS_ACE_FLAG 0x00000010 +#define ACE4_FAILED_ACCESS_ACE_FLAG 0x00000020 +#define ACE4_IDENTIFIER_GROUP 0x00000040 + +typedef uint32_t acemask4; +#define ACE4_READ_DATA 0x00000001 +#define ACE4_LIST_DIRECTORY 0x00000001 +#define ACE4_WRITE_DATA 0x00000002 +#define ACE4_ADD_FILE 0x00000002 +#define ACE4_APPEND_DATA 0x00000004 +#define ACE4_ADD_SUBDIRECTORY 0x00000004 +#define ACE4_READ_NAMED_ATTRS 0x00000008 +#define ACE4_WRITE_NAMED_ATTRS 0x00000010 +#define ACE4_EXECUTE 0x00000020 +#define ACE4_DELETE_CHILD 0x00000040 +#define ACE4_READ_ATTRIBUTES 0x00000080 +#define ACE4_WRITE_ATTRIBUTES 0x00000100 +#define ACE4_DELETE 0x00010000 +#define ACE4_READ_ACL 0x00020000 +#define ACE4_WRITE_ACL 0x00040000 +#define ACE4_WRITE_OWNER 0x00080000 +#define ACE4_SYNCHRONIZE 0x00100000 +#define ACE4_GENERIC_READ 0x00120081 +#define ACE4_GENERIC_WRITE 0x00160106 +#define ACE4_GENERIC_EXECUTE 0x001200A0 + +struct nfsace4 { + acetype4 type; + aceflag4 flag; + acemask4 access_mask; + utf8str_mixed who; +}; +typedef struct nfsace4 nfsace4; +#define MODE4_SUID 0x800 +#define MODE4_SGID 0x400 +#define MODE4_SVTX 0x200 +#define MODE4_RUSR 0x100 +#define MODE4_WUSR 0x080 +#define MODE4_XUSR 0x040 +#define MODE4_RGRP 0x020 +#define MODE4_WGRP 0x010 +#define MODE4_XGRP 0x008 +#define MODE4_ROTH 0x004 +#define MODE4_WOTH 0x002 +#define MODE4_XOTH 0x001 + +struct specdata4 { + uint32_t specdata1; + uint32_t specdata2; +}; +typedef struct specdata4 specdata4; +#define FH4_PERSISTENT 0x00000000 +#define FH4_NOEXPIRE_WITH_OPEN 0x00000001 +#define FH4_VOLATILE_ANY 0x00000002 +#define FH4_VOL_MIGRATION 0x00000004 +#define FH4_VOL_RENAME 0x00000008 + +typedef bitmap4 fattr4_supported_attrs; + +typedef nfs_ftype4 fattr4_type; + +typedef uint32_t fattr4_fh_expire_type; + +typedef changeid4 fattr4_change; + +typedef uint64_t fattr4_size; + +typedef uint32_t fattr4_link_support; + +typedef uint32_t fattr4_symlink_support; + +typedef uint32_t fattr4_named_attr; + +typedef fsid4 fattr4_fsid; + +typedef uint32_t fattr4_unique_handles; + +typedef uint32_t fattr4_lease_time; + +typedef nfsstat4 fattr4_rdattr_error; + +typedef struct { + uint32_t fattr4_acl_len; + nfsace4 *fattr4_acl_val; +} fattr4_acl; + +typedef uint32_t fattr4_aclsupport; + +typedef uint32_t fattr4_archive; + +typedef uint32_t fattr4_cansettime; + +typedef uint32_t fattr4_case_insensitive; + +typedef uint32_t fattr4_case_preserving; + +typedef uint32_t fattr4_chown_restricted; + +typedef uint64_t fattr4_fileid; + +typedef uint64_t fattr4_files_avail; + +typedef nfs_fh4 fattr4_filehandle; + +typedef uint64_t fattr4_files_free; + +typedef uint64_t fattr4_files_total; + +typedef fs_locations4 fattr4_fs_locations; + +typedef uint32_t fattr4_hidden; + +typedef uint32_t fattr4_homogeneous; + +typedef uint64_t fattr4_maxfilesize; + +typedef uint32_t fattr4_maxlink; + +typedef uint32_t fattr4_maxname; + +typedef uint64_t fattr4_maxread; + +typedef uint64_t fattr4_maxwrite; + +typedef utf8str_cs fattr4_mimetype; + +typedef mode4 fattr4_mode; + +typedef uint64_t fattr4_mounted_on_fileid; + +typedef uint32_t fattr4_no_trunc; + +typedef uint32_t fattr4_numlinks; + +typedef utf8str_mixed fattr4_owner; + +typedef utf8str_mixed fattr4_owner_group; + +typedef uint64_t fattr4_quota_avail_hard; + +typedef uint64_t fattr4_quota_avail_soft; + +typedef uint64_t fattr4_quota_used; + +typedef specdata4 fattr4_rawdev; + +typedef uint64_t fattr4_space_avail; + +typedef uint64_t fattr4_space_free; + +typedef uint64_t fattr4_space_total; + +typedef uint64_t fattr4_space_used; + +typedef uint32_t fattr4_system; + +typedef nfstime4 fattr4_time_access; + +typedef settime4 fattr4_time_access_set; + +typedef nfstime4 fattr4_time_backup; + +typedef nfstime4 fattr4_time_create; + +typedef nfstime4 fattr4_time_delta; + +typedef nfstime4 fattr4_time_metadata; + +typedef nfstime4 fattr4_time_modify; + +typedef settime4 fattr4_time_modify_set; +#define FATTR4_SUPPORTED_ATTRS 0 +#define FATTR4_TYPE 1 +#define FATTR4_FH_EXPIRE_TYPE 2 +#define FATTR4_CHANGE 3 +#define FATTR4_SIZE 4 +#define FATTR4_LINK_SUPPORT 5 +#define FATTR4_SYMLINK_SUPPORT 6 +#define FATTR4_NAMED_ATTR 7 +#define FATTR4_FSID 8 +#define FATTR4_UNIQUE_HANDLES 9 +#define FATTR4_LEASE_TIME 10 +#define FATTR4_RDATTR_ERROR 11 +#define FATTR4_FILEHANDLE 19 +#define FATTR4_ACL 12 +#define FATTR4_ACLSUPPORT 13 +#define FATTR4_ARCHIVE 14 +#define FATTR4_CANSETTIME 15 +#define FATTR4_CASE_INSENSITIVE 16 +#define FATTR4_CASE_PRESERVING 17 +#define FATTR4_CHOWN_RESTRICTED 18 +#define FATTR4_FILEID 20 +#define FATTR4_FILES_AVAIL 21 +#define FATTR4_FILES_FREE 22 +#define FATTR4_FILES_TOTAL 23 +#define FATTR4_FS_LOCATIONS 24 +#define FATTR4_HIDDEN 25 +#define FATTR4_HOMOGENEOUS 26 +#define FATTR4_MAXFILESIZE 27 +#define FATTR4_MAXLINK 28 +#define FATTR4_MAXNAME 29 +#define FATTR4_MAXREAD 30 +#define FATTR4_MAXWRITE 31 +#define FATTR4_MIMETYPE 32 +#define FATTR4_MODE 33 +#define FATTR4_NO_TRUNC 34 +#define FATTR4_NUMLINKS 35 +#define FATTR4_OWNER 36 +#define FATTR4_OWNER_GROUP 37 +#define FATTR4_QUOTA_AVAIL_HARD 38 +#define FATTR4_QUOTA_AVAIL_SOFT 39 +#define FATTR4_QUOTA_USED 40 +#define FATTR4_RAWDEV 41 +#define FATTR4_SPACE_AVAIL 42 +#define FATTR4_SPACE_FREE 43 +#define FATTR4_SPACE_TOTAL 44 +#define FATTR4_SPACE_USED 45 +#define FATTR4_SYSTEM 46 +#define FATTR4_TIME_ACCESS 47 +#define FATTR4_TIME_ACCESS_SET 48 +#define FATTR4_TIME_BACKUP 49 +#define FATTR4_TIME_CREATE 50 +#define FATTR4_TIME_DELTA 51 +#define FATTR4_TIME_METADATA 52 +#define FATTR4_TIME_MODIFY 53 +#define FATTR4_TIME_MODIFY_SET 54 +#define FATTR4_MOUNTED_ON_FILEID 55 + +typedef struct { + uint32_t attrlist4_len; + char *attrlist4_val; +} attrlist4; + +struct fattr4 { + bitmap4 attrmask; + attrlist4 attr_vals; +}; +typedef struct fattr4 fattr4; + +struct change_info4 { + uint32_t atomic; + changeid4 before; + changeid4 after; +}; +typedef struct change_info4 change_info4; + +struct clientaddr4 { + char *r_netid; + char *r_addr; +}; +typedef struct clientaddr4 clientaddr4; + +struct cb_client4 { + uint32_t cb_program; + clientaddr4 cb_location; +}; +typedef struct cb_client4 cb_client4; + +struct stateid4 { + uint32_t seqid; + char other[12]; +}; +typedef struct stateid4 stateid4; + +struct nfs_client_id4 { + verifier4 verifier; + struct { + uint32_t id_len; + char *id_val; + } id; +}; +typedef struct nfs_client_id4 nfs_client_id4; + +struct open_owner4 { + clientid4 clientid; + struct { + uint32_t owner_len; + char *owner_val; + } owner; +}; +typedef struct open_owner4 open_owner4; + +struct lock_owner4 { + clientid4 clientid; + struct { + uint32_t owner_len; + char *owner_val; + } owner; +}; +typedef struct lock_owner4 lock_owner4; + +enum nfs_lock_type4 { + READ_LT = 1, + WRITE_LT = 2, + READW_LT = 3, + WRITEW_LT = 4, +}; +typedef enum nfs_lock_type4 nfs_lock_type4; + +struct client_owner4 { + verifier4 co_verifier; + struct { + uint32_t co_ownerid_len; + char *co_ownerid_val; + } co_ownerid; +}; +typedef struct client_owner4 client_owner4; + +struct server_owner4 { + uint64_t so_minor_id; + struct { + uint32_t so_major_id_len; + char *so_major_id_val; + } so_major_id; +}; +typedef struct server_owner4 server_owner4; + +struct nfs_impl_id4 { + utf8str_cis nii_domain; + utf8str_cs nii_name; + nfstime4 nii_date; +}; +typedef struct nfs_impl_id4 nfs_impl_id4; +#define ACCESS4_READ 0x00000001 +#define ACCESS4_LOOKUP 0x00000002 +#define ACCESS4_MODIFY 0x00000004 +#define ACCESS4_EXTEND 0x00000008 +#define ACCESS4_DELETE 0x00000010 +#define ACCESS4_EXECUTE 0x00000020 + +struct ACCESS4args { + uint32_t access; +}; +typedef struct ACCESS4args ACCESS4args; + +struct ACCESS4resok { + uint32_t supported; + uint32_t access; +}; +typedef struct ACCESS4resok ACCESS4resok; + +struct ACCESS4res { + nfsstat4 status; + union { + ACCESS4resok resok4; + } ACCESS4res_u; +}; +typedef struct ACCESS4res ACCESS4res; + +struct CLOSE4args { + seqid4 seqid; + stateid4 open_stateid; +}; +typedef struct CLOSE4args CLOSE4args; + +struct CLOSE4res { + nfsstat4 status; + union { + stateid4 open_stateid; + } CLOSE4res_u; +}; +typedef struct CLOSE4res CLOSE4res; + +struct COMMIT4args { + offset4 offset; + count4 count; +}; +typedef struct COMMIT4args COMMIT4args; + +struct COMMIT4resok { + verifier4 writeverf; +}; +typedef struct COMMIT4resok COMMIT4resok; + +struct COMMIT4res { + nfsstat4 status; + union { + COMMIT4resok resok4; + } COMMIT4res_u; +}; +typedef struct COMMIT4res COMMIT4res; + +struct createtype4 { + nfs_ftype4 type; + union { + linktext4 linkdata; + specdata4 devdata; + } createtype4_u; +}; +typedef struct createtype4 createtype4; + +struct CREATE4args { + createtype4 objtype; + component4 objname; + fattr4 createattrs; +}; +typedef struct CREATE4args CREATE4args; + +struct CREATE4resok { + change_info4 cinfo; + bitmap4 attrset; +}; +typedef struct CREATE4resok CREATE4resok; + +struct CREATE4res { + nfsstat4 status; + union { + CREATE4resok resok4; + } CREATE4res_u; +}; +typedef struct CREATE4res CREATE4res; + +struct DELEGPURGE4args { + clientid4 clientid; +}; +typedef struct DELEGPURGE4args DELEGPURGE4args; + +struct DELEGPURGE4res { + nfsstat4 status; +}; +typedef struct DELEGPURGE4res DELEGPURGE4res; + +struct DELEGRETURN4args { + stateid4 deleg_stateid; +}; +typedef struct DELEGRETURN4args DELEGRETURN4args; + +struct DELEGRETURN4res { + nfsstat4 status; +}; +typedef struct DELEGRETURN4res DELEGRETURN4res; + +struct GETATTR4args { + bitmap4 attr_request; +}; +typedef struct GETATTR4args GETATTR4args; + +struct GETATTR4resok { + fattr4 obj_attributes; +}; +typedef struct GETATTR4resok GETATTR4resok; + +struct GETATTR4res { + nfsstat4 status; + union { + GETATTR4resok resok4; + } GETATTR4res_u; +}; +typedef struct GETATTR4res GETATTR4res; + +struct GETFH4resok { + nfs_fh4 object; +}; +typedef struct GETFH4resok GETFH4resok; + +struct GETFH4res { + nfsstat4 status; + union { + GETFH4resok resok4; + } GETFH4res_u; +}; +typedef struct GETFH4res GETFH4res; + +struct LINK4args { + component4 newname; +}; +typedef struct LINK4args LINK4args; + +struct LINK4resok { + change_info4 cinfo; +}; +typedef struct LINK4resok LINK4resok; + +struct LINK4res { + nfsstat4 status; + union { + LINK4resok resok4; + } LINK4res_u; +}; +typedef struct LINK4res LINK4res; + +struct open_to_lock_owner4 { + seqid4 open_seqid; + stateid4 open_stateid; + seqid4 lock_seqid; + lock_owner4 lock_owner; +}; +typedef struct open_to_lock_owner4 open_to_lock_owner4; + +struct exist_lock_owner4 { + stateid4 lock_stateid; + seqid4 lock_seqid; +}; +typedef struct exist_lock_owner4 exist_lock_owner4; + +struct locker4 { + uint32_t new_lock_owner; + union { + open_to_lock_owner4 open_owner; + exist_lock_owner4 lock_owner; + } locker4_u; +}; +typedef struct locker4 locker4; + +struct LOCK4args { + nfs_lock_type4 locktype; + uint32_t reclaim; + offset4 offset; + length4 length; + locker4 locker; +}; +typedef struct LOCK4args LOCK4args; + +struct LOCK4denied { + offset4 offset; + length4 length; + nfs_lock_type4 locktype; + lock_owner4 owner; +}; +typedef struct LOCK4denied LOCK4denied; + +struct LOCK4resok { + stateid4 lock_stateid; +}; +typedef struct LOCK4resok LOCK4resok; + +struct LOCK4res { + nfsstat4 status; + union { + LOCK4resok resok4; + LOCK4denied denied; + } LOCK4res_u; +}; +typedef struct LOCK4res LOCK4res; + +struct LOCKT4args { + nfs_lock_type4 locktype; + offset4 offset; + length4 length; + lock_owner4 owner; +}; +typedef struct LOCKT4args LOCKT4args; + +struct LOCKT4res { + nfsstat4 status; + union { + LOCK4denied denied; + } LOCKT4res_u; +}; +typedef struct LOCKT4res LOCKT4res; + +struct LOCKU4args { + nfs_lock_type4 locktype; + seqid4 seqid; + stateid4 lock_stateid; + offset4 offset; + length4 length; +}; +typedef struct LOCKU4args LOCKU4args; + +struct LOCKU4res { + nfsstat4 status; + union { + stateid4 lock_stateid; + } LOCKU4res_u; +}; +typedef struct LOCKU4res LOCKU4res; + +struct LOOKUP4args { + component4 objname; +}; +typedef struct LOOKUP4args LOOKUP4args; + +struct LOOKUP4res { + nfsstat4 status; +}; +typedef struct LOOKUP4res LOOKUP4res; + +struct LOOKUPP4res { + nfsstat4 status; +}; +typedef struct LOOKUPP4res LOOKUPP4res; + +struct NVERIFY4args { + fattr4 obj_attributes; +}; +typedef struct NVERIFY4args NVERIFY4args; + +struct NVERIFY4res { + nfsstat4 status; +}; +typedef struct NVERIFY4res NVERIFY4res; + +enum createmode4 { + UNCHECKED4 = 0, + GUARDED4 = 1, + EXCLUSIVE4 = 2, +}; +typedef enum createmode4 createmode4; + +struct createhow4 { + createmode4 mode; + union { + fattr4 createattrs; + verifier4 createverf; + } createhow4_u; +}; +typedef struct createhow4 createhow4; + +enum opentype4 { + OPEN4_NOCREATE = 0, + OPEN4_CREATE = 1, +}; +typedef enum opentype4 opentype4; + +struct openflag4 { + opentype4 opentype; + union { + createhow4 how; + } openflag4_u; +}; +typedef struct openflag4 openflag4; + +enum limit_by4 { + NFS_LIMIT_SIZE = 1, + NFS_LIMIT_BLOCKS = 2, +}; +typedef enum limit_by4 limit_by4; + +struct nfs_modified_limit4 { + uint32_t num_blocks; + uint32_t bytes_per_block; +}; +typedef struct nfs_modified_limit4 nfs_modified_limit4; + +struct nfs_space_limit4 { + limit_by4 limitby; + union { + uint64_t filesize; + nfs_modified_limit4 mod_blocks; + } nfs_space_limit4_u; +}; +typedef struct nfs_space_limit4 nfs_space_limit4; +#define OPEN4_SHARE_ACCESS_READ 0x00000001 +#define OPEN4_SHARE_ACCESS_WRITE 0x00000002 +#define OPEN4_SHARE_ACCESS_BOTH 0x00000003 +#define OPEN4_SHARE_DENY_NONE 0x00000000 +#define OPEN4_SHARE_DENY_READ 0x00000001 +#define OPEN4_SHARE_DENY_WRITE 0x00000002 +#define OPEN4_SHARE_DENY_BOTH 0x00000003 + +enum open_delegation_type4 { + OPEN_DELEGATE_NONE = 0, + OPEN_DELEGATE_READ = 1, + OPEN_DELEGATE_WRITE = 2, +}; +typedef enum open_delegation_type4 open_delegation_type4; + +enum open_claim_type4 { + CLAIM_NULL = 0, + CLAIM_PREVIOUS = 1, + CLAIM_DELEGATE_CUR = 2, + CLAIM_DELEGATE_PREV = 3, + CLAIM_FH = 4, + CLAIM_DELEG_CUR_FH = 5, + CLAIM_DELEG_PREV_FH = 6, +}; +typedef enum open_claim_type4 open_claim_type4; + +struct open_claim_delegate_cur4 { + stateid4 delegate_stateid; + component4 file; +}; +typedef struct open_claim_delegate_cur4 open_claim_delegate_cur4; + +struct open_claim4 { + open_claim_type4 claim; + union { + component4 file; + open_delegation_type4 delegate_type; + open_claim_delegate_cur4 delegate_cur_info; + component4 file_delegate_prev; + stateid4 oc_delegate_stateid; + } open_claim4_u; +}; +typedef struct open_claim4 open_claim4; + +struct OPEN4args { + seqid4 seqid; + uint32_t share_access; + uint32_t share_deny; + open_owner4 owner; + openflag4 openhow; + open_claim4 claim; +}; +typedef struct OPEN4args OPEN4args; + +struct open_read_delegation4 { + stateid4 stateid; + uint32_t recall; + nfsace4 permissions; +}; +typedef struct open_read_delegation4 open_read_delegation4; + +struct open_write_delegation4 { + stateid4 stateid; + uint32_t recall; + nfs_space_limit4 space_limit; + nfsace4 permissions; +}; +typedef struct open_write_delegation4 open_write_delegation4; + +struct open_delegation4 { + open_delegation_type4 delegation_type; + union { + open_read_delegation4 read; + open_write_delegation4 write; + } open_delegation4_u; +}; +typedef struct open_delegation4 open_delegation4; +#define OPEN4_RESULT_CONFIRM 0x00000002 +#define OPEN4_RESULT_LOCKTYPE_POSIX 0x00000004 + +struct OPEN4resok { + stateid4 stateid; + change_info4 cinfo; + uint32_t rflags; + bitmap4 attrset; + open_delegation4 delegation; +}; +typedef struct OPEN4resok OPEN4resok; + +struct OPEN4res { + nfsstat4 status; + union { + OPEN4resok resok4; + } OPEN4res_u; +}; +typedef struct OPEN4res OPEN4res; + +struct OPENATTR4args { + uint32_t createdir; +}; +typedef struct OPENATTR4args OPENATTR4args; + +struct OPENATTR4res { + nfsstat4 status; +}; +typedef struct OPENATTR4res OPENATTR4res; + +struct OPEN_CONFIRM4args { + stateid4 open_stateid; + seqid4 seqid; +}; +typedef struct OPEN_CONFIRM4args OPEN_CONFIRM4args; + +struct OPEN_CONFIRM4resok { + stateid4 open_stateid; +}; +typedef struct OPEN_CONFIRM4resok OPEN_CONFIRM4resok; + +struct OPEN_CONFIRM4res { + nfsstat4 status; + union { + OPEN_CONFIRM4resok resok4; + } OPEN_CONFIRM4res_u; +}; +typedef struct OPEN_CONFIRM4res OPEN_CONFIRM4res; + +struct OPEN_DOWNGRADE4args { + stateid4 open_stateid; + seqid4 seqid; + uint32_t share_access; + uint32_t share_deny; +}; +typedef struct OPEN_DOWNGRADE4args OPEN_DOWNGRADE4args; + +struct OPEN_DOWNGRADE4resok { + stateid4 open_stateid; +}; +typedef struct OPEN_DOWNGRADE4resok OPEN_DOWNGRADE4resok; + +struct OPEN_DOWNGRADE4res { + nfsstat4 status; + union { + OPEN_DOWNGRADE4resok resok4; + } OPEN_DOWNGRADE4res_u; +}; +typedef struct OPEN_DOWNGRADE4res OPEN_DOWNGRADE4res; + +struct PUTFH4args { + nfs_fh4 object; +}; +typedef struct PUTFH4args PUTFH4args; + +struct PUTFH4res { + nfsstat4 status; +}; +typedef struct PUTFH4res PUTFH4res; + +struct PUTPUBFH4res { + nfsstat4 status; +}; +typedef struct PUTPUBFH4res PUTPUBFH4res; + +struct PUTROOTFH4res { + nfsstat4 status; +}; +typedef struct PUTROOTFH4res PUTROOTFH4res; + +struct READ4args { + stateid4 stateid; + offset4 offset; + count4 count; +}; +typedef struct READ4args READ4args; + +struct READ4resok { + uint32_t eof; + struct { + uint32_t data_len; + char *data_val; + } data; +}; +typedef struct READ4resok READ4resok; + +struct READ4res { + nfsstat4 status; + union { + READ4resok resok4; + } READ4res_u; +}; +typedef struct READ4res READ4res; + +struct READDIR4args { + nfs_cookie4 cookie; + verifier4 cookieverf; + count4 dircount; + count4 maxcount; + bitmap4 attr_request; +}; +typedef struct READDIR4args READDIR4args; + +struct entry4 { + nfs_cookie4 cookie; + component4 name; + fattr4 attrs; + struct entry4 *nextentry; +}; +typedef struct entry4 entry4; + +struct dirlist4 { + entry4 *entries; + uint32_t eof; +}; +typedef struct dirlist4 dirlist4; + +struct READDIR4resok { + verifier4 cookieverf; + dirlist4 reply; +}; +typedef struct READDIR4resok READDIR4resok; + +struct READDIR4res { + nfsstat4 status; + union { + READDIR4resok resok4; + } READDIR4res_u; +}; +typedef struct READDIR4res READDIR4res; + +struct READLINK4resok { + linktext4 link; +}; +typedef struct READLINK4resok READLINK4resok; + +struct READLINK4res { + nfsstat4 status; + union { + READLINK4resok resok4; + } READLINK4res_u; +}; +typedef struct READLINK4res READLINK4res; + +struct REMOVE4args { + component4 target; +}; +typedef struct REMOVE4args REMOVE4args; + +struct REMOVE4resok { + change_info4 cinfo; +}; +typedef struct REMOVE4resok REMOVE4resok; + +struct REMOVE4res { + nfsstat4 status; + union { + REMOVE4resok resok4; + } REMOVE4res_u; +}; +typedef struct REMOVE4res REMOVE4res; + +struct RENAME4args { + component4 oldname; + component4 newname; +}; +typedef struct RENAME4args RENAME4args; + +struct RENAME4resok { + change_info4 source_cinfo; + change_info4 target_cinfo; +}; +typedef struct RENAME4resok RENAME4resok; + +struct RENAME4res { + nfsstat4 status; + union { + RENAME4resok resok4; + } RENAME4res_u; +}; +typedef struct RENAME4res RENAME4res; + +struct RENEW4args { + clientid4 clientid; +}; +typedef struct RENEW4args RENEW4args; + +struct RENEW4res { + nfsstat4 status; +}; +typedef struct RENEW4res RENEW4res; + +struct RESTOREFH4res { + nfsstat4 status; +}; +typedef struct RESTOREFH4res RESTOREFH4res; + +struct SAVEFH4res { + nfsstat4 status; +}; +typedef struct SAVEFH4res SAVEFH4res; + +struct SECINFO4args { + component4 name; +}; +typedef struct SECINFO4args SECINFO4args; + +enum rpc_gss_svc_t { + RPC_GSS_SVC_NONE = 1, + RPC_GSS_SVC_INTEGRITY = 2, + RPC_GSS_SVC_PRIVACY = 3, +}; +typedef enum rpc_gss_svc_t rpc_gss_svc_t; + +struct rpcsec_gss_info { + sec_oid4 oid; + qop4 qop; + rpc_gss_svc_t service; +}; +typedef struct rpcsec_gss_info rpcsec_gss_info; +#define RPCSEC_GSS 6 + +struct secinfo4 { + uint32_t flavor; + union { + rpcsec_gss_info flavor_info; + } secinfo4_u; +}; +typedef struct secinfo4 secinfo4; + +typedef struct { + uint32_t SECINFO4resok_len; + secinfo4 *SECINFO4resok_val; +} SECINFO4resok; + +struct SECINFO4res { + nfsstat4 status; + union { + SECINFO4resok resok4; + } SECINFO4res_u; +}; +typedef struct SECINFO4res SECINFO4res; + +struct SETATTR4args { + stateid4 stateid; + fattr4 obj_attributes; +}; +typedef struct SETATTR4args SETATTR4args; + +struct SETATTR4res { + nfsstat4 status; + bitmap4 attrsset; +}; +typedef struct SETATTR4res SETATTR4res; + +struct SETCLIENTID4args { + nfs_client_id4 client; + cb_client4 callback; + uint32_t callback_ident; +}; +typedef struct SETCLIENTID4args SETCLIENTID4args; + +struct SETCLIENTID4resok { + clientid4 clientid; + verifier4 setclientid_confirm; +}; +typedef struct SETCLIENTID4resok SETCLIENTID4resok; + +struct SETCLIENTID4res { + nfsstat4 status; + union { + SETCLIENTID4resok resok4; + clientaddr4 client_using; + } SETCLIENTID4res_u; +}; +typedef struct SETCLIENTID4res SETCLIENTID4res; + +struct SETCLIENTID_CONFIRM4args { + clientid4 clientid; + verifier4 setclientid_confirm; +}; +typedef struct SETCLIENTID_CONFIRM4args SETCLIENTID_CONFIRM4args; + +struct SETCLIENTID_CONFIRM4res { + nfsstat4 status; +}; +typedef struct SETCLIENTID_CONFIRM4res SETCLIENTID_CONFIRM4res; + +struct VERIFY4args { + fattr4 obj_attributes; +}; +typedef struct VERIFY4args VERIFY4args; + +struct VERIFY4res { + nfsstat4 status; +}; +typedef struct VERIFY4res VERIFY4res; + +enum stable_how4 { + UNSTABLE4 = 0, + DATA_SYNC4 = 1, + FILE_SYNC4 = 2, +}; +typedef enum stable_how4 stable_how4; + +struct WRITE4args { + stateid4 stateid; + offset4 offset; + stable_how4 stable; + struct { + uint32_t data_len; + char *data_val; + } data; +}; +typedef struct WRITE4args WRITE4args; + +struct WRITE4resok { + count4 count; + stable_how4 committed; + verifier4 writeverf; +}; +typedef struct WRITE4resok WRITE4resok; + +struct WRITE4res { + nfsstat4 status; + union { + WRITE4resok resok4; + } WRITE4res_u; +}; +typedef struct WRITE4res WRITE4res; + +struct RELEASE_LOCKOWNER4args { + lock_owner4 lock_owner; +}; +typedef struct RELEASE_LOCKOWNER4args RELEASE_LOCKOWNER4args; + +struct RELEASE_LOCKOWNER4res { + nfsstat4 status; +}; +typedef struct RELEASE_LOCKOWNER4res RELEASE_LOCKOWNER4res; + +typedef struct { + uint32_t gsshandle4_t_len; + char *gsshandle4_t_val; +} gsshandle4_t; + +struct callback_sec_parms4 { + uint32_t cb_secflavor; + union { + authsys_parms cbsp_sys_cred; + } callback_sec_parms4_u; +}; +typedef struct callback_sec_parms4 callback_sec_parms4; + +enum channel_dir_from_client4 { + CDFC4_FORE = 0x1, + CDFC4_BACK = 0x2, + CDFC4_FORE_OR_BOTH = 0x3, + CDFC4_BACK_OR_BOTH = 0x7, +}; +typedef enum channel_dir_from_client4 channel_dir_from_client4; + +struct BIND_CONN_TO_SESSION4args { + sessionid4 bctsa_sessid; + channel_dir_from_client4 bctsa_dir; + uint32_t bctsa_use_conn_in_rdma_mode; +}; +typedef struct BIND_CONN_TO_SESSION4args BIND_CONN_TO_SESSION4args; + +enum channel_dir_from_server4 { + CDFS4_FORE = 0x1, + CDFS4_BACK = 0x2, + CDFS4_BOTH = 0x3, +}; +typedef enum channel_dir_from_server4 channel_dir_from_server4; + +struct BIND_CONN_TO_SESSION4resok { + sessionid4 bctsr_sessid; + channel_dir_from_server4 bctsr_dir; + uint32_t bctsr_use_conn_in_rdma_mode; +}; +typedef struct BIND_CONN_TO_SESSION4resok BIND_CONN_TO_SESSION4resok; + +struct BIND_CONN_TO_SESSION4res { + nfsstat4 bctsr_status; + union { + BIND_CONN_TO_SESSION4resok bctsr_resok4; + } BIND_CONN_TO_SESSION4res_u; +}; +typedef struct BIND_CONN_TO_SESSION4res BIND_CONN_TO_SESSION4res; +#define EXCHGID4_FLAG_SUPP_MOVED_REFER 0x00000001 +#define EXCHGID4_FLAG_SUPP_MOVED_MIGR 0x00000002 +#define EXCHGID4_FLAG_BIND_PRINC_STATEID 0x00000100 +#define EXCHGID4_FLAG_USE_NON_PNFS 0x00010000 +#define EXCHGID4_FLAG_USE_PNFS_MDS 0x00020000 +#define EXCHGID4_FLAG_USE_PNFS_DS 0x00040000 +#define EXCHGID4_FLAG_MASK_PNFS 0x00070000 +#define EXCHGID4_FLAG_UPD_CONFIRMED_REC_A 0x40000000 +#define EXCHGID4_FLAG_CONFIRMED_R 0x80000000 + +struct state_protect_ops4 { + bitmap4 spo_must_enforce; + bitmap4 spo_must_allow; +}; +typedef struct state_protect_ops4 state_protect_ops4; + +struct ssv_sp_parms4 { + state_protect_ops4 ssp_ops; + struct { + uint32_t ssp_hash_algs_len; + sec_oid4 *ssp_hash_algs_val; + } ssp_hash_algs; + struct { + uint32_t ssp_encr_algs_len; + sec_oid4 *ssp_encr_algs_val; + } ssp_encr_algs; + uint32_t ssp_window; + uint32_t ssp_num_gss_handles; +}; +typedef struct ssv_sp_parms4 ssv_sp_parms4; + +enum state_protect_how4 { + SP4_NONE = 0, + SP4_MACH_CRED = 1, + SP4_SSV = 2, +}; +typedef enum state_protect_how4 state_protect_how4; + +struct state_protect4_a { + state_protect_how4 spa_how; + union { + state_protect_ops4 spa_mach_ops; + ssv_sp_parms4 spa_ssv_parms; + } state_protect4_a_u; +}; +typedef struct state_protect4_a state_protect4_a; + +struct EXCHANGE_ID4args { + client_owner4 eia_clientowner; + uint32_t eia_flags; + state_protect4_a eia_state_protect; + struct { + uint32_t eia_client_impl_id_len; + nfs_impl_id4 *eia_client_impl_id_val; + } eia_client_impl_id; +}; +typedef struct EXCHANGE_ID4args EXCHANGE_ID4args; + +struct ssv_prot_info4 { + state_protect_ops4 spi_ops; + uint32_t spi_hash_alg; + uint32_t spi_encr_alg; + uint32_t spi_ssv_len; + uint32_t spi_window; + struct { + uint32_t spi_handles_len; + gsshandle4_t *spi_handles_val; + } spi_handles; +}; +typedef struct ssv_prot_info4 ssv_prot_info4; + +struct state_protect4_r { + state_protect_how4 spr_how; + union { + state_protect_ops4 spr_mach_ops; + ssv_prot_info4 spr_ssv_info; + } state_protect4_r_u; +}; +typedef struct state_protect4_r state_protect4_r; + +struct EXCHANGE_ID4resok { + clientid4 eir_clientid; + sequenceid4 eir_sequenceid; + uint32_t eir_flags; + state_protect4_r eir_state_protect; + server_owner4 eir_server_owner; + struct { + uint32_t eir_server_scope_len; + char *eir_server_scope_val; + } eir_server_scope; + struct { + uint32_t eir_server_impl_id_len; + nfs_impl_id4 *eir_server_impl_id_val; + } eir_server_impl_id; +}; +typedef struct EXCHANGE_ID4resok EXCHANGE_ID4resok; + +struct EXCHANGE_ID4res { + nfsstat4 eir_status; + union { + EXCHANGE_ID4resok eir_resok4; + } EXCHANGE_ID4res_u; +}; +typedef struct EXCHANGE_ID4res EXCHANGE_ID4res; + +struct channel_attrs4 { + count4 ca_headerpadsize; + count4 ca_maxrequestsize; + count4 ca_maxresponsesize; + count4 ca_maxresponsesize_cached; + count4 ca_maxoperations; + count4 ca_maxrequests; + struct { + uint32_t ca_rdma_ird_len; + uint32_t *ca_rdma_ird_val; + } ca_rdma_ird; +}; +typedef struct channel_attrs4 channel_attrs4; +#define CREATE_SESSION4_FLAG_PERSIST 0x00000001 +#define CREATE_SESSION4_FLAG_CONN_BACK_CHAN 0x00000002 +#define CREATE_SESSION4_FLAG_CONN_RDMA 0x00000004 + +struct CREATE_SESSION4args { + clientid4 csa_clientid; + sequenceid4 csa_sequence; + uint32_t csa_flags; + channel_attrs4 csa_fore_chan_attrs; + channel_attrs4 csa_back_chan_attrs; + uint32_t csa_cb_program; + struct { + uint32_t csa_sec_parms_len; + callback_sec_parms4 *csa_sec_parms_val; + } csa_sec_parms; +}; +typedef struct CREATE_SESSION4args CREATE_SESSION4args; + +struct CREATE_SESSION4resok { + sessionid4 csr_sessionid; + sequenceid4 csr_sequence; + uint32_t csr_flags; + channel_attrs4 csr_fore_chan_attrs; + channel_attrs4 csr_back_chan_attrs; +}; +typedef struct CREATE_SESSION4resok CREATE_SESSION4resok; + +struct CREATE_SESSION4res { + nfsstat4 csr_status; + union { + CREATE_SESSION4resok csr_resok4; + } CREATE_SESSION4res_u; +}; +typedef struct CREATE_SESSION4res CREATE_SESSION4res; + +struct DESTROY_SESSION4args { + sessionid4 dsa_sessionid; +}; +typedef struct DESTROY_SESSION4args DESTROY_SESSION4args; + +struct DESTROY_SESSION4res { + nfsstat4 dsr_status; +}; +typedef struct DESTROY_SESSION4res DESTROY_SESSION4res; + +struct FREE_STATEID4args { + stateid4 fsa_stateid; +}; +typedef struct FREE_STATEID4args FREE_STATEID4args; + +struct FREE_STATEID4res { + nfsstat4 fsr_status; +}; +typedef struct FREE_STATEID4res FREE_STATEID4res; + +typedef nfstime4 attr_notice4; + +struct GET_DIR_DELEGATION4args { + uint32_t gdda_signal_deleg_avail; + bitmap4 gdda_notification_types; + attr_notice4 gdda_child_attr_delay; + attr_notice4 gdda_dir_attr_delay; + bitmap4 gdda_child_attributes; + bitmap4 gdda_dir_attributes; +}; +typedef struct GET_DIR_DELEGATION4args GET_DIR_DELEGATION4args; + +struct GET_DIR_DELEGATION4resok { + verifier4 gddr_cookieverf; + stateid4 gddr_stateid; + bitmap4 gddr_notification; + bitmap4 gddr_child_attributes; + bitmap4 gddr_dir_attributes; +}; +typedef struct GET_DIR_DELEGATION4resok GET_DIR_DELEGATION4resok; + +enum gddrnf4_status { + GDD4_OK = 0, + GDD4_UNAVAIL = 1, +}; +typedef enum gddrnf4_status gddrnf4_status; + +struct GET_DIR_DELEGATION4res_non_fatal { + gddrnf4_status gddrnf_status; + union { + GET_DIR_DELEGATION4resok gddrnf_resok4; + uint32_t gddrnf_will_signal_deleg_avail; + } GET_DIR_DELEGATION4res_non_fatal_u; +}; +typedef struct GET_DIR_DELEGATION4res_non_fatal GET_DIR_DELEGATION4res_non_fatal; + +struct GET_DIR_DELEGATION4res { + nfsstat4 gddr_status; + union { + GET_DIR_DELEGATION4res_non_fatal gddr_res_non_fatal4; + } GET_DIR_DELEGATION4res_u; +}; +typedef struct GET_DIR_DELEGATION4res GET_DIR_DELEGATION4res; + +struct GETDEVICEINFO4args { + deviceid4 gdia_device_id; + layouttype4 gdia_layout_type; + count4 gdia_maxcount; + bitmap4 gdia_notify_types; +}; +typedef struct GETDEVICEINFO4args GETDEVICEINFO4args; + +struct GETDEVICEINFO4resok { + device_addr4 gdir_device_addr; + bitmap4 gdir_notification; +}; +typedef struct GETDEVICEINFO4resok GETDEVICEINFO4resok; + +struct GETDEVICEINFO4res { + nfsstat4 gdir_status; + union { + GETDEVICEINFO4resok gdir_resok4; + count4 gdir_mincount; + } GETDEVICEINFO4res_u; +}; +typedef struct GETDEVICEINFO4res GETDEVICEINFO4res; + +struct GETDEVICELIST4args { + layouttype4 gdla_layout_type; + count4 gdla_maxdevices; + nfs_cookie4 gdla_cookie; + verifier4 gdla_cookieverf; +}; +typedef struct GETDEVICELIST4args GETDEVICELIST4args; + +struct GETDEVICELIST4resok { + nfs_cookie4 gdlr_cookie; + verifier4 gdlr_cookieverf; + struct { + uint32_t gdlr_deviceid_list_len; + deviceid4 *gdlr_deviceid_list_val; + } gdlr_deviceid_list; + uint32_t gdlr_eof; +}; +typedef struct GETDEVICELIST4resok GETDEVICELIST4resok; + +struct GETDEVICELIST4res { + nfsstat4 gdlr_status; + union { + GETDEVICELIST4resok gdlr_resok4; + } GETDEVICELIST4res_u; +}; +typedef struct GETDEVICELIST4res GETDEVICELIST4res; + +struct newtime4 { + uint32_t nt_timechanged; + union { + nfstime4 nt_time; + } newtime4_u; +}; +typedef struct newtime4 newtime4; + +struct newoffset4 { + uint32_t no_newoffset; + union { + offset4 no_offset; + } newoffset4_u; +}; +typedef struct newoffset4 newoffset4; + +struct LAYOUTCOMMIT4args { + offset4 loca_offset; + length4 loca_length; + uint32_t loca_reclaim; + stateid4 loca_stateid; + newoffset4 loca_last_write_offset; + newtime4 loca_time_modify; + layoutupdate4 loca_layoutupdate; +}; +typedef struct LAYOUTCOMMIT4args LAYOUTCOMMIT4args; + +struct newsize4 { + uint32_t ns_sizechanged; + union { + length4 ns_size; + } newsize4_u; +}; +typedef struct newsize4 newsize4; + +struct LAYOUTCOMMIT4resok { + newsize4 locr_newsize; +}; +typedef struct LAYOUTCOMMIT4resok LAYOUTCOMMIT4resok; + +struct LAYOUTCOMMIT4res { + nfsstat4 locr_status; + union { + LAYOUTCOMMIT4resok locr_resok4; + } LAYOUTCOMMIT4res_u; +}; +typedef struct LAYOUTCOMMIT4res LAYOUTCOMMIT4res; + +struct LAYOUTGET4args { + uint32_t loga_signal_layout_avail; + layouttype4 loga_layout_type; + layoutiomode4 loga_iomode; + offset4 loga_offset; + length4 loga_length; + length4 loga_minlength; + stateid4 loga_stateid; + count4 loga_maxcount; +}; +typedef struct LAYOUTGET4args LAYOUTGET4args; + +struct LAYOUTGET4resok { + uint32_t logr_return_on_close; + stateid4 logr_stateid; + struct { + uint32_t logr_layout_len; + layout4 *logr_layout_val; + } logr_layout; +}; +typedef struct LAYOUTGET4resok LAYOUTGET4resok; + +struct LAYOUTGET4res { + nfsstat4 logr_status; + union { + LAYOUTGET4resok logr_resok4; + uint32_t logr_will_signal_layout_avail; + } LAYOUTGET4res_u; +}; +typedef struct LAYOUTGET4res LAYOUTGET4res; +#define LAYOUT4_RET_REC_FILE 1 +#define LAYOUT4_RET_REC_FSID 2 +#define LAYOUT4_RET_REC_ALL 3 + +enum layoutreturn_type4 { + LAYOUTRETURN4_FILE = LAYOUT4_RET_REC_FILE, + LAYOUTRETURN4_FSID = LAYOUT4_RET_REC_FSID, + LAYOUTRETURN4_ALL = LAYOUT4_RET_REC_ALL, +}; +typedef enum layoutreturn_type4 layoutreturn_type4; + +struct layoutreturn_file4 { + offset4 lrf_offset; + length4 lrf_length; + stateid4 lrf_stateid; + struct { + uint32_t lrf_body_len; + char *lrf_body_val; + } lrf_body; +}; +typedef struct layoutreturn_file4 layoutreturn_file4; + +struct layoutreturn4 { + layoutreturn_type4 lr_returntype; + union { + layoutreturn_file4 lr_layout; + } layoutreturn4_u; +}; +typedef struct layoutreturn4 layoutreturn4; + +struct LAYOUTRETURN4args { + uint32_t lora_reclaim; + layouttype4 lora_layout_type; + layoutiomode4 lora_iomode; + layoutreturn4 lora_layoutreturn; +}; +typedef struct LAYOUTRETURN4args LAYOUTRETURN4args; + +struct layoutreturn_stateid { + uint32_t lrs_present; + union { + stateid4 lrs_stateid; + } layoutreturn_stateid_u; +}; +typedef struct layoutreturn_stateid layoutreturn_stateid; + +struct LAYOUTRETURN4res { + nfsstat4 lorr_status; + union { + layoutreturn_stateid lorr_stateid; + } LAYOUTRETURN4res_u; +}; +typedef struct LAYOUTRETURN4res LAYOUTRETURN4res; + +enum secinfo_style4 { + SECINFO_STYLE4_CURRENT_FH = 0, + SECINFO_STYLE4_PARENT = 1, +}; +typedef enum secinfo_style4 secinfo_style4; + +typedef secinfo_style4 SECINFO_NO_NAME4args; + +typedef SECINFO4res SECINFO_NO_NAME4res; + +struct SEQUENCE4args { + sessionid4 sa_sessionid; + sequenceid4 sa_sequenceid; + slotid4 sa_slotid; + slotid4 sa_highest_slotid; + uint32_t sa_cachethis; +}; +typedef struct SEQUENCE4args SEQUENCE4args; +#define SEQ4_STATUS_CB_PATH_DOWN 0x00000001 +#define SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING 0x00000002 +#define SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRED 0x00000004 +#define SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED 0x00000008 +#define SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED 0x00000010 +#define SEQ4_STATUS_ADMIN_STATE_REVOKED 0x00000020 +#define SEQ4_STATUS_RECALLABLE_STATE_REVOKED 0x00000040 +#define SEQ4_STATUS_LEASE_MOVED 0x00000080 +#define SEQ4_STATUS_RESTART_RECLAIM_NEEDED 0x00000100 +#define SEQ4_STATUS_CB_PATH_DOWN_SESSION 0x00000200 +#define SEQ4_STATUS_BACKCHANNEL_FAULT 0x00000400 +#define SEQ4_STATUS_DEVID_CHANGED 0x00000800 +#define SEQ4_STATUS_DEVID_DELETED 0x00001000 + +struct SEQUENCE4resok { + sessionid4 sr_sessionid; + sequenceid4 sr_sequenceid; + slotid4 sr_slotid; + slotid4 sr_highest_slotid; + slotid4 sr_target_highest_slotid; + uint32_t sr_status_flags; +}; +typedef struct SEQUENCE4resok SEQUENCE4resok; + +struct SEQUENCE4res { + nfsstat4 sr_status; + union { + SEQUENCE4resok sr_resok4; + } SEQUENCE4res_u; +}; +typedef struct SEQUENCE4res SEQUENCE4res; + +struct ssa_digest_input4 { + SEQUENCE4args sdi_seqargs; +}; +typedef struct ssa_digest_input4 ssa_digest_input4; + +struct SET_SSV4args { + struct { + uint32_t ssa_ssv_len; + char *ssa_ssv_val; + } ssa_ssv; + struct { + uint32_t ssa_digest_len; + char *ssa_digest_val; + } ssa_digest; +}; +typedef struct SET_SSV4args SET_SSV4args; + +struct ssr_digest_input4 { + SEQUENCE4res sdi_seqres; +}; +typedef struct ssr_digest_input4 ssr_digest_input4; + +struct SET_SSV4resok { + struct { + uint32_t ssr_digest_len; + char *ssr_digest_val; + } ssr_digest; +}; +typedef struct SET_SSV4resok SET_SSV4resok; + +struct SET_SSV4res { + nfsstat4 ssr_status; + union { + SET_SSV4resok ssr_resok4; + } SET_SSV4res_u; +}; +typedef struct SET_SSV4res SET_SSV4res; + +struct TEST_STATEID4args { + struct { + uint32_t ts_stateids_len; + stateid4 *ts_stateids_val; + } ts_stateids; +}; +typedef struct TEST_STATEID4args TEST_STATEID4args; + +struct TEST_STATEID4resok { + struct { + uint32_t tsr_status_codes_len; + nfsstat4 *tsr_status_codes_val; + } tsr_status_codes; +}; +typedef struct TEST_STATEID4resok TEST_STATEID4resok; + +struct TEST_STATEID4res { + nfsstat4 tsr_status; + union { + TEST_STATEID4resok tsr_resok4; + } TEST_STATEID4res_u; +}; +typedef struct TEST_STATEID4res TEST_STATEID4res; + +struct deleg_claim4 { + open_claim_type4 dc_claim; + union { + open_delegation_type4 dc_delegate_type; + } deleg_claim4_u; +}; +typedef struct deleg_claim4 deleg_claim4; + +struct WANT_DELEGATION4args { + uint32_t wda_want; + deleg_claim4 wda_claim; +}; +typedef struct WANT_DELEGATION4args WANT_DELEGATION4args; + +struct WANT_DELEGATION4res { + nfsstat4 wdr_status; + union { + open_delegation4 wdr_resok4; + } WANT_DELEGATION4res_u; +}; +typedef struct WANT_DELEGATION4res WANT_DELEGATION4res; + +struct DESTROY_CLIENTID4args { + clientid4 dca_clientid; +}; +typedef struct DESTROY_CLIENTID4args DESTROY_CLIENTID4args; + +struct DESTROY_CLIENTID4res { + nfsstat4 dcr_status; +}; +typedef struct DESTROY_CLIENTID4res DESTROY_CLIENTID4res; + +struct RECLAIM_COMPLETE4args { + uint32_t rca_one_fs; +}; +typedef struct RECLAIM_COMPLETE4args RECLAIM_COMPLETE4args; + +struct RECLAIM_COMPLETE4res { + nfsstat4 rcr_status; +}; +typedef struct RECLAIM_COMPLETE4res RECLAIM_COMPLETE4res; + +struct ILLEGAL4res { + nfsstat4 status; +}; +typedef struct ILLEGAL4res ILLEGAL4res; + +enum nfs_opnum4 { + OP_ACCESS = 3, + OP_CLOSE = 4, + OP_COMMIT = 5, + OP_CREATE = 6, + OP_DELEGPURGE = 7, + OP_DELEGRETURN = 8, + OP_GETATTR = 9, + OP_GETFH = 10, + OP_LINK = 11, + OP_LOCK = 12, + OP_LOCKT = 13, + OP_LOCKU = 14, + OP_LOOKUP = 15, + OP_LOOKUPP = 16, + OP_NVERIFY = 17, + OP_OPEN = 18, + OP_OPENATTR = 19, + OP_OPEN_CONFIRM = 20, + OP_OPEN_DOWNGRADE = 21, + OP_PUTFH = 22, + OP_PUTPUBFH = 23, + OP_PUTROOTFH = 24, + OP_READ = 25, + OP_READDIR = 26, + OP_READLINK = 27, + OP_REMOVE = 28, + OP_RENAME = 29, + OP_RENEW = 30, + OP_RESTOREFH = 31, + OP_SAVEFH = 32, + OP_SECINFO = 33, + OP_SETATTR = 34, + OP_SETCLIENTID = 35, + OP_SETCLIENTID_CONFIRM = 36, + OP_VERIFY = 37, + OP_WRITE = 38, + OP_RELEASE_LOCKOWNER = 39, + OP_BIND_CONN_TO_SESSION = 41, + OP_EXCHANGE_ID = 42, + OP_CREATE_SESSION = 43, + OP_DESTROY_SESSION = 44, + OP_FREE_STATEID = 45, + OP_GET_DIR_DELEGATION = 46, + OP_GETDEVICEINFO = 47, + OP_GETDEVICELIST = 48, + OP_LAYOUTCOMMIT = 49, + OP_LAYOUTGET = 50, + OP_LAYOUTRETURN = 51, + OP_SECINFO_NO_NAME = 52, + OP_SEQUENCE = 53, + OP_SET_SSV = 54, + OP_TEST_STATEID = 55, + OP_WANT_DELEGATION = 56, + OP_DESTROY_CLIENTID = 57, + OP_RECLAIM_COMPLETE = 58, + OP_ILLEGAL = 10044, +}; +typedef enum nfs_opnum4 nfs_opnum4; + +struct nfs_argop4 { + nfs_opnum4 argop; + union { + ACCESS4args opaccess; + CLOSE4args opclose; + COMMIT4args opcommit; + CREATE4args opcreate; + DELEGPURGE4args opdelegpurge; + DELEGRETURN4args opdelegreturn; + GETATTR4args opgetattr; + LINK4args oplink; + LOCK4args oplock; + LOCKT4args oplockt; + LOCKU4args oplocku; + LOOKUP4args oplookup; + NVERIFY4args opnverify; + OPEN4args opopen; + OPENATTR4args opopenattr; + OPEN_CONFIRM4args opopen_confirm; + OPEN_DOWNGRADE4args opopen_downgrade; + PUTFH4args opputfh; + READ4args opread; + READDIR4args opreaddir; + REMOVE4args opremove; + RENAME4args oprename; + RENEW4args oprenew; + SECINFO4args opsecinfo; + SETATTR4args opsetattr; + SETCLIENTID4args opsetclientid; + SETCLIENTID_CONFIRM4args opsetclientid_confirm; + VERIFY4args opverify; + WRITE4args opwrite; + RELEASE_LOCKOWNER4args oprelease_lockowner; + BIND_CONN_TO_SESSION4args opbindconntosession; + EXCHANGE_ID4args opexchangeid; + CREATE_SESSION4args opcreatesession; + DESTROY_SESSION4args opdestroysession; + FREE_STATEID4args opfreestateid; + GET_DIR_DELEGATION4args opgetdirdelegation; + GETDEVICEINFO4args opgetdeviceinfo; + GETDEVICELIST4args opgetdevicelist; + LAYOUTCOMMIT4args oplayoutcommit; + LAYOUTGET4args oplayoutget; + LAYOUTRETURN4args oplayoutreturn; + SECINFO_NO_NAME4args opsecinfononame; + SEQUENCE4args opsequence; + SET_SSV4args opsetssv; + TEST_STATEID4args opteststateid; + WANT_DELEGATION4args opwantdelegation; + DESTROY_CLIENTID4args opdestroyclientid; + RECLAIM_COMPLETE4args opreclaimcomplete; + } nfs_argop4_u; +}; +typedef struct nfs_argop4 nfs_argop4; + +struct nfs_resop4 { + nfs_opnum4 resop; + union { + ACCESS4res opaccess; + CLOSE4res opclose; + COMMIT4res opcommit; + CREATE4res opcreate; + DELEGPURGE4res opdelegpurge; + DELEGRETURN4res opdelegreturn; + GETATTR4res opgetattr; + GETFH4res opgetfh; + LINK4res oplink; + LOCK4res oplock; + LOCKT4res oplockt; + LOCKU4res oplocku; + LOOKUP4res oplookup; + LOOKUPP4res oplookupp; + NVERIFY4res opnverify; + OPEN4res opopen; + OPENATTR4res opopenattr; + OPEN_CONFIRM4res opopen_confirm; + OPEN_DOWNGRADE4res opopen_downgrade; + PUTFH4res opputfh; + PUTPUBFH4res opputpubfh; + PUTROOTFH4res opputrootfh; + READ4res opread; + READDIR4res opreaddir; + READLINK4res opreadlink; + REMOVE4res opremove; + RENAME4res oprename; + RENEW4res oprenew; + RESTOREFH4res oprestorefh; + SAVEFH4res opsavefh; + SECINFO4res opsecinfo; + SETATTR4res opsetattr; + SETCLIENTID4res opsetclientid; + SETCLIENTID_CONFIRM4res opsetclientid_confirm; + VERIFY4res opverify; + WRITE4res opwrite; + RELEASE_LOCKOWNER4res oprelease_lockowner; + BIND_CONN_TO_SESSION4res opbindconntosession; + EXCHANGE_ID4res opexchangeid; + CREATE_SESSION4res opcreatesession; + DESTROY_SESSION4res opdestroysession; + FREE_STATEID4res opfreestateid; + GET_DIR_DELEGATION4res opgetdirdelegation; + GETDEVICEINFO4res opgetdeviceinfo; + GETDEVICELIST4res opgetdevicelist; + LAYOUTCOMMIT4res oplayoutcommit; + LAYOUTGET4res oplayoutget; + LAYOUTRETURN4res oplayoutreturn; + SECINFO_NO_NAME4res opsecinfononame; + SEQUENCE4res opsequence; + SET_SSV4res opsetssv; + TEST_STATEID4res opteststateid; + WANT_DELEGATION4res opwantdelegation; + DESTROY_CLIENTID4res opdestroyclientid; + RECLAIM_COMPLETE4res opreclaimcomplete; + ILLEGAL4res opillegal; + } nfs_resop4_u; +}; +typedef struct nfs_resop4 nfs_resop4; + +struct COMPOUND4args { + utf8str_cs tag; + uint32_t minorversion; + struct { + uint32_t argarray_len; + nfs_argop4 *argarray_val; + } argarray; +}; +typedef struct COMPOUND4args COMPOUND4args; + +struct COMPOUND4res { + nfsstat4 status; + utf8str_cs tag; + struct { + uint32_t resarray_len; + nfs_resop4 *resarray_val; + } resarray; +}; +typedef struct COMPOUND4res COMPOUND4res; + +struct CB_GETATTR4args { + nfs_fh4 fh; + bitmap4 attr_request; +}; +typedef struct CB_GETATTR4args CB_GETATTR4args; + +struct CB_GETATTR4resok { + fattr4 obj_attributes; +}; +typedef struct CB_GETATTR4resok CB_GETATTR4resok; + +struct CB_GETATTR4res { + nfsstat4 status; + union { + CB_GETATTR4resok resok4; + } CB_GETATTR4res_u; +}; +typedef struct CB_GETATTR4res CB_GETATTR4res; + +struct CB_RECALL4args { + stateid4 stateid; + uint32_t truncate; + nfs_fh4 fh; +}; +typedef struct CB_RECALL4args CB_RECALL4args; + +struct CB_RECALL4res { + nfsstat4 status; +}; +typedef struct CB_RECALL4res CB_RECALL4res; + +struct CB_ILLEGAL4res { + nfsstat4 status; +}; +typedef struct CB_ILLEGAL4res CB_ILLEGAL4res; + +enum nfs_cb_opnum4 { + OP_CB_GETATTR = 3, + OP_CB_RECALL = 4, + OP_CB_ILLEGAL = 10044, +}; +typedef enum nfs_cb_opnum4 nfs_cb_opnum4; + +struct nfs_cb_argop4 { + uint32_t argop; + union { + CB_GETATTR4args opcbgetattr; + CB_RECALL4args opcbrecall; + } nfs_cb_argop4_u; +}; +typedef struct nfs_cb_argop4 nfs_cb_argop4; + +struct nfs_cb_resop4 { + uint32_t resop; + union { + CB_GETATTR4res opcbgetattr; + CB_RECALL4res opcbrecall; + CB_ILLEGAL4res opcbillegal; + } nfs_cb_resop4_u; +}; +typedef struct nfs_cb_resop4 nfs_cb_resop4; + +struct CB_COMPOUND4args { + utf8str_cs tag; + uint32_t minorversion; + uint32_t callback_ident; + struct { + uint32_t argarray_len; + nfs_cb_argop4 *argarray_val; + } argarray; +}; +typedef struct CB_COMPOUND4args CB_COMPOUND4args; + +struct CB_COMPOUND4res { + nfsstat4 status; + utf8str_cs tag; + struct { + uint32_t resarray_len; + nfs_cb_resop4 *resarray_val; + } resarray; +}; +typedef struct CB_COMPOUND4res CB_COMPOUND4res; + +enum rpc_gss_proc_t { + RPCSEC_GSS_DATA = 0, + RPCSEC_GSS_INIT = 1, + RPCSEC_GSS_CONTINUE_INIT = 2, + RPCSEC_GSS_DESTROY = 3, +}; +typedef enum rpc_gss_proc_t rpc_gss_proc_t; + +struct rpc_gss_cred_vers_1_t { + rpc_gss_proc_t gss_proc; + uint32_t seq_num; + rpc_gss_svc_t service; + struct { + uint32_t handle_len; + char *handle_val; + } handle; +}; +typedef struct rpc_gss_cred_vers_1_t rpc_gss_cred_vers_1_t; +#define RPCSEC_GSS_VERS_1 1 + +struct rpc_gss_cred_t { + uint32_t vers; + union { + rpc_gss_cred_vers_1_t rpc_gss_cred_vers_1_t; + } rpc_gss_cred_t_u; +}; +typedef struct rpc_gss_cred_t rpc_gss_cred_t; + +struct rpc_gss_init_arg { + struct { + uint32_t gss_token_len; + char *gss_token_val; + } gss_token; +}; +typedef struct rpc_gss_init_arg rpc_gss_init_arg; + +struct rpc_gss_init_res { + struct { + uint32_t handle_len; + char *handle_val; + } handle; + uint32_t gss_major; + uint32_t gss_minor; + uint32_t seq_window; + struct { + uint32_t gss_token_len; + char *gss_token_val; + } gss_token; +}; +typedef struct rpc_gss_init_res rpc_gss_init_res; + +struct rpc_gss_integ_data { + struct { + uint32_t databody_integ_len; + char *databody_integ_val; + } databody_integ; + struct { + uint32_t checksum_len; + char *checksum_val; + } checksum; +}; +typedef struct rpc_gss_integ_data rpc_gss_integ_data; + +#define NFS4_PROGRAM 100003 +#define NFS_V4 4 + +#if defined(__STDC__) || defined(__cplusplus) +#define NFSPROC4_NULL 0 +extern void * nfsproc4_null_4(void *, void *); +extern void * nfsproc4_null_4_svc(void *, struct svc_req *); +#define NFSPROC4_COMPOUND 1 +extern COMPOUND4res * nfsproc4_compound_4(COMPOUND4args *, void *); +extern COMPOUND4res * nfsproc4_compound_4_svc(COMPOUND4args *, struct svc_req *); +extern int nfs4_program_4_freeresult (void *, zdrproc_t, caddr_t); + +#else /* K&R C */ +#define NFSPROC4_NULL 0 +extern void * nfsproc4_null_4(); +extern void * nfsproc4_null_4_svc(); +#define NFSPROC4_COMPOUND 1 +extern COMPOUND4res * nfsproc4_compound_4(); +extern COMPOUND4res * nfsproc4_compound_4_svc(); +extern int nfs4_program_4_freeresult (); +#endif /* K&R C */ + +#define NFS4_CALLBACK 0x40000000 +#define NFS_CB 1 + +#if defined(__STDC__) || defined(__cplusplus) +#define CB_NULL 0 +extern void * cb_null_1(void *, void *); +extern void * cb_null_1_svc(void *, struct svc_req *); +#define CB_COMPOUND 1 +extern CB_COMPOUND4res * cb_compound_1(CB_COMPOUND4args *, void *); +extern CB_COMPOUND4res * cb_compound_1_svc(CB_COMPOUND4args *, struct svc_req *); +extern int nfs4_callback_1_freeresult (void *, zdrproc_t, caddr_t); + +#else /* K&R C */ +#define CB_NULL 0 +extern void * cb_null_1(); +extern void * cb_null_1_svc(); +#define CB_COMPOUND 1 +extern CB_COMPOUND4res * cb_compound_1(); +extern CB_COMPOUND4res * cb_compound_1_svc(); +extern int nfs4_callback_1_freeresult (); +#endif /* K&R C */ + +/* the zdr functions */ + +#if defined(__STDC__) || defined(__cplusplus) +extern uint32_t zdr_nfs_ftype4 (ZDR *, nfs_ftype4*); +extern uint32_t zdr_nfsstat4 (ZDR *, nfsstat4*); +extern uint32_t zdr_bitmap4 (ZDR *, bitmap4*); +extern uint32_t zdr_offset4 (ZDR *, offset4*); +extern uint32_t zdr_count4 (ZDR *, count4*); +extern uint32_t zdr_length4 (ZDR *, length4*); +extern uint32_t zdr_clientid4 (ZDR *, clientid4*); +extern uint32_t zdr_sequenceid4 (ZDR *, sequenceid4*); +extern uint32_t zdr_seqid4 (ZDR *, seqid4*); +extern uint32_t zdr_slotid4 (ZDR *, slotid4*); +extern uint32_t zdr_utf8string (ZDR *, utf8string*); +extern uint32_t zdr_utf8str_cis (ZDR *, utf8str_cis*); +extern uint32_t zdr_utf8str_cs (ZDR *, utf8str_cs*); +extern uint32_t zdr_utf8str_mixed (ZDR *, utf8str_mixed*); +extern uint32_t zdr_component4 (ZDR *, component4*); +extern uint32_t zdr_pathname4 (ZDR *, pathname4*); +extern uint32_t zdr_nfs_lockid4 (ZDR *, nfs_lockid4*); +extern uint32_t zdr_nfs_cookie4 (ZDR *, nfs_cookie4*); +extern uint32_t zdr_linktext4 (ZDR *, linktext4*); +extern uint32_t zdr_sec_oid4 (ZDR *, sec_oid4*); +extern uint32_t zdr_qop4 (ZDR *, qop4*); +extern uint32_t zdr_mode4 (ZDR *, mode4*); +extern uint32_t zdr_changeid4 (ZDR *, changeid4*); +extern uint32_t zdr_verifier4 (ZDR *, verifier4); +extern uint32_t zdr_sessionid4 (ZDR *, sessionid4); +extern uint32_t zdr_authsys_parms (ZDR *, authsys_parms*); +extern uint32_t zdr_deviceid4 (ZDR *, deviceid4); +extern uint32_t zdr_layouttype4 (ZDR *, layouttype4*); +extern uint32_t zdr_layoutupdate4 (ZDR *, layoutupdate4*); +extern uint32_t zdr_device_addr4 (ZDR *, device_addr4*); +extern uint32_t zdr_nfstime4 (ZDR *, nfstime4*); +extern uint32_t zdr_time_how4 (ZDR *, time_how4*); +extern uint32_t zdr_layoutiomode4 (ZDR *, layoutiomode4*); +extern uint32_t zdr_layout_content4 (ZDR *, layout_content4*); +extern uint32_t zdr_layout4 (ZDR *, layout4*); +extern uint32_t zdr_settime4 (ZDR *, settime4*); +extern uint32_t zdr_nfs_fh4 (ZDR *, nfs_fh4*); +extern uint32_t zdr_fsid4 (ZDR *, fsid4*); +extern uint32_t zdr_fs_location4 (ZDR *, fs_location4*); +extern uint32_t zdr_fs_locations4 (ZDR *, fs_locations4*); +extern uint32_t zdr_acetype4 (ZDR *, acetype4*); +extern uint32_t zdr_aceflag4 (ZDR *, aceflag4*); +extern uint32_t zdr_acemask4 (ZDR *, acemask4*); +extern uint32_t zdr_nfsace4 (ZDR *, nfsace4*); +extern uint32_t zdr_specdata4 (ZDR *, specdata4*); +extern uint32_t zdr_fattr4_supported_attrs (ZDR *, fattr4_supported_attrs*); +extern uint32_t zdr_fattr4_type (ZDR *, fattr4_type*); +extern uint32_t zdr_fattr4_fh_expire_type (ZDR *, fattr4_fh_expire_type*); +extern uint32_t zdr_fattr4_change (ZDR *, fattr4_change*); +extern uint32_t zdr_fattr4_size (ZDR *, fattr4_size*); +extern uint32_t zdr_fattr4_link_support (ZDR *, fattr4_link_support*); +extern uint32_t zdr_fattr4_symlink_support (ZDR *, fattr4_symlink_support*); +extern uint32_t zdr_fattr4_named_attr (ZDR *, fattr4_named_attr*); +extern uint32_t zdr_fattr4_fsid (ZDR *, fattr4_fsid*); +extern uint32_t zdr_fattr4_unique_handles (ZDR *, fattr4_unique_handles*); +extern uint32_t zdr_fattr4_lease_time (ZDR *, fattr4_lease_time*); +extern uint32_t zdr_fattr4_rdattr_error (ZDR *, fattr4_rdattr_error*); +extern uint32_t zdr_fattr4_acl (ZDR *, fattr4_acl*); +extern uint32_t zdr_fattr4_aclsupport (ZDR *, fattr4_aclsupport*); +extern uint32_t zdr_fattr4_archive (ZDR *, fattr4_archive*); +extern uint32_t zdr_fattr4_cansettime (ZDR *, fattr4_cansettime*); +extern uint32_t zdr_fattr4_case_insensitive (ZDR *, fattr4_case_insensitive*); +extern uint32_t zdr_fattr4_case_preserving (ZDR *, fattr4_case_preserving*); +extern uint32_t zdr_fattr4_chown_restricted (ZDR *, fattr4_chown_restricted*); +extern uint32_t zdr_fattr4_fileid (ZDR *, fattr4_fileid*); +extern uint32_t zdr_fattr4_files_avail (ZDR *, fattr4_files_avail*); +extern uint32_t zdr_fattr4_filehandle (ZDR *, fattr4_filehandle*); +extern uint32_t zdr_fattr4_files_free (ZDR *, fattr4_files_free*); +extern uint32_t zdr_fattr4_files_total (ZDR *, fattr4_files_total*); +extern uint32_t zdr_fattr4_fs_locations (ZDR *, fattr4_fs_locations*); +extern uint32_t zdr_fattr4_hidden (ZDR *, fattr4_hidden*); +extern uint32_t zdr_fattr4_homogeneous (ZDR *, fattr4_homogeneous*); +extern uint32_t zdr_fattr4_maxfilesize (ZDR *, fattr4_maxfilesize*); +extern uint32_t zdr_fattr4_maxlink (ZDR *, fattr4_maxlink*); +extern uint32_t zdr_fattr4_maxname (ZDR *, fattr4_maxname*); +extern uint32_t zdr_fattr4_maxread (ZDR *, fattr4_maxread*); +extern uint32_t zdr_fattr4_maxwrite (ZDR *, fattr4_maxwrite*); +extern uint32_t zdr_fattr4_mimetype (ZDR *, fattr4_mimetype*); +extern uint32_t zdr_fattr4_mode (ZDR *, fattr4_mode*); +extern uint32_t zdr_fattr4_mounted_on_fileid (ZDR *, fattr4_mounted_on_fileid*); +extern uint32_t zdr_fattr4_no_trunc (ZDR *, fattr4_no_trunc*); +extern uint32_t zdr_fattr4_numlinks (ZDR *, fattr4_numlinks*); +extern uint32_t zdr_fattr4_owner (ZDR *, fattr4_owner*); +extern uint32_t zdr_fattr4_owner_group (ZDR *, fattr4_owner_group*); +extern uint32_t zdr_fattr4_quota_avail_hard (ZDR *, fattr4_quota_avail_hard*); +extern uint32_t zdr_fattr4_quota_avail_soft (ZDR *, fattr4_quota_avail_soft*); +extern uint32_t zdr_fattr4_quota_used (ZDR *, fattr4_quota_used*); +extern uint32_t zdr_fattr4_rawdev (ZDR *, fattr4_rawdev*); +extern uint32_t zdr_fattr4_space_avail (ZDR *, fattr4_space_avail*); +extern uint32_t zdr_fattr4_space_free (ZDR *, fattr4_space_free*); +extern uint32_t zdr_fattr4_space_total (ZDR *, fattr4_space_total*); +extern uint32_t zdr_fattr4_space_used (ZDR *, fattr4_space_used*); +extern uint32_t zdr_fattr4_system (ZDR *, fattr4_system*); +extern uint32_t zdr_fattr4_time_access (ZDR *, fattr4_time_access*); +extern uint32_t zdr_fattr4_time_access_set (ZDR *, fattr4_time_access_set*); +extern uint32_t zdr_fattr4_time_backup (ZDR *, fattr4_time_backup*); +extern uint32_t zdr_fattr4_time_create (ZDR *, fattr4_time_create*); +extern uint32_t zdr_fattr4_time_delta (ZDR *, fattr4_time_delta*); +extern uint32_t zdr_fattr4_time_metadata (ZDR *, fattr4_time_metadata*); +extern uint32_t zdr_fattr4_time_modify (ZDR *, fattr4_time_modify*); +extern uint32_t zdr_fattr4_time_modify_set (ZDR *, fattr4_time_modify_set*); +extern uint32_t zdr_attrlist4 (ZDR *, attrlist4*); +extern uint32_t zdr_fattr4 (ZDR *, fattr4*); +extern uint32_t zdr_change_info4 (ZDR *, change_info4*); +extern uint32_t zdr_clientaddr4 (ZDR *, clientaddr4*); +extern uint32_t zdr_cb_client4 (ZDR *, cb_client4*); +extern uint32_t zdr_stateid4 (ZDR *, stateid4*); +extern uint32_t zdr_nfs_client_id4 (ZDR *, nfs_client_id4*); +extern uint32_t zdr_open_owner4 (ZDR *, open_owner4*); +extern uint32_t zdr_lock_owner4 (ZDR *, lock_owner4*); +extern uint32_t zdr_nfs_lock_type4 (ZDR *, nfs_lock_type4*); +extern uint32_t zdr_client_owner4 (ZDR *, client_owner4*); +extern uint32_t zdr_server_owner4 (ZDR *, server_owner4*); +extern uint32_t zdr_nfs_impl_id4 (ZDR *, nfs_impl_id4*); +extern uint32_t zdr_ACCESS4args (ZDR *, ACCESS4args*); +extern uint32_t zdr_ACCESS4resok (ZDR *, ACCESS4resok*); +extern uint32_t zdr_ACCESS4res (ZDR *, ACCESS4res*); +extern uint32_t zdr_CLOSE4args (ZDR *, CLOSE4args*); +extern uint32_t zdr_CLOSE4res (ZDR *, CLOSE4res*); +extern uint32_t zdr_COMMIT4args (ZDR *, COMMIT4args*); +extern uint32_t zdr_COMMIT4resok (ZDR *, COMMIT4resok*); +extern uint32_t zdr_COMMIT4res (ZDR *, COMMIT4res*); +extern uint32_t zdr_createtype4 (ZDR *, createtype4*); +extern uint32_t zdr_CREATE4args (ZDR *, CREATE4args*); +extern uint32_t zdr_CREATE4resok (ZDR *, CREATE4resok*); +extern uint32_t zdr_CREATE4res (ZDR *, CREATE4res*); +extern uint32_t zdr_DELEGPURGE4args (ZDR *, DELEGPURGE4args*); +extern uint32_t zdr_DELEGPURGE4res (ZDR *, DELEGPURGE4res*); +extern uint32_t zdr_DELEGRETURN4args (ZDR *, DELEGRETURN4args*); +extern uint32_t zdr_DELEGRETURN4res (ZDR *, DELEGRETURN4res*); +extern uint32_t zdr_GETATTR4args (ZDR *, GETATTR4args*); +extern uint32_t zdr_GETATTR4resok (ZDR *, GETATTR4resok*); +extern uint32_t zdr_GETATTR4res (ZDR *, GETATTR4res*); +extern uint32_t zdr_GETFH4resok (ZDR *, GETFH4resok*); +extern uint32_t zdr_GETFH4res (ZDR *, GETFH4res*); +extern uint32_t zdr_LINK4args (ZDR *, LINK4args*); +extern uint32_t zdr_LINK4resok (ZDR *, LINK4resok*); +extern uint32_t zdr_LINK4res (ZDR *, LINK4res*); +extern uint32_t zdr_open_to_lock_owner4 (ZDR *, open_to_lock_owner4*); +extern uint32_t zdr_exist_lock_owner4 (ZDR *, exist_lock_owner4*); +extern uint32_t zdr_locker4 (ZDR *, locker4*); +extern uint32_t zdr_LOCK4args (ZDR *, LOCK4args*); +extern uint32_t zdr_LOCK4denied (ZDR *, LOCK4denied*); +extern uint32_t zdr_LOCK4resok (ZDR *, LOCK4resok*); +extern uint32_t zdr_LOCK4res (ZDR *, LOCK4res*); +extern uint32_t zdr_LOCKT4args (ZDR *, LOCKT4args*); +extern uint32_t zdr_LOCKT4res (ZDR *, LOCKT4res*); +extern uint32_t zdr_LOCKU4args (ZDR *, LOCKU4args*); +extern uint32_t zdr_LOCKU4res (ZDR *, LOCKU4res*); +extern uint32_t zdr_LOOKUP4args (ZDR *, LOOKUP4args*); +extern uint32_t zdr_LOOKUP4res (ZDR *, LOOKUP4res*); +extern uint32_t zdr_LOOKUPP4res (ZDR *, LOOKUPP4res*); +extern uint32_t zdr_NVERIFY4args (ZDR *, NVERIFY4args*); +extern uint32_t zdr_NVERIFY4res (ZDR *, NVERIFY4res*); +extern uint32_t zdr_createmode4 (ZDR *, createmode4*); +extern uint32_t zdr_createhow4 (ZDR *, createhow4*); +extern uint32_t zdr_opentype4 (ZDR *, opentype4*); +extern uint32_t zdr_openflag4 (ZDR *, openflag4*); +extern uint32_t zdr_limit_by4 (ZDR *, limit_by4*); +extern uint32_t zdr_nfs_modified_limit4 (ZDR *, nfs_modified_limit4*); +extern uint32_t zdr_nfs_space_limit4 (ZDR *, nfs_space_limit4*); +extern uint32_t zdr_open_delegation_type4 (ZDR *, open_delegation_type4*); +extern uint32_t zdr_open_claim_type4 (ZDR *, open_claim_type4*); +extern uint32_t zdr_open_claim_delegate_cur4 (ZDR *, open_claim_delegate_cur4*); +extern uint32_t zdr_open_claim4 (ZDR *, open_claim4*); +extern uint32_t zdr_OPEN4args (ZDR *, OPEN4args*); +extern uint32_t zdr_open_read_delegation4 (ZDR *, open_read_delegation4*); +extern uint32_t zdr_open_write_delegation4 (ZDR *, open_write_delegation4*); +extern uint32_t zdr_open_delegation4 (ZDR *, open_delegation4*); +extern uint32_t zdr_OPEN4resok (ZDR *, OPEN4resok*); +extern uint32_t zdr_OPEN4res (ZDR *, OPEN4res*); +extern uint32_t zdr_OPENATTR4args (ZDR *, OPENATTR4args*); +extern uint32_t zdr_OPENATTR4res (ZDR *, OPENATTR4res*); +extern uint32_t zdr_OPEN_CONFIRM4args (ZDR *, OPEN_CONFIRM4args*); +extern uint32_t zdr_OPEN_CONFIRM4resok (ZDR *, OPEN_CONFIRM4resok*); +extern uint32_t zdr_OPEN_CONFIRM4res (ZDR *, OPEN_CONFIRM4res*); +extern uint32_t zdr_OPEN_DOWNGRADE4args (ZDR *, OPEN_DOWNGRADE4args*); +extern uint32_t zdr_OPEN_DOWNGRADE4resok (ZDR *, OPEN_DOWNGRADE4resok*); +extern uint32_t zdr_OPEN_DOWNGRADE4res (ZDR *, OPEN_DOWNGRADE4res*); +extern uint32_t zdr_PUTFH4args (ZDR *, PUTFH4args*); +extern uint32_t zdr_PUTFH4res (ZDR *, PUTFH4res*); +extern uint32_t zdr_PUTPUBFH4res (ZDR *, PUTPUBFH4res*); +extern uint32_t zdr_PUTROOTFH4res (ZDR *, PUTROOTFH4res*); +extern uint32_t zdr_READ4args (ZDR *, READ4args*); +extern uint32_t zdr_READ4resok (ZDR *, READ4resok*); +extern uint32_t zdr_READ4res (ZDR *, READ4res*); +extern uint32_t zdr_READDIR4args (ZDR *, READDIR4args*); +extern uint32_t zdr_entry4 (ZDR *, entry4*); +extern uint32_t zdr_dirlist4 (ZDR *, dirlist4*); +extern uint32_t zdr_READDIR4resok (ZDR *, READDIR4resok*); +extern uint32_t zdr_READDIR4res (ZDR *, READDIR4res*); +extern uint32_t zdr_READLINK4resok (ZDR *, READLINK4resok*); +extern uint32_t zdr_READLINK4res (ZDR *, READLINK4res*); +extern uint32_t zdr_REMOVE4args (ZDR *, REMOVE4args*); +extern uint32_t zdr_REMOVE4resok (ZDR *, REMOVE4resok*); +extern uint32_t zdr_REMOVE4res (ZDR *, REMOVE4res*); +extern uint32_t zdr_RENAME4args (ZDR *, RENAME4args*); +extern uint32_t zdr_RENAME4resok (ZDR *, RENAME4resok*); +extern uint32_t zdr_RENAME4res (ZDR *, RENAME4res*); +extern uint32_t zdr_RENEW4args (ZDR *, RENEW4args*); +extern uint32_t zdr_RENEW4res (ZDR *, RENEW4res*); +extern uint32_t zdr_RESTOREFH4res (ZDR *, RESTOREFH4res*); +extern uint32_t zdr_SAVEFH4res (ZDR *, SAVEFH4res*); +extern uint32_t zdr_SECINFO4args (ZDR *, SECINFO4args*); +extern uint32_t zdr_rpc_gss_svc_t (ZDR *, rpc_gss_svc_t*); +extern uint32_t zdr_rpcsec_gss_info (ZDR *, rpcsec_gss_info*); +extern uint32_t zdr_secinfo4 (ZDR *, secinfo4*); +extern uint32_t zdr_SECINFO4resok (ZDR *, SECINFO4resok*); +extern uint32_t zdr_SECINFO4res (ZDR *, SECINFO4res*); +extern uint32_t zdr_SETATTR4args (ZDR *, SETATTR4args*); +extern uint32_t zdr_SETATTR4res (ZDR *, SETATTR4res*); +extern uint32_t zdr_SETCLIENTID4args (ZDR *, SETCLIENTID4args*); +extern uint32_t zdr_SETCLIENTID4resok (ZDR *, SETCLIENTID4resok*); +extern uint32_t zdr_SETCLIENTID4res (ZDR *, SETCLIENTID4res*); +extern uint32_t zdr_SETCLIENTID_CONFIRM4args (ZDR *, SETCLIENTID_CONFIRM4args*); +extern uint32_t zdr_SETCLIENTID_CONFIRM4res (ZDR *, SETCLIENTID_CONFIRM4res*); +extern uint32_t zdr_VERIFY4args (ZDR *, VERIFY4args*); +extern uint32_t zdr_VERIFY4res (ZDR *, VERIFY4res*); +extern uint32_t zdr_stable_how4 (ZDR *, stable_how4*); +extern uint32_t zdr_WRITE4args (ZDR *, WRITE4args*); +extern uint32_t zdr_WRITE4resok (ZDR *, WRITE4resok*); +extern uint32_t zdr_WRITE4res (ZDR *, WRITE4res*); +extern uint32_t zdr_RELEASE_LOCKOWNER4args (ZDR *, RELEASE_LOCKOWNER4args*); +extern uint32_t zdr_RELEASE_LOCKOWNER4res (ZDR *, RELEASE_LOCKOWNER4res*); +extern uint32_t zdr_gsshandle4_t (ZDR *, gsshandle4_t*); +extern uint32_t zdr_callback_sec_parms4 (ZDR *, callback_sec_parms4*); +extern uint32_t zdr_channel_dir_from_client4 (ZDR *, channel_dir_from_client4*); +extern uint32_t zdr_BIND_CONN_TO_SESSION4args (ZDR *, BIND_CONN_TO_SESSION4args*); +extern uint32_t zdr_channel_dir_from_server4 (ZDR *, channel_dir_from_server4*); +extern uint32_t zdr_BIND_CONN_TO_SESSION4resok (ZDR *, BIND_CONN_TO_SESSION4resok*); +extern uint32_t zdr_BIND_CONN_TO_SESSION4res (ZDR *, BIND_CONN_TO_SESSION4res*); +extern uint32_t zdr_state_protect_ops4 (ZDR *, state_protect_ops4*); +extern uint32_t zdr_ssv_sp_parms4 (ZDR *, ssv_sp_parms4*); +extern uint32_t zdr_state_protect_how4 (ZDR *, state_protect_how4*); +extern uint32_t zdr_state_protect4_a (ZDR *, state_protect4_a*); +extern uint32_t zdr_EXCHANGE_ID4args (ZDR *, EXCHANGE_ID4args*); +extern uint32_t zdr_ssv_prot_info4 (ZDR *, ssv_prot_info4*); +extern uint32_t zdr_state_protect4_r (ZDR *, state_protect4_r*); +extern uint32_t zdr_EXCHANGE_ID4resok (ZDR *, EXCHANGE_ID4resok*); +extern uint32_t zdr_EXCHANGE_ID4res (ZDR *, EXCHANGE_ID4res*); +extern uint32_t zdr_channel_attrs4 (ZDR *, channel_attrs4*); +extern uint32_t zdr_CREATE_SESSION4args (ZDR *, CREATE_SESSION4args*); +extern uint32_t zdr_CREATE_SESSION4resok (ZDR *, CREATE_SESSION4resok*); +extern uint32_t zdr_CREATE_SESSION4res (ZDR *, CREATE_SESSION4res*); +extern uint32_t zdr_DESTROY_SESSION4args (ZDR *, DESTROY_SESSION4args*); +extern uint32_t zdr_DESTROY_SESSION4res (ZDR *, DESTROY_SESSION4res*); +extern uint32_t zdr_FREE_STATEID4args (ZDR *, FREE_STATEID4args*); +extern uint32_t zdr_FREE_STATEID4res (ZDR *, FREE_STATEID4res*); +extern uint32_t zdr_attr_notice4 (ZDR *, attr_notice4*); +extern uint32_t zdr_GET_DIR_DELEGATION4args (ZDR *, GET_DIR_DELEGATION4args*); +extern uint32_t zdr_GET_DIR_DELEGATION4resok (ZDR *, GET_DIR_DELEGATION4resok*); +extern uint32_t zdr_gddrnf4_status (ZDR *, gddrnf4_status*); +extern uint32_t zdr_GET_DIR_DELEGATION4res_non_fatal (ZDR *, GET_DIR_DELEGATION4res_non_fatal*); +extern uint32_t zdr_GET_DIR_DELEGATION4res (ZDR *, GET_DIR_DELEGATION4res*); +extern uint32_t zdr_GETDEVICEINFO4args (ZDR *, GETDEVICEINFO4args*); +extern uint32_t zdr_GETDEVICEINFO4resok (ZDR *, GETDEVICEINFO4resok*); +extern uint32_t zdr_GETDEVICEINFO4res (ZDR *, GETDEVICEINFO4res*); +extern uint32_t zdr_GETDEVICELIST4args (ZDR *, GETDEVICELIST4args*); +extern uint32_t zdr_GETDEVICELIST4resok (ZDR *, GETDEVICELIST4resok*); +extern uint32_t zdr_GETDEVICELIST4res (ZDR *, GETDEVICELIST4res*); +extern uint32_t zdr_newtime4 (ZDR *, newtime4*); +extern uint32_t zdr_newoffset4 (ZDR *, newoffset4*); +extern uint32_t zdr_LAYOUTCOMMIT4args (ZDR *, LAYOUTCOMMIT4args*); +extern uint32_t zdr_newsize4 (ZDR *, newsize4*); +extern uint32_t zdr_LAYOUTCOMMIT4resok (ZDR *, LAYOUTCOMMIT4resok*); +extern uint32_t zdr_LAYOUTCOMMIT4res (ZDR *, LAYOUTCOMMIT4res*); +extern uint32_t zdr_LAYOUTGET4args (ZDR *, LAYOUTGET4args*); +extern uint32_t zdr_LAYOUTGET4resok (ZDR *, LAYOUTGET4resok*); +extern uint32_t zdr_LAYOUTGET4res (ZDR *, LAYOUTGET4res*); +extern uint32_t zdr_layoutreturn_type4 (ZDR *, layoutreturn_type4*); +extern uint32_t zdr_layoutreturn_file4 (ZDR *, layoutreturn_file4*); +extern uint32_t zdr_layoutreturn4 (ZDR *, layoutreturn4*); +extern uint32_t zdr_LAYOUTRETURN4args (ZDR *, LAYOUTRETURN4args*); +extern uint32_t zdr_layoutreturn_stateid (ZDR *, layoutreturn_stateid*); +extern uint32_t zdr_LAYOUTRETURN4res (ZDR *, LAYOUTRETURN4res*); +extern uint32_t zdr_secinfo_style4 (ZDR *, secinfo_style4*); +extern uint32_t zdr_SECINFO_NO_NAME4args (ZDR *, SECINFO_NO_NAME4args*); +extern uint32_t zdr_SECINFO_NO_NAME4res (ZDR *, SECINFO_NO_NAME4res*); +extern uint32_t zdr_SEQUENCE4args (ZDR *, SEQUENCE4args*); +extern uint32_t zdr_SEQUENCE4resok (ZDR *, SEQUENCE4resok*); +extern uint32_t zdr_SEQUENCE4res (ZDR *, SEQUENCE4res*); +extern uint32_t zdr_ssa_digest_input4 (ZDR *, ssa_digest_input4*); +extern uint32_t zdr_SET_SSV4args (ZDR *, SET_SSV4args*); +extern uint32_t zdr_ssr_digest_input4 (ZDR *, ssr_digest_input4*); +extern uint32_t zdr_SET_SSV4resok (ZDR *, SET_SSV4resok*); +extern uint32_t zdr_SET_SSV4res (ZDR *, SET_SSV4res*); +extern uint32_t zdr_TEST_STATEID4args (ZDR *, TEST_STATEID4args*); +extern uint32_t zdr_TEST_STATEID4resok (ZDR *, TEST_STATEID4resok*); +extern uint32_t zdr_TEST_STATEID4res (ZDR *, TEST_STATEID4res*); +extern uint32_t zdr_deleg_claim4 (ZDR *, deleg_claim4*); +extern uint32_t zdr_WANT_DELEGATION4args (ZDR *, WANT_DELEGATION4args*); +extern uint32_t zdr_WANT_DELEGATION4res (ZDR *, WANT_DELEGATION4res*); +extern uint32_t zdr_DESTROY_CLIENTID4args (ZDR *, DESTROY_CLIENTID4args*); +extern uint32_t zdr_DESTROY_CLIENTID4res (ZDR *, DESTROY_CLIENTID4res*); +extern uint32_t zdr_RECLAIM_COMPLETE4args (ZDR *, RECLAIM_COMPLETE4args*); +extern uint32_t zdr_RECLAIM_COMPLETE4res (ZDR *, RECLAIM_COMPLETE4res*); +extern uint32_t zdr_ILLEGAL4res (ZDR *, ILLEGAL4res*); +extern uint32_t zdr_nfs_opnum4 (ZDR *, nfs_opnum4*); +extern uint32_t zdr_nfs_argop4 (ZDR *, nfs_argop4*); +extern uint32_t zdr_nfs_resop4 (ZDR *, nfs_resop4*); +extern uint32_t zdr_COMPOUND4args (ZDR *, COMPOUND4args*); +extern uint32_t zdr_COMPOUND4res (ZDR *, COMPOUND4res*); +extern uint32_t zdr_CB_GETATTR4args (ZDR *, CB_GETATTR4args*); +extern uint32_t zdr_CB_GETATTR4resok (ZDR *, CB_GETATTR4resok*); +extern uint32_t zdr_CB_GETATTR4res (ZDR *, CB_GETATTR4res*); +extern uint32_t zdr_CB_RECALL4args (ZDR *, CB_RECALL4args*); +extern uint32_t zdr_CB_RECALL4res (ZDR *, CB_RECALL4res*); +extern uint32_t zdr_CB_ILLEGAL4res (ZDR *, CB_ILLEGAL4res*); +extern uint32_t zdr_nfs_cb_opnum4 (ZDR *, nfs_cb_opnum4*); +extern uint32_t zdr_nfs_cb_argop4 (ZDR *, nfs_cb_argop4*); +extern uint32_t zdr_nfs_cb_resop4 (ZDR *, nfs_cb_resop4*); +extern uint32_t zdr_CB_COMPOUND4args (ZDR *, CB_COMPOUND4args*); +extern uint32_t zdr_CB_COMPOUND4res (ZDR *, CB_COMPOUND4res*); +extern uint32_t zdr_rpc_gss_proc_t (ZDR *, rpc_gss_proc_t*); +extern uint32_t zdr_rpc_gss_cred_vers_1_t (ZDR *, rpc_gss_cred_vers_1_t*); +extern uint32_t zdr_rpc_gss_cred_t (ZDR *, rpc_gss_cred_t*); +extern uint32_t zdr_rpc_gss_init_arg (ZDR *, rpc_gss_init_arg*); +extern uint32_t zdr_rpc_gss_init_res (ZDR *, rpc_gss_init_res*); +extern uint32_t zdr_rpc_gss_integ_data (ZDR *, rpc_gss_integ_data*); + +#else /* K&R C */ +extern uint32_t zdr_nfs_ftype4 (); +extern uint32_t zdr_nfsstat4 (); +extern uint32_t zdr_bitmap4 (); +extern uint32_t zdr_offset4 (); +extern uint32_t zdr_count4 (); +extern uint32_t zdr_length4 (); +extern uint32_t zdr_clientid4 (); +extern uint32_t zdr_sequenceid4 (); +extern uint32_t zdr_seqid4 (); +extern uint32_t zdr_slotid4 (); +extern uint32_t zdr_utf8string (); +extern uint32_t zdr_utf8str_cis (); +extern uint32_t zdr_utf8str_cs (); +extern uint32_t zdr_utf8str_mixed (); +extern uint32_t zdr_component4 (); +extern uint32_t zdr_pathname4 (); +extern uint32_t zdr_nfs_lockid4 (); +extern uint32_t zdr_nfs_cookie4 (); +extern uint32_t zdr_linktext4 (); +extern uint32_t zdr_sec_oid4 (); +extern uint32_t zdr_qop4 (); +extern uint32_t zdr_mode4 (); +extern uint32_t zdr_changeid4 (); +extern uint32_t zdr_verifier4 (); +extern uint32_t zdr_sessionid4 (); +extern uint32_t zdr_authsys_parms (); +extern uint32_t zdr_deviceid4 (); +extern uint32_t zdr_layouttype4 (); +extern uint32_t zdr_layoutupdate4 (); +extern uint32_t zdr_device_addr4 (); +extern uint32_t zdr_nfstime4 (); +extern uint32_t zdr_time_how4 (); +extern uint32_t zdr_layoutiomode4 (); +extern uint32_t zdr_layout_content4 (); +extern uint32_t zdr_layout4 (); +extern uint32_t zdr_settime4 (); +extern uint32_t zdr_nfs_fh4 (); +extern uint32_t zdr_fsid4 (); +extern uint32_t zdr_fs_location4 (); +extern uint32_t zdr_fs_locations4 (); +extern uint32_t zdr_acetype4 (); +extern uint32_t zdr_aceflag4 (); +extern uint32_t zdr_acemask4 (); +extern uint32_t zdr_nfsace4 (); +extern uint32_t zdr_specdata4 (); +extern uint32_t zdr_fattr4_supported_attrs (); +extern uint32_t zdr_fattr4_type (); +extern uint32_t zdr_fattr4_fh_expire_type (); +extern uint32_t zdr_fattr4_change (); +extern uint32_t zdr_fattr4_size (); +extern uint32_t zdr_fattr4_link_support (); +extern uint32_t zdr_fattr4_symlink_support (); +extern uint32_t zdr_fattr4_named_attr (); +extern uint32_t zdr_fattr4_fsid (); +extern uint32_t zdr_fattr4_unique_handles (); +extern uint32_t zdr_fattr4_lease_time (); +extern uint32_t zdr_fattr4_rdattr_error (); +extern uint32_t zdr_fattr4_acl (); +extern uint32_t zdr_fattr4_aclsupport (); +extern uint32_t zdr_fattr4_archive (); +extern uint32_t zdr_fattr4_cansettime (); +extern uint32_t zdr_fattr4_case_insensitive (); +extern uint32_t zdr_fattr4_case_preserving (); +extern uint32_t zdr_fattr4_chown_restricted (); +extern uint32_t zdr_fattr4_fileid (); +extern uint32_t zdr_fattr4_files_avail (); +extern uint32_t zdr_fattr4_filehandle (); +extern uint32_t zdr_fattr4_files_free (); +extern uint32_t zdr_fattr4_files_total (); +extern uint32_t zdr_fattr4_fs_locations (); +extern uint32_t zdr_fattr4_hidden (); +extern uint32_t zdr_fattr4_homogeneous (); +extern uint32_t zdr_fattr4_maxfilesize (); +extern uint32_t zdr_fattr4_maxlink (); +extern uint32_t zdr_fattr4_maxname (); +extern uint32_t zdr_fattr4_maxread (); +extern uint32_t zdr_fattr4_maxwrite (); +extern uint32_t zdr_fattr4_mimetype (); +extern uint32_t zdr_fattr4_mode (); +extern uint32_t zdr_fattr4_mounted_on_fileid (); +extern uint32_t zdr_fattr4_no_trunc (); +extern uint32_t zdr_fattr4_numlinks (); +extern uint32_t zdr_fattr4_owner (); +extern uint32_t zdr_fattr4_owner_group (); +extern uint32_t zdr_fattr4_quota_avail_hard (); +extern uint32_t zdr_fattr4_quota_avail_soft (); +extern uint32_t zdr_fattr4_quota_used (); +extern uint32_t zdr_fattr4_rawdev (); +extern uint32_t zdr_fattr4_space_avail (); +extern uint32_t zdr_fattr4_space_free (); +extern uint32_t zdr_fattr4_space_total (); +extern uint32_t zdr_fattr4_space_used (); +extern uint32_t zdr_fattr4_system (); +extern uint32_t zdr_fattr4_time_access (); +extern uint32_t zdr_fattr4_time_access_set (); +extern uint32_t zdr_fattr4_time_backup (); +extern uint32_t zdr_fattr4_time_create (); +extern uint32_t zdr_fattr4_time_delta (); +extern uint32_t zdr_fattr4_time_metadata (); +extern uint32_t zdr_fattr4_time_modify (); +extern uint32_t zdr_fattr4_time_modify_set (); +extern uint32_t zdr_attrlist4 (); +extern uint32_t zdr_fattr4 (); +extern uint32_t zdr_change_info4 (); +extern uint32_t zdr_clientaddr4 (); +extern uint32_t zdr_cb_client4 (); +extern uint32_t zdr_stateid4 (); +extern uint32_t zdr_nfs_client_id4 (); +extern uint32_t zdr_open_owner4 (); +extern uint32_t zdr_lock_owner4 (); +extern uint32_t zdr_nfs_lock_type4 (); +extern uint32_t zdr_client_owner4 (); +extern uint32_t zdr_server_owner4 (); +extern uint32_t zdr_nfs_impl_id4 (); +extern uint32_t zdr_ACCESS4args (); +extern uint32_t zdr_ACCESS4resok (); +extern uint32_t zdr_ACCESS4res (); +extern uint32_t zdr_CLOSE4args (); +extern uint32_t zdr_CLOSE4res (); +extern uint32_t zdr_COMMIT4args (); +extern uint32_t zdr_COMMIT4resok (); +extern uint32_t zdr_COMMIT4res (); +extern uint32_t zdr_createtype4 (); +extern uint32_t zdr_CREATE4args (); +extern uint32_t zdr_CREATE4resok (); +extern uint32_t zdr_CREATE4res (); +extern uint32_t zdr_DELEGPURGE4args (); +extern uint32_t zdr_DELEGPURGE4res (); +extern uint32_t zdr_DELEGRETURN4args (); +extern uint32_t zdr_DELEGRETURN4res (); +extern uint32_t zdr_GETATTR4args (); +extern uint32_t zdr_GETATTR4resok (); +extern uint32_t zdr_GETATTR4res (); +extern uint32_t zdr_GETFH4resok (); +extern uint32_t zdr_GETFH4res (); +extern uint32_t zdr_LINK4args (); +extern uint32_t zdr_LINK4resok (); +extern uint32_t zdr_LINK4res (); +extern uint32_t zdr_open_to_lock_owner4 (); +extern uint32_t zdr_exist_lock_owner4 (); +extern uint32_t zdr_locker4 (); +extern uint32_t zdr_LOCK4args (); +extern uint32_t zdr_LOCK4denied (); +extern uint32_t zdr_LOCK4resok (); +extern uint32_t zdr_LOCK4res (); +extern uint32_t zdr_LOCKT4args (); +extern uint32_t zdr_LOCKT4res (); +extern uint32_t zdr_LOCKU4args (); +extern uint32_t zdr_LOCKU4res (); +extern uint32_t zdr_LOOKUP4args (); +extern uint32_t zdr_LOOKUP4res (); +extern uint32_t zdr_LOOKUPP4res (); +extern uint32_t zdr_NVERIFY4args (); +extern uint32_t zdr_NVERIFY4res (); +extern uint32_t zdr_createmode4 (); +extern uint32_t zdr_createhow4 (); +extern uint32_t zdr_opentype4 (); +extern uint32_t zdr_openflag4 (); +extern uint32_t zdr_limit_by4 (); +extern uint32_t zdr_nfs_modified_limit4 (); +extern uint32_t zdr_nfs_space_limit4 (); +extern uint32_t zdr_open_delegation_type4 (); +extern uint32_t zdr_open_claim_type4 (); +extern uint32_t zdr_open_claim_delegate_cur4 (); +extern uint32_t zdr_open_claim4 (); +extern uint32_t zdr_OPEN4args (); +extern uint32_t zdr_open_read_delegation4 (); +extern uint32_t zdr_open_write_delegation4 (); +extern uint32_t zdr_open_delegation4 (); +extern uint32_t zdr_OPEN4resok (); +extern uint32_t zdr_OPEN4res (); +extern uint32_t zdr_OPENATTR4args (); +extern uint32_t zdr_OPENATTR4res (); +extern uint32_t zdr_OPEN_CONFIRM4args (); +extern uint32_t zdr_OPEN_CONFIRM4resok (); +extern uint32_t zdr_OPEN_CONFIRM4res (); +extern uint32_t zdr_OPEN_DOWNGRADE4args (); +extern uint32_t zdr_OPEN_DOWNGRADE4resok (); +extern uint32_t zdr_OPEN_DOWNGRADE4res (); +extern uint32_t zdr_PUTFH4args (); +extern uint32_t zdr_PUTFH4res (); +extern uint32_t zdr_PUTPUBFH4res (); +extern uint32_t zdr_PUTROOTFH4res (); +extern uint32_t zdr_READ4args (); +extern uint32_t zdr_READ4resok (); +extern uint32_t zdr_READ4res (); +extern uint32_t zdr_READDIR4args (); +extern uint32_t zdr_entry4 (); +extern uint32_t zdr_dirlist4 (); +extern uint32_t zdr_READDIR4resok (); +extern uint32_t zdr_READDIR4res (); +extern uint32_t zdr_READLINK4resok (); +extern uint32_t zdr_READLINK4res (); +extern uint32_t zdr_REMOVE4args (); +extern uint32_t zdr_REMOVE4resok (); +extern uint32_t zdr_REMOVE4res (); +extern uint32_t zdr_RENAME4args (); +extern uint32_t zdr_RENAME4resok (); +extern uint32_t zdr_RENAME4res (); +extern uint32_t zdr_RENEW4args (); +extern uint32_t zdr_RENEW4res (); +extern uint32_t zdr_RESTOREFH4res (); +extern uint32_t zdr_SAVEFH4res (); +extern uint32_t zdr_SECINFO4args (); +extern uint32_t zdr_rpc_gss_svc_t (); +extern uint32_t zdr_rpcsec_gss_info (); +extern uint32_t zdr_secinfo4 (); +extern uint32_t zdr_SECINFO4resok (); +extern uint32_t zdr_SECINFO4res (); +extern uint32_t zdr_SETATTR4args (); +extern uint32_t zdr_SETATTR4res (); +extern uint32_t zdr_SETCLIENTID4args (); +extern uint32_t zdr_SETCLIENTID4resok (); +extern uint32_t zdr_SETCLIENTID4res (); +extern uint32_t zdr_SETCLIENTID_CONFIRM4args (); +extern uint32_t zdr_SETCLIENTID_CONFIRM4res (); +extern uint32_t zdr_VERIFY4args (); +extern uint32_t zdr_VERIFY4res (); +extern uint32_t zdr_stable_how4 (); +extern uint32_t zdr_WRITE4args (); +extern uint32_t zdr_WRITE4resok (); +extern uint32_t zdr_WRITE4res (); +extern uint32_t zdr_RELEASE_LOCKOWNER4args (); +extern uint32_t zdr_RELEASE_LOCKOWNER4res (); +extern uint32_t zdr_gsshandle4_t (); +extern uint32_t zdr_callback_sec_parms4 (); +extern uint32_t zdr_channel_dir_from_client4 (); +extern uint32_t zdr_BIND_CONN_TO_SESSION4args (); +extern uint32_t zdr_channel_dir_from_server4 (); +extern uint32_t zdr_BIND_CONN_TO_SESSION4resok (); +extern uint32_t zdr_BIND_CONN_TO_SESSION4res (); +extern uint32_t zdr_state_protect_ops4 (); +extern uint32_t zdr_ssv_sp_parms4 (); +extern uint32_t zdr_state_protect_how4 (); +extern uint32_t zdr_state_protect4_a (); +extern uint32_t zdr_EXCHANGE_ID4args (); +extern uint32_t zdr_ssv_prot_info4 (); +extern uint32_t zdr_state_protect4_r (); +extern uint32_t zdr_EXCHANGE_ID4resok (); +extern uint32_t zdr_EXCHANGE_ID4res (); +extern uint32_t zdr_channel_attrs4 (); +extern uint32_t zdr_CREATE_SESSION4args (); +extern uint32_t zdr_CREATE_SESSION4resok (); +extern uint32_t zdr_CREATE_SESSION4res (); +extern uint32_t zdr_DESTROY_SESSION4args (); +extern uint32_t zdr_DESTROY_SESSION4res (); +extern uint32_t zdr_FREE_STATEID4args (); +extern uint32_t zdr_FREE_STATEID4res (); +extern uint32_t zdr_attr_notice4 (); +extern uint32_t zdr_GET_DIR_DELEGATION4args (); +extern uint32_t zdr_GET_DIR_DELEGATION4resok (); +extern uint32_t zdr_gddrnf4_status (); +extern uint32_t zdr_GET_DIR_DELEGATION4res_non_fatal (); +extern uint32_t zdr_GET_DIR_DELEGATION4res (); +extern uint32_t zdr_GETDEVICEINFO4args (); +extern uint32_t zdr_GETDEVICEINFO4resok (); +extern uint32_t zdr_GETDEVICEINFO4res (); +extern uint32_t zdr_GETDEVICELIST4args (); +extern uint32_t zdr_GETDEVICELIST4resok (); +extern uint32_t zdr_GETDEVICELIST4res (); +extern uint32_t zdr_newtime4 (); +extern uint32_t zdr_newoffset4 (); +extern uint32_t zdr_LAYOUTCOMMIT4args (); +extern uint32_t zdr_newsize4 (); +extern uint32_t zdr_LAYOUTCOMMIT4resok (); +extern uint32_t zdr_LAYOUTCOMMIT4res (); +extern uint32_t zdr_LAYOUTGET4args (); +extern uint32_t zdr_LAYOUTGET4resok (); +extern uint32_t zdr_LAYOUTGET4res (); +extern uint32_t zdr_layoutreturn_type4 (); +extern uint32_t zdr_layoutreturn_file4 (); +extern uint32_t zdr_layoutreturn4 (); +extern uint32_t zdr_LAYOUTRETURN4args (); +extern uint32_t zdr_layoutreturn_stateid (); +extern uint32_t zdr_LAYOUTRETURN4res (); +extern uint32_t zdr_secinfo_style4 (); +extern uint32_t zdr_SECINFO_NO_NAME4args (); +extern uint32_t zdr_SECINFO_NO_NAME4res (); +extern uint32_t zdr_SEQUENCE4args (); +extern uint32_t zdr_SEQUENCE4resok (); +extern uint32_t zdr_SEQUENCE4res (); +extern uint32_t zdr_ssa_digest_input4 (); +extern uint32_t zdr_SET_SSV4args (); +extern uint32_t zdr_ssr_digest_input4 (); +extern uint32_t zdr_SET_SSV4resok (); +extern uint32_t zdr_SET_SSV4res (); +extern uint32_t zdr_TEST_STATEID4args (); +extern uint32_t zdr_TEST_STATEID4resok (); +extern uint32_t zdr_TEST_STATEID4res (); +extern uint32_t zdr_deleg_claim4 (); +extern uint32_t zdr_WANT_DELEGATION4args (); +extern uint32_t zdr_WANT_DELEGATION4res (); +extern uint32_t zdr_DESTROY_CLIENTID4args (); +extern uint32_t zdr_DESTROY_CLIENTID4res (); +extern uint32_t zdr_RECLAIM_COMPLETE4args (); +extern uint32_t zdr_RECLAIM_COMPLETE4res (); +extern uint32_t zdr_ILLEGAL4res (); +extern uint32_t zdr_nfs_opnum4 (); +extern uint32_t zdr_nfs_argop4 (); +extern uint32_t zdr_nfs_resop4 (); +extern uint32_t zdr_COMPOUND4args (); +extern uint32_t zdr_COMPOUND4res (); +extern uint32_t zdr_CB_GETATTR4args (); +extern uint32_t zdr_CB_GETATTR4resok (); +extern uint32_t zdr_CB_GETATTR4res (); +extern uint32_t zdr_CB_RECALL4args (); +extern uint32_t zdr_CB_RECALL4res (); +extern uint32_t zdr_CB_ILLEGAL4res (); +extern uint32_t zdr_nfs_cb_opnum4 (); +extern uint32_t zdr_nfs_cb_argop4 (); +extern uint32_t zdr_nfs_cb_resop4 (); +extern uint32_t zdr_CB_COMPOUND4args (); +extern uint32_t zdr_CB_COMPOUND4res (); +extern uint32_t zdr_rpc_gss_proc_t (); +extern uint32_t zdr_rpc_gss_cred_vers_1_t (); +extern uint32_t zdr_rpc_gss_cred_t (); +extern uint32_t zdr_rpc_gss_init_arg (); +extern uint32_t zdr_rpc_gss_init_res (); +extern uint32_t zdr_rpc_gss_integ_data (); + +#endif /* K&R C */ + +#include + +#if defined(WIN32) && defined(libnfs_EXPORTS) +#define EXTERN __declspec( dllexport ) +#else +#ifndef EXTERN +#define EXTERN +#endif +#endif + +/* + * NFSv4 ACL + */ +/* + * Async nfs4 get acl + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is fattr4_acl * + * -errno : An error occured. + * data is the error string. + */ +EXTERN int nfs4_getacl_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + nfs_cb cb, void *private_data); + +/* + * Sync nfs4 get acl + * Function returns + * 0 : The operation was successful. + * -errno : The command failed. + * + * If the command was successful, the returned data in nfs4acl must be freed + * by calling nfs4_acl_free() + */ +EXTERN int nfs4_getacl(struct nfs_context *nfs, struct nfsfh *nfsfh, + fattr4_acl *nfs4acl); + +EXTERN void nfs4_acl_free(fattr4_acl *nfs4acl); + +#ifdef __cplusplus +} +#endif + +#endif /* !_NFS4_H_RPCGEN */ diff --git a/deps/libnfs/nfs4/libnfs-raw-nfs4.h.extra b/deps/libnfs/nfs4/libnfs-raw-nfs4.h.extra new file mode 100644 index 000000000000..52667264cead --- /dev/null +++ b/deps/libnfs/nfs4/libnfs-raw-nfs4.h.extra @@ -0,0 +1,49 @@ +#include + +#if defined(WIN32) && defined(libnfs_EXPORTS) +#define EXTERN __declspec( dllexport ) +#else +#ifndef EXTERN +#define EXTERN +#endif +#endif + +/* + * NFSv4 ACL + */ +/* + * Async nfs4 get acl + * Function returns + * 0 : The command was queued successfully. The callback will be invoked once + * the command completes. + * <0 : An error occured when trying to queue the command. + * The callback will not be invoked. + * + * When the callback is invoked, status indicates the result: + * 0 : Success. + * data is fattr4_acl * + * -errno : An error occured. + * data is the error string. + */ +EXTERN int nfs4_getacl_async(struct nfs_context *nfs, struct nfsfh *nfsfh, + nfs_cb cb, void *private_data); + +/* + * Sync nfs4 get acl + * Function returns + * 0 : The operation was successful. + * -errno : The command failed. + * + * If the command was successful, the returned data in nfs4acl must be freed + * by calling nfs4_acl_free() + */ +EXTERN int nfs4_getacl(struct nfs_context *nfs, struct nfsfh *nfsfh, + fattr4_acl *nfs4acl); + +EXTERN void nfs4_acl_free(fattr4_acl *nfs4acl); + +#ifdef __cplusplus +} +#endif + +#endif /* !_NFS4_H_RPCGEN */ diff --git a/deps/libnfs/nfs4/nfs4.c b/deps/libnfs/nfs4/nfs4.c new file mode 100644 index 000000000000..62bbf5aaaf2b --- /dev/null +++ b/deps/libnfs/nfs4/nfs4.c @@ -0,0 +1,443 @@ +/* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */ +/* + Copyright (C) 2016 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 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef PS2_EE +#include "ps2_compat.h" +#endif + +#ifdef WIN32 +#include +#else +#include +#endif/*WIN32*/ + +#include +#include +#include +#include +#include "libnfs-zdr.h" +#include "libnfs.h" +#include "libnfs-raw.h" +#include "libnfs-private.h" +#include "libnfs-raw-nfs4.h" + +char * +nfsstat4_to_str(int error) +{ + switch (error) { + case NFS4_OK: return "NFS4_OK"; break; + case NFS4ERR_PERM: return "NFS4ERR_PERM"; break; + case NFS4ERR_NOENT: return "NFS4ERR_NOENT"; break; + case NFS4ERR_IO: return "NFS4ERR_IO"; break; + case NFS4ERR_NXIO: return "NFS4ERR_NXIO"; break; + case NFS4ERR_ACCESS: return "NFS4ERR_ACCESS"; break; + case NFS4ERR_EXIST: return "NFS4ERR_EXIST"; break; + case NFS4ERR_XDEV: return "NFS4ERR_XDEV"; break; + case NFS4ERR_NOTDIR: return "NFS4ERR_NOTDIR"; break; + case NFS4ERR_ISDIR: return "NFS4ERR_ISDIR"; break; + case NFS4ERR_INVAL: return "NFS4ERR_INVAL"; break; + case NFS4ERR_FBIG: return "NFS4ERR_FBIG"; break; + case NFS4ERR_NOSPC: return "NFS4ERR_NOSPC"; break; + case NFS4ERR_ROFS: return"NFS4ERR_ROFS"; break; + case NFS4ERR_MLINK: return "NFS4ERR_MLINK"; break; + case NFS4ERR_NAMETOOLONG: return "NFS4ERR_NAMETOOLONG"; break; + case NFS4ERR_NOTEMPTY: return "NFS4ERR_NOTEMPTY"; break; + case NFS4ERR_DQUOT: return "NFS4ERR_DQUOT"; break; + case NFS4ERR_STALE: return "NFS4ERR_STALE"; break; + case NFS4ERR_BADHANDLE: return "NFS4ERR_BADHANDLE"; break; + case NFS4ERR_BAD_COOKIE: return "NFS4ERR_BAD_COOKIE"; break; + case NFS4ERR_NOTSUPP: return "NFS4ERR_NOTSUPP"; break; + case NFS4ERR_TOOSMALL: return "NFS4ERR_TOOSMALL"; break; + case NFS4ERR_SERVERFAULT: return "NFS4ERR_SERVERFAULT"; break; + case NFS4ERR_BADTYPE: return "NFS4ERR_BADTYPE"; break; + case NFS4ERR_DELAY: return "NFS4ERR_DELAY"; break; + case NFS4ERR_SAME: return "NFS4ERR_SAME"; break; + case NFS4ERR_DENIED: return "NFS4ERR_DENIED"; break; + case NFS4ERR_EXPIRED: return "NFS4ERR_EXPIRED"; break; + case NFS4ERR_LOCKED: return "NFS4ERR_LOCKED"; break; + case NFS4ERR_GRACE: return "NFS4ERR_GRACE"; break; + case NFS4ERR_FHEXPIRED: return "NFS4ERR_FHEXPIRED"; break; + case NFS4ERR_SHARE_DENIED: return "NFS4ERR_SHARE_DENIED"; break; + case NFS4ERR_WRONGSEC: return "NFS4ERR_WRONGSEC"; break; + case NFS4ERR_CLID_INUSE: return "NFS4ERR_CLID_INUSE"; break; + case NFS4ERR_RESOURCE: return "NFS4ERR_RESOURCE"; break; + case NFS4ERR_MOVED: return "NFS4ERR_MOVED"; break; + case NFS4ERR_NOFILEHANDLE: return "NFS4ERR_NOFILEHANDLE"; break; + case NFS4ERR_MINOR_VERS_MISMATCH: + return "NFS4ERR_MINOR_VERS_MISMATCH"; break; + case NFS4ERR_STALE_CLIENTID: return "NFS4ERR_STALE_CLIENTID"; break; + case NFS4ERR_STALE_STATEID: return "NFS4ERR_STALE_STATEID"; break; + case NFS4ERR_OLD_STATEID: return "NFS4ERR_OLD_STATEID"; break; + case NFS4ERR_BAD_STATEID: return "NFS4ERR_BAD_STATEID"; break; + case NFS4ERR_BAD_SEQID: return "NFS4ERR_BAD_SEQID"; break; + case NFS4ERR_NOT_SAME: return "NFS4ERR_NOT_SAME"; break; + case NFS4ERR_LOCK_RANGE: return "NFS4ERR_LOCK_RANGE"; break; + case NFS4ERR_SYMLINK: return "NFS4ERR_SYMLINK"; break; + case NFS4ERR_RESTOREFH: return "NFS4ERR_RESTOREFH"; break; + case NFS4ERR_LEASE_MOVED: return "NFS4ERR_LEASE_MOVED"; break; + case NFS4ERR_ATTRNOTSUPP: return "NFS4ERR_ATTRNOTSUPP"; break; + case NFS4ERR_NO_GRACE: return "NFS4ERR_NO_GRACE"; break; + case NFS4ERR_RECLAIM_BAD: return "NFS4ERR_RECLAIM_BAD"; break; + case NFS4ERR_RECLAIM_CONFLICT: return "NFS4ERR_RECLAIM_CONFLICT"; break; + case NFS4ERR_BADZDR: return "NFS4ERR_BADZDR"; break; + case NFS4ERR_LOCKS_HELD: return "NFS4ERR_LOCKS_HELD"; break; + case NFS4ERR_OPENMODE: return "NFS4ERR_OPENMODE"; break; + case NFS4ERR_BADOWNER: return "NFS4ERR_BADOWNER"; break; + case NFS4ERR_BADCHAR: return "NFS4ERR_BADCHAR"; break; + case NFS4ERR_BADNAME: return "NFS4ERR_BADNAME"; break; + case NFS4ERR_BAD_RANGE: return "NFS4ERR_BAD_RANGE"; break; + case NFS4ERR_LOCK_NOTSUPP: return "NFS4ERR_LOCK_NOTSUPP"; break; + case NFS4ERR_OP_ILLEGAL: return "NFS4ERR_OP_ILLEGAL"; break; + case NFS4ERR_DEADLOCK: return "NFS4ERR_DEADLOCK"; break; + case NFS4ERR_FILE_OPEN: return "NFS4ERR_FILE_OPEN"; break; + case NFS4ERR_ADMIN_REVOKED: return "NFS4ERR_ADMIN_REVOKED"; break; + case NFS4ERR_CB_PATH_DOWN: return "NFS4ERR_CB_PATH_DOWN"; break; + }; + return "unknown nfsv4 error"; +} + +int +nfsstat4_to_errno(int error) +{ + switch (error) { + case NFS4_OK: return 0; + case NFS4ERR_PERM: return -EPERM; + case NFS4ERR_NOENT: return -ENOENT ; + case NFS4ERR_IO: return -EIO; + case NFS4ERR_NXIO: return -ENXIO; + case NFS4ERR_ACCESS: return -EACCES ; + case NFS4ERR_EXIST: return -EEXIST; + case NFS4ERR_XDEV: return -EXDEV; + case NFS4ERR_NOTDIR: return -ENOTDIR ; + case NFS4ERR_ISDIR: return -EISDIR ; + case NFS4ERR_INVAL: return -EINVAL; + case NFS4ERR_FBIG: return -EFBIG; + case NFS4ERR_NOSPC: return -ENOSPC; + case NFS4ERR_ROFS: return -EROFS; + case NFS4ERR_MLINK: return -EMLINK; + case NFS4ERR_NAMETOOLONG: return -ENAMETOOLONG; + case NFS4ERR_NOTEMPTY: return -ENOTEMPTY; + case NFS4ERR_DQUOT: return -ERANGE; + case NFS4ERR_STALE: return -EIO; + case NFS4ERR_BADHANDLE: return -EINVAL; + case NFS4ERR_BAD_COOKIE: return -EINVAL; + case NFS4ERR_NOTSUPP: return -EINVAL; + case NFS4ERR_TOOSMALL: return -EIO; + case NFS4ERR_SERVERFAULT: return -EIO; + case NFS4ERR_BADTYPE: return -EINVAL; + case NFS4ERR_DELAY: return -EIO; + case NFS4ERR_SAME: return -EIO; + case NFS4ERR_DENIED: return -EIO; + case NFS4ERR_EXPIRED: return -EAGAIN; + case NFS4ERR_LOCKED: return -EIO; + case NFS4ERR_GRACE: return -EIO; + case NFS4ERR_FHEXPIRED: return -EAGAIN; + case NFS4ERR_SHARE_DENIED: return -EIO; + case NFS4ERR_WRONGSEC: return -EIO; + case NFS4ERR_CLID_INUSE: return -EIO; + case NFS4ERR_RESOURCE: return -EIO; + case NFS4ERR_MOVED: return -EIO; + case NFS4ERR_NOFILEHANDLE: return -EIO; + case NFS4ERR_MINOR_VERS_MISMATCH: return -EIO; + case NFS4ERR_STALE_CLIENTID: return -EIO; + case NFS4ERR_STALE_STATEID: return -EIO; + case NFS4ERR_OLD_STATEID: return -EIO; + case NFS4ERR_BAD_STATEID: return -EINVAL; + case NFS4ERR_BAD_SEQID: return -EINVAL; + case NFS4ERR_NOT_SAME: return -EIO; + case NFS4ERR_LOCK_RANGE: return -EIO; + case NFS4ERR_SYMLINK: return -EIO; + case NFS4ERR_RESTOREFH: return -EIO; + case NFS4ERR_ATTRNOTSUPP: return -EINVAL; + case NFS4ERR_NO_GRACE: return -EIO; + case NFS4ERR_RECLAIM_BAD: return -EIO; + case NFS4ERR_RECLAIM_CONFLICT: return -EIO; + case NFS4ERR_BADZDR: return -EINVAL; + case NFS4ERR_LOCKS_HELD: return -EIO; + case NFS4ERR_OPENMODE: return -EIO; + case NFS4ERR_BADOWNER: return -EINVAL; + case NFS4ERR_BADCHAR: return -EINVAL; + case NFS4ERR_BADNAME: return -EINVAL; + case NFS4ERR_BAD_RANGE: return -EINVAL; + case NFS4ERR_LOCK_NOTSUPP: return -EINVAL; + case NFS4ERR_OP_ILLEGAL: return -EIO; + case NFS4ERR_DEADLOCK: return -EIO; + case NFS4ERR_FILE_OPEN: return -EIO; + case NFS4ERR_ADMIN_REVOKED: return -EIO; + case NFS4ERR_CB_PATH_DOWN: return -EIO; + }; + return -ERANGE; +} + +struct rpc_pdu *rpc_nfs4_null_task(struct rpc_context *rpc, rpc_cb cb, + void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS4_PROGRAM, NFS_V4, NFSPROC4_NULL, cb, + private_data, (zdrproc_t)zdr_void, 0); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu " + "for NFS4/NULL call"); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for " + "NFS4/NULL call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs4_compound_task2(struct rpc_context *rpc, rpc_cb cb, + struct COMPOUND4args *args, + void *private_data, + size_t alloc_hint) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu2(rpc, NFS4_PROGRAM, NFS_V4, NFSPROC4_COMPOUND, + cb, private_data, (zdrproc_t)zdr_COMPOUND4res, + sizeof(COMPOUND4res), + alloc_hint, 0); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for " + "NFS4/COMPOUND call"); + return NULL; + } + + if (zdr_COMPOUND4args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode COMPOUND4args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for " + "NFS4/COMPOUND4 call"); + return NULL; + } + + return pdu; +} + + +struct rpc_pdu *rpc_nfs4_compound_task(struct rpc_context *rpc, rpc_cb cb, + struct COMPOUND4args *args, + void *private_data) +{ + return rpc_nfs4_compound_task2(rpc, cb, args, private_data, 0); +} + +struct rpc_pdu *rpc_nfs4_readv_task(struct rpc_context *rpc, rpc_cb cb, + const struct iovec *iov, int iovcnt, + struct COMPOUND4args *args, + void *private_data) +{ + struct rpc_pdu *pdu; + int i; + + if (iovcnt == 0 || iov == NULL) { + rpc_set_error(rpc, "Invalid arguments: iov and iovcnt must be specified"); + return NULL; + } + + /* + * It's disallowed since it's not tested. It may work. + */ + if (iovcnt > 1 && rpc->is_udp) { + rpc_set_error(rpc, "Invalid arguments: Vectored read not supported for UDP transport"); + return NULL; + } + + /* + * Don't accept more iovecs than what readv() can handle. + */ + if (iovcnt > RPC_MAX_VECTORS) { + rpc_set_error(rpc, "Invalid arguments: iovcnt must be <= %d", RPC_MAX_VECTORS); + return NULL; + } + + pdu = rpc_allocate_pdu2(rpc, NFS4_PROGRAM, NFS_V4, NFSPROC4_COMPOUND, + cb, private_data, (zdrproc_t)zdr_COMPOUND4res, + sizeof(COMPOUND4res), 0, 0); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for " + "NFS4/COMPOUND call"); + return NULL; + } + + if (zdr_COMPOUND4args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode COMPOUND4args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + pdu->in.base = (struct iovec *) malloc(sizeof(struct iovec) * iovcnt * 2); + if (!pdu->in.base) { + rpc_set_error(rpc, "error: Failed to allocate memory"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + pdu->in.iov = pdu->in.base; + pdu->in.iov_ref = pdu->in.base + iovcnt; + pdu->in.iovcnt = pdu->in.iovcnt_ref = iovcnt; + + for (i = 0; i < iovcnt; i++) { + pdu->in.iov[i] = pdu->in.iov_ref[i] = iov[i]; + pdu->in.remaining_size += iov[i].iov_len; + } + + pdu->requested_read_count = pdu->in.remaining_size; + pdu->zero_copy_iov = 1; + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for " + "NFS4/COMPOUND4 call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs4_read_task(struct rpc_context *rpc, rpc_cb cb, + void *buf, size_t count, + struct COMPOUND4args *args, + void *private_data) +{ + struct iovec iov; + + iov.iov_base = buf; + iov.iov_len = count; + + return rpc_nfs4_readv_task(rpc, cb, &iov, 1, args, private_data); +} + +struct rpc_pdu *rpc_nfs4_writev_task(struct rpc_context *rpc, rpc_cb cb, + const struct iovec *iov, int iovcnt, + struct COMPOUND4args *args, + void *private_data) +{ + struct rpc_pdu *pdu; + int start; + uint32_t len; + static uint32_t zero_padding; + int i; + + if (iovcnt == 0 || iov == NULL) { + rpc_set_error(rpc, "Invalid arguments: iov and iovcnt must be specified"); + return NULL; + } + + if (iovcnt > 1 && rpc->is_udp) { + rpc_set_error(rpc, "Invalid arguments: Vectored write not supported for UDP transport"); + return NULL; + } + + pdu = rpc_allocate_pdu2(rpc, NFS4_PROGRAM, NFS_V4, NFSPROC4_COMPOUND, + cb, private_data, (zdrproc_t)zdr_COMPOUND4res, + sizeof(COMPOUND4res), 0, iovcnt); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for " + "NFS4/COMPOUND call"); + return NULL; + } + + start = zdr_getpos(&pdu->zdr); + + if (zdr_COMPOUND4args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode COMPOUND4args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + /* Add an iovector for the COMPOUND4/.../WRITE4 header */ + if (rpc_add_iovector(rpc, &pdu->out, &pdu->outdata.data[start + 4], + zdr_getpos(&pdu->zdr) - start, NULL) < 0) { + rpc_free_pdu(rpc, pdu); + return NULL; + } + + /* Calculate data length to encode in the RPC request */ + len = 0; + for (i = 0; i < iovcnt; i++) { + len += iov[i].iov_len; + } + + /* Add an iovector for the length of the byte/array blob */ + start = zdr_getpos(&pdu->zdr); + zdr_u_int(&pdu->zdr, &len); + if (rpc_add_iovector(rpc, &pdu->out, &pdu->outdata.data[start + 4], + 4, NULL) < 0) { + rpc_free_pdu(rpc, pdu); + return NULL; + } + + /* Add iovector(s) for the data itself */ + for (i = 0; i < iovcnt; i++) { + if (rpc_add_iovector(rpc, &pdu->out, + iov[i].iov_base, + iov[i].iov_len, NULL) < 0) { + rpc_free_pdu(rpc, pdu); + return NULL; + } + } + + /* We may need to pad this to 4 byte boundary */ + if (len & 0x03) { + if (rpc_add_iovector(rpc, &pdu->out, (char *)&zero_padding, + 4 - (len & 0x03), + NULL) < 0) { + rpc_free_pdu(rpc, pdu); + return NULL; + } + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for " + "NFS4/COMPOUND4 call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu *rpc_nfs4_write_task(struct rpc_context *rpc, rpc_cb cb, + const void *buf, size_t count, + struct COMPOUND4args *args, + void *private_data) +{ + /* + * We don't have an iovec definition with const iov_base pointer, but + * rpc_nfs4_writev_task() won't modify the contents of *buf, so the + * following cast is safe. + */ + struct iovec iov; + + iov.iov_base = (void *) buf; + iov.iov_len = count; + + return rpc_nfs4_writev_task(rpc, cb, &iov, 1, args, private_data); +} diff --git a/deps/libnfs/nfs4/nfs4.x b/deps/libnfs/nfs4/nfs4.x new file mode 100644 index 000000000000..8d941ad26c3e --- /dev/null +++ b/deps/libnfs/nfs4/nfs4.x @@ -0,0 +1,2414 @@ +/* This is based on RFC3530 */ + +/* + * NFS v4 Definitions + */ + + +/* + * Copyright (C) The Internet Society (1998,1999,2000,2001,2002). + * All Rights Reserved. + */ + +/* + * nfs4_prot.x + * + */ + +/* + * Sizes + */ +const NFS4_FHSIZE = 128; +const NFS4_VERIFIER_SIZE = 8; +const NFS4_OPAQUE_LIMIT = 1024; +const NFS4_SESSIONID_SIZE = 16; +/* + * File types + */ +enum nfs_ftype4 { + NF4REG = 1, /* Regular File */ + NF4DIR = 2, /* Directory */ + NF4BLK = 3, /* Special File - block device */ + NF4CHR = 4, /* Special File - character device */ + NF4LNK = 5, /* Symbolic Link */ + NF4SOCK = 6, /* Special File - socket */ + NF4FIFO = 7, /* Special File - fifo */ + NF4ATTRDIR = 8, /* Attribute Directory */ + NF4NAMEDATTR = 9 /* Named Attribute */ +}; + +/* + * Error status + */ +enum nfsstat4 { + NFS4_OK = 0, /* everything is okay */ + NFS4ERR_PERM = 1, /* caller not privileged */ + NFS4ERR_NOENT = 2, /* no such file/directory */ + NFS4ERR_IO = 5, /* hard I/O error */ + NFS4ERR_NXIO = 6, /* no such device */ + NFS4ERR_ACCESS = 13, /* access denied */ + NFS4ERR_EXIST = 17, /* file already exists */ + NFS4ERR_XDEV = 18, /* different filesystems */ + /* Unused/reserved 19 */ + NFS4ERR_NOTDIR = 20, /* should be a directory */ + NFS4ERR_ISDIR = 21, /* should not be directory */ + NFS4ERR_INVAL = 22, /* invalid argument */ + NFS4ERR_FBIG = 27, /* file exceeds server max */ + NFS4ERR_NOSPC = 28, /* no space on filesystem */ + NFS4ERR_ROFS = 30, /* read-only filesystem */ + NFS4ERR_MLINK = 31, /* too many hard links */ + NFS4ERR_NAMETOOLONG = 63, /* name exceeds server max */ + NFS4ERR_NOTEMPTY = 66, /* directory not empty */ + NFS4ERR_DQUOT = 69, /* hard quota limit reached*/ + NFS4ERR_STALE = 70, /* file no longer exists */ + NFS4ERR_BADHANDLE = 10001,/* Illegal filehandle */ + NFS4ERR_BAD_COOKIE = 10003,/* READDIR cookie is stale */ + NFS4ERR_NOTSUPP = 10004,/* operation not supported */ + NFS4ERR_TOOSMALL = 10005,/* response limit exceeded */ + NFS4ERR_SERVERFAULT = 10006,/* undefined server error */ + NFS4ERR_BADTYPE = 10007,/* type invalid for CREATE */ + NFS4ERR_DELAY = 10008,/* file "busy" - retry */ + NFS4ERR_SAME = 10009,/* nverify says attrs same */ + NFS4ERR_DENIED = 10010,/* lock unavailable */ + NFS4ERR_EXPIRED = 10011,/* lock lease expired */ + NFS4ERR_LOCKED = 10012,/* I/O failed due to lock */ + NFS4ERR_GRACE = 10013,/* in grace period */ + NFS4ERR_FHEXPIRED = 10014,/* filehandle expired */ + NFS4ERR_SHARE_DENIED = 10015,/* share reserve denied */ + NFS4ERR_WRONGSEC = 10016,/* wrong security flavor */ + NFS4ERR_CLID_INUSE = 10017,/* clientid in use */ + NFS4ERR_RESOURCE = 10018,/* resource exhaustion */ + NFS4ERR_MOVED = 10019,/* filesystem relocated */ + NFS4ERR_NOFILEHANDLE = 10020,/* current FH is not set */ + NFS4ERR_MINOR_VERS_MISMATCH = 10021,/* minor vers not supp */ + NFS4ERR_STALE_CLIENTID = 10022,/* server has rebooted */ + NFS4ERR_STALE_STATEID = 10023,/* server has rebooted */ + NFS4ERR_OLD_STATEID = 10024,/* state is out of sync */ + NFS4ERR_BAD_STATEID = 10025,/* incorrect stateid */ + NFS4ERR_BAD_SEQID = 10026,/* request is out of seq. */ + NFS4ERR_NOT_SAME = 10027,/* verify - attrs not same */ + NFS4ERR_LOCK_RANGE = 10028,/* lock range not supported*/ + NFS4ERR_SYMLINK = 10029,/* should be file/directory*/ + NFS4ERR_RESTOREFH = 10030,/* no saved filehandle */ + NFS4ERR_LEASE_MOVED = 10031,/* some filesystem moved */ + NFS4ERR_ATTRNOTSUPP = 10032,/* recommended attr not sup*/ + NFS4ERR_NO_GRACE = 10033,/* reclaim outside of grace*/ + NFS4ERR_RECLAIM_BAD = 10034,/* reclaim error at server */ + NFS4ERR_RECLAIM_CONFLICT = 10035,/* conflict on reclaim */ + NFS4ERR_BADZDR = 10036,/* ZDR decode failed */ + NFS4ERR_LOCKS_HELD = 10037,/* file locks held at CLOSE*/ + NFS4ERR_OPENMODE = 10038,/* conflict in OPEN and I/O*/ + NFS4ERR_BADOWNER = 10039,/* owner translation bad */ + NFS4ERR_BADCHAR = 10040,/* utf-8 char not supported*/ + NFS4ERR_BADNAME = 10041,/* name not supported */ + NFS4ERR_BAD_RANGE = 10042,/* lock range not supported*/ + NFS4ERR_LOCK_NOTSUPP = 10043,/* no atomic up/downgrade */ + NFS4ERR_OP_ILLEGAL = 10044,/* undefined operation */ + NFS4ERR_DEADLOCK = 10045,/* file locking deadlock */ + NFS4ERR_FILE_OPEN = 10046,/* open file blocks op. */ + NFS4ERR_ADMIN_REVOKED = 10047,/* lockowner state revoked */ + NFS4ERR_CB_PATH_DOWN = 10048,/* callback path down */ + NFS4ERR_BADIOMODE = 10049, + NFS4ERR_BADLAYOUT = 10050, + NFS4ERR_BAD_SESSION_DIGEST = 10051, + NFS4ERR_BADSESSION = 10052, + NFS4ERR_BADSLOT = 10053, + NFS4ERR_COMPLETE_ALREADY = 10054, + NFS4ERR_CONN_NOT_BOUND_TO_SESSION = 10055, + NFS4ERR_DELEG_ALREADY_WANTED = 10056, + NFS4ERR_BACK_CHAN_BUSY = 10057, + NFS4ERR_LAYOUTTRYLATER = 10058, + NFS4ERR_LAYOUTUNAVAILABLE = 10059, + NFS4ERR_NOMATCHING_LAYOUT = 10060, + NFS4ERR_RECALLCONFLICT = 10061 +}; + +/* + * Basic data types + */ +typedef uint32_t bitmap4<>; +typedef uint64_t offset4; +typedef uint32_t count4; +typedef uint64_t length4; +typedef uint64_t clientid4; +typedef uint32_t sequenceid4; +typedef uint32_t seqid4; +typedef uint32_t slotid4; +typedef opaque utf8string<>; +typedef utf8string utf8str_cis; +typedef utf8string utf8str_cs; +typedef utf8string utf8str_mixed; +typedef utf8str_cs component4; +typedef component4 pathname4<>; +typedef uint64_t nfs_lockid4; +typedef uint64_t nfs_cookie4; +typedef utf8str_cs linktext4; +typedef opaque sec_oid4<>; +typedef uint32_t qop4; +typedef uint32_t mode4; +typedef uint64_t changeid4; +typedef opaque verifier4[NFS4_VERIFIER_SIZE]; +typedef opaque sessionid4[NFS4_SESSIONID_SIZE]; +/* + * Authsys_parms + */ +struct authsys_parms { + unsigned int stamp; + string machinename<255>; + unsigned int uid; + unsigned int gid; + unsigned int gids<16>; +}; + +const NFS4_DEVICEID4_SIZE = 16; + +typedef opaque deviceid4[NFS4_DEVICEID4_SIZE]; + +enum layouttype4 { + LAYOUT4_NFSV4_1_FILES = 0x1, + LAYOUT4_OSD2_OBJECTS = 0x2, + LAYOUT4_BLOCK_VOLUME = 0x3 +}; + +struct layoutupdate4 { + layouttype4 lou_type; + opaque lou_body<>; +}; + + +struct device_addr4 { + layouttype4 da_layout_type; + opaque da_addr_body<>; +}; + +/* + * Timeval + */ +struct nfstime4 { + int64_t seconds; + uint32_t nseconds; +}; + +enum time_how4 { + SET_TO_SERVER_TIME4 = 0, + SET_TO_CLIENT_TIME4 = 1 +}; + +enum layoutiomode4 { + LAYOUTIOMODE4_READ = 1, + LAYOUTIOMODE4_RW = 2, + LAYOUTIOMODE4_ANY = 3 +}; + +struct layout_content4 { + layouttype4 loc_type; + opaque loc_body<>; +}; + +struct layout4 { + offset4 lo_offset; + length4 lo_length; + layoutiomode4 lo_iomode; + layout_content4 lo_content; +}; + +union settime4 switch (time_how4 set_it) { + case SET_TO_CLIENT_TIME4: + nfstime4 time; + default: + void; +}; + +/* + * File access handle + */ +typedef opaque nfs_fh4; + +/* + * File attribute definitions + */ + +/* + * FSID structure for major/minor + */ +struct fsid4 { + uint64_t major; + uint64_t minor; +}; + +/* + * Filesystem locations attribute for relocation/migration + */ +struct fs_location4 { + utf8str_cis server<>; + pathname4 rootpath; +}; + +struct fs_locations4 { + pathname4 fs_root; + fs_location4 locations<>; +}; + +/* + * Various Access Control Entry definitions + */ + +/* + * Mask that indicates which Access Control Entries are supported. + * Values for the fattr4_aclsupport attribute. + */ +const ACL4_SUPPORT_ALLOW_ACL = 0x00000001; +const ACL4_SUPPORT_DENY_ACL = 0x00000002; +const ACL4_SUPPORT_AUDIT_ACL = 0x00000004; +const ACL4_SUPPORT_ALARM_ACL = 0x00000008; + + +typedef uint32_t acetype4; +/* + * acetype4 values, others can be added as needed. + */ +const ACE4_ACCESS_ALLOWED_ACE_TYPE = 0x00000000; +const ACE4_ACCESS_DENIED_ACE_TYPE = 0x00000001; +const ACE4_SYSTEM_AUDIT_ACE_TYPE = 0x00000002; +const ACE4_SYSTEM_ALARM_ACE_TYPE = 0x00000003; + + +/* + * ACE flag + */ +typedef uint32_t aceflag4; + +/* + * ACE flag values + */ +const ACE4_FILE_INHERIT_ACE = 0x00000001; +const ACE4_DIRECTORY_INHERIT_ACE = 0x00000002; +const ACE4_NO_PROPAGATE_INHERIT_ACE = 0x00000004; +const ACE4_INHERIT_ONLY_ACE = 0x00000008; +const ACE4_SUCCESSFUL_ACCESS_ACE_FLAG = 0x00000010; +const ACE4_FAILED_ACCESS_ACE_FLAG = 0x00000020; +const ACE4_IDENTIFIER_GROUP = 0x00000040; + + +/* + * ACE mask + */ +typedef uint32_t acemask4; + +/* + * ACE mask values + */ +const ACE4_READ_DATA = 0x00000001; +const ACE4_LIST_DIRECTORY = 0x00000001; +const ACE4_WRITE_DATA = 0x00000002; +const ACE4_ADD_FILE = 0x00000002; +const ACE4_APPEND_DATA = 0x00000004; +const ACE4_ADD_SUBDIRECTORY = 0x00000004; +const ACE4_READ_NAMED_ATTRS = 0x00000008; +const ACE4_WRITE_NAMED_ATTRS = 0x00000010; +const ACE4_EXECUTE = 0x00000020; +const ACE4_DELETE_CHILD = 0x00000040; +const ACE4_READ_ATTRIBUTES = 0x00000080; +const ACE4_WRITE_ATTRIBUTES = 0x00000100; +const ACE4_DELETE = 0x00010000; +const ACE4_READ_ACL = 0x00020000; +const ACE4_WRITE_ACL = 0x00040000; +const ACE4_WRITE_OWNER = 0x00080000; +const ACE4_SYNCHRONIZE = 0x00100000; + +/* + * ACE4_GENERIC_READ -- defined as combination of + * ACE4_READ_ACL | + * ACE4_READ_DATA | + * ACE4_READ_ATTRIBUTES | + * ACE4_SYNCHRONIZE + */ +const ACE4_GENERIC_READ = 0x00120081; + +/* + * ACE4_GENERIC_WRITE -- defined as combination of + * ACE4_READ_ACL | + * ACE4_WRITE_DATA | + * ACE4_WRITE_ATTRIBUTES | + * ACE4_WRITE_ACL | + * ACE4_APPEND_DATA | + * ACE4_SYNCHRONIZE + */ +const ACE4_GENERIC_WRITE = 0x00160106; + +/* + * ACE4_GENERIC_EXECUTE -- defined as combination of + * ACE4_READ_ACL + * ACE4_READ_ATTRIBUTES + * ACE4_EXECUTE + * ACE4_SYNCHRONIZE + */ +const ACE4_GENERIC_EXECUTE = 0x001200A0; + + +/* + * Access Control Entry definition + */ +struct nfsace4 { + acetype4 type; + aceflag4 flag; + acemask4 access_mask; + utf8str_mixed who; +}; + +/* + * Field definitions for the fattr4_mode attribute + */ +const MODE4_SUID = 0x800; /* set user id on execution */ +const MODE4_SGID = 0x400; /* set group id on execution */ +const MODE4_SVTX = 0x200; /* save text even after use */ +const MODE4_RUSR = 0x100; /* read permission: owner */ +const MODE4_WUSR = 0x080; /* write permission: owner */ +const MODE4_XUSR = 0x040; /* execute permission: owner */ +const MODE4_RGRP = 0x020; /* read permission: group */ +const MODE4_WGRP = 0x010; /* write permission: group */ +const MODE4_XGRP = 0x008; /* execute permission: group */ +const MODE4_ROTH = 0x004; /* read permission: other */ +const MODE4_WOTH = 0x002; /* write permission: other */ +const MODE4_XOTH = 0x001; /* execute permission: other */ + +/* + * Special data/attribute associated with + * file types NF4BLK and NF4CHR. + */ +struct specdata4 { + uint32_t specdata1; /* major device number */ + uint32_t specdata2; /* minor device number */ +}; + +/* + * Values for fattr4_fh_expire_type + */ +const FH4_PERSISTENT = 0x00000000; +const FH4_NOEXPIRE_WITH_OPEN = 0x00000001; +const FH4_VOLATILE_ANY = 0x00000002; +const FH4_VOL_MIGRATION = 0x00000004; +const FH4_VOL_RENAME = 0x00000008; + + +typedef bitmap4 fattr4_supported_attrs; +typedef nfs_ftype4 fattr4_type; +typedef uint32_t fattr4_fh_expire_type; +typedef changeid4 fattr4_change; +typedef uint64_t fattr4_size; +typedef bool fattr4_link_support; +typedef bool fattr4_symlink_support; +typedef bool fattr4_named_attr; +typedef fsid4 fattr4_fsid; +typedef bool fattr4_unique_handles; +typedef uint32_t fattr4_lease_time; +typedef nfsstat4 fattr4_rdattr_error; +typedef nfsace4 fattr4_acl<>; +typedef uint32_t fattr4_aclsupport; +typedef bool fattr4_archive; +typedef bool fattr4_cansettime; +typedef bool fattr4_case_insensitive; +typedef bool fattr4_case_preserving; +typedef bool fattr4_chown_restricted; +typedef uint64_t fattr4_fileid; +typedef uint64_t fattr4_files_avail; +typedef nfs_fh4 fattr4_filehandle; +typedef uint64_t fattr4_files_free; +typedef uint64_t fattr4_files_total; +typedef fs_locations4 fattr4_fs_locations; +typedef bool fattr4_hidden; +typedef bool fattr4_homogeneous; +typedef uint64_t fattr4_maxfilesize; +typedef uint32_t fattr4_maxlink; +typedef uint32_t fattr4_maxname; +typedef uint64_t fattr4_maxread; +typedef uint64_t fattr4_maxwrite; +typedef utf8str_cs fattr4_mimetype; +typedef mode4 fattr4_mode; +typedef uint64_t fattr4_mounted_on_fileid; +typedef bool fattr4_no_trunc; +typedef uint32_t fattr4_numlinks; +typedef utf8str_mixed fattr4_owner; +typedef utf8str_mixed fattr4_owner_group; +typedef uint64_t fattr4_quota_avail_hard; +typedef uint64_t fattr4_quota_avail_soft; +typedef uint64_t fattr4_quota_used; +typedef specdata4 fattr4_rawdev; +typedef uint64_t fattr4_space_avail; +typedef uint64_t fattr4_space_free; +typedef uint64_t fattr4_space_total; +typedef uint64_t fattr4_space_used; +typedef bool fattr4_system; +typedef nfstime4 fattr4_time_access; +typedef settime4 fattr4_time_access_set; +typedef nfstime4 fattr4_time_backup; +typedef nfstime4 fattr4_time_create; +typedef nfstime4 fattr4_time_delta; +typedef nfstime4 fattr4_time_metadata; +typedef nfstime4 fattr4_time_modify; +typedef settime4 fattr4_time_modify_set; + + +/* + * Mandatory Attributes + */ +const FATTR4_SUPPORTED_ATTRS = 0; +const FATTR4_TYPE = 1; +const FATTR4_FH_EXPIRE_TYPE = 2; +const FATTR4_CHANGE = 3; +const FATTR4_SIZE = 4; +const FATTR4_LINK_SUPPORT = 5; +const FATTR4_SYMLINK_SUPPORT = 6; +const FATTR4_NAMED_ATTR = 7; +const FATTR4_FSID = 8; +const FATTR4_UNIQUE_HANDLES = 9; +const FATTR4_LEASE_TIME = 10; +const FATTR4_RDATTR_ERROR = 11; +const FATTR4_FILEHANDLE = 19; + +/* + * Recommended Attributes + */ +const FATTR4_ACL = 12; +const FATTR4_ACLSUPPORT = 13; +const FATTR4_ARCHIVE = 14; +const FATTR4_CANSETTIME = 15; +const FATTR4_CASE_INSENSITIVE = 16; +const FATTR4_CASE_PRESERVING = 17; +const FATTR4_CHOWN_RESTRICTED = 18; +const FATTR4_FILEID = 20; +const FATTR4_FILES_AVAIL = 21; +const FATTR4_FILES_FREE = 22; +const FATTR4_FILES_TOTAL = 23; +const FATTR4_FS_LOCATIONS = 24; +const FATTR4_HIDDEN = 25; +const FATTR4_HOMOGENEOUS = 26; +const FATTR4_MAXFILESIZE = 27; +const FATTR4_MAXLINK = 28; +const FATTR4_MAXNAME = 29; +const FATTR4_MAXREAD = 30; +const FATTR4_MAXWRITE = 31; +const FATTR4_MIMETYPE = 32; +const FATTR4_MODE = 33; +const FATTR4_NO_TRUNC = 34; +const FATTR4_NUMLINKS = 35; +const FATTR4_OWNER = 36; +const FATTR4_OWNER_GROUP = 37; +const FATTR4_QUOTA_AVAIL_HARD = 38; +const FATTR4_QUOTA_AVAIL_SOFT = 39; +const FATTR4_QUOTA_USED = 40; +const FATTR4_RAWDEV = 41; +const FATTR4_SPACE_AVAIL = 42; +const FATTR4_SPACE_FREE = 43; +const FATTR4_SPACE_TOTAL = 44; +const FATTR4_SPACE_USED = 45; +const FATTR4_SYSTEM = 46; +const FATTR4_TIME_ACCESS = 47; +const FATTR4_TIME_ACCESS_SET = 48; +const FATTR4_TIME_BACKUP = 49; +const FATTR4_TIME_CREATE = 50; +const FATTR4_TIME_DELTA = 51; +const FATTR4_TIME_METADATA = 52; +const FATTR4_TIME_MODIFY = 53; +const FATTR4_TIME_MODIFY_SET = 54; +const FATTR4_MOUNTED_ON_FILEID = 55; + +typedef opaque attrlist4<>; + +/* + * File attribute container + */ +struct fattr4 { + bitmap4 attrmask; + attrlist4 attr_vals; +}; + +/* + * Change info for the client + */ +struct change_info4 { + bool atomic; + changeid4 before; + changeid4 after; +}; + +struct clientaddr4 { + /* see struct rpcb in RFC 1833 */ + string r_netid<>; /* network id */ + string r_addr<>; /* universal address */ +}; + +/* + * Callback program info as provided by the client + */ +struct cb_client4 { + uint32_t cb_program; + clientaddr4 cb_location; +}; + +/* + * Stateid + */ +struct stateid4 { + uint32_t seqid; + opaque other[12]; +}; + +/* + * Client ID + */ +struct nfs_client_id4 { + verifier4 verifier; + opaque id; +}; + +struct open_owner4 { + clientid4 clientid; + opaque owner; +}; + +struct lock_owner4 { + clientid4 clientid; + opaque owner; +}; + +enum nfs_lock_type4 { + READ_LT = 1, + WRITE_LT = 2, + READW_LT = 3, /* blocking read */ + WRITEW_LT = 4 /* blocking write */ +}; + +/* + * Client owner + */ +struct client_owner4 { + verifier4 co_verifier; + opaque co_ownerid; +}; + +/* + * Server owner + */ +struct server_owner4 { + uint64_t so_minor_id; + opaque so_major_id; +}; + +/* + * NFS implementation details + */ +struct nfs_impl_id4 { + utf8str_cis nii_domain; + utf8str_cs nii_name; + nfstime4 nii_date; +}; + +/* + * ACCESS: Check access permission + */ +const ACCESS4_READ = 0x00000001; +const ACCESS4_LOOKUP = 0x00000002; +const ACCESS4_MODIFY = 0x00000004; +const ACCESS4_EXTEND = 0x00000008; +const ACCESS4_DELETE = 0x00000010; +const ACCESS4_EXECUTE = 0x00000020; + +struct ACCESS4args { + /* CURRENT_FH: object */ + uint32_t access; +}; + +struct ACCESS4resok { + uint32_t supported; + uint32_t access; +}; + +union ACCESS4res switch (nfsstat4 status) { + case NFS4_OK: + ACCESS4resok resok4; + default: + void; +}; + +/* + * CLOSE: Close a file and release share reservations + */ +struct CLOSE4args { + /* CURRENT_FH: object */ + seqid4 seqid; + stateid4 open_stateid; +}; + +union CLOSE4res switch (nfsstat4 status) { + case NFS4_OK: + stateid4 open_stateid; + default: + void; +}; + +/* + * COMMIT: Commit cached data on server to stable storage + */ +struct COMMIT4args { + /* CURRENT_FH: file */ + offset4 offset; + count4 count; +}; + +struct COMMIT4resok { + verifier4 writeverf; +}; + + +union COMMIT4res switch (nfsstat4 status) { + case NFS4_OK: + COMMIT4resok resok4; + default: + void; +}; + +/* + * CREATE: Create a non-regular file + */ +union createtype4 switch (nfs_ftype4 type) { + case NF4LNK: + linktext4 linkdata; + case NF4BLK: + case NF4CHR: + specdata4 devdata; + case NF4SOCK: + case NF4FIFO: + case NF4DIR: + void; + default: + void; /* server should return NFS4ERR_BADTYPE */ +}; + +struct CREATE4args { + /* CURRENT_FH: directory for creation */ + createtype4 objtype; + component4 objname; + fattr4 createattrs; +}; + +struct CREATE4resok { + change_info4 cinfo; + bitmap4 attrset; /* attributes set */ +}; + +union CREATE4res switch (nfsstat4 status) { + case NFS4_OK: + CREATE4resok resok4; + default: + void; +}; + +/* + * DELEGPURGE: Purge Delegations Awaiting Recovery + */ +struct DELEGPURGE4args { + clientid4 clientid; +}; + +struct DELEGPURGE4res { + nfsstat4 status; +}; + +/* + * DELEGRETURN: Return a delegation + */ +struct DELEGRETURN4args { + /* CURRENT_FH: delegated file */ + stateid4 deleg_stateid; +}; + +struct DELEGRETURN4res { + nfsstat4 status; +}; + +/* + * GETATTR: Get file attributes + */ +struct GETATTR4args { + /* CURRENT_FH: directory or file */ + bitmap4 attr_request; +}; + +struct GETATTR4resok { + fattr4 obj_attributes; +}; + +union GETATTR4res switch (nfsstat4 status) { + case NFS4_OK: + GETATTR4resok resok4; + default: + void; +}; + +/* + * GETFH: Get current filehandle + */ +struct GETFH4resok { + nfs_fh4 object; +}; + +union GETFH4res switch (nfsstat4 status) { + case NFS4_OK: + GETFH4resok resok4; + default: + void; +}; + +/* + * LINK: Create link to an object + */ +struct LINK4args { + /* SAVED_FH: source object */ + /* CURRENT_FH: target directory */ + component4 newname; +}; + +struct LINK4resok { + change_info4 cinfo; +}; + +union LINK4res switch (nfsstat4 status) { + case NFS4_OK: + LINK4resok resok4; + default: + void; +}; + +/* + * For LOCK, transition from open_owner to new lock_owner + */ +struct open_to_lock_owner4 { + seqid4 open_seqid; + stateid4 open_stateid; + seqid4 lock_seqid; + lock_owner4 lock_owner; +}; + +/* + * For LOCK, existing lock_owner continues to request file locks + */ +struct exist_lock_owner4 { + stateid4 lock_stateid; + seqid4 lock_seqid; +}; + +union locker4 switch (bool new_lock_owner) { + case TRUE: + open_to_lock_owner4 open_owner; + case FALSE: + exist_lock_owner4 lock_owner; +}; + +/* + * LOCK/LOCKT/LOCKU: Record lock management + */ +struct LOCK4args { + /* CURRENT_FH: file */ + nfs_lock_type4 locktype; + bool reclaim; + offset4 offset; + length4 length; + locker4 locker; +}; + +struct LOCK4denied { + offset4 offset; + length4 length; + nfs_lock_type4 locktype; + lock_owner4 owner; +}; + +struct LOCK4resok { + stateid4 lock_stateid; +}; + +union LOCK4res switch (nfsstat4 status) { + case NFS4_OK: + LOCK4resok resok4; + case NFS4ERR_DENIED: + LOCK4denied denied; + default: + void; +}; + +struct LOCKT4args { + /* CURRENT_FH: file */ + nfs_lock_type4 locktype; + offset4 offset; + length4 length; + lock_owner4 owner; +}; + +union LOCKT4res switch (nfsstat4 status) { + case NFS4ERR_DENIED: + LOCK4denied denied; + case NFS4_OK: + void; + default: + void; +}; + +struct LOCKU4args { + /* CURRENT_FH: file */ + nfs_lock_type4 locktype; + seqid4 seqid; + stateid4 lock_stateid; + offset4 offset; + length4 length; +}; + +union LOCKU4res switch (nfsstat4 status) { + case NFS4_OK: + stateid4 lock_stateid; + default: + void; +}; + +/* + * LOOKUP: Lookup filename + */ +struct LOOKUP4args { + /* CURRENT_FH: directory */ + component4 objname; +}; + +struct LOOKUP4res { + /* CURRENT_FH: object */ + nfsstat4 status; +}; + +/* + * LOOKUPP: Lookup parent directory + */ +struct LOOKUPP4res { + /* CURRENT_FH: directory */ + nfsstat4 status; +}; + +/* + * NVERIFY: Verify attributes different + */ +struct NVERIFY4args { + /* CURRENT_FH: object */ + fattr4 obj_attributes; +}; + +struct NVERIFY4res { + nfsstat4 status; +}; + +/* + * Various definitions for OPEN + */ +enum createmode4 { + UNCHECKED4 = 0, + GUARDED4 = 1, + EXCLUSIVE4 = 2 +}; + +union createhow4 switch (createmode4 mode) { + case UNCHECKED4: + case GUARDED4: + fattr4 createattrs; + case EXCLUSIVE4: + verifier4 createverf; +}; + +enum opentype4 { + OPEN4_NOCREATE = 0, + OPEN4_CREATE = 1 +}; + +union openflag4 switch (opentype4 opentype) { + case OPEN4_CREATE: + createhow4 how; + default: + void; +}; + +/* Next definitions used for OPEN delegation */ +enum limit_by4 { + NFS_LIMIT_SIZE = 1, + NFS_LIMIT_BLOCKS = 2 + /* others as needed */ +}; + +struct nfs_modified_limit4 { + uint32_t num_blocks; + uint32_t bytes_per_block; +}; + +union nfs_space_limit4 switch (limit_by4 limitby) { + /* limit specified as file size */ + case NFS_LIMIT_SIZE: + uint64_t filesize; + /* limit specified by number of blocks */ + case NFS_LIMIT_BLOCKS: + nfs_modified_limit4 mod_blocks; +} ; + +/* + * Share Access and Deny constants for open argument + */ +const OPEN4_SHARE_ACCESS_READ = 0x00000001; +const OPEN4_SHARE_ACCESS_WRITE = 0x00000002; +const OPEN4_SHARE_ACCESS_BOTH = 0x00000003; + +const OPEN4_SHARE_DENY_NONE = 0x00000000; +const OPEN4_SHARE_DENY_READ = 0x00000001; +const OPEN4_SHARE_DENY_WRITE = 0x00000002; +const OPEN4_SHARE_DENY_BOTH = 0x00000003; + +enum open_delegation_type4 { + OPEN_DELEGATE_NONE = 0, + OPEN_DELEGATE_READ = 1, + OPEN_DELEGATE_WRITE = 2 +}; + +enum open_claim_type4 { + CLAIM_NULL = 0, + CLAIM_PREVIOUS = 1, + CLAIM_DELEGATE_CUR = 2, + CLAIM_DELEGATE_PREV = 3, + CLAIM_FH = 4, /* new to v4.1 */ + CLAIM_DELEG_CUR_FH = 5, /* new to v4.1 */ + CLAIM_DELEG_PREV_FH = 6 /* new to v4.1 */ +}; + +struct open_claim_delegate_cur4 { + stateid4 delegate_stateid; + component4 file; +}; + +union open_claim4 switch (open_claim_type4 claim) { + /* + * No special rights to file. Ordinary OPEN of the specified file. + */ + case CLAIM_NULL: + /* CURRENT_FH: directory */ + component4 file; + + /* + * Right to the file established by an open previous to server + * reboot. File identified by filehandle obtained at that time + * rather than by name. + */ + case CLAIM_PREVIOUS: + /* CURRENT_FH: file being reclaimed */ + open_delegation_type4 delegate_type; + + /* + * Right to file based on a delegation granted by the server. + * File is specified by name. + */ + case CLAIM_DELEGATE_CUR: + /* CURRENT_FH: directory */ + open_claim_delegate_cur4 delegate_cur_info; + + /* Right to file based on a delegation granted to a previous boot + * instance of the client. File is specified by name. + */ + case CLAIM_DELEGATE_PREV: + /* CURRENT_FH: directory */ + component4 file_delegate_prev; + + /* + * Like CLAIM_NULL. No special rights + * to file. Ordinary OPEN of the + * specified file by current filehandle. + */ + case CLAIM_FH: /* new to v4.1 */ + /* CURRENT_FH: regular file to open */ + void; + + /* + * Like CLAIM_DELEGATE_PREV. Right to file based on a + * delegation granted to a previous boot + * instance of the client. File is identified by + * by filehandle. + */ + case CLAIM_DELEG_PREV_FH: /* new to v4.1 */ + /* CURRENT_FH: file being opened */ + void; + + /* + * Like CLAIM_DELEGATE_CUR. Right to file based on + * a delegation granted by the server. + * File is identified by filehandle. + */ + case CLAIM_DELEG_CUR_FH: /* new to v4.1 */ + /* CURRENT_FH: file being opened */ + stateid4 oc_delegate_stateid; +}; + +/* + * OPEN: Open a file, potentially receiving an open delegation + */ +struct OPEN4args { + seqid4 seqid; + uint32_t share_access; + uint32_t share_deny; + open_owner4 owner; + openflag4 openhow; + open_claim4 claim; +}; + +struct open_read_delegation4 { + stateid4 stateid; /* Stateid for delegation*/ + bool recall; /* Pre-recalled flag for + delegations obtained + by reclaim + (CLAIM_PREVIOUS) */ + nfsace4 permissions; /* Defines users who don't + need an ACCESS call to + open for read */ +}; + +struct open_write_delegation4 { + stateid4 stateid; /* Stateid for delegation */ + bool recall; /* Pre-recalled flag for + delegations obtained + by reclaim + (CLAIM_PREVIOUS) */ + nfs_space_limit4 space_limit; /* Defines condition that + the client must check to + determine whether the + file needs to be flushed + to the server on close. + */ + nfsace4 permissions; /* Defines users who don't + need an ACCESS call as + part of a delegated + open. */ +}; + +union open_delegation4 +switch (open_delegation_type4 delegation_type) { + case OPEN_DELEGATE_NONE: + void; + case OPEN_DELEGATE_READ: + open_read_delegation4 read; + case OPEN_DELEGATE_WRITE: + open_write_delegation4 write; +}; +/* + * Result flags + */ +/* Client must confirm open */ +const OPEN4_RESULT_CONFIRM = 0x00000002; +/* Type of file locking behavior at the server */ +const OPEN4_RESULT_LOCKTYPE_POSIX = 0x00000004; + +struct OPEN4resok { + stateid4 stateid; /* Stateid for open */ + change_info4 cinfo; /* Directory Change Info */ + uint32_t rflags; /* Result flags */ + bitmap4 attrset; /* attribute set for create*/ + open_delegation4 delegation; /* Info on any open + delegation */ +}; + +union OPEN4res switch (nfsstat4 status) { + case NFS4_OK: + /* CURRENT_FH: opened file */ + OPEN4resok resok4; + default: + void; +}; + +/* + * OPENATTR: open named attributes directory + */ +struct OPENATTR4args { + /* CURRENT_FH: object */ + bool createdir; +}; + +struct OPENATTR4res { + /* CURRENT_FH: named attr directory */ + nfsstat4 status; +}; + +/* + * OPEN_CONFIRM: confirm the open + */ +struct OPEN_CONFIRM4args { + /* CURRENT_FH: opened file */ + stateid4 open_stateid; + seqid4 seqid; +}; + +struct OPEN_CONFIRM4resok { + stateid4 open_stateid; +}; + +union OPEN_CONFIRM4res switch (nfsstat4 status) { + case NFS4_OK: + OPEN_CONFIRM4resok resok4; + default: + void; +}; + +/* + * OPEN_DOWNGRADE: downgrade the access/deny for a file + */ +struct OPEN_DOWNGRADE4args { + /* CURRENT_FH: opened file */ + stateid4 open_stateid; + seqid4 seqid; + uint32_t share_access; + uint32_t share_deny; +}; + +struct OPEN_DOWNGRADE4resok { + stateid4 open_stateid; +}; + +union OPEN_DOWNGRADE4res switch(nfsstat4 status) { + case NFS4_OK: + OPEN_DOWNGRADE4resok resok4; + default: + void; +}; + +/* + * PUTFH: Set current filehandle + */ +struct PUTFH4args { + nfs_fh4 object; +}; + +struct PUTFH4res { + /* CURRENT_FH: */ + nfsstat4 status; +}; + +/* + * PUTPUBFH: Set public filehandle + */ +struct PUTPUBFH4res { + /* CURRENT_FH: public fh */ + nfsstat4 status; +}; + +/* + * PUTROOTFH: Set root filehandle + */ +struct PUTROOTFH4res { + + /* CURRENT_FH: root fh */ + nfsstat4 status; +}; + +/* + * READ: Read from file + */ +struct READ4args { + /* CURRENT_FH: file */ + stateid4 stateid; + offset4 offset; + count4 count; +}; + +struct READ4resok { + bool eof; + opaque data<>; +}; + +union READ4res switch (nfsstat4 status) { + case NFS4_OK: + READ4resok resok4; + default: + void; +}; + +/* + * READDIR: Read directory + */ +struct READDIR4args { + /* CURRENT_FH: directory */ + nfs_cookie4 cookie; + verifier4 cookieverf; + count4 dircount; + count4 maxcount; + bitmap4 attr_request; +}; + +struct entry4 { + nfs_cookie4 cookie; + component4 name; + fattr4 attrs; + entry4 *nextentry; +}; + +struct dirlist4 { + entry4 *entries; + bool eof; +}; + +struct READDIR4resok { + verifier4 cookieverf; + dirlist4 reply; +}; + + +union READDIR4res switch (nfsstat4 status) { + case NFS4_OK: + READDIR4resok resok4; + default: + void; +}; + + +/* + * READLINK: Read symbolic link + */ +struct READLINK4resok { + linktext4 link; +}; + +union READLINK4res switch (nfsstat4 status) { + case NFS4_OK: + READLINK4resok resok4; + default: + void; +}; + +/* + * REMOVE: Remove filesystem object + */ +struct REMOVE4args { + /* CURRENT_FH: directory */ + component4 target; +}; + +struct REMOVE4resok { + change_info4 cinfo; +}; + +union REMOVE4res switch (nfsstat4 status) { + case NFS4_OK: + REMOVE4resok resok4; + default: + void; +}; + +/* + * RENAME: Rename directory entry + */ +struct RENAME4args { + /* SAVED_FH: source directory */ + component4 oldname; + /* CURRENT_FH: target directory */ + + component4 newname; +}; + +struct RENAME4resok { + change_info4 source_cinfo; + change_info4 target_cinfo; +}; + +union RENAME4res switch (nfsstat4 status) { + case NFS4_OK: + RENAME4resok resok4; + default: + void; +}; + +/* + * RENEW: Renew a Lease + */ +struct RENEW4args { + clientid4 clientid; +}; + +struct RENEW4res { + nfsstat4 status; +}; + +/* + * RESTOREFH: Restore saved filehandle + */ + +struct RESTOREFH4res { + /* CURRENT_FH: value of saved fh */ + nfsstat4 status; +}; + +/* + * SAVEFH: Save current filehandle + */ +struct SAVEFH4res { + /* SAVED_FH: value of current fh */ + nfsstat4 status; +}; + +/* + * SECINFO: Obtain Available Security Mechanisms + */ +struct SECINFO4args { + component4 name; +}; + +enum rpc_gss_svc_t { + RPC_GSS_SVC_NONE = 1, + RPC_GSS_SVC_INTEGRITY = 2, + RPC_GSS_SVC_PRIVACY = 3 +}; + +struct rpcsec_gss_info { + sec_oid4 oid; + qop4 qop; + rpc_gss_svc_t service; +}; + +const RPCSEC_GSS = 6; + +union secinfo4 switch (uint32_t flavor) { + case RPCSEC_GSS: + rpcsec_gss_info flavor_info; + default: + void; +}; + +typedef secinfo4 SECINFO4resok<>; + +union SECINFO4res switch (nfsstat4 status) { + case NFS4_OK: + SECINFO4resok resok4; + default: + void; +}; + +/* + * SETATTR: Set attributes + */ +struct SETATTR4args { + /* CURRENT_FH: target object */ + stateid4 stateid; + fattr4 obj_attributes; +}; + +struct SETATTR4res { + nfsstat4 status; + bitmap4 attrsset; +}; + +/* + * SETCLIENTID + */ +struct SETCLIENTID4args { + nfs_client_id4 client; + cb_client4 callback; + uint32_t callback_ident; + +}; + +struct SETCLIENTID4resok { + clientid4 clientid; + verifier4 setclientid_confirm; +}; + +union SETCLIENTID4res switch (nfsstat4 status) { + case NFS4_OK: + SETCLIENTID4resok resok4; + case NFS4ERR_CLID_INUSE: + clientaddr4 client_using; + default: + void; +}; + +struct SETCLIENTID_CONFIRM4args { + clientid4 clientid; + verifier4 setclientid_confirm; +}; + +struct SETCLIENTID_CONFIRM4res { + nfsstat4 status; +}; + +/* + * VERIFY: Verify attributes same + */ +struct VERIFY4args { + /* CURRENT_FH: object */ + fattr4 obj_attributes; +}; + +struct VERIFY4res { + nfsstat4 status; +}; + +/* + * WRITE: Write to file + */ +enum stable_how4 { + UNSTABLE4 = 0, + DATA_SYNC4 = 1, + FILE_SYNC4 = 2 +}; + +struct WRITE4args { + /* CURRENT_FH: file */ + stateid4 stateid; + offset4 offset; + stable_how4 stable; + opaque data<>; +}; + +struct WRITE4resok { + count4 count; + stable_how4 committed; + verifier4 writeverf; +}; + +union WRITE4res switch (nfsstat4 status) { + case NFS4_OK: + WRITE4resok resok4; + default: + void; +}; + +/* + * RELEASE_LOCKOWNER: Notify server to release lockowner + */ +struct RELEASE_LOCKOWNER4args { + lock_owner4 lock_owner; +}; + +struct RELEASE_LOCKOWNER4res { + nfsstat4 status; +}; + +/* + * BACKCHANNEL_CTL + */ +typedef opaque gsshandle4_t<>; + +/* +struct gss_cb_handles4 { + rpc_gss_svc_t gcbp_service; RFC 2203 + gsshandle4_t gcbp_handle_from_server; + gsshandle4_t gcbp_handle_from_client; +}; +*/ + +union callback_sec_parms4 switch (uint32_t cb_secflavor) { +case AUTH_NONE: + void; +case AUTH_SYS: + authsys_parms cbsp_sys_cred; /* RFC 1831 */ +/* + * case RPCSEC_GSS: + * gss_cb_handles4 cbsp_gss_handles; + */ +}; + +/* +struct BACKCHANNEL_CTL4args { + uint32_t bca_cb_program; + callback_sec_parms4 bca_sec_parms<>; +}; +*/ + +/* + * BIND_CONN_TO_SESSION + */ +enum channel_dir_from_client4 { + CDFC4_FORE = 0x1, + CDFC4_BACK = 0x2, + CDFC4_FORE_OR_BOTH = 0x3, + CDFC4_BACK_OR_BOTH = 0x7 +}; + +struct BIND_CONN_TO_SESSION4args { + sessionid4 bctsa_sessid; + channel_dir_from_client4 bctsa_dir; + bool bctsa_use_conn_in_rdma_mode; +}; + +enum channel_dir_from_server4 { + CDFS4_FORE = 0x1, + CDFS4_BACK = 0x2, + CDFS4_BOTH = 0x3 +}; + +struct BIND_CONN_TO_SESSION4resok { + sessionid4 bctsr_sessid; + channel_dir_from_server4 bctsr_dir; + bool bctsr_use_conn_in_rdma_mode; +}; + +union BIND_CONN_TO_SESSION4res switch (nfsstat4 bctsr_status) { +case NFS4_OK: + BIND_CONN_TO_SESSION4resok bctsr_resok4; +default: + void; +}; + +/* + * EXCHANGE_ID + */ +const EXCHGID4_FLAG_SUPP_MOVED_REFER = 0x00000001; +const EXCHGID4_FLAG_SUPP_MOVED_MIGR = 0x00000002; + +const EXCHGID4_FLAG_BIND_PRINC_STATEID = 0x00000100; + +const EXCHGID4_FLAG_USE_NON_PNFS = 0x00010000; +const EXCHGID4_FLAG_USE_PNFS_MDS = 0x00020000; +const EXCHGID4_FLAG_USE_PNFS_DS = 0x00040000; + +const EXCHGID4_FLAG_MASK_PNFS = 0x00070000; + +const EXCHGID4_FLAG_UPD_CONFIRMED_REC_A = 0x40000000; +const EXCHGID4_FLAG_CONFIRMED_R = 0x80000000; + +struct state_protect_ops4 { + bitmap4 spo_must_enforce; + bitmap4 spo_must_allow; +}; + +struct ssv_sp_parms4 { + state_protect_ops4 ssp_ops; + sec_oid4 ssp_hash_algs<>; + sec_oid4 ssp_encr_algs<>; + uint32_t ssp_window; + uint32_t ssp_num_gss_handles; +}; + +enum state_protect_how4 { + SP4_NONE = 0, + SP4_MACH_CRED = 1, + SP4_SSV = 2 +}; + +union state_protect4_a switch(state_protect_how4 spa_how) { +case SP4_NONE: + void; +case SP4_MACH_CRED: + state_protect_ops4 spa_mach_ops; +case SP4_SSV: + ssv_sp_parms4 spa_ssv_parms; +}; + +struct EXCHANGE_ID4args { + client_owner4 eia_clientowner; + uint32_t eia_flags; + state_protect4_a eia_state_protect; + nfs_impl_id4 eia_client_impl_id<1>; +}; + +struct ssv_prot_info4 { + state_protect_ops4 spi_ops; + uint32_t spi_hash_alg; + uint32_t spi_encr_alg; + uint32_t spi_ssv_len; + uint32_t spi_window; + gsshandle4_t spi_handles<>; +}; + +union state_protect4_r switch(state_protect_how4 spr_how) { +case SP4_NONE: + void; +case SP4_MACH_CRED: + state_protect_ops4 spr_mach_ops; +case SP4_SSV: + ssv_prot_info4 spr_ssv_info; +}; + +struct EXCHANGE_ID4resok { + clientid4 eir_clientid; + sequenceid4 eir_sequenceid; + uint32_t eir_flags; + state_protect4_r eir_state_protect; + server_owner4 eir_server_owner; + opaque eir_server_scope; + nfs_impl_id4 eir_server_impl_id<1>; +}; + +union EXCHANGE_ID4res switch (nfsstat4 eir_status) { +case NFS4_OK: + EXCHANGE_ID4resok eir_resok4; +default: + void; +}; + +/* + * CREATE_SESSION + */ +struct channel_attrs4 { + count4 ca_headerpadsize; + count4 ca_maxrequestsize; + count4 ca_maxresponsesize; + count4 ca_maxresponsesize_cached; + count4 ca_maxoperations; + count4 ca_maxrequests; + uint32_t ca_rdma_ird<1>; +}; + +const CREATE_SESSION4_FLAG_PERSIST = 0x00000001; +const CREATE_SESSION4_FLAG_CONN_BACK_CHAN = 0x00000002; +const CREATE_SESSION4_FLAG_CONN_RDMA = 0x00000004; + +struct CREATE_SESSION4args { + clientid4 csa_clientid; + sequenceid4 csa_sequence; + uint32_t csa_flags; + channel_attrs4 csa_fore_chan_attrs; + channel_attrs4 csa_back_chan_attrs; + uint32_t csa_cb_program; + callback_sec_parms4 csa_sec_parms<>; +}; + +struct CREATE_SESSION4resok { + sessionid4 csr_sessionid; + sequenceid4 csr_sequence; + uint32_t csr_flags; + channel_attrs4 csr_fore_chan_attrs; + channel_attrs4 csr_back_chan_attrs; +}; + +union CREATE_SESSION4res switch (nfsstat4 csr_status) { +case NFS4_OK: + CREATE_SESSION4resok csr_resok4; +default: + void; +}; + +/* + * DESTROY_SESSION + */ +struct DESTROY_SESSION4args { + sessionid4 dsa_sessionid; +}; + +struct DESTROY_SESSION4res { + nfsstat4 dsr_status; +}; + +/* + * FREE_STATEID + */ +struct FREE_STATEID4args { + stateid4 fsa_stateid; +}; + +struct FREE_STATEID4res { + nfsstat4 fsr_status; +}; + +/* + * GET_DIR_DELEGATION + */ +typedef nfstime4 attr_notice4; + +struct GET_DIR_DELEGATION4args { + bool gdda_signal_deleg_avail; + bitmap4 gdda_notification_types; + attr_notice4 gdda_child_attr_delay; + attr_notice4 gdda_dir_attr_delay; + bitmap4 gdda_child_attributes; + bitmap4 gdda_dir_attributes; +}; + +struct GET_DIR_DELEGATION4resok { + verifier4 gddr_cookieverf; + stateid4 gddr_stateid; + bitmap4 gddr_notification; + bitmap4 gddr_child_attributes; + bitmap4 gddr_dir_attributes; +}; + +enum gddrnf4_status { + GDD4_OK = 0, + GDD4_UNAVAIL = 1 +}; + +union GET_DIR_DELEGATION4res_non_fatal switch (gddrnf4_status gddrnf_status) { + case GDD4_OK: + GET_DIR_DELEGATION4resok gddrnf_resok4; + case GDD4_UNAVAIL: + bool gddrnf_will_signal_deleg_avail; +}; + +union GET_DIR_DELEGATION4res switch (nfsstat4 gddr_status) { + case NFS4_OK: + GET_DIR_DELEGATION4res_non_fatal gddr_res_non_fatal4; + default: + void; +}; + +/* + * GETDEVICEINFO + */ +struct GETDEVICEINFO4args { + deviceid4 gdia_device_id; + layouttype4 gdia_layout_type; + count4 gdia_maxcount; + bitmap4 gdia_notify_types; +}; + +struct GETDEVICEINFO4resok { + device_addr4 gdir_device_addr; + bitmap4 gdir_notification; +}; + +union GETDEVICEINFO4res switch (nfsstat4 gdir_status) { +case NFS4_OK: + GETDEVICEINFO4resok gdir_resok4; +case NFS4ERR_TOOSMALL: + count4 gdir_mincount; +default: + void; +}; + +/* + * GETDEVICELIST + */ +struct GETDEVICELIST4args { + layouttype4 gdla_layout_type; + count4 gdla_maxdevices; + nfs_cookie4 gdla_cookie; + verifier4 gdla_cookieverf; +}; + +struct GETDEVICELIST4resok { + nfs_cookie4 gdlr_cookie; + verifier4 gdlr_cookieverf; + deviceid4 gdlr_deviceid_list<>; + bool gdlr_eof; +}; + +union GETDEVICELIST4res switch (nfsstat4 gdlr_status) { +case NFS4_OK: + GETDEVICELIST4resok gdlr_resok4; +default: + void; +}; + +/* + * LAYOUTCOMMIT + */ +union newtime4 switch (bool nt_timechanged) { +case TRUE: + nfstime4 nt_time; +case FALSE: + void; +}; + +union newoffset4 switch (bool no_newoffset) { +case TRUE: + offset4 no_offset; +case FALSE: + void; +}; + +struct LAYOUTCOMMIT4args { + offset4 loca_offset; + length4 loca_length; + bool loca_reclaim; + stateid4 loca_stateid; + newoffset4 loca_last_write_offset; + newtime4 loca_time_modify; + layoutupdate4 loca_layoutupdate; +}; + +union newsize4 switch (bool ns_sizechanged) { +case TRUE: + length4 ns_size; +case FALSE: + void; +}; + +struct LAYOUTCOMMIT4resok { + newsize4 locr_newsize; +}; + +union LAYOUTCOMMIT4res switch (nfsstat4 locr_status) { +case NFS4_OK: + LAYOUTCOMMIT4resok locr_resok4; +default: + void; +}; + +/* + * LAYOUTGET + */ +struct LAYOUTGET4args { + bool loga_signal_layout_avail; + layouttype4 loga_layout_type; + layoutiomode4 loga_iomode; + offset4 loga_offset; + length4 loga_length; + length4 loga_minlength; + stateid4 loga_stateid; + count4 loga_maxcount; +}; + +struct LAYOUTGET4resok { + bool logr_return_on_close; + stateid4 logr_stateid; + layout4 logr_layout<>; +}; + +union LAYOUTGET4res switch (nfsstat4 logr_status) { +case NFS4_OK: + LAYOUTGET4resok logr_resok4; +case NFS4ERR_LAYOUTTRYLATER: + bool logr_will_signal_layout_avail; +default: + void; +}; + +/* + * LAYOUTRETURN + */ +const LAYOUT4_RET_REC_FILE = 1; +const LAYOUT4_RET_REC_FSID = 2; +const LAYOUT4_RET_REC_ALL = 3; + +enum layoutreturn_type4 { + LAYOUTRETURN4_FILE = LAYOUT4_RET_REC_FILE, + LAYOUTRETURN4_FSID = LAYOUT4_RET_REC_FSID, + LAYOUTRETURN4_ALL = LAYOUT4_RET_REC_ALL +}; + +struct layoutreturn_file4 { + offset4 lrf_offset; + length4 lrf_length; + stateid4 lrf_stateid; + opaque lrf_body<>; +}; + +union layoutreturn4 switch(layoutreturn_type4 lr_returntype) { + case LAYOUTRETURN4_FILE: + layoutreturn_file4 lr_layout; + default: + void; +}; + +struct LAYOUTRETURN4args { + bool lora_reclaim; + layouttype4 lora_layout_type; + layoutiomode4 lora_iomode; + layoutreturn4 lora_layoutreturn; +}; + +union layoutreturn_stateid switch (bool lrs_present) { +case TRUE: + stateid4 lrs_stateid; +case FALSE: + void; +}; + +union LAYOUTRETURN4res switch (nfsstat4 lorr_status) { +case NFS4_OK: + layoutreturn_stateid lorr_stateid; +default: + void; +}; + +/* + * SECINFO_NO_NAME + */ +enum secinfo_style4 { + SECINFO_STYLE4_CURRENT_FH = 0, + SECINFO_STYLE4_PARENT = 1 +}; + +typedef secinfo_style4 SECINFO_NO_NAME4args; + +typedef SECINFO4res SECINFO_NO_NAME4res; + +/* + * SEQUENCE + */ +struct SEQUENCE4args { + sessionid4 sa_sessionid; + sequenceid4 sa_sequenceid; + slotid4 sa_slotid; + slotid4 sa_highest_slotid; + bool sa_cachethis; +}; + +const SEQ4_STATUS_CB_PATH_DOWN = 0x00000001; +const SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING = 0x00000002; +const SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRED = 0x00000004; +const SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED = 0x00000008; +const SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED = 0x00000010; +const SEQ4_STATUS_ADMIN_STATE_REVOKED = 0x00000020; +const SEQ4_STATUS_RECALLABLE_STATE_REVOKED = 0x00000040; +const SEQ4_STATUS_LEASE_MOVED = 0x00000080; +const SEQ4_STATUS_RESTART_RECLAIM_NEEDED = 0x00000100; +const SEQ4_STATUS_CB_PATH_DOWN_SESSION = 0x00000200; +const SEQ4_STATUS_BACKCHANNEL_FAULT = 0x00000400; +const SEQ4_STATUS_DEVID_CHANGED = 0x00000800; +const SEQ4_STATUS_DEVID_DELETED = 0x00001000; + +struct SEQUENCE4resok { + sessionid4 sr_sessionid; + sequenceid4 sr_sequenceid; + slotid4 sr_slotid; + slotid4 sr_highest_slotid; + slotid4 sr_target_highest_slotid; + uint32_t sr_status_flags; +}; + +union SEQUENCE4res switch (nfsstat4 sr_status) { +case NFS4_OK: + SEQUENCE4resok sr_resok4; +default: + void; +}; + +/* + * SET_SSV + */ +struct ssa_digest_input4 { + SEQUENCE4args sdi_seqargs; +}; + +struct SET_SSV4args { + opaque ssa_ssv<>; + opaque ssa_digest<>; +}; + +struct ssr_digest_input4 { + SEQUENCE4res sdi_seqres; +}; + +struct SET_SSV4resok { + opaque ssr_digest<>; +}; + +union SET_SSV4res switch (nfsstat4 ssr_status) { +case NFS4_OK: + SET_SSV4resok ssr_resok4; +default: + void; +}; + +/* + * TEST_STATEID + */ +struct TEST_STATEID4args { + stateid4 ts_stateids<>; +}; + +struct TEST_STATEID4resok { + nfsstat4 tsr_status_codes<>; +}; + +union TEST_STATEID4res switch (nfsstat4 tsr_status) { + case NFS4_OK: + TEST_STATEID4resok tsr_resok4; + default: + void; +}; + +/* + * WANT_DELEGATION + */ +union deleg_claim4 switch (open_claim_type4 dc_claim) { +case CLAIM_FH: + void; +case CLAIM_DELEG_PREV_FH: + void; +case CLAIM_PREVIOUS: + open_delegation_type4 dc_delegate_type; +}; + +struct WANT_DELEGATION4args { + uint32_t wda_want; + deleg_claim4 wda_claim; +}; + +union WANT_DELEGATION4res switch (nfsstat4 wdr_status) { +case NFS4_OK: + open_delegation4 wdr_resok4; +default: + void; +}; + +/* + * DESTROY_CLIENTID + */ +struct DESTROY_CLIENTID4args { + clientid4 dca_clientid; +}; + +struct DESTROY_CLIENTID4res { + nfsstat4 dcr_status; +}; + +/* + * RECLAIM_COMPLETE + */ +struct RECLAIM_COMPLETE4args { + bool rca_one_fs; +}; + +struct RECLAIM_COMPLETE4res { + nfsstat4 rcr_status; +}; + +/* + * ILLEGAL: Response for illegal operation numbers + */ +struct ILLEGAL4res { + nfsstat4 status; +}; + +/* + * Operation arrays + */ + +enum nfs_opnum4 { + OP_ACCESS = 3, + OP_CLOSE = 4, + OP_COMMIT = 5, + OP_CREATE = 6, + OP_DELEGPURGE = 7, + OP_DELEGRETURN = 8, + OP_GETATTR = 9, + OP_GETFH = 10, + OP_LINK = 11, + OP_LOCK = 12, + OP_LOCKT = 13, + OP_LOCKU = 14, + OP_LOOKUP = 15, + OP_LOOKUPP = 16, + OP_NVERIFY = 17, + OP_OPEN = 18, + OP_OPENATTR = 19, + OP_OPEN_CONFIRM = 20, + OP_OPEN_DOWNGRADE = 21, + OP_PUTFH = 22, + OP_PUTPUBFH = 23, + OP_PUTROOTFH = 24, + OP_READ = 25, + OP_READDIR = 26, + OP_READLINK = 27, + OP_REMOVE = 28, + OP_RENAME = 29, + OP_RENEW = 30, + OP_RESTOREFH = 31, + OP_SAVEFH = 32, + OP_SECINFO = 33, + OP_SETATTR = 34, + OP_SETCLIENTID = 35, + OP_SETCLIENTID_CONFIRM = 36, + OP_VERIFY = 37, + OP_WRITE = 38, + OP_RELEASE_LOCKOWNER = 39, + OP_BIND_CONN_TO_SESSION = 41, + OP_EXCHANGE_ID = 42, + OP_CREATE_SESSION = 43, + OP_DESTROY_SESSION = 44, + OP_FREE_STATEID = 45, + OP_GET_DIR_DELEGATION = 46, + OP_GETDEVICEINFO = 47, + OP_GETDEVICELIST = 48, + OP_LAYOUTCOMMIT = 49, + OP_LAYOUTGET = 50, + OP_LAYOUTRETURN = 51, + OP_SECINFO_NO_NAME = 52, + OP_SEQUENCE = 53, + OP_SET_SSV = 54, + OP_TEST_STATEID = 55, + OP_WANT_DELEGATION = 56, + OP_DESTROY_CLIENTID = 57, + OP_RECLAIM_COMPLETE = 58, + OP_ILLEGAL = 10044 +}; + +union nfs_argop4 switch (nfs_opnum4 argop) { + case OP_ACCESS: ACCESS4args opaccess; + case OP_CLOSE: CLOSE4args opclose; + case OP_COMMIT: COMMIT4args opcommit; + case OP_CREATE: CREATE4args opcreate; + case OP_DELEGPURGE: DELEGPURGE4args opdelegpurge; + case OP_DELEGRETURN: DELEGRETURN4args opdelegreturn; + case OP_GETATTR: GETATTR4args opgetattr; + case OP_GETFH: void; + case OP_LINK: LINK4args oplink; + case OP_LOCK: LOCK4args oplock; + case OP_LOCKT: LOCKT4args oplockt; + case OP_LOCKU: LOCKU4args oplocku; + case OP_LOOKUP: LOOKUP4args oplookup; + case OP_LOOKUPP: void; + case OP_NVERIFY: NVERIFY4args opnverify; + case OP_OPEN: OPEN4args opopen; + case OP_OPENATTR: OPENATTR4args opopenattr; + case OP_OPEN_CONFIRM: OPEN_CONFIRM4args opopen_confirm; + case OP_OPEN_DOWNGRADE: OPEN_DOWNGRADE4args opopen_downgrade; + case OP_PUTFH: PUTFH4args opputfh; + case OP_PUTPUBFH: void; + case OP_PUTROOTFH: void; + case OP_READ: READ4args opread; + case OP_READDIR: READDIR4args opreaddir; + case OP_READLINK: void; + case OP_REMOVE: REMOVE4args opremove; + case OP_RENAME: RENAME4args oprename; + case OP_RENEW: RENEW4args oprenew; + case OP_RESTOREFH: void; + case OP_SAVEFH: void; + case OP_SECINFO: SECINFO4args opsecinfo; + case OP_SETATTR: SETATTR4args opsetattr; + case OP_SETCLIENTID: SETCLIENTID4args opsetclientid; + case OP_SETCLIENTID_CONFIRM: SETCLIENTID_CONFIRM4args + opsetclientid_confirm; + case OP_VERIFY: VERIFY4args opverify; + case OP_WRITE: WRITE4args opwrite; + case OP_RELEASE_LOCKOWNER: RELEASE_LOCKOWNER4args + oprelease_lockowner; + case OP_BIND_CONN_TO_SESSION: BIND_CONN_TO_SESSION4args opbindconntosession; + case OP_EXCHANGE_ID: EXCHANGE_ID4args opexchangeid; + case OP_CREATE_SESSION: CREATE_SESSION4args opcreatesession; + case OP_DESTROY_SESSION: DESTROY_SESSION4args opdestroysession; + case OP_FREE_STATEID: FREE_STATEID4args opfreestateid; + case OP_GET_DIR_DELEGATION: GET_DIR_DELEGATION4args opgetdirdelegation; + case OP_GETDEVICEINFO: GETDEVICEINFO4args opgetdeviceinfo; + case OP_GETDEVICELIST: GETDEVICELIST4args opgetdevicelist; + case OP_LAYOUTCOMMIT: LAYOUTCOMMIT4args oplayoutcommit; + case OP_LAYOUTGET: LAYOUTGET4args oplayoutget; + case OP_LAYOUTRETURN: LAYOUTRETURN4args oplayoutreturn; + case OP_SECINFO_NO_NAME: SECINFO_NO_NAME4args opsecinfononame; + case OP_SEQUENCE: SEQUENCE4args opsequence; + case OP_SET_SSV: SET_SSV4args opsetssv; + case OP_TEST_STATEID: TEST_STATEID4args opteststateid; + case OP_WANT_DELEGATION: WANT_DELEGATION4args opwantdelegation; + case OP_DESTROY_CLIENTID: DESTROY_CLIENTID4args opdestroyclientid; + case OP_RECLAIM_COMPLETE: RECLAIM_COMPLETE4args opreclaimcomplete; + case OP_ILLEGAL: void; +}; + +union nfs_resop4 switch (nfs_opnum4 resop){ + case OP_ACCESS: ACCESS4res opaccess; + case OP_CLOSE: CLOSE4res opclose; + case OP_COMMIT: COMMIT4res opcommit; + case OP_CREATE: CREATE4res opcreate; + case OP_DELEGPURGE: DELEGPURGE4res opdelegpurge; + case OP_DELEGRETURN: DELEGRETURN4res opdelegreturn; + case OP_GETATTR: GETATTR4res opgetattr; + case OP_GETFH: GETFH4res opgetfh; + case OP_LINK: LINK4res oplink; + case OP_LOCK: LOCK4res oplock; + case OP_LOCKT: LOCKT4res oplockt; + case OP_LOCKU: LOCKU4res oplocku; + case OP_LOOKUP: LOOKUP4res oplookup; + case OP_LOOKUPP: LOOKUPP4res oplookupp; + case OP_NVERIFY: NVERIFY4res opnverify; + case OP_OPEN: OPEN4res opopen; + case OP_OPENATTR: OPENATTR4res opopenattr; + case OP_OPEN_CONFIRM: OPEN_CONFIRM4res opopen_confirm; + case OP_OPEN_DOWNGRADE: OPEN_DOWNGRADE4res opopen_downgrade; + case OP_PUTFH: PUTFH4res opputfh; + case OP_PUTPUBFH: PUTPUBFH4res opputpubfh; + case OP_PUTROOTFH: PUTROOTFH4res opputrootfh; + case OP_READ: READ4res opread; + case OP_READDIR: READDIR4res opreaddir; + case OP_READLINK: READLINK4res opreadlink; + case OP_REMOVE: REMOVE4res opremove; + case OP_RENAME: RENAME4res oprename; + case OP_RENEW: RENEW4res oprenew; + case OP_RESTOREFH: RESTOREFH4res oprestorefh; + case OP_SAVEFH: SAVEFH4res opsavefh; + case OP_SECINFO: SECINFO4res opsecinfo; + case OP_SETATTR: SETATTR4res opsetattr; + case OP_SETCLIENTID: SETCLIENTID4res opsetclientid; + case OP_SETCLIENTID_CONFIRM: SETCLIENTID_CONFIRM4res + opsetclientid_confirm; + case OP_VERIFY: VERIFY4res opverify; + case OP_WRITE: WRITE4res opwrite; + case OP_RELEASE_LOCKOWNER: RELEASE_LOCKOWNER4res + oprelease_lockowner; + case OP_BIND_CONN_TO_SESSION: BIND_CONN_TO_SESSION4res opbindconntosession; + case OP_EXCHANGE_ID: EXCHANGE_ID4res opexchangeid; + case OP_CREATE_SESSION: CREATE_SESSION4res opcreatesession; + case OP_DESTROY_SESSION: DESTROY_SESSION4res opdestroysession; + case OP_FREE_STATEID: FREE_STATEID4res opfreestateid; + case OP_GET_DIR_DELEGATION: GET_DIR_DELEGATION4res opgetdirdelegation; + case OP_GETDEVICEINFO: GETDEVICEINFO4res opgetdeviceinfo; + case OP_GETDEVICELIST: GETDEVICELIST4res opgetdevicelist; + case OP_LAYOUTCOMMIT: LAYOUTCOMMIT4res oplayoutcommit; + case OP_LAYOUTGET: LAYOUTGET4res oplayoutget; + case OP_LAYOUTRETURN: LAYOUTRETURN4res oplayoutreturn; + case OP_SECINFO_NO_NAME: SECINFO_NO_NAME4res opsecinfononame; + case OP_SEQUENCE: SEQUENCE4res opsequence; + case OP_SET_SSV: SET_SSV4res opsetssv; + case OP_TEST_STATEID: TEST_STATEID4res opteststateid; + case OP_WANT_DELEGATION: WANT_DELEGATION4res opwantdelegation; + case OP_DESTROY_CLIENTID: DESTROY_CLIENTID4res opdestroyclientid; + case OP_RECLAIM_COMPLETE: RECLAIM_COMPLETE4res opreclaimcomplete; + case OP_ILLEGAL: ILLEGAL4res opillegal; +}; + +struct COMPOUND4args { + utf8str_cs tag; + uint32_t minorversion; + nfs_argop4 argarray<>; +}; + +struct COMPOUND4res { + nfsstat4 status; + utf8str_cs tag; + nfs_resop4 resarray<>; +}; + +/* + * Remote file service routines + */ +program NFS4_PROGRAM { + version NFS_V4 { + void + NFSPROC4_NULL(void) = 0; + + COMPOUND4res + NFSPROC4_COMPOUND(COMPOUND4args) = 1; + + } = 4; +} = 100003; + + + +/* + * NFS4 Callback Procedure Definitions and Program + */ + +/* + * CB_GETATTR: Get Current Attributes + */ +struct CB_GETATTR4args { + nfs_fh4 fh; + bitmap4 attr_request; +}; + +struct CB_GETATTR4resok { + fattr4 obj_attributes; +}; + +union CB_GETATTR4res switch (nfsstat4 status) { + case NFS4_OK: + CB_GETATTR4resok resok4; + default: + void; +}; + +/* + * CB_RECALL: Recall an Open Delegation + */ +struct CB_RECALL4args { + stateid4 stateid; + bool truncate; + nfs_fh4 fh; +}; + +struct CB_RECALL4res { + nfsstat4 status; +}; + +/* + * CB_ILLEGAL: Response for illegal operation numbers + */ +struct CB_ILLEGAL4res { + nfsstat4 status; +}; + +/* + * Various definitions for CB_COMPOUND + */ +enum nfs_cb_opnum4 { + OP_CB_GETATTR = 3, + OP_CB_RECALL = 4, + OP_CB_ILLEGAL = 10044 +}; + +union nfs_cb_argop4 switch (unsigned argop) { + case OP_CB_GETATTR: CB_GETATTR4args opcbgetattr; + case OP_CB_RECALL: CB_RECALL4args opcbrecall; + case OP_CB_ILLEGAL: void; +}; + +union nfs_cb_resop4 switch (unsigned resop){ + case OP_CB_GETATTR: CB_GETATTR4res opcbgetattr; + case OP_CB_RECALL: CB_RECALL4res opcbrecall; + case OP_CB_ILLEGAL: CB_ILLEGAL4res opcbillegal; +}; + +struct CB_COMPOUND4args { + utf8str_cs tag; + uint32_t minorversion; + uint32_t callback_ident; + nfs_cb_argop4 argarray<>; +}; + +struct CB_COMPOUND4res { + nfsstat4 status; + utf8str_cs tag; + nfs_cb_resop4 resarray<>; +}; + + +/* + * Program number is in the transient range since the client + * will assign the exact transient program number and provide + * that to the server via the SETCLIENTID operation. + */ +program NFS4_CALLBACK { + version NFS_CB { + void + CB_NULL(void) = 0; + CB_COMPOUND4res + CB_COMPOUND(CB_COMPOUND4args) = 1; + } = 1; +} = 0x40000000; + +/* + * GSS definitions + */ +/* RPCSEC_GSS control procedures */ +enum rpc_gss_proc_t { + RPCSEC_GSS_DATA = 0, + RPCSEC_GSS_INIT = 1, + RPCSEC_GSS_CONTINUE_INIT = 2, + RPCSEC_GSS_DESTROY = 3 +}; + +struct rpc_gss_cred_vers_1_t { + rpc_gss_proc_t gss_proc; /* control procedure */ + unsigned int seq_num; /* sequence number */ + rpc_gss_svc_t service; /* service used */ + opaque handle<>; /* context handle */ +}; + +const RPCSEC_GSS_VERS_1 = 1; + +union rpc_gss_cred_t switch (unsigned int vers) { /* version of RPCSEC_GSS */ + case RPCSEC_GSS_VERS_1: + rpc_gss_cred_vers_1_t rpc_gss_cred_vers_1_t; +}; + +struct rpc_gss_init_arg { + opaque gss_token<>; +}; + +struct rpc_gss_init_res { + opaque handle<>; + unsigned int gss_major; + unsigned int gss_minor; + unsigned int seq_window; + opaque gss_token<>; +}; + +struct rpc_gss_integ_data { + opaque databody_integ<>; + opaque checksum<>; +}; diff --git a/deps/libnfs/nlm/CMakeLists.txt b/deps/libnfs/nlm/CMakeLists.txt new file mode 100644 index 000000000000..f584b643fb4a --- /dev/null +++ b/deps/libnfs/nlm/CMakeLists.txt @@ -0,0 +1,5 @@ +set(SOURCES libnfs-raw-nlm.c + nlm.c) +set(HEADERS libnfs-raw-nlm.h) + +core_add_library(nlm) diff --git a/deps/libnfs/nlm/Makefile.am b/deps/libnfs/nlm/Makefile.am new file mode 100644 index 000000000000..64bf77642c83 --- /dev/null +++ b/deps/libnfs/nlm/Makefile.am @@ -0,0 +1,25 @@ +noinst_LTLIBRARIES = libnlm.la + +nlm_SOURCES_GENERATED = +nlm_HEADERS_GENERATED = +nlm_GENERATED = $(nlm_SOURCES_GENERATED) $(nlm_HEADERS_GENERATED) + +CLEANFILES = $(nlm_GENERATED) nlm-stamp + +libnlm_la_CPPFLAGS = -I$(abs_top_srcdir)/include \ + -I$(abs_top_srcdir)/include/nfsc \ + -I$(abs_top_srcdir)/win32 +libnlm_la_SOURCES = \ + $(nlm_SOURCES_GENERATED) \ + nlm.c libnfs-raw-nlm.c libnfs-raw-nlm.h + +$(nlm_GENERATED) : nlm-stamp +nlm-stamp : nlm.x + rm -f $(nlm_GENERATED) + touch nlm-stamp + +compile_rpc: + cat nlm.x | head -29 >libnfs-raw-nlm.h + rpcgen -h nlm.x | sed -e "s/#include /#include /" | sed -e "s/xdr/zdr/g" -e "s/XDR/ZDR/g" -e "s/ CLIENT / void /g" -e "s/SVCXPRT /void /g" -e "s/bool_t/uint32_t/g" >> libnfs-raw-nlm.h + cat nlm.x | head -29 >libnfs-raw-nlm.c + rpcgen -c nlm.x | sed -e "s/#include \".*nlm.h\"/#include \"libnfs-xdr.h\"\n#include \"libnfs-raw-nlm.h\"/" -e "s/xdr/zdr/g" -e "s/XDR/ZDR/g" -e "s/register int32_t \*buf;/register int32_t *buf;\n buf = NULL;/" -e "s/bool_t/uint32_t/g" >> libnfs-raw-nlm.c diff --git a/deps/libnfs/nlm/libnfs-raw-nlm.c b/deps/libnfs/nlm/libnfs-raw-nlm.c new file mode 100644 index 000000000000..69133f53b135 --- /dev/null +++ b/deps/libnfs/nlm/libnfs-raw-nlm.c @@ -0,0 +1,302 @@ +/* +Copyright (c) 2014, Ronnie Sahlberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +/* + * Please do not edit this file. + * It was generated using rpcgen. + */ + +#include "libnfs-zdr.h" +#include "libnfs-raw-nlm.h" + +uint32_t +zdr_nlm_fh4 (ZDR *zdrs, nlm_fh4 *objp) +{ + if (!zdr_bytes (zdrs, (char **)&objp->data.data_val, &objp->data.data_len, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_nlm4_oh (ZDR *zdrs, nlm4_oh *objp) +{ + if (!zdr_string (zdrs, objp, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_nlm_cookie (ZDR *zdrs, nlm_cookie *objp) +{ + if (!zdr_bytes (zdrs, (char **)&objp->data.data_val, &objp->data.data_len, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_nlmstat4 (ZDR *zdrs, nlmstat4 *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_nlm4_holder (ZDR *zdrs, nlm4_holder *objp) +{ + if (!zdr_bool (zdrs, &objp->exclusive)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->svid)) + return FALSE; + if (!zdr_nlm4_oh (zdrs, &objp->oh)) + return FALSE; + if (!zdr_uint64_t (zdrs, &objp->l_offset)) + return FALSE; + if (!zdr_uint64_t (zdrs, &objp->l_len)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_nlm4_lock (ZDR *zdrs, nlm4_lock *objp) +{ + if (!zdr_string (zdrs, &objp->caller_name, NLM_MAXNAME)) + return FALSE; + if (!zdr_nlm_fh4 (zdrs, &objp->fh)) + return FALSE; + if (!zdr_nlm4_oh (zdrs, &objp->oh)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->svid)) + return FALSE; + if (!zdr_uint64_t (zdrs, &objp->l_offset)) + return FALSE; + if (!zdr_uint64_t (zdrs, &objp->l_len)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_nlm4_share (ZDR *zdrs, nlm4_share *objp) +{ + if (!zdr_string (zdrs, &objp->caller_name, NLM_MAXNAME)) + return FALSE; + if (!zdr_nlm_fh4 (zdrs, &objp->fh)) + return FALSE; + if (!zdr_nlm4_oh (zdrs, &objp->oh)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->mode)) + return FALSE; + if (!zdr_u_int (zdrs, &objp->access)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_nlm4_testres_denied (ZDR *zdrs, nlm4_testres_denied *objp) +{ + if (!zdr_nlm4_holder (zdrs, &objp->holder)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_nlm4_testreply (ZDR *zdrs, nlm4_testreply *objp) +{ + if (!zdr_nlmstat4 (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case NLM4_DENIED: + if (!zdr_nlm4_testres_denied (zdrs, &objp->nlm4_testreply_u.lock)) + return FALSE; + break; + default: + break; + } + return TRUE; +} + +uint32_t +zdr_NLM4_TESTres (ZDR *zdrs, NLM4_TESTres *objp) +{ + if (!zdr_nlm_cookie (zdrs, &objp->cookie)) + return FALSE; + if (!zdr_nlm4_testreply (zdrs, &objp->reply)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_NLM4_TESTargs (ZDR *zdrs, NLM4_TESTargs *objp) +{ + if (!zdr_nlm_cookie (zdrs, &objp->cookie)) + return FALSE; + if (!zdr_bool (zdrs, &objp->exclusive)) + return FALSE; + if (!zdr_nlm4_lock (zdrs, &objp->lock)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_NLM4_CANCres (ZDR *zdrs, NLM4_CANCres *objp) +{ + if (!zdr_nlm_cookie (zdrs, &objp->cookie)) + return FALSE; + if (!zdr_nlmstat4 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_NLM4_CANCargs (ZDR *zdrs, NLM4_CANCargs *objp) +{ + if (!zdr_nlm_cookie (zdrs, &objp->cookie)) + return FALSE; + if (!zdr_bool (zdrs, &objp->block)) + return FALSE; + if (!zdr_bool (zdrs, &objp->exclusive)) + return FALSE; + if (!zdr_nlm4_lock (zdrs, &objp->lock)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_NLM4_UNLOCKres (ZDR *zdrs, NLM4_UNLOCKres *objp) +{ + if (!zdr_nlm_cookie (zdrs, &objp->cookie)) + return FALSE; + if (!zdr_nlmstat4 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_NLM4_UNLOCKargs (ZDR *zdrs, NLM4_UNLOCKargs *objp) +{ + if (!zdr_nlm_cookie (zdrs, &objp->cookie)) + return FALSE; + if (!zdr_nlm4_lock (zdrs, &objp->lock)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_NLM4_LOCKres (ZDR *zdrs, NLM4_LOCKres *objp) +{ + if (!zdr_nlm_cookie (zdrs, &objp->cookie)) + return FALSE; + if (!zdr_nlmstat4 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_NLM4_LOCKargs (ZDR *zdrs, NLM4_LOCKargs *objp) +{ + if (!zdr_nlm_cookie (zdrs, &objp->cookie)) + return FALSE; + if (!zdr_bool (zdrs, &objp->block)) + return FALSE; + if (!zdr_bool (zdrs, &objp->exclusive)) + return FALSE; + if (!zdr_nlm4_lock (zdrs, &objp->lock)) + return FALSE; + if (!zdr_bool (zdrs, &objp->reclaim)) + return FALSE; + if (!zdr_int (zdrs, &objp->state)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_NLM4_GRANTEDargs (ZDR *zdrs, NLM4_GRANTEDargs *objp) +{ + if (!zdr_nlm_cookie (zdrs, &objp->cookie)) + return FALSE; + if (!zdr_bool (zdrs, &objp->exclusive)) + return FALSE; + if (!zdr_nlm4_lock (zdrs, &objp->lock)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_NLM4_GRANTEDres (ZDR *zdrs, NLM4_GRANTEDres *objp) +{ + if (!zdr_nlm_cookie (zdrs, &objp->cookie)) + return FALSE; + if (!zdr_nlmstat4 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_NLM4_SHAREres(ZDR *zdrs, NLM4_SHAREres *objp) +{ + if (!zdr_nlm_cookie (zdrs, &objp->cookie)) + return FALSE; + if (!zdr_nlmstat4 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_NLM4_SHAREargs(ZDR *zdrs, NLM4_SHAREargs *objp) +{ + if (!zdr_nlm_cookie (zdrs, &objp->cookie)) + return FALSE; + if (!zdr_nlm4_share (zdrs, &objp->share)) + return FALSE; + if (!zdr_bool (zdrs, &objp->reclaim)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_NLM4_UNSHAREres(ZDR *zdrs, NLM4_UNSHAREres *objp) +{ + if (!zdr_nlm_cookie (zdrs, &objp->cookie)) + return FALSE; + if (!zdr_nlmstat4 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_NLM4_UNSHAREargs(ZDR *zdrs, NLM4_SHAREargs *objp) +{ + if (!zdr_nlm_cookie (zdrs, &objp->cookie)) + return FALSE; + if (!zdr_nlm4_share (zdrs, &objp->share)) + return FALSE; + if (!zdr_bool (zdrs, &objp->reclaim)) + return FALSE; + return TRUE; +} diff --git a/deps/libnfs/nlm/libnfs-raw-nlm.h b/deps/libnfs/nlm/libnfs-raw-nlm.h new file mode 100644 index 000000000000..783433740bf5 --- /dev/null +++ b/deps/libnfs/nlm/libnfs-raw-nlm.h @@ -0,0 +1,387 @@ +/* +Copyright (c) 2014, Ronnie Sahlberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +/* + * Please do not edit this file. + * It was generated using rpcgen. + */ + +#ifndef _NLM_H_RPCGEN +#define _NLM_H_RPCGEN + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +struct nlm_fh4 { + struct { + uint32_t data_len; + char *data_val; + } data; +}; +typedef struct nlm_fh4 nlm_fh4; + +typedef char *nlm4_oh; + +struct nlm_cookie { + struct { + uint32_t data_len; + char *data_val; + } data; +}; +typedef struct nlm_cookie nlm_cookie; + +enum nlmstat4 { + NLM4_GRANTED = 0, + NLM4_DENIED = 1, + NLM4_DENIED_NOLOCKS = 2, + NLM4_BLOCKED = 3, + NLM4_DENIED_GRACE_PERIOD = 4, + NLM4_DEADLCK = 5, + NLM4_ROFS = 6, + NLM4_STALE_FH = 7, + NLM4_FBIG = 8, + NLM4_FAILED = 9, +}; +typedef enum nlmstat4 nlmstat4; + +struct nlm4_holder { + uint32_t exclusive; + uint32_t svid; + nlm4_oh oh; + uint64_t l_offset; + uint64_t l_len; +}; +typedef struct nlm4_holder nlm4_holder; +#define NLM_MAXNAME 256 + +struct nlm4_lock { + char *caller_name; + struct nlm_fh4 fh; + nlm4_oh oh; + uint32_t svid; + uint64_t l_offset; + uint64_t l_len; +}; +typedef struct nlm4_lock nlm4_lock; + +struct nlm4_share { + char *caller_name; + struct nlm_fh4 fh; + nlm4_oh oh; + uint32_t mode; + uint32_t access; +}; +typedef struct nlm4_share nlm4_share; + +struct nlm4_testres_denied { + nlm4_holder holder; +}; +typedef struct nlm4_testres_denied nlm4_testres_denied; + +struct nlm4_testreply { + nlmstat4 status; + union { + nlm4_testres_denied lock; + } nlm4_testreply_u; +}; +typedef struct nlm4_testreply nlm4_testreply; + +struct NLM4_TESTres { + nlm_cookie cookie; + nlm4_testreply reply; +}; +typedef struct NLM4_TESTres NLM4_TESTres; + +struct NLM4_TESTargs { + nlm_cookie cookie; + uint32_t exclusive; + nlm4_lock lock; +}; +typedef struct NLM4_TESTargs NLM4_TESTargs; + +struct NLM4_CANCres { + nlm_cookie cookie; + nlmstat4 status; +}; +typedef struct NLM4_CANCres NLM4_CANCres; + +struct NLM4_CANCargs { + nlm_cookie cookie; + uint32_t block; + uint32_t exclusive; + nlm4_lock lock; +}; +typedef struct NLM4_CANCargs NLM4_CANCargs; + +struct NLM4_UNLOCKres { + nlm_cookie cookie; + nlmstat4 status; +}; +typedef struct NLM4_UNLOCKres NLM4_UNLOCKres; + +struct NLM4_UNLOCKargs { + nlm_cookie cookie; + nlm4_lock lock; +}; +typedef struct NLM4_UNLOCKargs NLM4_UNLOCKargs; + +struct NLM4_LOCKres { + nlm_cookie cookie; + nlmstat4 status; +}; +typedef struct NLM4_LOCKres NLM4_LOCKres; + +struct NLM4_LOCKargs { + nlm_cookie cookie; + uint32_t block; + uint32_t exclusive; + nlm4_lock lock; + uint32_t reclaim; + int state; +}; +typedef struct NLM4_LOCKargs NLM4_LOCKargs; + +struct NLM4_GRANTEDargs { + nlm_cookie cookie; + uint32_t exclusive; + nlm4_lock lock; +}; +typedef struct NLM4_GRANTEDargs NLM4_GRANTEDargs; + +struct NLM4_GRANTEDres { + nlm_cookie cookie; + nlmstat4 status; +}; +typedef struct NLM4_GRANTEDres NLM4_GRANTEDres; + +struct NLM4_SHAREargs { + nlm_cookie cookie; + nlm4_share share; + bool_t reclaim; +}; +typedef struct NLM4_SHAREargs NLM4_SHAREargs; + +struct NLM4_SHAREres { + nlm_cookie cookie; + nlmstat4 status; + int32_t sequence; +}; +typedef struct NLM4_SHAREres NLM4_SHAREres; + +struct NLM4_UNSHAREres { + nlm_cookie cookie; + nlmstat4 status; + int32_t sequence; +}; +typedef struct NLM4_UNSHAREres NLM4_UNSHAREres; + +#define NLM_PROGRAM 100021 +#define NLM_V4 4 + +#if defined(__STDC__) || defined(__cplusplus) +#define NLM4_NULL 0 +extern void * nlm4_null_4(void *, void *); +extern void * nlm4_null_4_svc(void *, struct svc_req *); +#define NLM4_TEST 1 +extern NLM4_TESTres * nlm4_test_4(NLM4_TESTargs *, void *); +extern NLM4_TESTres * nlm4_test_4_svc(NLM4_TESTargs *, struct svc_req *); +#define NLM4_LOCK 2 +extern NLM4_LOCKres * nlm4_lock_4(NLM4_LOCKargs *, void *); +extern NLM4_LOCKres * nlm4_lock_4_svc(NLM4_LOCKargs *, struct svc_req *); +#define NLM4_CANCEL 3 +extern NLM4_CANCres * nlm4_cancel_4(NLM4_CANCargs *, void *); +extern NLM4_CANCres * nlm4_cancel_4_svc(NLM4_CANCargs *, struct svc_req *); +#define NLM4_UNLOCK 4 +extern NLM4_UNLOCKres * nlm4_unlock_4(NLM4_UNLOCKargs *, void *); +extern NLM4_UNLOCKres * nlm4_unlock_4_svc(NLM4_UNLOCKargs *, struct svc_req *); +#define NLM4_GRANT 5 +extern NLM4_GRANTEDres * nlm4_grant_4(NLM4_GRANTEDargs *, void *); +extern NLM4_GRANTEDres * nlm4_grant_4_svc(NLM4_GRANTEDargs *, struct svc_req *); +#define NLM4_TEST_MSG 6 +extern void * nlm4_test_msg_4(NLM4_TESTargs *, void *); +extern void * nlm4_test_msg_4_svc(NLM4_TESTargs *, struct svc_req *); +#define NLM4_LOCK_MSG 7 +extern void * nlm4_lock_msg_4(NLM4_LOCKargs *, void *); +extern void * nlm4_lock_msg_4_svc(NLM4_LOCKargs *, struct svc_req *); +#define NLM4_CANCEL_MSG 8 +extern void * nlm4_cancel_msg_4(NLM4_CANCargs *, void *); +extern void * nlm4_cancel_msg_4_svc(NLM4_CANCargs *, struct svc_req *); +#define NLM4_UNLOCK_MSG 9 +extern void * nlm4_unlock_msg_4(NLM4_UNLOCKargs *, void *); +extern void * nlm4_unlock_msg_4_svc(NLM4_UNLOCKargs *, struct svc_req *); +#define NLM4_GRANT_MSG 10 +extern void * nlm4_grant_msg_4(NLM4_GRANTEDargs *, void *); +extern void * nlm4_grant_msg_4_svc(NLM4_GRANTEDargs *, struct svc_req *); +#define NLM4_TEST_RES 11 +extern void * nlm4_test_res_4(NLM4_TESTres *, void *); +extern void * nlm4_test_res_4_svc(NLM4_TESTres *, struct svc_req *); +#define NLM4_LOCK_RES 12 +extern void * nlm4_lock_res_4(NLM4_LOCKres *, void *); +extern void * nlm4_lock_res_4_svc(NLM4_LOCKres *, struct svc_req *); +#define NLM4_CANCEL_RES 13 +extern void * nlm4_cancel_res_4(NLM4_CANCres *, void *); +extern void * nlm4_cancel_res_4_svc(NLM4_CANCres *, struct svc_req *); +#define NLM4_UNLOCK_RES 14 +extern void * nlm4_unlock_res_4(NLM4_UNLOCKres *, void *); +extern void * nlm4_unlock_res_4_svc(NLM4_UNLOCKres *, struct svc_req *); +#define NLM4_GRANT_RES 15 +extern void * nlm4_grant_res_4(NLM4_GRANTEDres *, void *); +extern void * nlm4_grant_res_4_svc(NLM4_GRANTEDres *, struct svc_req *); +extern int nlm_program_4_freeresult (void *, zdrproc_t, caddr_t); +#define NLM4_SHARE 20 +extern NLM4_SHAREres *nlm4_share_4(NLM4_SHAREargs *, void *); +extern NLM4_SHAREres *nlm4_share_4_svc(NLM4_SHAREargs *, + struct svc_req *); +#define NLM4_UNSHARE 21 +extern NLM4_SHAREres *nlm4_unshare_4(NLM4_SHAREargs *, void *); +extern NLM4_SHAREres *nlm4_unshare_4_svc(NLM4_SHAREargs *, + struct svc_req *); + +#else /* K&R C */ +#define NLM4_NULL 0 +extern void * nlm4_null_4(); +extern void * nlm4_null_4_svc(); +#define NLM4_TEST 1 +extern NLM4_TESTres * nlm4_test_4(); +extern NLM4_TESTres * nlm4_test_4_svc(); +#define NLM4_LOCK 2 +extern NLM4_LOCKres * nlm4_lock_4(); +extern NLM4_LOCKres * nlm4_lock_4_svc(); +#define NLM4_CANCEL 3 +extern NLM4_CANCres * nlm4_cancel_4(); +extern NLM4_CANCres * nlm4_cancel_4_svc(); +#define NLM4_UNLOCK 4 +extern NLM4_UNLOCKres * nlm4_unlock_4(); +extern NLM4_UNLOCKres * nlm4_unlock_4_svc(); +#define NLM4_GRANT 5 +extern NLM4_GRANTEDres * nlm4_grant_4(); +extern NLM4_GRANTEDres * nlm4_grant_4_svc(); +#define NLM4_TEST_MSG 6 +extern void * nlm4_test_msg_4(); +extern void * nlm4_test_msg_4_svc(); +#define NLM4_LOCK_MSG 7 +extern void * nlm4_lock_msg_4(); +extern void * nlm4_lock_msg_4_svc(); +#define NLM4_CANCEL_MSG 8 +extern void * nlm4_cancel_msg_4(); +extern void * nlm4_cancel_msg_4_svc(); +#define NLM4_UNLOCK_MSG 9 +extern void * nlm4_unlock_msg_4(); +extern void * nlm4_unlock_msg_4_svc(); +#define NLM4_GRANT_MSG 10 +extern void * nlm4_grant_msg_4(); +extern void * nlm4_grant_msg_4_svc(); +#define NLM4_TEST_RES 11 +extern void * nlm4_test_res_4(); +extern void * nlm4_test_res_4_svc(); +#define NLM4_LOCK_RES 12 +extern void * nlm4_lock_res_4(); +extern void * nlm4_lock_res_4_svc(); +#define NLM4_CANCEL_RES 13 +extern void * nlm4_cancel_res_4(); +extern void * nlm4_cancel_res_4_svc(); +#define NLM4_UNLOCK_RES 14 +extern void * nlm4_unlock_res_4(); +extern void * nlm4_unlock_res_4_svc(); +#define NLM4_GRANT_RES 15 +extern void * nlm4_grant_res_4(); +extern void * nlm4_grant_res_4_svc(); +extern int nlm_program_4_freeresult (); +#define NLM4_SHARE 20 +extern NLM4_SHAREres *nlm4_share_4(); +extern NLM4_SHAREres *nlm4_share_4_svc(); +#define NLM4_UNSHARE 21 +extern NLM4_SHAREres *nlm4_unshare_4(); +extern NLM4_SHAREres *nlm4_unshare_4_svc(); +#endif /* K&R C */ + +/* the zdr functions */ + +#if defined(__STDC__) || defined(__cplusplus) +extern uint32_t zdr_nlm_fh4 (ZDR *, nlm_fh4*); +extern uint32_t zdr_nlm4_oh (ZDR *, nlm4_oh*); +extern uint32_t zdr_nlm_cookie (ZDR *, nlm_cookie*); +extern uint32_t zdr_nlmstat4 (ZDR *, nlmstat4*); +extern uint32_t zdr_nlm4_holder (ZDR *, nlm4_holder*); +extern uint32_t zdr_nlm4_lock (ZDR *, nlm4_lock*); +extern uint32_t zdr_nlm4_share (ZDR *, nlm4_share*); +extern uint32_t zdr_nlm4_testres_denied (ZDR *, nlm4_testres_denied*); +extern uint32_t zdr_nlm4_testreply (ZDR *, nlm4_testreply*); +extern uint32_t zdr_NLM4_TESTres (ZDR *, NLM4_TESTres*); +extern uint32_t zdr_NLM4_TESTargs (ZDR *, NLM4_TESTargs*); +extern uint32_t zdr_NLM4_CANCres (ZDR *, NLM4_CANCres*); +extern uint32_t zdr_NLM4_CANCargs (ZDR *, NLM4_CANCargs*); +extern uint32_t zdr_NLM4_UNLOCKres (ZDR *, NLM4_UNLOCKres*); +extern uint32_t zdr_NLM4_UNLOCKargs (ZDR *, NLM4_UNLOCKargs*); +extern uint32_t zdr_NLM4_LOCKres (ZDR *, NLM4_LOCKres*); +extern uint32_t zdr_NLM4_LOCKargs (ZDR *, NLM4_LOCKargs*); +extern uint32_t zdr_NLM4_GRANTEDargs (ZDR *, NLM4_GRANTEDargs*); +extern uint32_t zdr_NLM4_GRANTEDres (ZDR *, NLM4_GRANTEDres*); +extern uint32_t zdr_NLM4_SHAREres (ZDR *, NLM4_SHAREres*); +extern uint32_t zdr_NLM4_SHAREargs (ZDR *, NLM4_SHAREargs*); +extern uint32_t zdr_NLM4_UNSHAREres (ZDR *, NLM4_UNSHAREres*); +extern uint32_t zdr_NLM4_UNSHAREargs (ZDR *, NLM4_SHAREargs*); + +#else /* K&R C */ +extern uint32_t zdr_nlm_fh4 (); +extern uint32_t zdr_nlm4_oh (); +extern uint32_t zdr_nlm_cookie (); +extern uint32_t zdr_nlmstat4 (); +extern uint32_t zdr_nlm4_holder (); +extern uint32_t zdr_nlm4_lock (); +extern uint32_t zdr_nlm4_share (); +extern uint32_t zdr_nlm4_testres_denied (); +extern uint32_t zdr_nlm4_testreply (); +extern uint32_t zdr_NLM4_TESTres (); +extern uint32_t zdr_NLM4_TESTargs (); +extern uint32_t zdr_NLM4_CANCres (); +extern uint32_t zdr_NLM4_CANCargs (); +extern uint32_t zdr_NLM4_UNLOCKres (); +extern uint32_t zdr_NLM4_UNLOCKargs (); +extern uint32_t zdr_NLM4_LOCKres (); +extern uint32_t zdr_NLM4_LOCKargs (); +extern uint32_t zdr_NLM4_GRANTEDargs (); +extern uint32_t zdr_NLM4_GRANTEDres (); +extern uint32_t zdr_NLM4_SHAREres (); +extern uint32_t zdr_NLM4_SHAREargs (); +extern uint32_t zdr_NLM4_UNSHAREres (); +extern uint32_t zdr_NLM4_UNSHAREargs (); + +#endif /* K&R C */ + +#ifdef __cplusplus +} +#endif + +#endif /* !_NLM_H_RPCGEN */ diff --git a/deps/libnfs/nlm/nlm.c b/deps/libnfs/nlm/nlm.c new file mode 100644 index 000000000000..903ffb301ecb --- /dev/null +++ b/deps/libnfs/nlm/nlm.c @@ -0,0 +1,225 @@ +/* + Copyright (C) 2012 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 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef WIN32 +#include +#endif/*WIN32*/ + +#include +#include +#include "libnfs-zdr.h" +#include "libnfs.h" +#include "libnfs-raw.h" +#include "libnfs-private.h" +#include "libnfs-raw-nlm.h" + +struct rpc_pdu * +rpc_nlm4_null_task(struct rpc_context *rpc, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NLM_PROGRAM, NLM_V4, NLM4_NULL, cb, private_data, (zdrproc_t)zdr_void, 0); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nlm/null call"); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nlm/null call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_nlm4_test_task(struct rpc_context *rpc, rpc_cb cb, struct NLM4_TESTargs *args, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NLM_PROGRAM, NLM_V4, NLM4_TEST, cb, private_data, (zdrproc_t)zdr_NLM4_TESTres, sizeof(NLM4_TESTres)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nlm/test call"); + return NULL; + } + + if (zdr_NLM4_TESTargs(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode NLM4_TESTargs"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nlm/test call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_nlm4_lock_task(struct rpc_context *rpc, rpc_cb cb, struct NLM4_LOCKargs *args, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NLM_PROGRAM, NLM_V4, NLM4_LOCK, cb, private_data, (zdrproc_t)zdr_NLM4_LOCKres, sizeof(NLM4_LOCKres)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nlm/lock call"); + return NULL; + } + + if (zdr_NLM4_LOCKargs(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode NLM4_LOCKargs"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nlm/lock call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_nlm4_cancel_task(struct rpc_context *rpc, rpc_cb cb, struct NLM4_CANCargs *args, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NLM_PROGRAM, NLM_V4, NLM4_CANCEL, cb, private_data, (zdrproc_t)zdr_NLM4_CANCres, sizeof(NLM4_CANCres)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nlm/cancel call"); + return NULL; + } + + if (zdr_NLM4_CANCargs(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode NLM4_CANCargs"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nlm/cancel call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_nlm4_unlock_task(struct rpc_context *rpc, rpc_cb cb, struct NLM4_UNLOCKargs *args, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NLM_PROGRAM, NLM_V4, NLM4_UNLOCK, cb, private_data, (zdrproc_t)zdr_NLM4_UNLOCKres, sizeof(NLM4_UNLOCKres)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nlm/unlock call"); + return NULL; + } + + if (zdr_NLM4_UNLOCKargs(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode NLM4_UNLOCKargs"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nlm/unlock call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_nlm4_share_task(struct rpc_context *rpc, rpc_cb cb, struct NLM4_SHAREargs *args, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NLM_PROGRAM, NLM_V4, NLM4_SHARE, cb, private_data, (zdrproc_t)zdr_NLM4_SHAREres, sizeof(NLM4_SHAREres)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nlm/lock call"); + return NULL; + } + + if (zdr_NLM4_SHAREargs(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode NLM4_LOCKargs"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nlm/lock call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_nlm4_unshare_task(struct rpc_context *rpc, rpc_cb cb, struct NLM4_SHAREargs *args, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NLM_PROGRAM, NLM_V4, NLM4_UNSHARE, cb, private_data, (zdrproc_t)zdr_NLM4_UNSHAREres, sizeof(NLM4_UNSHAREres)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nlm/lock call"); + return NULL; + } + + if (zdr_NLM4_UNSHAREargs(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode NLM4_LOCKargs"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nlm/lock call"); + return NULL; + } + + return pdu; +} + +char *nlmstat4_to_str(int st) +{ + enum nlmstat4 stat = st; + + char *str = "unknown nlm stat"; + switch (stat) { + case NLM4_GRANTED: str="NLM4_GRANTED";break; + case NLM4_DENIED: str="NLM4_DENIED";break; + case NLM4_DENIED_NOLOCKS: str="NLM4_DENIED_NOLOCKS";break; + case NLM4_BLOCKED: str="NLM4_BLOCKED";break; + case NLM4_DENIED_GRACE_PERIOD: str="NLM4_DENIED_GRACE_PERIOD";break; + case NLM4_DEADLCK: str="NLM4_DEADLCK";break; + case NLM4_ROFS: str="NLM4_ROFS";break; + case NLM4_STALE_FH: str="NLM4_STALE_FH";break; + case NLM4_FBIG: str="NLM4_FBIG";break; + case NLM4_FAILED: str="NLM4_FAILED";break; + } + return str; +} + + + + diff --git a/deps/libnfs/nlm/nlm.x b/deps/libnfs/nlm/nlm.x new file mode 100644 index 000000000000..072aa99321b7 --- /dev/null +++ b/deps/libnfs/nlm/nlm.x @@ -0,0 +1,210 @@ +/* +Copyright (c) 2014, Ronnie Sahlberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +struct nlm_fh4 { + opaque data<>; +}; + +typedef string nlm4_oh<>; + +struct nlm_cookie { + opaque data<>; +}; + +enum nlmstat4 { + NLM4_GRANTED = 0, + NLM4_DENIED = 1, + NLM4_DENIED_NOLOCKS = 2, + NLM4_BLOCKED = 3, + NLM4_DENIED_GRACE_PERIOD = 4, + NLM4_DEADLCK = 5, + NLM4_ROFS = 6, + NLM4_STALE_FH = 7, + NLM4_FBIG = 8, + NLM4_FAILED = 9 +}; + +struct nlm4_holder { + bool exclusive; + unsigned int svid; + nlm4_oh oh; + uint64_t l_offset; + uint64_t l_len; +}; + +const NLM_MAXNAME = 256; +struct nlm4_lock { + string caller_name; + struct nlm_fh4 fh; + nlm4_oh oh; + unsigned int svid; + uint64_t l_offset; + uint64_t l_len; +}; + +struct nlm4_share { + string caller_name; + struct nlm_fh4 fh; + nlm4_oh oh; + unsigned int mode; + unsigned int access; +}; + +struct nlm4_testres_denied { + nlm4_holder holder; +}; + +union nlm4_testreply switch (nlmstat4 status) { + case NLM4_DENIED: + nlm4_testres_denied lock; + default: + void; +}; + +struct NLM4_TESTres { + nlm_cookie cookie; + nlm4_testreply reply; +}; + +struct NLM4_TESTargs { + nlm_cookie cookie; + bool exclusive; + nlm4_lock lock; +}; + +struct NLM4_CANCres { + nlm_cookie cookie; + nlmstat4 status; +}; + +struct NLM4_CANCargs { + nlm_cookie cookie; + bool block; + bool exclusive; + nlm4_lock lock; +}; + +struct NLM4_UNLOCKres { + nlm_cookie cookie; + nlmstat4 status; +}; + +struct NLM4_UNLOCKargs { + nlm_cookie cookie; + nlm4_lock lock; +}; + +struct NLM4_LOCKres { + nlm_cookie cookie; + nlmstat4 status; +}; + +struct NLM4_LOCKargs { + nlm_cookie cookie; + bool block; + bool exclusive; + nlm4_lock lock; + bool reclaim; + int state; +}; + +struct NLM4_GRANTEDargs { + nlm_cookie cookie; + bool exclusive; + nlm4_lock lock; +}; + +struct NLM4_GRANTEDres { + nlm_cookie cookie; + nlmstat4 status; +}; + +program NLM_PROGRAM { + version NLM_V4 { + void + NLM4_NULL(void) = 0; + + NLM4_TESTres + NLM4_TEST(NLM4_TESTargs) = 1; + + NLM4_LOCKres + NLM4_LOCK(NLM4_LOCKargs) = 2; + + NLM4_CANCres + NLM4_CANCEL(NLM4_CANCargs) = 3; + + NLM4_UNLOCKres + NLM4_UNLOCK(NLM4_UNLOCKargs) = 4; + + NLM4_GRANTEDres + NLM4_GRANT(NLM4_GRANTEDargs) = 5; + + void + NLM4_TEST_MSG(NLM4_TESTargs) = 6; + + void + NLM4_LOCK_MSG(NLM4_LOCKargs) = 7; + + void + NLM4_CANCEL_MSG(NLM4_CANCargs) = 8; + + void + NLM4_UNLOCK_MSG(NLM4_UNLOCKargs) = 9; + + void + NLM4_GRANT_MSG(NLM4_GRANTEDargs) = 10; + + void + NLM4_TEST_RES(NLM4_TESTres) = 11; + + void + NLM4_LOCK_RES(NLM4_LOCKres) = 12; + + void + NLM4_CANCEL_RES(NLM4_CANCres) = 13; + + void + NLM4_UNLOCK_RES(NLM4_UNLOCKres) = 14; + + void + NLM4_GRANT_RES(NLM4_GRANTEDres) = 15; + +/* nlm4_shareres */ +/* NLM4_SHARE(nlm4_shareargs) = 20; */ + +/* nlm4_shareres */ +/* NLM4_UNSHARE(nlm4_shareargs) = 21; */ + +/* nlm4_res */ +/* NLM4_NM_LOCK(nlm4_lockargs) = 22; */ + +/* void */ +/* NLM4_FREE_ALL(nlm4_notify) = 23; */ + } = 4; +} = 100021; diff --git a/deps/libnfs/nsm/CMakeLists.txt b/deps/libnfs/nsm/CMakeLists.txt new file mode 100644 index 000000000000..cc9f0e2021ad --- /dev/null +++ b/deps/libnfs/nsm/CMakeLists.txt @@ -0,0 +1,5 @@ +set(SOURCES libnfs-raw-nsm.c + nsm.c) +set(HEADERS libnfs-raw-nsm.h) + +core_add_library(nsm) diff --git a/deps/libnfs/nsm/Makefile.am b/deps/libnfs/nsm/Makefile.am new file mode 100644 index 000000000000..360f5eaf5e3e --- /dev/null +++ b/deps/libnfs/nsm/Makefile.am @@ -0,0 +1,25 @@ +noinst_LTLIBRARIES = libnsm.la + +nsm_SOURCES_GENERATED = +nsm_HEADERS_GENERATED = +nsm_GENERATED = $(nsm_SOURCES_GENERATED) $(nsm_HEADERS_GENERATED) + +CLEANFILES = $(nsm_GENERATED) nsm-stamp + +libnsm_la_CPPFLAGS = -I$(abs_top_srcdir)/include \ + -I$(abs_top_srcdir)/include/nfsc \ + -I$(abs_top_srcdir)/win32 +libnsm_la_SOURCES = \ + $(nsm_SOURCES_GENERATED) \ + nsm.c libnfs-raw-nsm.c libnfs-raw-nsm.h + +$(nsm_GENERATED) : nsm-stamp +nsm-stamp : nsm.x + rm -f $(nsm_GENERATED) + touch nsm-stamp + +compile_rpc: + cat nsm.x | head -29 >libnfs-raw-nsm.h + rpcgen -h nsm.x | sed -e "s/#include /#include /" | sed -e "s/xdr/zdr/g" -e "s/XDR/ZDR/g" -e "s/ CLIENT / void /g" -e "s/SVCXPRT /void /g" -e "s/bool_t/uint32_t/g" >> libnfs-raw-nsm.h + cat nsm.x | head -29 >libnfs-raw-nsm.c + rpcgen -c nsm.x | sed -e "s/#include \".*nsm.h\"/#include \"libnfs-xdr.h\"\n#include \"libnfs-raw-nsm.h\"/" -e "s/xdr/zdr/g" -e "s/XDR/ZDR/g" -e "s/register int32_t \*buf;/register int32_t *buf;\n buf = NULL;/" -e "s/bool_t/uint32_t/g" >> libnfs-raw-nsm.c diff --git a/deps/libnfs/nsm/libnfs-raw-nsm.c b/deps/libnfs/nsm/libnfs-raw-nsm.c new file mode 100644 index 000000000000..5c917d364a6d --- /dev/null +++ b/deps/libnfs/nsm/libnfs-raw-nsm.c @@ -0,0 +1,148 @@ +/* +Copyright (c) 2014, Ronnie Sahlberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +/* + * Please do not edit this file. + * It was generated using rpcgen. + */ + +#include "libnfs-zdr.h" +#include "libnfs-raw-nsm.h" + +uint32_t +zdr_nsmstat1 (ZDR *zdrs, nsmstat1 *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_nsm_my_id (ZDR *zdrs, nsm_my_id *objp) +{ + if (!zdr_string (zdrs, &objp->my_name, NSM_MAXSTRLEN)) + return FALSE; + if (!zdr_int (zdrs, &objp->my_prog)) + return FALSE; + if (!zdr_int (zdrs, &objp->my_vers)) + return FALSE; + if (!zdr_int (zdrs, &objp->my_proc)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_nsm_mon_id (ZDR *zdrs, nsm_mon_id *objp) +{ + if (!zdr_string (zdrs, &objp->mon_name, NSM_MAXSTRLEN)) + return FALSE; + if (!zdr_nsm_my_id (zdrs, &objp->my_id)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_NSM1_STATres (ZDR *zdrs, NSM1_STATres *objp) +{ + if (!zdr_nsmstat1 (zdrs, &objp->res)) + return FALSE; + if (!zdr_int (zdrs, &objp->state)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_NSM1_STATargs (ZDR *zdrs, NSM1_STATargs *objp) +{ + if (!zdr_string (zdrs, &objp->mon_name, NSM_MAXSTRLEN)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_NSM1_MONres (ZDR *zdrs, NSM1_MONres *objp) +{ + if (!zdr_nsmstat1 (zdrs, &objp->res)) + return FALSE; + if (!zdr_int (zdrs, &objp->state)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_NSM1_MONargs (ZDR *zdrs, NSM1_MONargs *objp) +{ + if (!zdr_nsm_mon_id (zdrs, &objp->mon_id)) + return FALSE; + if (!zdr_opaque (zdrs, objp->priv, 16)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_NSM1_UNMONres (ZDR *zdrs, NSM1_UNMONres *objp) +{ + if (!zdr_int (zdrs, &objp->state)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_NSM1_UNMONargs (ZDR *zdrs, NSM1_UNMONargs *objp) +{ + if (!zdr_nsm_mon_id (zdrs, &objp->mon_id)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_NSM1_UNMONALLres (ZDR *zdrs, NSM1_UNMONALLres *objp) +{ + if (!zdr_int (zdrs, &objp->state)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_NSM1_UNMONALLargs (ZDR *zdrs, NSM1_UNMONALLargs *objp) +{ + if (!zdr_nsm_my_id (zdrs, &objp->my_id)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_NSM1_NOTIFYargs (ZDR *zdrs, NSM1_NOTIFYargs *objp) +{ + if (!zdr_string (zdrs, &objp->mon_name, NSM_MAXSTRLEN)) + return FALSE; + if (!zdr_int (zdrs, &objp->state)) + return FALSE; + return TRUE; +} diff --git a/deps/libnfs/nsm/libnfs-raw-nsm.h b/deps/libnfs/nsm/libnfs-raw-nsm.h new file mode 100644 index 000000000000..e35e0c2015c9 --- /dev/null +++ b/deps/libnfs/nsm/libnfs-raw-nsm.h @@ -0,0 +1,204 @@ +/* +Copyright (c) 2014, Ronnie Sahlberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +/* + * Please do not edit this file. + * It was generated using rpcgen. + */ + +#ifndef _NSM_H_RPCGEN +#define _NSM_H_RPCGEN + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +#define NSM_MAXSTRLEN 1024 + +enum nsmstat1 { + NSM_STAT_SUCC = 0, + NSM_STAT_FAIL = 1, +}; +typedef enum nsmstat1 nsmstat1; + +struct nsm_my_id { + char *my_name; + int my_prog; + int my_vers; + int my_proc; +}; +typedef struct nsm_my_id nsm_my_id; + +struct nsm_mon_id { + char *mon_name; + struct nsm_my_id my_id; +}; +typedef struct nsm_mon_id nsm_mon_id; + +struct NSM1_STATres { + nsmstat1 res; + int state; +}; +typedef struct NSM1_STATres NSM1_STATres; + +struct NSM1_STATargs { + char *mon_name; +}; +typedef struct NSM1_STATargs NSM1_STATargs; + +struct NSM1_MONres { + nsmstat1 res; + int state; +}; +typedef struct NSM1_MONres NSM1_MONres; + +struct NSM1_MONargs { + struct nsm_mon_id mon_id; + char priv[16]; +}; +typedef struct NSM1_MONargs NSM1_MONargs; + +struct NSM1_UNMONres { + int state; +}; +typedef struct NSM1_UNMONres NSM1_UNMONres; + +struct NSM1_UNMONargs { + struct nsm_mon_id mon_id; +}; +typedef struct NSM1_UNMONargs NSM1_UNMONargs; + +struct NSM1_UNMONALLres { + int state; +}; +typedef struct NSM1_UNMONALLres NSM1_UNMONALLres; + +struct NSM1_UNMONALLargs { + struct nsm_my_id my_id; +}; +typedef struct NSM1_UNMONALLargs NSM1_UNMONALLargs; + +struct NSM1_NOTIFYargs { + char *mon_name; + int state; +}; +typedef struct NSM1_NOTIFYargs NSM1_NOTIFYargs; + +#define NSM_PROGRAM 100024 +#define NSM_V1 1 + +#if defined(__STDC__) || defined(__cplusplus) +#define NSM1_NULL 0 +extern void * nsm1_null_1(void *, void *); +extern void * nsm1_null_1_svc(void *, struct svc_req *); +#define NSM1_STAT 1 +extern struct NSM1_STATres * nsm1_stat_1(struct NSM1_STATargs *, void *); +extern struct NSM1_STATres * nsm1_stat_1_svc(struct NSM1_STATargs *, struct svc_req *); +#define NSM1_MON 2 +extern struct NSM1_MONres * nsm1_mon_1(struct NSM1_MONargs *, void *); +extern struct NSM1_MONres * nsm1_mon_1_svc(struct NSM1_MONargs *, struct svc_req *); +#define NSM1_UNMON 3 +extern struct NSM1_UNMONres * nsm1_unmon_1(struct NSM1_UNMONargs *, void *); +extern struct NSM1_UNMONres * nsm1_unmon_1_svc(struct NSM1_UNMONargs *, struct svc_req *); +#define NSM1_UNMON_ALL 4 +extern struct NSM1_UNMONALLres * nsm1_unmon_all_1(struct NSM1_UNMONALLargs *, void *); +extern struct NSM1_UNMONALLres * nsm1_unmon_all_1_svc(struct NSM1_UNMONALLargs *, struct svc_req *); +#define NSM1_SIMU_CRASH 5 +extern void * nsm1_simu_crash_1(void *, void *); +extern void * nsm1_simu_crash_1_svc(void *, struct svc_req *); +#define NSM1_NOTIFY 6 +extern void * nsm1_notify_1(struct NSM1_NOTIFYargs *, void *); +extern void * nsm1_notify_1_svc(struct NSM1_NOTIFYargs *, struct svc_req *); +extern int nsm_program_1_freeresult (void *, zdrproc_t, caddr_t); + +#else /* K&R C */ +#define NSM1_NULL 0 +extern void * nsm1_null_1(); +extern void * nsm1_null_1_svc(); +#define NSM1_STAT 1 +extern struct NSM1_STATres * nsm1_stat_1(); +extern struct NSM1_STATres * nsm1_stat_1_svc(); +#define NSM1_MON 2 +extern struct NSM1_MONres * nsm1_mon_1(); +extern struct NSM1_MONres * nsm1_mon_1_svc(); +#define NSM1_UNMON 3 +extern struct NSM1_UNMONres * nsm1_unmon_1(); +extern struct NSM1_UNMONres * nsm1_unmon_1_svc(); +#define NSM1_UNMON_ALL 4 +extern struct NSM1_UNMONALLres * nsm1_unmon_all_1(); +extern struct NSM1_UNMONALLres * nsm1_unmon_all_1_svc(); +#define NSM1_SIMU_CRASH 5 +extern void * nsm1_simu_crash_1(); +extern void * nsm1_simu_crash_1_svc(); +#define NSM1_NOTIFY 6 +extern void * nsm1_notify_1(); +extern void * nsm1_notify_1_svc(); +extern int nsm_program_1_freeresult (); +#endif /* K&R C */ + +/* the zdr functions */ + +#if defined(__STDC__) || defined(__cplusplus) +extern uint32_t zdr_nsmstat1 (ZDR *, nsmstat1*); +extern uint32_t zdr_nsm_my_id (ZDR *, nsm_my_id*); +extern uint32_t zdr_nsm_mon_id (ZDR *, nsm_mon_id*); +extern uint32_t zdr_NSM1_STATres (ZDR *, NSM1_STATres*); +extern uint32_t zdr_NSM1_STATargs (ZDR *, NSM1_STATargs*); +extern uint32_t zdr_NSM1_MONres (ZDR *, NSM1_MONres*); +extern uint32_t zdr_NSM1_MONargs (ZDR *, NSM1_MONargs*); +extern uint32_t zdr_NSM1_UNMONres (ZDR *, NSM1_UNMONres*); +extern uint32_t zdr_NSM1_UNMONargs (ZDR *, NSM1_UNMONargs*); +extern uint32_t zdr_NSM1_UNMONALLres (ZDR *, NSM1_UNMONALLres*); +extern uint32_t zdr_NSM1_UNMONALLargs (ZDR *, NSM1_UNMONALLargs*); +extern uint32_t zdr_NSM1_NOTIFYargs (ZDR *, NSM1_NOTIFYargs*); + +#else /* K&R C */ +extern uint32_t zdr_nsmstat1 (); +extern uint32_t zdr_nsm_my_id (); +extern uint32_t zdr_nsm_mon_id (); +extern uint32_t zdr_NSM1_STATres (); +extern uint32_t zdr_NSM1_STATargs (); +extern uint32_t zdr_NSM1_MONres (); +extern uint32_t zdr_NSM1_MONargs (); +extern uint32_t zdr_NSM1_UNMONres (); +extern uint32_t zdr_NSM1_UNMONargs (); +extern uint32_t zdr_NSM1_UNMONALLres (); +extern uint32_t zdr_NSM1_UNMONALLargs (); +extern uint32_t zdr_NSM1_NOTIFYargs (); + +#endif /* K&R C */ + +#ifdef __cplusplus +} +#endif + +#endif /* !_NSM_H_RPCGEN */ diff --git a/deps/libnfs/nsm/nsm.c b/deps/libnfs/nsm/nsm.c new file mode 100644 index 000000000000..6ef1178584a5 --- /dev/null +++ b/deps/libnfs/nsm/nsm.c @@ -0,0 +1,207 @@ +/* + Copyright (C) 2013 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 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef WIN32 +#include +#endif/*WIN32*/ + +#include +#include +#include "libnfs-zdr.h" +#include "libnfs.h" +#include "libnfs-raw.h" +#include "libnfs-private.h" +#include "libnfs-raw-nsm.h" + +struct rpc_pdu * +rpc_nsm1_null_task(struct rpc_context *rpc, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NSM_PROGRAM, NSM_V1, NSM1_NULL, cb, private_data, (zdrproc_t)zdr_void, 0); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nsm/null call"); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nsm/null call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_nsm1_stat_task(struct rpc_context *rpc, rpc_cb cb, struct NSM1_STATargs *args, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NSM_PROGRAM, NSM_V1, NSM1_STAT, cb, private_data, (zdrproc_t)zdr_NSM1_STATres, sizeof(NSM1_STATres)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nsm/stat call"); + return NULL; + } + + if (zdr_NSM1_STATargs(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode NSM1_STATargs"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nsm/stat call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_nsm1_mon_task(struct rpc_context *rpc, rpc_cb cb, struct NSM1_MONargs *args, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NSM_PROGRAM, NSM_V1, NSM1_MON, cb, private_data, (zdrproc_t)zdr_NSM1_MONres, sizeof(NSM1_MONres)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nsm/mon call"); + return NULL; + } + + if (zdr_NSM1_MONargs(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode NSM1_MONargs"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nsm/mon call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_nsm1_unmon_task(struct rpc_context *rpc, rpc_cb cb, struct NSM1_UNMONargs *args, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NSM_PROGRAM, NSM_V1, NSM1_UNMON, cb, private_data, (zdrproc_t)zdr_NSM1_UNMONres, sizeof(NSM1_UNMONres)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nsm/unmon call"); + return NULL; + } + + if (zdr_NSM1_UNMONargs(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode NSM1_UNMONargs"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nsm/unmon call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_nsm1_unmonall_task(struct rpc_context *rpc, rpc_cb cb, struct NSM1_UNMONALLargs *args, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NSM_PROGRAM, NSM_V1, NSM1_UNMON_ALL, cb, private_data, (zdrproc_t)zdr_NSM1_UNMONALLres, sizeof(NSM1_UNMONALLres)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nsm/unmonall call"); + return NULL; + } + + if (zdr_NSM1_UNMONALLargs(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode NSM1_UNMONALLargs"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nsm/unmonall call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_nsm1_simucrash_task(struct rpc_context *rpc, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NSM_PROGRAM, NSM_V1, NSM1_SIMU_CRASH, cb, private_data, (zdrproc_t)zdr_void, 0); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nsm/simucrash call"); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nsm/simucrash call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_nsm1_notify_task(struct rpc_context *rpc, rpc_cb cb, struct NSM1_NOTIFYargs *args, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NSM_PROGRAM, NSM_V1, NSM1_NOTIFY, cb, private_data, (zdrproc_t)zdr_void, 0); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nsm/notify call"); + return NULL; + } + + if (zdr_NSM1_NOTIFYargs(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode NSM1_NOTIFYargs"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nsm/notify call"); + return NULL; + } + + return pdu; +} + +char *nsmstat1_to_str(int st) +{ + enum nsmstat1 stat = st; + + char *str = "unknown n1m stat"; + switch (stat) { + case NSM_STAT_SUCC: str="NSM_STAT_SUCC";break; + case NSM_STAT_FAIL: str="NSM_STAT_FAIL";break; + } + return str; +} diff --git a/deps/libnfs/nsm/nsm.x b/deps/libnfs/nsm/nsm.x new file mode 100644 index 000000000000..430a5e44a717 --- /dev/null +++ b/deps/libnfs/nsm/nsm.x @@ -0,0 +1,108 @@ +/* +Copyright (c) 2014, Ronnie Sahlberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +/* + * This defines the maximum length of the string + * identifying the caller. + */ +const NSM_MAXSTRLEN = 1024; + +enum nsmstat1 { + NSM_STAT_SUCC = 0, /* NSM agrees to monitor. */ + NSM_STAT_FAIL = 1 /* NSM cannot monitor. */ +}; + +struct nsm_my_id { + string my_name; /* hostname */ + int my_prog; /* RPC program number */ + int my_vers; /* program version number */ + int my_proc; /* procedure number */ +}; + +struct nsm_mon_id { + string mon_name; /* name of the host to be monitored */ + struct nsm_my_id my_id; +}; + +struct NSM1_STATres { + nsmstat1 res; + int state; +}; + +struct NSM1_STATargs { + string mon_name; +}; + +struct NSM1_MONres { + nsmstat1 res; + int state; +}; + +struct NSM1_MONargs { + struct nsm_mon_id mon_id; + opaque priv[16]; /* private information */ +}; + +struct NSM1_UNMONres { + int state; /* state number of NSM */ +}; + +struct NSM1_UNMONargs { + struct nsm_mon_id mon_id; +}; + +struct NSM1_UNMONALLres { + int state; /* state number of NSM */ +}; + +struct NSM1_UNMONALLargs { + struct nsm_my_id my_id; +}; + +struct NSM1_NOTIFYargs { + string mon_name; + int state; +}; + +/* + * Protocol description for the NSM program. + */ +program NSM_PROGRAM { + version NSM_V1 { + void NSM1_NULL(void) = 0; + struct NSM1_STATres NSM1_STAT(struct NSM1_STATargs) = 1; + struct NSM1_MONres NSM1_MON(struct NSM1_MONargs) = 2; + struct NSM1_UNMONres NSM1_UNMON(struct NSM1_UNMONargs) = 3; + struct NSM1_UNMONALLres NSM1_UNMON_ALL(struct NSM1_UNMONALLargs) = 4; + void NSM1_SIMU_CRASH(void) = 5; + void NSM1_NOTIFY(struct NSM1_NOTIFYargs) = 6; + } = 1; +} = 100024; + + diff --git a/deps/libnfs/portmap/CMakeLists.txt b/deps/libnfs/portmap/CMakeLists.txt new file mode 100644 index 000000000000..600f73aedff2 --- /dev/null +++ b/deps/libnfs/portmap/CMakeLists.txt @@ -0,0 +1,5 @@ +set(SOURCES libnfs-raw-portmap.c + portmap.c) +set(HEADERS libnfs-raw-portmap.h) + +core_add_library(portmap) diff --git a/deps/libnfs/portmap/Makefile.am b/deps/libnfs/portmap/Makefile.am new file mode 100644 index 000000000000..d62c9437d3a6 --- /dev/null +++ b/deps/libnfs/portmap/Makefile.am @@ -0,0 +1,25 @@ +noinst_LTLIBRARIES = libportmap.la + +portmap_SOURCES_GENERATED = +portmap_HEADERS_GENERATED = +portmap_GENERATED = $(portmap_SOURCES_GENERATED) $(portmap_HEADERS_GENERATED) + +CLEANFILES = $(portmap_GENERATED) portmap-stamp + +libportmap_la_CPPFLAGS = -I$(abs_top_srcdir)/include \ + -I$(abs_top_srcdir)/include/nfsc \ + -I$(abs_top_srcdir)/win32 +libportmap_la_SOURCES = \ + $(portmap_SOURCES_GENERATED) \ + portmap.c libnfs-raw-portmap.c libnfs-raw-portmap.h + +$(portmap_GENERATED) : portmap-stamp +portmap-stamp : portmap.x + rm -f $(portmap_GENERATED) + touch portmap-stamp + +compile_rpc: + cat portmap.x | head -29 >libnfs-raw-portmap.h + rpcgen -h portmap.x | sed -e "s/#include /#include /" | sed -e "s/xdr/zdr/g" -e "s/XDR/ZDR/g" -e "s/ CLIENT / void /g" -e "s/SVCXPRT /void /g" -e "s/bool_t/uint32_t/g" -e "s/u_int/uint32_t/" >> libnfs-raw-portmap.h + cat portmap.x | head -29 >libnfs-raw-portmap.c + rpcgen -c portmap.x | sed -e "s/#include \".*portmap.h\"/#include \"libnfs-zdr.h\"\n#include \"libnfs-raw-portmap.h\"/" -e "s/xdr/zdr/g" -e "s/XDR/ZDR/g" -e "s/register int32_t \*buf;//" -e "s/bool_t/uint32_t/g" -e "s/[ \t]*buf = / int32_t *buf;\n buf = /" -e "s/\(u_int \*\)/uint32_t \*/" >> libnfs-raw-portmap.c diff --git a/deps/libnfs/portmap/libnfs-raw-portmap.c b/deps/libnfs/portmap/libnfs-raw-portmap.c new file mode 100644 index 000000000000..3e25f2b0c82a --- /dev/null +++ b/deps/libnfs/portmap/libnfs-raw-portmap.c @@ -0,0 +1,780 @@ +/* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */ +/* +Copyright (c) 2014, Ronnie Sahlberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ +/* + * Please do not edit this file. + * It was generated using rpcgen. + */ + +#include "libnfs-zdr.h" +#include "libnfs-raw-portmap.h" + +uint32_t +zdr_pmap2_mapping (ZDR *zdrs, pmap2_mapping *objp) +{ + + + if (!zdr_uint32_t (zdrs, &objp->prog)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->vers)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->prot)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->port)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_pmap2_call_args (ZDR *zdrs, pmap2_call_args *objp) +{ + + + if (!zdr_uint32_t (zdrs, &objp->prog)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->vers)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->proc)) + return FALSE; + if (!zdr_bytes (zdrs, (char **)&objp->args.args_val, (uint32_t *) &objp->args.args_len, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_pmap2_call_result (ZDR *zdrs, pmap2_call_result *objp) +{ + + + if (!zdr_uint32_t (zdrs, &objp->port)) + return FALSE; + if (!zdr_bytes (zdrs, (char **)&objp->res.res_val, (uint32_t *) &objp->res.res_len, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_pmap2_mapping_list (ZDR *zdrs, pmap2_mapping_list *objp) +{ + + + if (!zdr_pmap2_mapping (zdrs, &objp->map)) + return FALSE; + if (!zdr_pointer (zdrs, (char **)&objp->next, sizeof (pmap2_mapping_list), (zdrproc_t) zdr_pmap2_mapping_list)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_pmap2_dump_result (ZDR *zdrs, pmap2_dump_result *objp) +{ + + + if (!zdr_pointer (zdrs, (char **)&objp->list, sizeof (pmap2_mapping_list), (zdrproc_t) zdr_pmap2_mapping_list)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_pmap3_string_result (ZDR *zdrs, pmap3_string_result *objp) +{ + + + if (!zdr_string (zdrs, &objp->addr, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_pmap3_mapping (ZDR *zdrs, pmap3_mapping *objp) +{ + + + if (!zdr_uint32_t (zdrs, &objp->prog)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->vers)) + return FALSE; + if (!zdr_string (zdrs, &objp->netid, ~0)) + return FALSE; + if (!zdr_string (zdrs, &objp->addr, ~0)) + return FALSE; + if (!zdr_string (zdrs, &objp->owner, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_pmap3_mapping_list (ZDR *zdrs, pmap3_mapping_list *objp) +{ + + + if (!zdr_pmap3_mapping (zdrs, &objp->map)) + return FALSE; + if (!zdr_pointer (zdrs, (char **)&objp->next, sizeof (pmap3_mapping_list), (zdrproc_t) zdr_pmap3_mapping_list)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_pmap3_dump_result (ZDR *zdrs, pmap3_dump_result *objp) +{ + + + if (!zdr_pointer (zdrs, (char **)&objp->list, sizeof (pmap3_mapping_list), (zdrproc_t) zdr_pmap3_mapping_list)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_pmap3_call_args (ZDR *zdrs, pmap3_call_args *objp) +{ + + + if (!zdr_uint32_t (zdrs, &objp->prog)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->vers)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->proc)) + return FALSE; + if (!zdr_bytes (zdrs, (char **)&objp->args.args_val, (uint32_t *) &objp->args.args_len, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_rpcb_rmtcallres (ZDR *zdrs, rpcb_rmtcallres *objp) +{ + + + if (!zdr_string (zdrs, &objp->addr, ~0)) + return FALSE; + if (!zdr_bytes (zdrs, (char **)&objp->results.results_val, (uint32_t *) &objp->results.results_len, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_pmap3_netbuf (ZDR *zdrs, pmap3_netbuf *objp) +{ + + + if (!zdr_uint32_t (zdrs, &objp->maxlen)) + return FALSE; + if (!zdr_bytes (zdrs, (char **)&objp->buf.buf_val, (uint32_t *) &objp->buf.buf_len, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_pmap4_string_result (ZDR *zdrs, pmap4_string_result *objp) +{ + + + if (!zdr_string (zdrs, &objp->addr, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_pmap4_mapping (ZDR *zdrs, pmap4_mapping *objp) +{ + + + if (!zdr_uint32_t (zdrs, &objp->prog)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->vers)) + return FALSE; + if (!zdr_string (zdrs, &objp->netid, ~0)) + return FALSE; + if (!zdr_string (zdrs, &objp->addr, ~0)) + return FALSE; + if (!zdr_string (zdrs, &objp->owner, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_pmap4_mapping_list (ZDR *zdrs, pmap4_mapping_list *objp) +{ + + + if (!zdr_pmap4_mapping (zdrs, &objp->map)) + return FALSE; + if (!zdr_pointer (zdrs, (char **)&objp->next, sizeof (pmap4_mapping_list), (zdrproc_t) zdr_pmap4_mapping_list)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_pmap4_dump_result (ZDR *zdrs, pmap4_dump_result *objp) +{ + + + if (!zdr_pointer (zdrs, (char **)&objp->list, sizeof (pmap4_mapping_list), (zdrproc_t) zdr_pmap4_mapping_list)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_pmap4_bcast_args (ZDR *zdrs, pmap4_bcast_args *objp) +{ + + + if (!zdr_uint32_t (zdrs, &objp->prog)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->vers)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->proc)) + return FALSE; + if (!zdr_bytes (zdrs, (char **)&objp->args.args_val, (uint32_t *) &objp->args.args_len, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_pmap4_netbuf (ZDR *zdrs, pmap4_netbuf *objp) +{ + + + if (!zdr_uint32_t (zdrs, &objp->maxlen)) + return FALSE; + if (!zdr_bytes (zdrs, (char **)&objp->buf.buf_val, (uint32_t *) &objp->buf.buf_len, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_pmap4_indirect_args (ZDR *zdrs, pmap4_indirect_args *objp) +{ + + + if (!zdr_uint32_t (zdrs, &objp->prog)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->vers)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->proc)) + return FALSE; + if (!zdr_bytes (zdrs, (char **)&objp->args.args_val, (uint32_t *) &objp->args.args_len, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_rpcbs_addrlist (ZDR *zdrs, rpcbs_addrlist *objp) +{ + + + if (!zdr_uint32_t (zdrs, &objp->prog)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->vers)) + return FALSE; + if (!zdr_int32_t (zdrs, &objp->success)) + return FALSE; + if (!zdr_int32_t (zdrs, &objp->failure)) + return FALSE; + if (!zdr_string (zdrs, &objp->netid, ~0)) + return FALSE; + if (!zdr_pointer (zdrs, (char **)&objp->next, sizeof (rpcbs_addrlist), (zdrproc_t) zdr_rpcbs_addrlist)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_rpcbs_rmtcalllist (ZDR *zdrs, rpcbs_rmtcalllist *objp) +{ + + + if (!zdr_uint32_t (zdrs, &objp->prog)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->vers)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->proc)) + return FALSE; + if (!zdr_int32_t (zdrs, &objp->success)) + return FALSE; + if (!zdr_int32_t (zdrs, &objp->failure)) + return FALSE; + if (!zdr_int32_t (zdrs, &objp->indirect)) + return FALSE; + if (!zdr_string (zdrs, &objp->netid, ~0)) + return FALSE; + if (!zdr_pointer (zdrs, (char **)&objp->next, sizeof (rpcbs_rmtcalllist), (zdrproc_t) zdr_rpcbs_rmtcalllist)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_rpcbs_proc (ZDR *zdrs, rpcbs_proc objp) +{ + + + if (!zdr_vector (zdrs, (char *)objp, RPCBSTAT_HIGHPROC, + sizeof (int), (zdrproc_t) zdr_int)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_rpcbs_addrlist_ptr (ZDR *zdrs, rpcbs_addrlist_ptr *objp) +{ + + + if (!zdr_pointer (zdrs, (char **)objp, sizeof (rpcbs_addrlist), (zdrproc_t) zdr_rpcbs_addrlist)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_rpcbs_rmtcalllist_ptr (ZDR *zdrs, rpcbs_rmtcalllist_ptr *objp) +{ + + + if (!zdr_pointer (zdrs, (char **)objp, sizeof (rpcbs_rmtcalllist), (zdrproc_t) zdr_rpcbs_rmtcalllist)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_rpcb_stat (ZDR *zdrs, rpcb_stat *objp) +{ + + + if (!zdr_rpcbs_proc (zdrs, objp->info)) + return FALSE; + if (!zdr_int32_t (zdrs, &objp->setinfo)) + return FALSE; + if (!zdr_int32_t (zdrs, &objp->unsetinfo)) + return FALSE; + if (!zdr_rpcbs_addrlist_ptr (zdrs, &objp->addrinfo)) + return FALSE; + if (!zdr_rpcbs_rmtcalllist_ptr (zdrs, &objp->rmtinfo)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_pmap4_stat_byvers (ZDR *zdrs, pmap4_stat_byvers objp) +{ + + + if (!zdr_vector (zdrs, (char *)objp, RPCBVERS_STAT, + sizeof (rpcb_stat), (zdrproc_t) zdr_rpcb_stat)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_rpcb_entry (ZDR *zdrs, rpcb_entry *objp) +{ + + + if (!zdr_string (zdrs, &objp->r_maddr, ~0)) + return FALSE; + if (!zdr_string (zdrs, &objp->r_nc_netid, ~0)) + return FALSE; + if (!zdr_uint32_t (zdrs, &objp->r_nc_semantics)) + return FALSE; + if (!zdr_string (zdrs, &objp->r_nc_protofmly, ~0)) + return FALSE; + if (!zdr_string (zdrs, &objp->r_nc_proto, ~0)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_rpcb_entry_list (ZDR *zdrs, rpcb_entry_list *objp) +{ + + + if (!zdr_rpcb_entry (zdrs, &objp->rpcb_entry_map)) + return FALSE; + if (!zdr_pointer (zdrs, (char **)&objp->next, sizeof (rpcb_entry_list), (zdrproc_t) zdr_rpcb_entry_list)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_pmap4_entry_list_ptr (ZDR *zdrs, pmap4_entry_list_ptr *objp) +{ + + + if (!zdr_pointer (zdrs, (char **)objp, sizeof (rpcb_entry_list), (zdrproc_t) zdr_rpcb_entry_list)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP2SETargs (ZDR *zdrs, PMAP2SETargs *objp) +{ + + + if (!zdr_pmap2_mapping (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP2UNSETargs (ZDR *zdrs, PMAP2UNSETargs *objp) +{ + + + if (!zdr_pmap2_mapping (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP2GETPORTargs (ZDR *zdrs, PMAP2GETPORTargs *objp) +{ + + + if (!zdr_pmap2_mapping (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP2CALLITargs (ZDR *zdrs, PMAP2CALLITargs *objp) +{ + + + if (!zdr_pmap2_call_args (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP2CALLITres (ZDR *zdrs, PMAP2CALLITres *objp) +{ + + + if (!zdr_pmap2_call_result (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP2DUMPres (ZDR *zdrs, PMAP2DUMPres *objp) +{ + + + if (!zdr_pmap2_dump_result (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP3SETargs (ZDR *zdrs, PMAP3SETargs *objp) +{ + + + if (!zdr_pmap3_mapping (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP3UNSETargs (ZDR *zdrs, PMAP3UNSETargs *objp) +{ + + + if (!zdr_pmap3_mapping (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP3GETADDRargs (ZDR *zdrs, PMAP3GETADDRargs *objp) +{ + + + if (!zdr_pmap3_mapping (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP3GETADDRres (ZDR *zdrs, PMAP3GETADDRres *objp) +{ + + + if (!zdr_pmap3_string_result (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP3DUMPres (ZDR *zdrs, PMAP3DUMPres *objp) +{ + + + if (!zdr_pmap3_dump_result (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP3CALLITargs (ZDR *zdrs, PMAP3CALLITargs *objp) +{ + + + if (!zdr_pmap3_call_args (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP3CALLITres (ZDR *zdrs, PMAP3CALLITres *objp) +{ + + + if (!zdr_rpcb_rmtcallres (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP3UADDR2TADDRargs (ZDR *zdrs, PMAP3UADDR2TADDRargs *objp) +{ + + + if (!zdr_pmap3_string_result (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP3UADDR2TADDRres (ZDR *zdrs, PMAP3UADDR2TADDRres *objp) +{ + + + if (!zdr_pmap3_netbuf (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP3TADDR2UADDRargs (ZDR *zdrs, PMAP3TADDR2UADDRargs *objp) +{ + + + if (!zdr_pmap3_netbuf (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP3TADDR2UADDRres (ZDR *zdrs, PMAP3TADDR2UADDRres *objp) +{ + + + if (!zdr_pmap3_string_result (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP4SETargs (ZDR *zdrs, PMAP4SETargs *objp) +{ + + + if (!zdr_pmap4_mapping (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP4UNSETargs (ZDR *zdrs, PMAP4UNSETargs *objp) +{ + + + if (!zdr_pmap4_mapping (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP4GETADDRargs (ZDR *zdrs, PMAP4GETADDRargs *objp) +{ + + + if (!zdr_pmap4_mapping (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP4GETADDRres (ZDR *zdrs, PMAP4GETADDRres *objp) +{ + + + if (!zdr_pmap4_string_result (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP4DUMPres (ZDR *zdrs, PMAP4DUMPres *objp) +{ + + + if (!zdr_pmap4_dump_result (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP4BCASTargs (ZDR *zdrs, PMAP4BCASTargs *objp) +{ + + + if (!zdr_pmap4_bcast_args (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP4BCASTres (ZDR *zdrs, PMAP4BCASTres *objp) +{ + + + if (!zdr_rpcb_rmtcallres (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP4UADDR2TADDRargs (ZDR *zdrs, PMAP4UADDR2TADDRargs *objp) +{ + + + if (!zdr_pmap3_string_result (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP4UADDR2TADDRres (ZDR *zdrs, PMAP4UADDR2TADDRres *objp) +{ + + + if (!zdr_pmap4_netbuf (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP4TADDR2UADDRargs (ZDR *zdrs, PMAP4TADDR2UADDRargs *objp) +{ + + + if (!zdr_pmap4_netbuf (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP4TADDR2UADDRres (ZDR *zdrs, PMAP4TADDR2UADDRres *objp) +{ + + + if (!zdr_pmap4_string_result (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP4GETVERSADDRargs (ZDR *zdrs, PMAP4GETVERSADDRargs *objp) +{ + + + if (!zdr_pmap4_mapping (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP4GETVERSADDRres (ZDR *zdrs, PMAP4GETVERSADDRres *objp) +{ + + + if (!zdr_pmap4_string_result (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP4INDIRECTargs (ZDR *zdrs, PMAP4INDIRECTargs *objp) +{ + + + if (!zdr_pmap4_indirect_args (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP4INDIRECTres (ZDR *zdrs, PMAP4INDIRECTres *objp) +{ + + + if (!zdr_rpcb_rmtcallres (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP4GETSTATres (ZDR *zdrs, PMAP4GETSTATres objp) +{ + + + if (!zdr_pmap4_stat_byvers (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP4GETADDRLISTargs (ZDR *zdrs, PMAP4GETADDRLISTargs *objp) +{ + + + if (!zdr_pmap4_mapping (zdrs, objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_PMAP4GETADDRLISTres (ZDR *zdrs, PMAP4GETADDRLISTres *objp) +{ + + + if (!zdr_pmap4_entry_list_ptr (zdrs, objp)) + return FALSE; + return TRUE; +} diff --git a/deps/libnfs/portmap/libnfs-raw-portmap.h b/deps/libnfs/portmap/libnfs-raw-portmap.h new file mode 100644 index 000000000000..7d547c277cea --- /dev/null +++ b/deps/libnfs/portmap/libnfs-raw-portmap.h @@ -0,0 +1,665 @@ +/* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */ +/* +Copyright (c) 2014, Ronnie Sahlberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ +/* + * Please do not edit this file. + * It was generated using rpcgen. + */ + +#ifndef _PORTMAP_H_RPCGEN +#define _PORTMAP_H_RPCGEN + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +#define PMAP_PORT 111 + +struct pmap2_mapping { + uint32_t prog; + uint32_t vers; + uint32_t prot; + uint32_t port; +}; +typedef struct pmap2_mapping pmap2_mapping; + +struct pmap2_call_args { + uint32_t prog; + uint32_t vers; + uint32_t proc; + struct { + uint32_t args_len; + char *args_val; + } args; +}; +typedef struct pmap2_call_args pmap2_call_args; + +struct pmap2_call_result { + uint32_t port; + struct { + uint32_t res_len; + char *res_val; + } res; +}; +typedef struct pmap2_call_result pmap2_call_result; + +struct pmap2_mapping_list { + pmap2_mapping map; + struct pmap2_mapping_list *next; +}; +typedef struct pmap2_mapping_list pmap2_mapping_list; + +struct pmap2_dump_result { + struct pmap2_mapping_list *list; +}; +typedef struct pmap2_dump_result pmap2_dump_result; + +struct pmap3_string_result { + char *addr; +}; +typedef struct pmap3_string_result pmap3_string_result; + +struct pmap3_mapping { + uint32_t prog; + uint32_t vers; + char *netid; + char *addr; + char *owner; +}; +typedef struct pmap3_mapping pmap3_mapping; + +struct pmap3_mapping_list { + pmap3_mapping map; + struct pmap3_mapping_list *next; +}; +typedef struct pmap3_mapping_list pmap3_mapping_list; + +struct pmap3_dump_result { + struct pmap3_mapping_list *list; +}; +typedef struct pmap3_dump_result pmap3_dump_result; + +struct pmap3_call_args { + uint32_t prog; + uint32_t vers; + uint32_t proc; + struct { + uint32_t args_len; + char *args_val; + } args; +}; +typedef struct pmap3_call_args pmap3_call_args; + +struct rpcb_rmtcallres { + char *addr; + struct { + uint32_t results_len; + char *results_val; + } results; +}; +typedef struct rpcb_rmtcallres rpcb_rmtcallres; + +struct pmap3_netbuf { + uint32_t maxlen; + struct { + uint32_t buf_len; + char *buf_val; + } buf; +}; +typedef struct pmap3_netbuf pmap3_netbuf; + +struct pmap4_string_result { + char *addr; +}; +typedef struct pmap4_string_result pmap4_string_result; + +struct pmap4_mapping { + uint32_t prog; + uint32_t vers; + char *netid; + char *addr; + char *owner; +}; +typedef struct pmap4_mapping pmap4_mapping; + +struct pmap4_mapping_list { + pmap4_mapping map; + struct pmap4_mapping_list *next; +}; +typedef struct pmap4_mapping_list pmap4_mapping_list; + +struct pmap4_dump_result { + struct pmap4_mapping_list *list; +}; +typedef struct pmap4_dump_result pmap4_dump_result; + +struct pmap4_bcast_args { + uint32_t prog; + uint32_t vers; + uint32_t proc; + struct { + uint32_t args_len; + char *args_val; + } args; +}; +typedef struct pmap4_bcast_args pmap4_bcast_args; + +struct pmap4_netbuf { + uint32_t maxlen; + struct { + uint32_t buf_len; + char *buf_val; + } buf; +}; +typedef struct pmap4_netbuf pmap4_netbuf; + +struct pmap4_indirect_args { + uint32_t prog; + uint32_t vers; + uint32_t proc; + struct { + uint32_t args_len; + char *args_val; + } args; +}; +typedef struct pmap4_indirect_args pmap4_indirect_args; +#define RPCBSTAT_HIGHPROC 13 +#define RPCBVERS_STAT 3 +#define RPCBVERS_4_STAT 2 +#define RPCBVERS_3_STAT 1 +#define RPCBVERS_2_STAT 0 + +struct rpcbs_addrlist { + uint32_t prog; + uint32_t vers; + int32_t success; + int32_t failure; + char *netid; + struct rpcbs_addrlist *next; +}; +typedef struct rpcbs_addrlist rpcbs_addrlist; + +struct rpcbs_rmtcalllist { + uint32_t prog; + uint32_t vers; + uint32_t proc; + int32_t success; + int32_t failure; + int32_t indirect; + char *netid; + struct rpcbs_rmtcalllist *next; +}; +typedef struct rpcbs_rmtcalllist rpcbs_rmtcalllist; + +typedef int rpcbs_proc[RPCBSTAT_HIGHPROC]; + +typedef rpcbs_addrlist *rpcbs_addrlist_ptr; + +typedef rpcbs_rmtcalllist *rpcbs_rmtcalllist_ptr; + +struct rpcb_stat { + rpcbs_proc info; + int32_t setinfo; + int32_t unsetinfo; + rpcbs_addrlist_ptr addrinfo; + rpcbs_rmtcalllist_ptr rmtinfo; +}; +typedef struct rpcb_stat rpcb_stat; + +typedef rpcb_stat pmap4_stat_byvers[RPCBVERS_STAT]; +#define NC_TPI_CLTS 1 +#define NC_TPI_COTS 2 +#define NC_TPI_COTS_ORD 3 +#define NC_TPI_RAW 4 + +struct rpcb_entry { + char *r_maddr; + char *r_nc_netid; + uint32_t r_nc_semantics; + char *r_nc_protofmly; + char *r_nc_proto; +}; +typedef struct rpcb_entry rpcb_entry; + +struct rpcb_entry_list { + rpcb_entry rpcb_entry_map; + struct rpcb_entry_list *next; +}; +typedef struct rpcb_entry_list rpcb_entry_list; + +typedef rpcb_entry_list *pmap4_entry_list_ptr; + +typedef pmap2_mapping PMAP2SETargs; + +typedef pmap2_mapping PMAP2UNSETargs; + +typedef pmap2_mapping PMAP2GETPORTargs; + +typedef pmap2_call_args PMAP2CALLITargs; + +typedef pmap2_call_result PMAP2CALLITres; + +typedef pmap2_dump_result PMAP2DUMPres; + +typedef pmap3_mapping PMAP3SETargs; + +typedef pmap3_mapping PMAP3UNSETargs; + +typedef pmap3_mapping PMAP3GETADDRargs; + +typedef pmap3_string_result PMAP3GETADDRres; + +typedef pmap3_dump_result PMAP3DUMPres; + +typedef pmap3_call_args PMAP3CALLITargs; + +typedef rpcb_rmtcallres PMAP3CALLITres; + +typedef pmap3_string_result PMAP3UADDR2TADDRargs; + +typedef pmap3_netbuf PMAP3UADDR2TADDRres; + +typedef pmap3_netbuf PMAP3TADDR2UADDRargs; + +typedef pmap3_string_result PMAP3TADDR2UADDRres; + +typedef pmap4_mapping PMAP4SETargs; + +typedef pmap4_mapping PMAP4UNSETargs; + +typedef pmap4_mapping PMAP4GETADDRargs; + +typedef pmap4_string_result PMAP4GETADDRres; + +typedef pmap4_dump_result PMAP4DUMPres; + +typedef pmap4_bcast_args PMAP4BCASTargs; + +typedef rpcb_rmtcallres PMAP4BCASTres; + +typedef pmap3_string_result PMAP4UADDR2TADDRargs; + +typedef pmap4_netbuf PMAP4UADDR2TADDRres; + +typedef pmap4_netbuf PMAP4TADDR2UADDRargs; + +typedef pmap4_string_result PMAP4TADDR2UADDRres; + +typedef pmap4_mapping PMAP4GETVERSADDRargs; + +typedef pmap4_string_result PMAP4GETVERSADDRres; + +typedef pmap4_indirect_args PMAP4INDIRECTargs; + +typedef rpcb_rmtcallres PMAP4INDIRECTres; + +typedef pmap4_stat_byvers PMAP4GETSTATres; + +typedef pmap4_mapping PMAP4GETADDRLISTargs; + +typedef pmap4_entry_list_ptr PMAP4GETADDRLISTres; + +#define PMAP_PROGRAM 100000 +#define PMAP_V2 2 + +#if defined(__STDC__) || defined(__cplusplus) +#define PMAP2_NULL 0 +extern void * pmap2_null_2(void *, void *); +extern void * pmap2_null_2_svc(void *, struct svc_req *); +#define PMAP2_SET 1 +extern uint32_t * pmap2_set_2(PMAP2SETargs *, void *); +extern uint32_t * pmap2_set_2_svc(PMAP2SETargs *, struct svc_req *); +#define PMAP2_UNSET 2 +extern uint32_t * pmap2_unset_2(PMAP2UNSETargs *, void *); +extern uint32_t * pmap2_unset_2_svc(PMAP2UNSETargs *, struct svc_req *); +#define PMAP2_GETPORT 3 +extern uint32_t * pmap2_getport_2(PMAP2GETPORTargs *, void *); +extern uint32_t * pmap2_getport_2_svc(PMAP2GETPORTargs *, struct svc_req *); +#define PMAP2_DUMP 4 +extern PMAP2DUMPres * pmap2_dump_2(void *, void *); +extern PMAP2DUMPres * pmap2_dump_2_svc(void *, struct svc_req *); +#define PMAP2_CALLIT 5 +extern PMAP2CALLITres * pmap2_callit_2(PMAP2CALLITargs *, void *); +extern PMAP2CALLITres * pmap2_callit_2_svc(PMAP2CALLITargs *, struct svc_req *); +extern int pmap_program_2_freeresult (void *, zdrproc_t, caddr_t); + +#else /* K&R C */ +#define PMAP2_NULL 0 +extern void * pmap2_null_2(); +extern void * pmap2_null_2_svc(); +#define PMAP2_SET 1 +extern uint32_t * pmap2_set_2(); +extern uint32_t * pmap2_set_2_svc(); +#define PMAP2_UNSET 2 +extern uint32_t * pmap2_unset_2(); +extern uint32_t * pmap2_unset_2_svc(); +#define PMAP2_GETPORT 3 +extern uint32_t * pmap2_getport_2(); +extern uint32_t * pmap2_getport_2_svc(); +#define PMAP2_DUMP 4 +extern PMAP2DUMPres * pmap2_dump_2(); +extern PMAP2DUMPres * pmap2_dump_2_svc(); +#define PMAP2_CALLIT 5 +extern PMAP2CALLITres * pmap2_callit_2(); +extern PMAP2CALLITres * pmap2_callit_2_svc(); +extern int pmap_program_2_freeresult (); +#endif /* K&R C */ +#define PMAP_V3 3 + +#if defined(__STDC__) || defined(__cplusplus) +#define PMAP3_NULL 0 +extern void * pmap3_null_3(void *, void *); +extern void * pmap3_null_3_svc(void *, struct svc_req *); +#define PMAP3_SET 1 +extern uint32_t * pmap3_set_3(PMAP3SETargs *, void *); +extern uint32_t * pmap3_set_3_svc(PMAP3SETargs *, struct svc_req *); +#define PMAP3_UNSET 2 +extern uint32_t * pmap3_unset_3(PMAP3UNSETargs *, void *); +extern uint32_t * pmap3_unset_3_svc(PMAP3UNSETargs *, struct svc_req *); +#define PMAP3_GETADDR 3 +extern PMAP3GETADDRres * pmap3_getaddr_3(PMAP3GETADDRargs *, void *); +extern PMAP3GETADDRres * pmap3_getaddr_3_svc(PMAP3GETADDRargs *, struct svc_req *); +#define PMAP3_DUMP 4 +extern PMAP3DUMPres * pmap3_dump_3(void *, void *); +extern PMAP3DUMPres * pmap3_dump_3_svc(void *, struct svc_req *); +#define PMAP3_CALLIT 5 +extern PMAP3CALLITres * pmap3_callit_3(PMAP3CALLITargs *, void *); +extern PMAP3CALLITres * pmap3_callit_3_svc(PMAP3CALLITargs *, struct svc_req *); +#define PMAP3_GETTIME 6 +extern uint32_t * pmap3_gettime_3(void *, void *); +extern uint32_t * pmap3_gettime_3_svc(void *, struct svc_req *); +#define PMAP3_UADDR2TADDR 7 +extern PMAP3UADDR2TADDRres * pmap3_uaddr2taddr_3(PMAP3UADDR2TADDRargs *, void *); +extern PMAP3UADDR2TADDRres * pmap3_uaddr2taddr_3_svc(PMAP3UADDR2TADDRargs *, struct svc_req *); +#define PMAP3_TADDR2UADDR 8 +extern PMAP3TADDR2UADDRres * pmap3_taddr2uaddr_3(PMAP3TADDR2UADDRargs *, void *); +extern PMAP3TADDR2UADDRres * pmap3_taddr2uaddr_3_svc(PMAP3TADDR2UADDRargs *, struct svc_req *); +extern int pmap_program_3_freeresult (void *, zdrproc_t, caddr_t); + +#else /* K&R C */ +#define PMAP3_NULL 0 +extern void * pmap3_null_3(); +extern void * pmap3_null_3_svc(); +#define PMAP3_SET 1 +extern uint32_t * pmap3_set_3(); +extern uint32_t * pmap3_set_3_svc(); +#define PMAP3_UNSET 2 +extern uint32_t * pmap3_unset_3(); +extern uint32_t * pmap3_unset_3_svc(); +#define PMAP3_GETADDR 3 +extern PMAP3GETADDRres * pmap3_getaddr_3(); +extern PMAP3GETADDRres * pmap3_getaddr_3_svc(); +#define PMAP3_DUMP 4 +extern PMAP3DUMPres * pmap3_dump_3(); +extern PMAP3DUMPres * pmap3_dump_3_svc(); +#define PMAP3_CALLIT 5 +extern PMAP3CALLITres * pmap3_callit_3(); +extern PMAP3CALLITres * pmap3_callit_3_svc(); +#define PMAP3_GETTIME 6 +extern uint32_t * pmap3_gettime_3(); +extern uint32_t * pmap3_gettime_3_svc(); +#define PMAP3_UADDR2TADDR 7 +extern PMAP3UADDR2TADDRres * pmap3_uaddr2taddr_3(); +extern PMAP3UADDR2TADDRres * pmap3_uaddr2taddr_3_svc(); +#define PMAP3_TADDR2UADDR 8 +extern PMAP3TADDR2UADDRres * pmap3_taddr2uaddr_3(); +extern PMAP3TADDR2UADDRres * pmap3_taddr2uaddr_3_svc(); +extern int pmap_program_3_freeresult (); +#endif /* K&R C */ +#define PMAP_V4 4 + +#if defined(__STDC__) || defined(__cplusplus) +#define PMAP4_NULL 0 +extern void * pmap4_null_4(void *, void *); +extern void * pmap4_null_4_svc(void *, struct svc_req *); +#define PMAP4_SET 1 +extern uint32_t * pmap4_set_4(PMAP4SETargs *, void *); +extern uint32_t * pmap4_set_4_svc(PMAP4SETargs *, struct svc_req *); +#define PMAP4_UNSET 2 +extern uint32_t * pmap4_unset_4(PMAP4UNSETargs *, void *); +extern uint32_t * pmap4_unset_4_svc(PMAP4UNSETargs *, struct svc_req *); +#define PMAP4_GETADDR 3 +extern PMAP4GETADDRres * pmap4_getaddr_4(PMAP4GETADDRargs *, void *); +extern PMAP4GETADDRres * pmap4_getaddr_4_svc(PMAP4GETADDRargs *, struct svc_req *); +#define PMAP4_DUMP 4 +extern PMAP4DUMPres * pmap4_dump_4(void *, void *); +extern PMAP4DUMPres * pmap4_dump_4_svc(void *, struct svc_req *); +#define PMAP4_BCAST 5 +extern PMAP4BCASTres * pmap4_bcast_4(PMAP4BCASTargs *, void *); +extern PMAP4BCASTres * pmap4_bcast_4_svc(PMAP4BCASTargs *, struct svc_req *); +#define PMAP4_GETTIME 6 +extern uint32_t * pmap4_gettime_4(void *, void *); +extern uint32_t * pmap4_gettime_4_svc(void *, struct svc_req *); +#define PMAP4_UADDR2TADDR 7 +extern PMAP4UADDR2TADDRres * pmap4_uaddr2taddr_4(PMAP4UADDR2TADDRargs *, void *); +extern PMAP4UADDR2TADDRres * pmap4_uaddr2taddr_4_svc(PMAP4UADDR2TADDRargs *, struct svc_req *); +#define PMAP4_TADDR2UADDR 8 +extern PMAP4TADDR2UADDRres * pmap4_taddr2uaddr_4(PMAP4TADDR2UADDRargs *, void *); +extern PMAP4TADDR2UADDRres * pmap4_taddr2uaddr_4_svc(PMAP4TADDR2UADDRargs *, struct svc_req *); +#define PMAP4_GETVERSADDR 9 +extern PMAP4GETVERSADDRres * pmap4_getversaddr_4(PMAP4GETVERSADDRargs *, void *); +extern PMAP4GETVERSADDRres * pmap4_getversaddr_4_svc(PMAP4GETVERSADDRargs *, struct svc_req *); +#define PMAP4_INDIRECT 10 +extern PMAP4INDIRECTres * pmap4_indirect_4(PMAP4INDIRECTargs *, void *); +extern PMAP4INDIRECTres * pmap4_indirect_4_svc(PMAP4INDIRECTargs *, struct svc_req *); +#define PMAP4_GETADDRLIST 11 +extern PMAP4GETADDRLISTres * pmap4_getaddrlist_4(PMAP4GETADDRLISTargs *, void *); +extern PMAP4GETADDRLISTres * pmap4_getaddrlist_4_svc(PMAP4GETADDRLISTargs *, struct svc_req *); +#define PMAP4_GETSTAT 12 +extern rpcb_stat * pmap4_getstat_4(void *, void *); +extern rpcb_stat * pmap4_getstat_4_svc(void *, struct svc_req *); +extern int pmap_program_4_freeresult (void *, zdrproc_t, caddr_t); + +#else /* K&R C */ +#define PMAP4_NULL 0 +extern void * pmap4_null_4(); +extern void * pmap4_null_4_svc(); +#define PMAP4_SET 1 +extern uint32_t * pmap4_set_4(); +extern uint32_t * pmap4_set_4_svc(); +#define PMAP4_UNSET 2 +extern uint32_t * pmap4_unset_4(); +extern uint32_t * pmap4_unset_4_svc(); +#define PMAP4_GETADDR 3 +extern PMAP4GETADDRres * pmap4_getaddr_4(); +extern PMAP4GETADDRres * pmap4_getaddr_4_svc(); +#define PMAP4_DUMP 4 +extern PMAP4DUMPres * pmap4_dump_4(); +extern PMAP4DUMPres * pmap4_dump_4_svc(); +#define PMAP4_BCAST 5 +extern PMAP4BCASTres * pmap4_bcast_4(); +extern PMAP4BCASTres * pmap4_bcast_4_svc(); +#define PMAP4_GETTIME 6 +extern uint32_t * pmap4_gettime_4(); +extern uint32_t * pmap4_gettime_4_svc(); +#define PMAP4_UADDR2TADDR 7 +extern PMAP4UADDR2TADDRres * pmap4_uaddr2taddr_4(); +extern PMAP4UADDR2TADDRres * pmap4_uaddr2taddr_4_svc(); +#define PMAP4_TADDR2UADDR 8 +extern PMAP4TADDR2UADDRres * pmap4_taddr2uaddr_4(); +extern PMAP4TADDR2UADDRres * pmap4_taddr2uaddr_4_svc(); +#define PMAP4_GETVERSADDR 9 +extern PMAP4GETVERSADDRres * pmap4_getversaddr_4(); +extern PMAP4GETVERSADDRres * pmap4_getversaddr_4_svc(); +#define PMAP4_INDIRECT 10 +extern PMAP4INDIRECTres * pmap4_indirect_4(); +extern PMAP4INDIRECTres * pmap4_indirect_4_svc(); +#define PMAP4_GETADDRLIST 11 +extern PMAP4GETADDRLISTres * pmap4_getaddrlist_4(); +extern PMAP4GETADDRLISTres * pmap4_getaddrlist_4_svc(); +#define PMAP4_GETSTAT 12 +extern rpcb_stat * pmap4_getstat_4(); +extern rpcb_stat * pmap4_getstat_4_svc(); +extern int pmap_program_4_freeresult (); +#endif /* K&R C */ + +/* the zdr functions */ + +#if defined(__STDC__) || defined(__cplusplus) +extern uint32_t zdr_pmap2_mapping (ZDR *, pmap2_mapping*); +extern uint32_t zdr_pmap2_call_args (ZDR *, pmap2_call_args*); +extern uint32_t zdr_pmap2_call_result (ZDR *, pmap2_call_result*); +extern uint32_t zdr_pmap2_mapping_list (ZDR *, pmap2_mapping_list*); +extern uint32_t zdr_pmap2_dump_result (ZDR *, pmap2_dump_result*); +extern uint32_t zdr_pmap3_string_result (ZDR *, pmap3_string_result*); +extern uint32_t zdr_pmap3_mapping (ZDR *, pmap3_mapping*); +extern uint32_t zdr_pmap3_mapping_list (ZDR *, pmap3_mapping_list*); +extern uint32_t zdr_pmap3_dump_result (ZDR *, pmap3_dump_result*); +extern uint32_t zdr_pmap3_call_args (ZDR *, pmap3_call_args*); +extern uint32_t zdr_rpcb_rmtcallres (ZDR *, rpcb_rmtcallres*); +extern uint32_t zdr_pmap3_netbuf (ZDR *, pmap3_netbuf*); +extern uint32_t zdr_pmap4_string_result (ZDR *, pmap4_string_result*); +extern uint32_t zdr_pmap4_mapping (ZDR *, pmap4_mapping*); +extern uint32_t zdr_pmap4_mapping_list (ZDR *, pmap4_mapping_list*); +extern uint32_t zdr_pmap4_dump_result (ZDR *, pmap4_dump_result*); +extern uint32_t zdr_pmap4_bcast_args (ZDR *, pmap4_bcast_args*); +extern uint32_t zdr_pmap4_netbuf (ZDR *, pmap4_netbuf*); +extern uint32_t zdr_pmap4_indirect_args (ZDR *, pmap4_indirect_args*); +extern uint32_t zdr_rpcbs_addrlist (ZDR *, rpcbs_addrlist*); +extern uint32_t zdr_rpcbs_rmtcalllist (ZDR *, rpcbs_rmtcalllist*); +extern uint32_t zdr_rpcbs_proc (ZDR *, rpcbs_proc); +extern uint32_t zdr_rpcbs_addrlist_ptr (ZDR *, rpcbs_addrlist_ptr*); +extern uint32_t zdr_rpcbs_rmtcalllist_ptr (ZDR *, rpcbs_rmtcalllist_ptr*); +extern uint32_t zdr_rpcb_stat (ZDR *, rpcb_stat*); +extern uint32_t zdr_pmap4_stat_byvers (ZDR *, pmap4_stat_byvers); +extern uint32_t zdr_rpcb_entry (ZDR *, rpcb_entry*); +extern uint32_t zdr_rpcb_entry_list (ZDR *, rpcb_entry_list*); +extern uint32_t zdr_pmap4_entry_list_ptr (ZDR *, pmap4_entry_list_ptr*); +extern uint32_t zdr_PMAP2SETargs (ZDR *, PMAP2SETargs*); +extern uint32_t zdr_PMAP2UNSETargs (ZDR *, PMAP2UNSETargs*); +extern uint32_t zdr_PMAP2GETPORTargs (ZDR *, PMAP2GETPORTargs*); +extern uint32_t zdr_PMAP2CALLITargs (ZDR *, PMAP2CALLITargs*); +extern uint32_t zdr_PMAP2CALLITres (ZDR *, PMAP2CALLITres*); +extern uint32_t zdr_PMAP2DUMPres (ZDR *, PMAP2DUMPres*); +extern uint32_t zdr_PMAP3SETargs (ZDR *, PMAP3SETargs*); +extern uint32_t zdr_PMAP3UNSETargs (ZDR *, PMAP3UNSETargs*); +extern uint32_t zdr_PMAP3GETADDRargs (ZDR *, PMAP3GETADDRargs*); +extern uint32_t zdr_PMAP3GETADDRres (ZDR *, PMAP3GETADDRres*); +extern uint32_t zdr_PMAP3DUMPres (ZDR *, PMAP3DUMPres*); +extern uint32_t zdr_PMAP3CALLITargs (ZDR *, PMAP3CALLITargs*); +extern uint32_t zdr_PMAP3CALLITres (ZDR *, PMAP3CALLITres*); +extern uint32_t zdr_PMAP3UADDR2TADDRargs (ZDR *, PMAP3UADDR2TADDRargs*); +extern uint32_t zdr_PMAP3UADDR2TADDRres (ZDR *, PMAP3UADDR2TADDRres*); +extern uint32_t zdr_PMAP3TADDR2UADDRargs (ZDR *, PMAP3TADDR2UADDRargs*); +extern uint32_t zdr_PMAP3TADDR2UADDRres (ZDR *, PMAP3TADDR2UADDRres*); +extern uint32_t zdr_PMAP4SETargs (ZDR *, PMAP4SETargs*); +extern uint32_t zdr_PMAP4UNSETargs (ZDR *, PMAP4UNSETargs*); +extern uint32_t zdr_PMAP4GETADDRargs (ZDR *, PMAP4GETADDRargs*); +extern uint32_t zdr_PMAP4GETADDRres (ZDR *, PMAP4GETADDRres*); +extern uint32_t zdr_PMAP4DUMPres (ZDR *, PMAP4DUMPres*); +extern uint32_t zdr_PMAP4BCASTargs (ZDR *, PMAP4BCASTargs*); +extern uint32_t zdr_PMAP4BCASTres (ZDR *, PMAP4BCASTres*); +extern uint32_t zdr_PMAP4UADDR2TADDRargs (ZDR *, PMAP4UADDR2TADDRargs*); +extern uint32_t zdr_PMAP4UADDR2TADDRres (ZDR *, PMAP4UADDR2TADDRres*); +extern uint32_t zdr_PMAP4TADDR2UADDRargs (ZDR *, PMAP4TADDR2UADDRargs*); +extern uint32_t zdr_PMAP4TADDR2UADDRres (ZDR *, PMAP4TADDR2UADDRres*); +extern uint32_t zdr_PMAP4GETVERSADDRargs (ZDR *, PMAP4GETVERSADDRargs*); +extern uint32_t zdr_PMAP4GETVERSADDRres (ZDR *, PMAP4GETVERSADDRres*); +extern uint32_t zdr_PMAP4INDIRECTargs (ZDR *, PMAP4INDIRECTargs*); +extern uint32_t zdr_PMAP4INDIRECTres (ZDR *, PMAP4INDIRECTres*); +extern uint32_t zdr_PMAP4GETSTATres (ZDR *, PMAP4GETSTATres); +extern uint32_t zdr_PMAP4GETADDRLISTargs (ZDR *, PMAP4GETADDRLISTargs*); +extern uint32_t zdr_PMAP4GETADDRLISTres (ZDR *, PMAP4GETADDRLISTres*); + +#else /* K&R C */ +extern uint32_t zdr_pmap2_mapping (); +extern uint32_t zdr_pmap2_call_args (); +extern uint32_t zdr_pmap2_call_result (); +extern uint32_t zdr_pmap2_mapping_list (); +extern uint32_t zdr_pmap2_dump_result (); +extern uint32_t zdr_pmap3_string_result (); +extern uint32_t zdr_pmap3_mapping (); +extern uint32_t zdr_pmap3_mapping_list (); +extern uint32_t zdr_pmap3_dump_result (); +extern uint32_t zdr_pmap3_call_args (); +extern uint32_t zdr_rpcb_rmtcallres (); +extern uint32_t zdr_pmap3_netbuf (); +extern uint32_t zdr_pmap4_string_result (); +extern uint32_t zdr_pmap4_mapping (); +extern uint32_t zdr_pmap4_mapping_list (); +extern uint32_t zdr_pmap4_dump_result (); +extern uint32_t zdr_pmap4_bcast_args (); +extern uint32_t zdr_pmap4_netbuf (); +extern uint32_t zdr_pmap4_indirect_args (); +extern uint32_t zdr_rpcbs_addrlist (); +extern uint32_t zdr_rpcbs_rmtcalllist (); +extern uint32_t zdr_rpcbs_proc (); +extern uint32_t zdr_rpcbs_addrlist_ptr (); +extern uint32_t zdr_rpcbs_rmtcalllist_ptr (); +extern uint32_t zdr_rpcb_stat (); +extern uint32_t zdr_pmap4_stat_byvers (); +extern uint32_t zdr_rpcb_entry (); +extern uint32_t zdr_rpcb_entry_list (); +extern uint32_t zdr_pmap4_entry_list_ptr (); +extern uint32_t zdr_PMAP2SETargs (); +extern uint32_t zdr_PMAP2UNSETargs (); +extern uint32_t zdr_PMAP2GETPORTargs (); +extern uint32_t zdr_PMAP2CALLITargs (); +extern uint32_t zdr_PMAP2CALLITres (); +extern uint32_t zdr_PMAP2DUMPres (); +extern uint32_t zdr_PMAP3SETargs (); +extern uint32_t zdr_PMAP3UNSETargs (); +extern uint32_t zdr_PMAP3GETADDRargs (); +extern uint32_t zdr_PMAP3GETADDRres (); +extern uint32_t zdr_PMAP3DUMPres (); +extern uint32_t zdr_PMAP3CALLITargs (); +extern uint32_t zdr_PMAP3CALLITres (); +extern uint32_t zdr_PMAP3UADDR2TADDRargs (); +extern uint32_t zdr_PMAP3UADDR2TADDRres (); +extern uint32_t zdr_PMAP3TADDR2UADDRargs (); +extern uint32_t zdr_PMAP3TADDR2UADDRres (); +extern uint32_t zdr_PMAP4SETargs (); +extern uint32_t zdr_PMAP4UNSETargs (); +extern uint32_t zdr_PMAP4GETADDRargs (); +extern uint32_t zdr_PMAP4GETADDRres (); +extern uint32_t zdr_PMAP4DUMPres (); +extern uint32_t zdr_PMAP4BCASTargs (); +extern uint32_t zdr_PMAP4BCASTres (); +extern uint32_t zdr_PMAP4UADDR2TADDRargs (); +extern uint32_t zdr_PMAP4UADDR2TADDRres (); +extern uint32_t zdr_PMAP4TADDR2UADDRargs (); +extern uint32_t zdr_PMAP4TADDR2UADDRres (); +extern uint32_t zdr_PMAP4GETVERSADDRargs (); +extern uint32_t zdr_PMAP4GETVERSADDRres (); +extern uint32_t zdr_PMAP4INDIRECTargs (); +extern uint32_t zdr_PMAP4INDIRECTres (); +extern uint32_t zdr_PMAP4GETSTATres (); +extern uint32_t zdr_PMAP4GETADDRLISTargs (); +extern uint32_t zdr_PMAP4GETADDRLISTres (); + +#endif /* K&R C */ + +#ifdef __cplusplus +} +#endif + +#endif /* !_PORTMAP_H_RPCGEN */ diff --git a/deps/libnfs/portmap/portmap.c b/deps/libnfs/portmap/portmap.c new file mode 100644 index 000000000000..ff4cde06c649 --- /dev/null +++ b/deps/libnfs/portmap/portmap.c @@ -0,0 +1,729 @@ +/* + 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 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef WIN32 +#include +#endif/*WIN32*/ + +#include +#include "libnfs-zdr.h" +#include "libnfs.h" +#include "libnfs-raw.h" +#include "libnfs-private.h" +#include "libnfs-raw-portmap.h" + +/* + * PORTMAP v2 + */ +struct rpc_pdu * +rpc_pmap2_null_task(struct rpc_context *rpc, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V2, PMAP2_NULL, cb, private_data, (zdrproc_t)zdr_void, 0); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP2/NULL call"); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for PORTMAP2/NULL call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_pmap2_getport_task(struct rpc_context *rpc, int program, int version, int protocol, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + struct pmap2_mapping m; + + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V2, PMAP2_GETPORT, cb, private_data, (zdrproc_t)zdr_int, sizeof(uint32_t)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP2/GETPORT call"); + return NULL; + } + + m.prog = program; + m.vers = version; + m.prot = protocol; + m.port = 0; + if (zdr_pmap2_mapping(&pdu->zdr, &m) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP2/GETPORT call"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue PORTMAP2/GETPORT pdu"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_pmap2_set_task(struct rpc_context *rpc, int program, int version, int protocol, int port, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + struct pmap2_mapping m; + + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V2, PMAP2_SET, cb, private_data, (zdrproc_t)zdr_int, sizeof(uint32_t)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP2/SET call"); + return NULL; + } + + m.prog = program; + m.vers = version; + m.prot = protocol; + m.port = port; + if (zdr_pmap2_mapping(&pdu->zdr, &m) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP2/SET call"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue PORTMAP2/SET pdu"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_pmap2_unset_task(struct rpc_context *rpc, int program, int version, int protocol, int port, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + struct pmap2_mapping m; + + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V2, PMAP2_UNSET, cb, private_data, (zdrproc_t)zdr_int, sizeof(uint32_t)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP2/UNSET call"); + return NULL; + } + + m.prog = program; + m.vers = version; + m.prot = protocol; + m.port = port; + if (zdr_pmap2_mapping(&pdu->zdr, &m) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP2/UNSET call"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue PORTMAP2/UNSET pdu"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_pmap2_dump_task(struct rpc_context *rpc, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V2, PMAP2_DUMP, cb, private_data, (zdrproc_t)zdr_pmap2_dump_result, sizeof(pmap2_dump_result)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP2/DUMP call"); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue PORTMAP2/DUMP pdu"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_pmap2_callit_task(struct rpc_context *rpc, int program, int version, int procedure, char *data, int datalen, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + struct pmap2_call_args ca; + + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V2, PMAP2_CALLIT, cb, private_data, (zdrproc_t)zdr_pmap2_call_result, sizeof(pmap2_call_result)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP2/CALLIT call"); + return NULL; + } + + ca.prog = program; + ca.vers = version; + ca.proc = procedure; + ca.args.args_len = datalen; + ca.args.args_val = data; + + if (zdr_pmap2_call_args(&pdu->zdr, &ca) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP2/CALLIT call"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue PORTMAP2/CALLIT pdu: %s", rpc_get_error(rpc)); + return NULL; + } + + return pdu; +} + +/* + * PORTMAP v3 + */ +struct rpc_pdu * +rpc_pmap3_null_task(struct rpc_context *rpc, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V3, PMAP3_NULL, cb, private_data, (zdrproc_t)zdr_void, 0); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP3/NULL call"); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for PORTMAP3/NULL call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_pmap3_set_task(struct rpc_context *rpc, struct pmap3_mapping *map, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V3, PMAP3_SET, cb, private_data, (zdrproc_t)zdr_int, sizeof(uint32_t)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP3/SET call"); + return NULL; + } + + if (zdr_pmap3_mapping(&pdu->zdr, map) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP3/SET call"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue PORTMAP3/SET pdu"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_pmap3_unset_task(struct rpc_context *rpc, struct pmap3_mapping *map, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V3, PMAP3_UNSET, cb, private_data, (zdrproc_t)zdr_int, sizeof(uint32_t)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP3/UNSET call"); + return NULL; + } + + if (zdr_pmap3_mapping(&pdu->zdr, map) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP3/UNSET call"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue PORTMAP3/UNSET pdu"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_pmap3_getaddr_task(struct rpc_context *rpc, struct pmap3_mapping *map, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V3, PMAP3_GETADDR, cb, private_data, (zdrproc_t)zdr_pmap3_string_result, sizeof(pmap3_string_result)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP3/GETADDR call"); + return NULL; + } + + if (zdr_pmap3_mapping(&pdu->zdr, map) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP3/GETADDR call"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue PORTMAP3/GETADDR pdu"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_pmap3_dump_task(struct rpc_context *rpc, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V3, PMAP3_DUMP, cb, private_data, (zdrproc_t)zdr_pmap3_dump_result, sizeof(pmap3_dump_result)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP3/DUMP call"); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue PORTMAP3/DUMP pdu"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_pmap3_gettime_task(struct rpc_context *rpc, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V3, PMAP3_GETTIME, cb, private_data, (zdrproc_t)zdr_int, sizeof(uint32_t)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP3/GETTIME call"); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue PORTMAP3/GETTIME pdu"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_pmap3_callit_task(struct rpc_context *rpc, int program, int version, int procedure, char *data, int datalen, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + struct pmap3_call_args ca; + + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V3, PMAP3_CALLIT, cb, private_data, (zdrproc_t)zdr_rpcb_rmtcallres, sizeof(rpcb_rmtcallres)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP3/CALLIT call"); + return NULL; + } + + ca.prog = program; + ca.vers = version; + ca.proc = procedure; + ca.args.args_len = datalen; + ca.args.args_val = data; + + if (zdr_pmap3_call_args(&pdu->zdr, &ca) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP3/CALLIT call"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue PORTMAP3/CALLIT pdu: %s", rpc_get_error(rpc)); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_pmap3_uaddr2taddr_task(struct rpc_context *rpc, char *uaddr, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V3, PMAP3_UADDR2TADDR, cb, private_data, (zdrproc_t)zdr_pmap3_netbuf, sizeof(pmap3_netbuf)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP3/UADDR2TADDR call"); + return NULL; + } + + if (zdr_string(&pdu->zdr, &uaddr, 255) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP3/UADDR2TADDR call"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue PORTMAP3/UADDR2TADDR pdu: %s", rpc_get_error(rpc)); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_pmap3_taddr2uaddr_task(struct rpc_context *rpc, struct pmap3_netbuf *nb, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V3, PMAP3_TADDR2UADDR, cb, private_data, (zdrproc_t)zdr_pmap3_string_result, sizeof(pmap3_string_result)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP3/TADDR2UADDR call"); + return NULL; + } + + if (zdr_pmap3_netbuf(&pdu->zdr, nb) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP3/TADDR2UADDR call"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue PORTMAP3/TADDR2UADDR pdu: %s", rpc_get_error(rpc)); + return NULL; + } + + return pdu; +} + +/* + * PORTMAP v4 + */ +struct rpc_pdu * +rpc_pmap4_null_task(struct rpc_context *rpc, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V4, PMAP4_NULL, cb, private_data, (zdrproc_t)zdr_void, 0); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP4/NULL call"); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for PORTMAP4/NULL call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_pmap4_set_task(struct rpc_context *rpc, struct pmap4_mapping *map, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V4, PMAP4_SET, cb, private_data, (zdrproc_t)zdr_int, sizeof(uint32_t)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP4/SET call"); + return NULL; + } + + if (zdr_pmap4_mapping(&pdu->zdr, map) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP4/SET call"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue PORTMAP4/SET pdu"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_pmap4_unset_task(struct rpc_context *rpc, struct pmap4_mapping *map, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V4, PMAP3_UNSET, cb, private_data, (zdrproc_t)zdr_int, sizeof(uint32_t)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP4/UNSET call"); + return NULL; + } + + if (zdr_pmap4_mapping(&pdu->zdr, map) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP4/UNSET call"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue PORTMAP4/UNSET pdu"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_pmap4_getaddr_task(struct rpc_context *rpc, struct pmap4_mapping *map, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V4, PMAP4_GETADDR, cb, private_data, (zdrproc_t)zdr_pmap4_string_result, sizeof(pmap4_string_result)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP4/GETADDR call"); + return NULL; + } + + if (zdr_pmap4_mapping(&pdu->zdr, map) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP4/GETADDR call"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue PORTMAP4/GETADDR pdu"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_pmap4_dump_task(struct rpc_context *rpc, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V4, PMAP4_DUMP, cb, private_data, (zdrproc_t)zdr_pmap4_dump_result, sizeof(pmap4_dump_result)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP4/DUMP call"); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue PORTMAP4/DUMP pdu"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_pmap4_gettime_task(struct rpc_context *rpc, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V4, PMAP4_GETTIME, cb, private_data, (zdrproc_t)zdr_int, sizeof(uint32_t)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP4/GETTIME call"); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue PORTMAP4/GETTIME pdu"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_pmap4_bcast_task(struct rpc_context *rpc, int program, int version, int procedure, char *data, int datalen, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + struct pmap4_bcast_args ca; + + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V4, PMAP4_BCAST, cb, private_data, (zdrproc_t)zdr_rpcb_rmtcallres, sizeof(rpcb_rmtcallres)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP4/BCAST call"); + return NULL; + } + + ca.prog = program; + ca.vers = version; + ca.proc = procedure; + ca.args.args_len = datalen; + ca.args.args_val = data; + + if (zdr_pmap4_bcast_args(&pdu->zdr, &ca) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP4/BCAST call"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue PORTMAP4/BCAST pdu: %s", rpc_get_error(rpc)); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_pmap4_uaddr2taddr_task(struct rpc_context *rpc, char *uaddr, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V4, PMAP4_UADDR2TADDR, cb, private_data, (zdrproc_t)zdr_pmap4_netbuf, sizeof(pmap4_netbuf)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP4/UADDR2TADDR call"); + return NULL; + } + + if (zdr_string(&pdu->zdr, &uaddr, 255) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP4/UADDR2TADDR call"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue PORTMAP4/UADDR2TADDR pdu: %s", rpc_get_error(rpc)); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_pmap4_taddr2uaddr_task(struct rpc_context *rpc, struct pmap4_netbuf *nb, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V4, PMAP4_TADDR2UADDR, cb, private_data, (zdrproc_t)zdr_pmap4_string_result, sizeof(pmap4_string_result)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP4/TADDR2UADDR call"); + return NULL; + } + + if (zdr_pmap4_netbuf(&pdu->zdr, nb) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP4/TADDR2UADDR call"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue PORTMAP4/TADDR2UADDR pdu: %s", rpc_get_error(rpc)); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_pmap4_getversaddr_task(struct rpc_context *rpc, struct pmap4_mapping *map, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V4, PMAP4_GETVERSADDR, cb, private_data, (zdrproc_t)zdr_pmap4_string_result, sizeof(pmap4_string_result)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP4/GETVERSADDR call"); + return NULL; + } + + if (zdr_pmap4_mapping(&pdu->zdr, map) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP4/GETVERSADDR call"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue PORTMAP4/GETVERSADDR pdu"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_pmap4_indirect_task(struct rpc_context *rpc, int program, int version, int procedure, char *data, int datalen, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + struct pmap4_indirect_args ca; + + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V4, PMAP4_INDIRECT, cb, private_data, (zdrproc_t)zdr_rpcb_rmtcallres, sizeof(rpcb_rmtcallres)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP4/INDIRECT call"); + return NULL; + } + + ca.prog = program; + ca.vers = version; + ca.proc = procedure; + ca.args.args_len = datalen; + ca.args.args_val = data; + + if (zdr_pmap4_indirect_args(&pdu->zdr, &ca) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP4/INDIRECT call"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue PORTMAP4/INDIRECT pdu: %s", rpc_get_error(rpc)); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_pmap4_getstat_task(struct rpc_context *rpc, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V4, PMAP4_GETSTAT, cb, private_data, (zdrproc_t)zdr_pmap4_stat_byvers, sizeof(pmap4_stat_byvers)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP4/GETSTAT call"); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue PORTMAP4/GETSTAT pdu"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_pmap4_getaddrlist_task(struct rpc_context *rpc, struct pmap4_mapping *map, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V4, PMAP4_GETADDRLIST, cb, private_data, (zdrproc_t)zdr_pmap4_entry_list_ptr, sizeof(pmap4_entry_list_ptr)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP4/GETADDRLIST call"); + return NULL; + } + + if (zdr_pmap4_mapping(&pdu->zdr, map) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP4/GETADDRLIST call"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue PORTMAP4/GETADDRLIST pdu"); + return NULL; + } + + return pdu; +} diff --git a/deps/libnfs/portmap/portmap.x b/deps/libnfs/portmap/portmap.x new file mode 100644 index 000000000000..e39d3113150f --- /dev/null +++ b/deps/libnfs/portmap/portmap.x @@ -0,0 +1,337 @@ +/* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */ +/* +Copyright (c) 2014, Ronnie Sahlberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +const PMAP_PORT = 111; /* portmapper port number */ + +struct pmap2_mapping { + uint32_t prog; + uint32_t vers; + uint32_t prot; + uint32_t port; +}; + +struct pmap2_call_args { + uint32_t prog; + uint32_t vers; + uint32_t proc; + opaque args<>; +}; + +struct pmap2_call_result { + uint32_t port; + opaque res<>; +}; + +struct pmap2_mapping_list { + pmap2_mapping map; + pmap2_mapping_list *next; +}; + +struct pmap2_dump_result { + struct pmap2_mapping_list *list; +}; + +struct pmap3_string_result { + string addr<>; +}; + +struct pmap3_mapping { + uint32_t prog; + uint32_t vers; + string netid<>; + string addr<>; + string owner<>; +}; + +struct pmap3_mapping_list { + pmap3_mapping map; + pmap3_mapping_list *next; +}; + +struct pmap3_dump_result { + struct pmap3_mapping_list *list; +}; + +struct pmap3_call_args { + uint32_t prog; + uint32_t vers; + uint32_t proc; + opaque args<>; +}; + +struct rpcb_rmtcallres { + string addr<>; + opaque results<>; +}; + +struct pmap3_netbuf { + uint32_t maxlen; + /* This pretty much contains a sockaddr_storage. + * Beware differences in endianess for ss_family + * and whether or not ss_len exists. + */ + opaque buf<>; +}; + +struct pmap4_string_result { + string addr<>; +}; + +struct pmap4_mapping { + uint32_t prog; + uint32_t vers; + string netid<>; + string addr<>; + string owner<>; +}; + +struct pmap4_mapping_list { + pmap4_mapping map; + pmap4_mapping_list *next; +}; + +struct pmap4_dump_result { + struct pmap4_mapping_list *list; +}; + +struct pmap4_bcast_args { + uint32_t prog; + uint32_t vers; + uint32_t proc; + opaque args<>; +}; + +struct pmap4_netbuf { + uint32_t maxlen; + /* This pretty much contains a sockaddr_storage. + * Beware differences in endianess for ss_family + * and whether or not ss_len exists. + */ + opaque buf<>; +}; + +struct pmap4_indirect_args { + uint32_t prog; + uint32_t vers; + uint32_t proc; + opaque args<>; +}; + +const RPCBSTAT_HIGHPROC = 13; /* # of procs in rpcbind V4 plus one */ +const RPCBVERS_STAT = 3; /* provide only for rpcbind V2, V3 and V4 */ +const RPCBVERS_4_STAT = 2; +const RPCBVERS_3_STAT = 1; +const RPCBVERS_2_STAT = 0; + +struct rpcbs_addrlist { + uint32_t prog; + uint32_t vers; + int32_t success; + int32_t failure; + string netid<>; + struct rpcbs_addrlist *next; +}; + +struct rpcbs_rmtcalllist { + uint32_t prog; + uint32_t vers; + uint32_t proc; + int32_t success; + int32_t failure; + int32_t indirect; /* whether callit or indirect */ + string netid<>; + struct rpcbs_rmtcalllist *next; +}; + +typedef int rpcbs_proc[RPCBSTAT_HIGHPROC]; +typedef rpcbs_addrlist *rpcbs_addrlist_ptr; +typedef rpcbs_rmtcalllist *rpcbs_rmtcalllist_ptr; + +struct rpcb_stat { + rpcbs_proc info; + int32_t setinfo; + int32_t unsetinfo; + rpcbs_addrlist_ptr addrinfo; + rpcbs_rmtcalllist_ptr rmtinfo; +}; + +typedef rpcb_stat pmap4_stat_byvers[RPCBVERS_STAT]; + +/* Semantics */ +const NC_TPI_CLTS = 1; +const NC_TPI_COTS = 2; +const NC_TPI_COTS_ORD = 3; +const NC_TPI_RAW = 4; + +struct rpcb_entry { + string r_maddr<>; /* merged address of service */ + string r_nc_netid<>; /* netid field */ + uint32_t r_nc_semantics; /* semantics of transport */ + string r_nc_protofmly<>; /* protocol family */ + string r_nc_proto<>; /* protocol name */ +}; + +struct rpcb_entry_list { + rpcb_entry rpcb_entry_map; + struct rpcb_entry_list *next; +}; + +typedef rpcb_entry_list *pmap4_entry_list_ptr; + + +typedef pmap2_mapping PMAP2SETargs; +typedef pmap2_mapping PMAP2UNSETargs; +typedef pmap2_mapping PMAP2GETPORTargs; +typedef pmap2_call_args PMAP2CALLITargs; +typedef pmap2_call_result PMAP2CALLITres; +typedef pmap2_dump_result PMAP2DUMPres; + +typedef pmap3_mapping PMAP3SETargs; +typedef pmap3_mapping PMAP3UNSETargs; +typedef pmap3_mapping PMAP3GETADDRargs; +typedef pmap3_string_result PMAP3GETADDRres; +typedef pmap3_dump_result PMAP3DUMPres; +typedef pmap3_call_args PMAP3CALLITargs; +typedef rpcb_rmtcallres PMAP3CALLITres; +typedef pmap3_string_result PMAP3UADDR2TADDRargs; +typedef pmap3_netbuf PMAP3UADDR2TADDRres; +typedef pmap3_netbuf PMAP3TADDR2UADDRargs; +typedef pmap3_string_result PMAP3TADDR2UADDRres; + +typedef pmap4_mapping PMAP4SETargs; +typedef pmap4_mapping PMAP4UNSETargs; +typedef pmap4_mapping PMAP4GETADDRargs; +typedef pmap4_string_result PMAP4GETADDRres; +typedef pmap4_dump_result PMAP4DUMPres; +typedef pmap4_bcast_args PMAP4BCASTargs; +typedef rpcb_rmtcallres PMAP4BCASTres; +typedef pmap3_string_result PMAP4UADDR2TADDRargs; +typedef pmap4_netbuf PMAP4UADDR2TADDRres; +typedef pmap4_netbuf PMAP4TADDR2UADDRargs; +typedef pmap4_string_result PMAP4TADDR2UADDRres; +typedef pmap4_mapping PMAP4GETVERSADDRargs; +typedef pmap4_string_result PMAP4GETVERSADDRres; +typedef pmap4_indirect_args PMAP4INDIRECTargs; +typedef rpcb_rmtcallres PMAP4INDIRECTres; +typedef pmap4_stat_byvers PMAP4GETSTATres; +typedef pmap4_mapping PMAP4GETADDRLISTargs; +typedef pmap4_entry_list_ptr PMAP4GETADDRLISTres; + + +program PMAP_PROGRAM { + version PMAP_V2 { + void + PMAP2_NULL(void) = 0; + + uint32_t + PMAP2_SET(PMAP2SETargs) = 1; + + uint32_t + PMAP2_UNSET(PMAP2UNSETargs) = 2; + + uint32_t + PMAP2_GETPORT(PMAP2GETPORTargs) = 3; + + PMAP2DUMPres + PMAP2_DUMP(void) = 4; + + PMAP2CALLITres + PMAP2_CALLIT(PMAP2CALLITargs) = 5; + } = 2; + version PMAP_V3 { + void + PMAP3_NULL(void) = 0; + + uint32_t + PMAP3_SET(PMAP3SETargs) = 1; + + uint32_t + PMAP3_UNSET(PMAP3UNSETargs) = 2; + + PMAP3GETADDRres + PMAP3_GETADDR(PMAP3GETADDRargs) = 3; + + PMAP3DUMPres + PMAP3_DUMP(void) = 4; + + PMAP3CALLITres + PMAP3_CALLIT(PMAP3CALLITargs) = 5; + + uint32_t + PMAP3_GETTIME(void) = 6; + + PMAP3UADDR2TADDRres + PMAP3_UADDR2TADDR(PMAP3UADDR2TADDRargs) = 7; + + PMAP3TADDR2UADDRres + PMAP3_TADDR2UADDR(PMAP3TADDR2UADDRargs) = 8; + } = 3; + version PMAP_V4 { + void + PMAP4_NULL(void) = 0; + + uint32_t + PMAP4_SET(PMAP4SETargs) = 1; + + uint32_t + PMAP4_UNSET(PMAP4UNSETargs) = 2; + + PMAP4GETADDRres + PMAP4_GETADDR(PMAP4GETADDRargs) = 3; + + PMAP4DUMPres + PMAP4_DUMP(void) = 4; + + PMAP4BCASTres + PMAP4_BCAST(PMAP4BCASTargs) = 5; + + uint32_t + PMAP4_GETTIME(void) = 6; + + PMAP4UADDR2TADDRres + PMAP4_UADDR2TADDR(PMAP4UADDR2TADDRargs) = 7; + + PMAP4TADDR2UADDRres + PMAP4_TADDR2UADDR(PMAP4TADDR2UADDRargs) = 8; + + PMAP4GETVERSADDRres + PMAP4_GETVERSADDR(PMAP4GETVERSADDRargs) = 9; + + PMAP4INDIRECTres + PMAP4_INDIRECT(PMAP4INDIRECTargs) = 10; + + PMAP4GETADDRLISTres + PMAP4_GETADDRLIST(PMAP4GETADDRLISTargs) = 11; + + PMAP4GETSTATres + PMAP4_GETSTAT(void) = 12; + } = 4; +} = 100000; + diff --git a/deps/libnfs/rquota/CMakeLists.txt b/deps/libnfs/rquota/CMakeLists.txt new file mode 100644 index 000000000000..fe5068db277a --- /dev/null +++ b/deps/libnfs/rquota/CMakeLists.txt @@ -0,0 +1,5 @@ +set(SOURCES libnfs-raw-rquota.c + rquota.c) +set(HEADERS libnfs-raw-rquota.h) + +core_add_library(rquota) diff --git a/deps/libnfs/rquota/Makefile.am b/deps/libnfs/rquota/Makefile.am new file mode 100644 index 000000000000..3940e34fb33c --- /dev/null +++ b/deps/libnfs/rquota/Makefile.am @@ -0,0 +1,25 @@ +noinst_LTLIBRARIES = librquota.la + +rquota_SOURCES_GENERATED = +rquota_HEADERS_GENERATED = +rquota_GENERATED = $(rquota_SOURCES_GENERATED) $(rquota_HEADERS_GENERATED) + +CLEANFILES = $(rquota_GENERATED) rquota-stamp + +librquota_la_CPPFLAGS = -I$(abs_top_srcdir)/include \ + -I$(abs_top_srcdir)/include/nfsc \ + -I$(abs_top_srcdir)/win32 +librquota_la_SOURCES = \ + $(rquota_SOURCES_GENERATED) \ + rquota.c libnfs-raw-rquota.c libnfs-raw-rquota.h + +$(rquota_GENERATED) : rquota-stamp +rquota-stamp : rquota.x + rm -f $(rquota_GENERATED) + touch rquota-stamp + +compile_rpc: + cat rquota.x | head -29 >libnfs-raw-rquota.h + rpcgen -h rquota.x | sed -e "s/#include /#include /" | sed -e "s/xdr/zdr/g" -e "s/XDR/ZDR/g" -e "s/ CLIENT / void /g" -e "s/SVCXPRT /void /g" -e "s/bool_t/uint32_t/g" >> libnfs-raw-rquota.h + cat rquota.x | head -29 >libnfs-raw-rquota.c + rpcgen -c rquota.x | sed -e "s/#include \".*rquota.h\"/#include \"libnfs-xdr.h\"\n#include \"libnfs-raw-rquota.h\"/" -e "s/xdr/zdr/g" -e "s/XDR/ZDR/g" -e "s/register int32_t \*buf;/register int32_t *buf;\n buf = NULL;/" -e "s/bool_t/uint32_t/g" >> libnfs-raw-rquota.c diff --git a/deps/libnfs/rquota/libnfs-raw-rquota.c b/deps/libnfs/rquota/libnfs-raw-rquota.c new file mode 100644 index 000000000000..0fea51bd310b --- /dev/null +++ b/deps/libnfs/rquota/libnfs-raw-rquota.c @@ -0,0 +1,201 @@ +/* +Copyright (c) 2014, Ronnie Sahlberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +/* + * Please do not edit this file. + * It was generated using rpcgen. + */ + +#include "libnfs-zdr.h" +#include "libnfs-raw-rquota.h" + +uint32_t +zdr_rquotastat (ZDR *zdrs, rquotastat *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_exportpath (ZDR *zdrs, exportpath *objp) +{ + if (!zdr_string (zdrs, objp, RQUOTAPATHLEN)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_GETQUOTA1args (ZDR *zdrs, GETQUOTA1args *objp) +{ + if (!zdr_exportpath (zdrs, &objp->export)) + return FALSE; + if (!zdr_int (zdrs, &objp->uid)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_quotatype (ZDR *zdrs, quotatype *objp) +{ + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_GETQUOTA2args (ZDR *zdrs, GETQUOTA2args *objp) +{ + if (!zdr_exportpath (zdrs, &objp->export)) + return FALSE; + if (!zdr_quotatype (zdrs, &objp->type)) + return FALSE; + if (!zdr_int (zdrs, &objp->uid)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_GETQUOTA1res_ok (ZDR *zdrs, GETQUOTA1res_ok *objp) +{ + register int32_t *buf; + buf = NULL; + + if (zdrs->x_op == ZDR_ENCODE) { + buf = ZDR_INLINE (zdrs, 10 * BYTES_PER_ZDR_UNIT); + if (buf == NULL) { + if (!zdr_int (zdrs, &objp->bsize)) + return FALSE; + if (!zdr_int (zdrs, &objp->active)) + return FALSE; + if (!zdr_int (zdrs, &objp->bhardlimit)) + return FALSE; + if (!zdr_int (zdrs, &objp->bsoftlimit)) + return FALSE; + if (!zdr_int (zdrs, &objp->curblocks)) + return FALSE; + if (!zdr_int (zdrs, &objp->fhardlimit)) + return FALSE; + if (!zdr_int (zdrs, &objp->fsoftlimit)) + return FALSE; + if (!zdr_int (zdrs, &objp->curfiles)) + return FALSE; + if (!zdr_int (zdrs, &objp->btimeleft)) + return FALSE; + if (!zdr_int (zdrs, &objp->ftimeleft)) + return FALSE; + } else { + IZDR_PUT_LONG(buf, objp->bsize); + IZDR_PUT_LONG(buf, objp->active); + IZDR_PUT_LONG(buf, objp->bhardlimit); + IZDR_PUT_LONG(buf, objp->bsoftlimit); + IZDR_PUT_LONG(buf, objp->curblocks); + IZDR_PUT_LONG(buf, objp->fhardlimit); + IZDR_PUT_LONG(buf, objp->fsoftlimit); + IZDR_PUT_LONG(buf, objp->curfiles); + IZDR_PUT_LONG(buf, objp->btimeleft); + IZDR_PUT_LONG(buf, objp->ftimeleft); + } + return TRUE; + } else if (zdrs->x_op == ZDR_DECODE) { + buf = ZDR_INLINE (zdrs, 10 * BYTES_PER_ZDR_UNIT); + if (buf == NULL) { + if (!zdr_int (zdrs, &objp->bsize)) + return FALSE; + if (!zdr_int (zdrs, &objp->active)) + return FALSE; + if (!zdr_int (zdrs, &objp->bhardlimit)) + return FALSE; + if (!zdr_int (zdrs, &objp->bsoftlimit)) + return FALSE; + if (!zdr_int (zdrs, &objp->curblocks)) + return FALSE; + if (!zdr_int (zdrs, &objp->fhardlimit)) + return FALSE; + if (!zdr_int (zdrs, &objp->fsoftlimit)) + return FALSE; + if (!zdr_int (zdrs, &objp->curfiles)) + return FALSE; + if (!zdr_int (zdrs, &objp->btimeleft)) + return FALSE; + if (!zdr_int (zdrs, &objp->ftimeleft)) + return FALSE; + } else { + objp->bsize = IZDR_GET_LONG(buf); + objp->active = IZDR_GET_LONG(buf); + objp->bhardlimit = IZDR_GET_LONG(buf); + objp->bsoftlimit = IZDR_GET_LONG(buf); + objp->curblocks = IZDR_GET_LONG(buf); + objp->fhardlimit = IZDR_GET_LONG(buf); + objp->fsoftlimit = IZDR_GET_LONG(buf); + objp->curfiles = IZDR_GET_LONG(buf); + objp->btimeleft = IZDR_GET_LONG(buf); + objp->ftimeleft = IZDR_GET_LONG(buf); + } + return TRUE; + } + + if (!zdr_int (zdrs, &objp->bsize)) + return FALSE; + if (!zdr_int (zdrs, &objp->active)) + return FALSE; + if (!zdr_int (zdrs, &objp->bhardlimit)) + return FALSE; + if (!zdr_int (zdrs, &objp->bsoftlimit)) + return FALSE; + if (!zdr_int (zdrs, &objp->curblocks)) + return FALSE; + if (!zdr_int (zdrs, &objp->fhardlimit)) + return FALSE; + if (!zdr_int (zdrs, &objp->fsoftlimit)) + return FALSE; + if (!zdr_int (zdrs, &objp->curfiles)) + return FALSE; + if (!zdr_int (zdrs, &objp->btimeleft)) + return FALSE; + if (!zdr_int (zdrs, &objp->ftimeleft)) + return FALSE; + return TRUE; +} + +uint32_t +zdr_GETQUOTA1res (ZDR *zdrs, GETQUOTA1res *objp) +{ + if (!zdr_rquotastat (zdrs, &objp->status)) + return FALSE; + switch (objp->status) { + case RQUOTA_OK: + if (!zdr_GETQUOTA1res_ok (zdrs, &objp->GETQUOTA1res_u.quota)) + return FALSE; + break; + default: + break; + } + return TRUE; +} diff --git a/deps/libnfs/rquota/libnfs-raw-rquota.h b/deps/libnfs/rquota/libnfs-raw-rquota.h new file mode 100644 index 000000000000..27ea104ad863 --- /dev/null +++ b/deps/libnfs/rquota/libnfs-raw-rquota.h @@ -0,0 +1,177 @@ +/* +Copyright (c) 2014, Ronnie Sahlberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +/* + * Please do not edit this file. + * It was generated using rpcgen. + */ + +#ifndef _RQUOTA_H_RPCGEN +#define _RQUOTA_H_RPCGEN + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +#define RQUOTAPATHLEN 1024 + +enum rquotastat { + RQUOTA_OK = 1, + RQUOTA_NOQUOTA = 2, + RQUOTA_EPERM = 3, +}; +typedef enum rquotastat rquotastat; + +typedef char *exportpath; + +struct GETQUOTA1args { + exportpath export; + int uid; +}; +typedef struct GETQUOTA1args GETQUOTA1args; + +enum quotatype { + RQUOTA_TYPE_UID = 0, + RQUOTA_TYPE_GID = 1, +}; +typedef enum quotatype quotatype; + +struct GETQUOTA2args { + exportpath export; + quotatype type; + int uid; +}; +typedef struct GETQUOTA2args GETQUOTA2args; + +struct GETQUOTA1res_ok { + int bsize; + int active; + int bhardlimit; + int bsoftlimit; + int curblocks; + int fhardlimit; + int fsoftlimit; + int curfiles; + int btimeleft; + int ftimeleft; +}; +typedef struct GETQUOTA1res_ok GETQUOTA1res_ok; + +struct GETQUOTA1res { + rquotastat status; + union { + GETQUOTA1res_ok quota; + } GETQUOTA1res_u; +}; +typedef struct GETQUOTA1res GETQUOTA1res; + +#define RQUOTA_PROGRAM 100011 +#define RQUOTA_V1 1 + +#if defined(__STDC__) || defined(__cplusplus) +#define RQUOTA1_NULL 0 +extern void * rquota1_null_1(void *, void *); +extern void * rquota1_null_1_svc(void *, struct svc_req *); +#define RQUOTA1_GETQUOTA 1 +extern GETQUOTA1res * rquota1_getquota_1(GETQUOTA1args *, void *); +extern GETQUOTA1res * rquota1_getquota_1_svc(GETQUOTA1args *, struct svc_req *); +#define RQUOTA1_GETACTIVEQUOTA 2 +extern GETQUOTA1res * rquota1_getactivequota_1(GETQUOTA1args *, void *); +extern GETQUOTA1res * rquota1_getactivequota_1_svc(GETQUOTA1args *, struct svc_req *); +extern int rquota_program_1_freeresult (void *, zdrproc_t, caddr_t); + +#else /* K&R C */ +#define RQUOTA1_NULL 0 +extern void * rquota1_null_1(); +extern void * rquota1_null_1_svc(); +#define RQUOTA1_GETQUOTA 1 +extern GETQUOTA1res * rquota1_getquota_1(); +extern GETQUOTA1res * rquota1_getquota_1_svc(); +#define RQUOTA1_GETACTIVEQUOTA 2 +extern GETQUOTA1res * rquota1_getactivequota_1(); +extern GETQUOTA1res * rquota1_getactivequota_1_svc(); +extern int rquota_program_1_freeresult (); +#endif /* K&R C */ +#define RQUOTA_V2 2 + +#if defined(__STDC__) || defined(__cplusplus) +#define RQUOTA2_NULL 0 +extern void * rquota2_null_2(void *, void *); +extern void * rquota2_null_2_svc(void *, struct svc_req *); +#define RQUOTA2_GETQUOTA 1 +extern GETQUOTA1res * rquota2_getquota_2(GETQUOTA2args *, void *); +extern GETQUOTA1res * rquota2_getquota_2_svc(GETQUOTA2args *, struct svc_req *); +#define RQUOTA2_GETACTIVEQUOTA 2 +extern GETQUOTA1res * rquota2_getactivequota_2(GETQUOTA2args *, void *); +extern GETQUOTA1res * rquota2_getactivequota_2_svc(GETQUOTA2args *, struct svc_req *); +extern int rquota_program_2_freeresult (void *, zdrproc_t, caddr_t); + +#else /* K&R C */ +#define RQUOTA2_NULL 0 +extern void * rquota2_null_2(); +extern void * rquota2_null_2_svc(); +#define RQUOTA2_GETQUOTA 1 +extern GETQUOTA1res * rquota2_getquota_2(); +extern GETQUOTA1res * rquota2_getquota_2_svc(); +#define RQUOTA2_GETACTIVEQUOTA 2 +extern GETQUOTA1res * rquota2_getactivequota_2(); +extern GETQUOTA1res * rquota2_getactivequota_2_svc(); +extern int rquota_program_2_freeresult (); +#endif /* K&R C */ + +/* the zdr functions */ + +#if defined(__STDC__) || defined(__cplusplus) +extern uint32_t zdr_rquotastat (ZDR *, rquotastat*); +extern uint32_t zdr_exportpath (ZDR *, exportpath*); +extern uint32_t zdr_GETQUOTA1args (ZDR *, GETQUOTA1args*); +extern uint32_t zdr_quotatype (ZDR *, quotatype*); +extern uint32_t zdr_GETQUOTA2args (ZDR *, GETQUOTA2args*); +extern uint32_t zdr_GETQUOTA1res_ok (ZDR *, GETQUOTA1res_ok*); +extern uint32_t zdr_GETQUOTA1res (ZDR *, GETQUOTA1res*); + +#else /* K&R C */ +extern uint32_t zdr_rquotastat (); +extern uint32_t zdr_exportpath (); +extern uint32_t zdr_GETQUOTA1args (); +extern uint32_t zdr_quotatype (); +extern uint32_t zdr_GETQUOTA2args (); +extern uint32_t zdr_GETQUOTA1res_ok (); +extern uint32_t zdr_GETQUOTA1res (); + +#endif /* K&R C */ + +#ifdef __cplusplus +} +#endif + +#endif /* !_RQUOTA_H_RPCGEN */ diff --git a/deps/libnfs/rquota/rquota.c b/deps/libnfs/rquota/rquota.c new file mode 100644 index 000000000000..c591c07837bd --- /dev/null +++ b/deps/libnfs/rquota/rquota.c @@ -0,0 +1,213 @@ +/* + 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 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef WIN32 +#include +#endif/*WIN32*/ + +#include +#include +#include +#include "libnfs-zdr.h" +#include "libnfs.h" +#include "libnfs-raw.h" +#include "libnfs-private.h" +#include "libnfs-raw-rquota.h" + + + +char *rquotastat_to_str(int error) +{ + switch (error) { + case RQUOTA_OK: return "RQUOTA_OK"; break; + case RQUOTA_NOQUOTA: return "RQUOTA_NOQUOTA"; break; + case RQUOTA_EPERM: return "RQUOTA_EPERM"; break; + }; + return "unknown rquota error"; +} + +int rquotastat_to_errno(int error) +{ + switch (error) { + case RQUOTA_OK: return 0; break; + case RQUOTA_NOQUOTA: return -ENOENT; break; + case RQUOTA_EPERM: return -EPERM; break; + }; + return -ENOENT; +} + + +struct rpc_pdu * +rpc_rquota1_null_task(struct rpc_context *rpc, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, RQUOTA_PROGRAM, RQUOTA_V1, RQUOTA1_NULL, cb, private_data, (zdrproc_t)zdr_void, 0); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for rquota1/null call"); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for rquota1/null call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_rquota1_getquota_task(struct rpc_context *rpc, rpc_cb cb, char *export, int uid, void *private_data) +{ + struct rpc_pdu *pdu; + GETQUOTA1args args; + + pdu = rpc_allocate_pdu(rpc, RQUOTA_PROGRAM, RQUOTA_V1, RQUOTA1_GETQUOTA, cb, private_data, (zdrproc_t)zdr_GETQUOTA1res, sizeof(GETQUOTA1res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for rquota1/getquota call"); + return NULL; + } + + args.export = export; + args.uid = uid; + + if (zdr_GETQUOTA1args(&pdu->zdr, &args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode GETQUOTA1args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for rquota1/getquota call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_rquota1_getactivequota_task(struct rpc_context *rpc, rpc_cb cb, char *export, int uid, void *private_data) +{ + struct rpc_pdu *pdu; + GETQUOTA1args args; + + pdu = rpc_allocate_pdu(rpc, RQUOTA_PROGRAM, RQUOTA_V1, RQUOTA1_GETACTIVEQUOTA, cb, private_data, (zdrproc_t)zdr_GETQUOTA1res, sizeof(GETQUOTA1res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for rquota1/getactivequota call"); + return NULL; + } + + args.export = export; + args.uid = uid; + + if (zdr_GETQUOTA1args(&pdu->zdr, &args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode GETQUOTA1args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for rquota1/getactivequota call"); + return NULL; + } + + return pdu; +} + + +struct rpc_pdu * +rpc_rquota2_null_task(struct rpc_context *rpc, rpc_cb cb, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, RQUOTA_PROGRAM, RQUOTA_V2, RQUOTA2_NULL, cb, private_data, (zdrproc_t)zdr_void, 0); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for rquota2/null call"); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for rquota2/null call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_rquota2_getquota_task(struct rpc_context *rpc, rpc_cb cb, char *export, int type, int uid, void *private_data) +{ + struct rpc_pdu *pdu; + GETQUOTA2args args; + + pdu = rpc_allocate_pdu(rpc, RQUOTA_PROGRAM, RQUOTA_V2, RQUOTA2_GETQUOTA, cb, private_data, (zdrproc_t)zdr_GETQUOTA1res, sizeof(GETQUOTA1res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for rquota2/getquota call"); + return NULL; + } + + args.export = export; + args.type = type; + args.uid = uid; + + if (zdr_GETQUOTA2args(&pdu->zdr, &args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode GETQUOTA2args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for rquota2/getquota call"); + return NULL; + } + + return pdu; +} + +struct rpc_pdu * +rpc_rquota2_getactivequota_task(struct rpc_context *rpc, rpc_cb cb, char *export, int type, int uid, void *private_data) +{ + struct rpc_pdu *pdu; + GETQUOTA2args args; + + pdu = rpc_allocate_pdu(rpc, RQUOTA_PROGRAM, RQUOTA_V2, RQUOTA2_GETACTIVEQUOTA, cb, private_data, (zdrproc_t)zdr_GETQUOTA1res, sizeof(GETQUOTA1res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for rquota2/getactivequota call"); + return NULL; + } + + args.export = export; + args.type = type; + args.uid = uid; + + if (zdr_GETQUOTA2args(&pdu->zdr, &args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode GETQUOTA2args"); + rpc_free_pdu(rpc, pdu); + return NULL; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for rquota2/getactivequota call"); + return NULL; + } + + return pdu; +} diff --git a/deps/libnfs/rquota/rquota.x b/deps/libnfs/rquota/rquota.x new file mode 100644 index 000000000000..e0a764f71841 --- /dev/null +++ b/deps/libnfs/rquota/rquota.x @@ -0,0 +1,99 @@ +/* +Copyright (c) 2014, Ronnie Sahlberg +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +const RQUOTAPATHLEN = 1024; /* Guess this is max. It is max for mount so probably rquota too */ + +enum rquotastat { + RQUOTA_OK = 1, + RQUOTA_NOQUOTA = 2, + RQUOTA_EPERM = 3 +}; + +typedef string exportpath; + +struct GETQUOTA1args { + exportpath export; + int uid; +}; + +enum quotatype { + RQUOTA_TYPE_UID = 0, + RQUOTA_TYPE_GID = 1 +}; + +struct GETQUOTA2args { + exportpath export; + quotatype type; + int uid; +}; + +struct GETQUOTA1res_ok { + int bsize; + int active; + int bhardlimit; + int bsoftlimit; + int curblocks; + int fhardlimit; + int fsoftlimit; + int curfiles; + int btimeleft; + int ftimeleft; +}; + +union GETQUOTA1res switch (rquotastat status) { + case RQUOTA_OK: + GETQUOTA1res_ok quota; + default: + void; +}; + +program RQUOTA_PROGRAM { + version RQUOTA_V1 { + void + RQUOTA1_NULL(void) = 0; + + GETQUOTA1res + RQUOTA1_GETQUOTA(GETQUOTA1args) = 1; + + GETQUOTA1res + RQUOTA1_GETACTIVEQUOTA(GETQUOTA1args) = 2; + } = 1; + + version RQUOTA_V2 { + void + RQUOTA2_NULL(void) = 0; + + GETQUOTA1res + RQUOTA2_GETQUOTA(GETQUOTA2args) = 1; + + GETQUOTA1res + RQUOTA2_GETACTIVEQUOTA(GETQUOTA2args) = 2; + } = 2; +} = 100011; + diff --git a/deps/libnfs/win32/win32_compat.c b/deps/libnfs/win32/win32_compat.c new file mode 100644 index 000000000000..02e99306e103 --- /dev/null +++ b/deps/libnfs/win32/win32_compat.c @@ -0,0 +1,217 @@ +/* +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 _U_; + +#else +#include +#include +#include + +#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; + size_t strLen = strlen(src) + 1; +#ifdef UNICODE + wchar_t *srcNonConst = (wchar_t *)malloc(strLen*sizeof(wchar_t)); + if (srcNonConst == NULL) { + return -1; + } + memset(srcNonConst, 0, strLen*sizeof(wchar_t)); + MultiByteToWideChar(CP_ACP, 0, src, -1, srcNonConst, strLen); +#else + char *srcNonConst = (char *)malloc(strLen); + if (srcNonConst == NULL) { + return -1; + } + memset(srcNonConst, 0, strLen); + strncpy(srcNonConst, src, strLen); +#endif + + if (WSAStringToAddress(srcNonConst,af,NULL,(LPSOCKADDR)&sa,&len) == 0) { + ret = 1; + memcpy(dst, &sa.sin_addr, sizeof(struct in_addr)); + } else { + if( WSAGetLastError() == WSAEINVAL ) { + ret = -1; + } + } + free(srcNonConst); + 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) + { + SOCKET 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 + +#ifndef __MINGW32__ +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 + +#ifdef __MINGW32__ +char* libnfs_strndup(const char* s, size_t n) +#else +char* strndup(const char* s, size_t n) +#endif +{ + size_t len; + for(len=0; len path) @@ -774,7 +774,14 @@ char *path_resolve_realpath(char *s, size_t len, bool resolve_symlinks) #if !defined(RARCH_CONSOLE) && defined(RARCH_INTERNAL) #ifdef _WIN32 char *ret = NULL; - wchar_t *rel_path = utf8_to_utf16_string_alloc(s); + wchar_t *rel_path; + + /* Leave VFS URL schemes alone — collapsing nfs:// to nfs:/ (etc.) + * breaks network path dispatch. */ + if (s && strstr(s, "://")) + return s; + + rel_path = utf8_to_utf16_string_alloc(s); if (rel_path) { wchar_t abs_path[PATH_MAX_LENGTH]; @@ -797,6 +804,12 @@ char *path_resolve_realpath(char *s, size_t len, bool resolve_symlinks) char *p; const char *next; const char *buf_end; + + /* Leave VFS URL schemes alone — collapsing nfs:// to nfs:/ (etc.) + * breaks network path dispatch. */ + if (s && strstr(s, "://")) + return s; + if (resolve_symlinks) { char *real_path; diff --git a/libretro-common/include/vfs/vfs.h b/libretro-common/include/vfs/vfs.h index 91ccdbffa262..54d81877edc6 100644 --- a/libretro-common/include/vfs/vfs.h +++ b/libretro-common/include/vfs/vfs.h @@ -62,7 +62,8 @@ enum vfs_scheme VFS_SCHEME_NONE = 0, VFS_SCHEME_CDROM, VFS_SCHEME_SAF, - VFS_SCHEME_SMB + VFS_SCHEME_SMB, + VFS_SCHEME_NFS }; #if !(defined(__WINRT__) && defined(__cplusplus_winrt)) @@ -103,6 +104,10 @@ struct libretro_vfs_implementation_file intptr_t smb_fh; intptr_t smb_ctx; #endif +#ifdef HAVE_NFSCLIENT + intptr_t nfs_fh; + intptr_t nfs_ctx; +#endif #if defined(HAVE_CDROM) && defined(__APPLE__) void *iokit_plugin; /* IOCFPlugInInterface ** */ void *iokit_mmc; /* MMCDeviceInterface ** */ diff --git a/libretro-common/string/stdstring.c b/libretro-common/string/stdstring.c index 4ccd4ee5d5a6..a6f1fb09607c 100644 --- a/libretro-common/string/stdstring.c +++ b/libretro-common/string/stdstring.c @@ -227,7 +227,12 @@ size_t word_wrap( /* Early return if src string length is less * than line width */ if (src_len < (size_t)line_width) + { + /* In-place wrap is a no-op; fortified strlcpy aborts on overlap. */ + if (s == src) + return src_len; return strlcpy(s, src, len); + } while (*src != '\0') { diff --git a/libretro-common/vfs/vfs_implementation.c b/libretro-common/vfs/vfs_implementation.c index 90fa67bf3b2b..cb8621de628b 100644 --- a/libretro-common/vfs/vfs_implementation.c +++ b/libretro-common/vfs/vfs_implementation.c @@ -220,6 +220,10 @@ #include "vfs_implementation_smb.h" #endif +#ifdef HAVE_NFSCLIENT +#include "vfs_implementation_nfs.h" +#endif + #if (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE - 0) >= 200112) || (defined(__POSIX_VISIBLE) && __POSIX_VISIBLE >= 200112) || (defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112) || __USE_LARGEFILE || (defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64) #ifndef HAVE_64BIT_OFFSETS #define HAVE_64BIT_OFFSETS @@ -262,6 +266,16 @@ static int path_is_smb(const char *p) } #endif +#ifdef HAVE_NFSCLIENT +static int path_is_nfs(const char *p) +{ + return (p + && p[0] == 'n' && p[1] == 'f' && p[2] == 's' + && p[3] == ':' && p[4] == '/' && p[5] == '/' + && p[6] != '\0'); +} +#endif + #if defined(ANDROID) && defined(HAVE_SAF) static int path_is_saf(const char *p) { @@ -291,6 +305,10 @@ int64_t retro_vfs_file_seek_internal( if (stream->scheme == VFS_SCHEME_SMB) return retro_vfs_file_seek_smb(stream, offset, whence); #endif +#ifdef HAVE_NFSCLIENT + if (stream->scheme == VFS_SCHEME_NFS) + return retro_vfs_file_seek_nfs(stream, offset, whence); +#endif #ifdef ATLEAST_VC2005 /* VC2005 and up have a special 64-bit fseek */ return _fseeki64(stream->fp, offset, whence); @@ -413,6 +431,13 @@ libretro_vfs_implementation_file *retro_vfs_file_open_impl( } #endif +#ifdef HAVE_NFSCLIENT + if (path_is_nfs(path)) + { + stream->scheme = VFS_SCHEME_NFS; + } +#endif + #if defined(ANDROID) && defined(HAVE_SAF) if (path_is_saf(path)) { @@ -500,6 +525,13 @@ libretro_vfs_implementation_file *retro_vfs_file_open_impl( break; #endif +#ifdef HAVE_NFSCLIENT + case VFS_SCHEME_NFS: + if (!retro_vfs_file_open_nfs(stream, path, mode, hints)) + goto error; + break; +#endif + #if defined(ANDROID) && defined(HAVE_SAF) case VFS_SCHEME_SAF: { @@ -716,6 +748,14 @@ int retro_vfs_file_close_impl(libretro_vfs_implementation_file *stream) } #endif +#ifdef HAVE_NFSCLIENT + if (stream->scheme == VFS_SCHEME_NFS) + { + retro_vfs_file_close_nfs(stream); + goto nfsend; + } +#endif + if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) { if (stream->fp) @@ -745,6 +785,9 @@ int retro_vfs_file_close_impl(libretro_vfs_implementation_file *stream) #endif #ifdef HAVE_SMBCLIENT smbend: +#endif +#ifdef HAVE_NFSCLIENT +nfsend: #endif if (stream->buf) @@ -769,6 +812,10 @@ int retro_vfs_file_error_impl(libretro_vfs_implementation_file *stream) #ifdef HAVE_SMBCLIENT if (stream->scheme == VFS_SCHEME_SMB) return retro_vfs_file_error_smb(stream); +#endif +#ifdef HAVE_NFSCLIENT + if (stream->scheme == VFS_SCHEME_NFS) + return retro_vfs_file_error_nfs(stream); #endif if (!stream->fp) return -1; @@ -834,6 +881,10 @@ int64_t retro_vfs_file_tell_impl(libretro_vfs_implementation_file *stream) if (stream->scheme == VFS_SCHEME_SMB) return retro_vfs_file_tell_smb(stream); #endif +#ifdef HAVE_NFSCLIENT + if (stream->scheme == VFS_SCHEME_NFS) + return retro_vfs_file_tell_nfs(stream); +#endif #ifdef ATLEAST_VC2005 /* VC2005 and up have a special 64-bit ftell */ return _ftelli64(stream->fp); @@ -877,6 +928,10 @@ int64_t retro_vfs_file_read_impl(libretro_vfs_implementation_file *stream, #ifdef HAVE_SMBCLIENT if (stream->scheme == VFS_SCHEME_SMB) return retro_vfs_file_read_smb(stream, s, len); +#endif +#ifdef HAVE_NFSCLIENT + if (stream->scheme == VFS_SCHEME_NFS) + return retro_vfs_file_read_nfs(stream, s, len); #endif return fread(s, 1, (size_t)len, stream->fp); } @@ -933,6 +988,16 @@ int64_t retro_vfs_file_write_impl(libretro_vfs_implementation_file *stream, cons stream->size = pos + ret; return ret; } +#endif +#ifdef HAVE_NFSCLIENT + if (stream->scheme == VFS_SCHEME_NFS) + { + pos = retro_vfs_file_tell_nfs(stream); + ret = retro_vfs_file_write_nfs(stream, s, len); + if (ret != -1 && pos + ret > stream->size) + stream->size = pos + ret; + return ret; + } #endif pos = retro_vfs_file_tell_impl(stream); ret = fwrite(s, 1, (size_t)len, stream->fp); @@ -967,6 +1032,10 @@ int retro_vfs_file_flush_impl(libretro_vfs_implementation_file *stream) #ifdef HAVE_SMBCLIENT if (stream->scheme == VFS_SCHEME_SMB) return 0; +#endif +#ifdef HAVE_NFSCLIENT + if (stream->scheme == VFS_SCHEME_NFS) + return 0; #endif if (stream->fp && fflush(stream->fp) == 0) return 0; @@ -1125,6 +1194,11 @@ int retro_vfs_stat_64_impl(const char *path, int64_t *size) return retro_vfs_stat_smb(path, size); #endif +#ifdef HAVE_NFSCLIENT + if (path_is_nfs(path)) + return retro_vfs_stat_nfs(path, size); +#endif + #if defined(ANDROID) && defined(HAVE_SAF) if (path_is_saf(path)) { @@ -1428,6 +1502,10 @@ struct libretro_vfs_implementation_dir smb_dir_handle* smb_handle; char smb_path[PATH_MAX_LENGTH]; #endif +#ifdef HAVE_NFSCLIENT + nfs_dir_handle* nfs_handle; + char nfs_path[PATH_MAX_LENGTH]; +#endif }; static bool dirent_check_err(libretro_vfs_implementation_dir *rdir) @@ -1489,6 +1567,22 @@ libretro_vfs_implementation_dir *retro_vfs_opendir_impl( } #endif +#ifdef HAVE_NFSCLIENT + if (path_is_nfs(name)) + { + nfs_dir_handle *dh = retro_vfs_opendir_nfs(name, include_hidden); + if (!dh || !dh->dir) + { + free(rdir->orig_path); + free(rdir); + return NULL; + } + rdir->nfs_handle = dh; + rdir->nfs_path[0] = '\0'; + return rdir; + } +#endif + #if defined(ANDROID) && defined(HAVE_SAF) rdir->saf_directory = NULL; @@ -1577,6 +1671,18 @@ bool retro_vfs_readdir_impl(libretro_vfs_implementation_dir *rdir) if (path_is_smb(rdir->orig_path)) return false; #endif +#ifdef HAVE_NFSCLIENT + if (rdir->nfs_handle && rdir->nfs_handle->dir) + { + struct nfs_dirent *de = retro_vfs_readdir_nfs(rdir->nfs_handle); + if (!de) + return false; + strlcpy(rdir->nfs_path, de->name, sizeof(rdir->nfs_path)); + return true; + } + if (path_is_nfs(rdir->orig_path)) + return false; +#endif #if defined(ANDROID) && defined(HAVE_SAF) if (rdir->saf_directory != NULL) return retro_vfs_readdir_saf(rdir->saf_directory); @@ -1609,6 +1715,10 @@ const char *retro_vfs_dirent_get_name_impl(libretro_vfs_implementation_dir *rdir if (rdir->smb_handle && rdir->smb_handle->dir) return rdir->smb_path; #endif +#ifdef HAVE_NFSCLIENT + if (rdir->nfs_handle && rdir->nfs_handle->dir) + return rdir->nfs_path; +#endif #if defined(ANDROID) && defined(HAVE_SAF) if (rdir->saf_directory != NULL) return retro_vfs_dirent_get_name_saf(rdir->saf_directory); @@ -1686,6 +1796,23 @@ bool retro_vfs_dirent_is_dir_impl(libretro_vfs_implementation_dir *rdir) if (rdir->smb_handle && rdir->smb_handle->dir) return retro_vfs_dirent_is_dir_smb(rdir); #endif +#ifdef HAVE_NFSCLIENT + if (rdir->nfs_handle && rdir->nfs_handle->dir) + { + char full[PATH_MAX_LENGTH]; + const char *name = retro_vfs_dirent_get_name_impl(rdir); + int64_t sz = 0; + int st = 0; + + if (!name) + return false; + + fill_pathname_join_special(full, rdir->orig_path, name, sizeof(full)); + st = retro_vfs_stat_nfs(full, &sz); + + return (st & RETRO_VFS_STAT_IS_DIRECTORY) != 0; + } +#endif #if defined(ANDROID) && defined(HAVE_SAF) if (rdir->saf_directory != NULL) return retro_vfs_dirent_is_dir_saf(rdir->saf_directory); @@ -1731,6 +1858,14 @@ int retro_vfs_closedir_impl(libretro_vfs_implementation_dir *rdir) } #endif +#ifdef HAVE_NFSCLIENT + if (rdir->nfs_handle && rdir->nfs_handle->dir) + { + retro_vfs_closedir_nfs(rdir->nfs_handle); + rdir->nfs_handle = NULL; + } +#endif + #if defined(ANDROID) && defined(HAVE_SAF) if (rdir->saf_directory != NULL) ret = retro_vfs_closedir_saf(rdir->saf_directory); diff --git a/libretro-common/vfs/vfs_implementation_nfs.c b/libretro-common/vfs/vfs_implementation_nfs.c new file mode 100644 index 000000000000..67ba88ba721c --- /dev/null +++ b/libretro-common/vfs/vfs_implementation_nfs.c @@ -0,0 +1,633 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2025 - The RetroArch Team + * + * RetroArch 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 Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch 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 RetroArch. + * If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include "vfs_implementation_nfs.h" + +#define NFS_PREFIX "nfs://" +/* NF3DIR from libnfs-raw-nfs.h — avoid pulling the full raw header. */ +#define RETRO_NFS_TYPE_DIR 2 +#define RETRO_NFS_VERSION_3 3 + +static struct nfs_context **nfs_context_pool = NULL; +static int nfs_next_context_index = 0; +static bool nfs_initialized = false; +static int nfs_max_context_configured = 0; +static const struct nfs_settings *nfs_cfg = NULL; +static char nfs_last_error[256] = {0}; + +static void nfs_set_last_error(const char *msg) +{ + if (msg && *msg) + strlcpy(nfs_last_error, msg, sizeof(nfs_last_error)); + else + nfs_last_error[0] = '\0'; +} + +const char *nfs_get_last_error(void) +{ + return nfs_last_error; +} + +static struct nfs_context *get_nfs_context(void) +{ + int idx; + + if (!nfs_initialized) + return NULL; + + if (!nfs_context_pool || nfs_max_context_configured == 0) + return NULL; + + if (nfs_next_context_index < 0 || nfs_next_context_index >= nfs_max_context_configured) + nfs_next_context_index = 0; + + idx = nfs_next_context_index; + nfs_next_context_index = (nfs_next_context_index + 1) % nfs_max_context_configured; + + if (!nfs_context_pool[idx]) + return NULL; + + return nfs_context_pool[idx]; +} + +static void nfs_reset(unsigned num_contexts) +{ + unsigned i; + + for (i = 0; i < num_contexts; i++) + { + if (nfs_context_pool[i]) + nfs_destroy_context(nfs_context_pool[i]); + } + + free(nfs_context_pool); + nfs_context_pool = NULL; + + nfs_initialized = false; + nfs_next_context_index = 0; + nfs_max_context_configured = 0; +} + +bool nfs_init_cfg(const struct nfs_settings *new_cfg) +{ + nfs_cfg = new_cfg; + return true; +} + +static bool nfs_init(void) +{ + char server[256]; + char export_path[PATH_MAX_LENGTH]; + unsigned i; + unsigned max_nfs_contexts; + + if (nfs_initialized) + return true; + + if (!network_init()) + { + nfs_set_last_error("network_init failed"); + return false; + } + + if (!nfs_cfg || !nfs_cfg->server_address || !*nfs_cfg->server_address) + { + nfs_set_last_error("NFS server not configured"); + return false; + } + + if (!nfs_cfg->export_path || !*nfs_cfg->export_path) + { + nfs_set_last_error("NFS export not configured"); + return false; + } + + max_nfs_contexts = nfs_cfg->num_contexts; + if (max_nfs_contexts == 0) + max_nfs_contexts = 1; + + nfs_context_pool = (struct nfs_context **)calloc( + max_nfs_contexts, sizeof(struct nfs_context *)); + if (!nfs_context_pool) + return false; + + strlcpy(server, nfs_cfg->server_address, sizeof(server)); + /* MOUNT protocol expects an absolute export path. */ + if (nfs_cfg->export_path[0] == '/') + strlcpy(export_path, nfs_cfg->export_path, sizeof(export_path)); + else + { + export_path[0] = '/'; + strlcpy(export_path + 1, nfs_cfg->export_path, + sizeof(export_path) - 1); + } + + nfs_set_last_error(NULL); + + for (i = 0; i < max_nfs_contexts; i++) + { + struct nfs_context *nfs; + const char *err; + + nfs = nfs_init_context(); + if (!nfs) + { + nfs_set_last_error("nfs_init_context failed"); + nfs_reset((unsigned)nfs_max_context_configured); + return false; + } + + /* NFSv3, no Kerberos. */ + nfs_set_version(nfs, RETRO_NFS_VERSION_3); + + if (nfs_cfg->timeout) + nfs_set_timeout(nfs, (int)nfs_cfg->timeout * 1000); + + if (nfs_mount(nfs, server, export_path) != 0) + { + err = nfs_get_error(nfs); + nfs_set_last_error(err && *err ? err : "nfs_mount failed"); + nfs_destroy_context(nfs); + nfs_reset((unsigned)nfs_max_context_configured); + return false; + } + + nfs_context_pool[i] = nfs; + nfs_max_context_configured = (int)i + 1; + } + + nfs_initialized = true; + return true; +} + +bool nfs_probe_connection(void) +{ + /* Remount with current settings so browse reflects edits without restart. */ + nfs_shutdown(); + return nfs_init(); +} + +void nfs_shutdown(void) +{ + if (!nfs_initialized || nfs_max_context_configured == 0) + return; + + nfs_reset((unsigned)nfs_max_context_configured); +} + +/* Build path relative to the mounted export from settings / URL. */ +static bool nfs_build_path(char *dest, size_t dest_size, const char *relative_path) +{ + char temp_path[PATH_MAX_LENGTH]; + const char *p; + size_t _len = 0; + size_t sz = sizeof(temp_path); + + if (string_starts_with(relative_path, NFS_PREFIX)) + { + p = relative_path + strlen(NFS_PREFIX); + /* Skip server */ + while (*p && *p != '/') + p++; + /* Skip export (next path component, may contain multiple segments + * matching settings export — fall back to rest of URL after server). */ + if (*p == '/') + { + char export_norm[PATH_MAX_LENGTH]; + const char *export_cfg = (nfs_cfg && nfs_cfg->export_path) + ? nfs_cfg->export_path : NULL; + size_t export_len; + + /* Match mount-time normalization (leading '/'). */ + export_norm[0] = '\0'; + if (export_cfg && *export_cfg) + { + if (export_cfg[0] == '/') + strlcpy(export_norm, export_cfg, sizeof(export_norm)); + else + { + export_norm[0] = '/'; + strlcpy(export_norm + 1, export_cfg, sizeof(export_norm) - 1); + } + } + export_len = strlen(export_norm); + + if (export_len > 0 && string_starts_with(p, export_norm)) + { + p += export_len; + if (*p == '/') + p++; + strlcpy(dest, p, dest_size); + return true; + } + + /* No configured export match: keep path after server. */ + strlcpy(dest, p, dest_size); + return true; + } + + dest[0] = '\0'; + return true; + } + + temp_path[0] = '\0'; + + if (nfs_cfg && nfs_cfg->subdir && *nfs_cfg->subdir) + { + _len = strlcpy(temp_path, nfs_cfg->subdir, sz); + if (_len > 0 && _len < sz && temp_path[_len - 1] != '/') + { + temp_path[_len++] = '/'; + temp_path[_len ] = '\0'; + } + } + + if (relative_path && relative_path[0]) + { + if (relative_path[0] == '/') + relative_path++; + if (_len < sz) + strlcpy(temp_path + _len, relative_path, sz - _len); + } + + strlcpy(dest, temp_path, dest_size); + return true; +} + +bool retro_vfs_file_open_nfs(libretro_vfs_implementation_file *stream, + const char *path, unsigned mode, unsigned hints) +{ + char full_path[PATH_MAX_LENGTH]; + struct nfsfh *fh = NULL; + struct nfs_context *nfs; + int flags = 0; + int ret; + + (void)hints; + + if (!stream) + return false; + + stream->nfs_fh = (intptr_t)0; + stream->nfs_ctx = (intptr_t)0; + + if (mode & RETRO_VFS_FILE_ACCESS_READ) + { + if (mode & RETRO_VFS_FILE_ACCESS_WRITE) + flags = O_RDWR; + else + flags = O_RDONLY; + } + else if (mode & RETRO_VFS_FILE_ACCESS_WRITE) + flags = O_WRONLY; + else + return false; + + /* Match local VFS: WRITE creates; without UPDATE_EXISTING also truncates. */ + if (mode & RETRO_VFS_FILE_ACCESS_WRITE) + { + flags |= O_CREAT; + if (!(mode & RETRO_VFS_FILE_ACCESS_UPDATE_EXISTING)) + flags |= O_TRUNC; + } + + if (!nfs_init()) + return false; + + nfs = get_nfs_context(); + if (!nfs) + return false; + + if (!nfs_build_path(full_path, sizeof(full_path), path)) + return false; + + if (full_path[0] == '\0') + strlcpy(full_path, "/", sizeof(full_path)); + + if (flags & O_CREAT) + ret = nfs_open2(nfs, full_path, flags, 0644, &fh); + else + ret = nfs_open(nfs, full_path, flags, &fh); + + if (ret != 0 || !fh) + { + const char *err = nfs_get_error(nfs); + char msg[256]; + snprintf(msg, sizeof(msg), "nfs_open(\"%.180s\"): %.40s", + full_path, (err && *err) ? err : "failed"); + nfs_set_last_error(msg); + return false; + } + + stream->nfs_fh = (intptr_t)(uintptr_t)fh; + stream->nfs_ctx = (intptr_t)(uintptr_t)nfs; + stream->scheme = VFS_SCHEME_NFS; + return true; +} + +int64_t retro_vfs_file_read_nfs(libretro_vfs_implementation_file *stream, + void *s, uint64_t len) +{ + uint8_t *ptr = (uint8_t *)s; + uint64_t total = 0; + struct nfs_context *ctx; + struct nfsfh *fh; + + if (!nfs_initialized || !stream || !s || stream->nfs_fh == 0) + return -1; + + if (len == 0) + return 0; + + ctx = (struct nfs_context *)(void *)(uintptr_t)stream->nfs_ctx; + fh = (struct nfsfh *)(void *)(uintptr_t)stream->nfs_fh; + if (!ctx || !fh) + return -1; + + /* libnfs may return short reads; accumulate like a regular fread(). */ + while (total < len) + { + size_t want = (size_t)(len - total); + int ret; + + if (want > (size_t)INT32_MAX) + want = (size_t)INT32_MAX; + + ret = nfs_read(ctx, fh, ptr + total, want); + if (ret < 0) + return (total > 0) ? (int64_t)total : -1; + if (ret == 0) + break; + + total += (uint64_t)ret; + } + + return (int64_t)total; +} + +int64_t retro_vfs_file_write_nfs(libretro_vfs_implementation_file *stream, + const void *s, uint64_t len) +{ + const uint8_t *ptr = (const uint8_t *)s; + uint64_t total = 0; + struct nfs_context *ctx; + struct nfsfh *fh; + + if (!nfs_initialized || !stream || !s || stream->nfs_fh == 0) + return -1; + + if (len == 0) + return 0; + + ctx = (struct nfs_context *)(void *)(uintptr_t)stream->nfs_ctx; + fh = (struct nfsfh *)(void *)(uintptr_t)stream->nfs_fh; + if (!ctx || !fh) + return -1; + + while (total < len) + { + uint64_t want = len - total; + int ret; + + if (want > (uint64_t)INT32_MAX) + want = (uint64_t)INT32_MAX; + + ret = nfs_write(ctx, fh, ptr + total, want); + if (ret < 0) + return (total > 0) ? (int64_t)total : -1; + if (ret == 0) + break; + + total += (uint64_t)ret; + } + + return (int64_t)total; +} + +int64_t retro_vfs_file_seek_nfs(libretro_vfs_implementation_file *stream, + int64_t offset, int whence) +{ + uint64_t newpos = 0; + struct nfsfh *fh; + struct nfs_context *ctx; + int ret; + + if (!nfs_initialized || !stream || !stream->nfs_ctx) + return -1; + + if (stream->nfs_fh == 0 || stream->nfs_fh == (intptr_t)-1) + return -1; + + fh = (struct nfsfh *)(void *)(uintptr_t)stream->nfs_fh; + ctx = (struct nfs_context *)(void *)(uintptr_t)stream->nfs_ctx; + if (!fh || !ctx) + return -1; + + if (whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END) + return -1; + + ret = nfs_lseek(ctx, fh, offset, whence, &newpos); + if (ret < 0) + return -1; + + return (int64_t)newpos; +} + +int64_t retro_vfs_file_tell_nfs(libretro_vfs_implementation_file *stream) +{ + uint64_t cur = 0; + struct nfsfh *fh; + struct nfs_context *ctx; + int ret; + + if (!nfs_initialized || !stream || !stream->nfs_ctx) + return -1; + + if (stream->nfs_fh == 0 || stream->nfs_fh == (intptr_t)-1) + return -1; + + fh = (struct nfsfh *)(void *)(uintptr_t)stream->nfs_fh; + ctx = (struct nfs_context *)(void *)(uintptr_t)stream->nfs_ctx; + if (!fh || !ctx) + return -1; + + ret = nfs_lseek(ctx, fh, 0, SEEK_CUR, &cur); + if (ret < 0) + return -1; + + return (int64_t)cur; +} + +int retro_vfs_file_close_nfs(libretro_vfs_implementation_file *stream) +{ + int ret; + struct nfs_context *ctx; + + if (!nfs_initialized) + return -1; + + if (!stream || stream->nfs_fh == 0 || stream->nfs_fh == (intptr_t)-1) + return -1; + + ctx = (struct nfs_context *)(void *)(uintptr_t)stream->nfs_ctx; + if (!ctx) + return -1; + + ret = nfs_close(ctx, (struct nfsfh *)(void *)(uintptr_t)stream->nfs_fh); + + stream->nfs_fh = (intptr_t)-1; + stream->nfs_ctx = (intptr_t)0; + + return ret; +} + +nfs_dir_handle *retro_vfs_opendir_nfs(const char *path, bool include_hidden) +{ + char full_path[PATH_MAX_LENGTH]; + struct nfsdir *dir = NULL; + struct nfs_context *nfs; + nfs_dir_handle *handle; + int ret; + + (void)include_hidden; + + if (!nfs_init()) + return NULL; + + if (!nfs_build_path(full_path, sizeof(full_path), path)) + return NULL; + + if (full_path[0] == '\0') + strlcpy(full_path, "/", sizeof(full_path)); + + nfs = get_nfs_context(); + if (!nfs) + return NULL; + + ret = nfs_opendir(nfs, full_path, &dir); + if (ret != 0 || !dir) + return NULL; + + handle = (nfs_dir_handle *)malloc(sizeof(*handle)); + if (!handle) + { + nfs_closedir(nfs, dir); + return NULL; + } + + handle->ctx = nfs; + handle->dir = dir; + return handle; +} + +struct nfs_dirent *retro_vfs_readdir_nfs(nfs_dir_handle *dh) +{ + struct nfsdirent *ent; + static struct nfs_dirent result; + + if (!nfs_initialized || !dh || !dh->ctx || !dh->dir) + return NULL; + + ent = nfs_readdir(dh->ctx, dh->dir); + if (!ent) + return NULL; + + memset(&result, 0, sizeof(result)); + strlcpy(result.name, ent->name ? ent->name : "", sizeof(result.name)); + result.type = (ent->type == RETRO_NFS_TYPE_DIR) ? 1 : 0; + result.size = (int64_t)ent->size; + + return &result; +} + +int retro_vfs_closedir_nfs(nfs_dir_handle *dh) +{ + if (!nfs_initialized || !dh || !dh->ctx || !dh->dir) + return -1; + + nfs_closedir(dh->ctx, dh->dir); + free(dh); + return 0; +} + +int retro_vfs_stat_nfs(const char *path, int64_t *size) +{ + char rel_path[PATH_MAX_LENGTH]; + struct nfs_stat_64 st; + struct nfs_context *nfs; + + if (!nfs_init()) + return 0; + + if (!nfs_build_path(rel_path, sizeof(rel_path), path)) + return 0; + + if (rel_path[0] == '\0') + strlcpy(rel_path, "/", sizeof(rel_path)); + + nfs = get_nfs_context(); + if (!nfs) + return 0; + + if (nfs_stat64(nfs, rel_path, &st) != 0) + return 0; + + if (size) + *size = (st.nfs_size > (uint64_t)INT64_MAX) + ? INT64_MAX + : (int64_t)st.nfs_size; + + return RETRO_VFS_STAT_IS_VALID | + ((st.nfs_mode & S_IFMT) == S_IFDIR ? RETRO_VFS_STAT_IS_DIRECTORY : 0); +} + +int retro_vfs_file_error_nfs(libretro_vfs_implementation_file *stream) +{ + struct nfs_context *ctx; + const char *err; + + if (!nfs_initialized) + return -1; + + if (!stream || stream->nfs_fh == 0 || stream->nfs_fh == (intptr_t)-1) + return -1; + + if (!stream->nfs_ctx) + return -1; + + ctx = (struct nfs_context *)(void *)(uintptr_t)stream->nfs_ctx; + if (!ctx) + return -1; + + err = nfs_get_error(ctx); + if (err && err[0] != '\0') + return -1; + + return 0; +} diff --git a/libretro-common/vfs/vfs_implementation_nfs.h b/libretro-common/vfs/vfs_implementation_nfs.h new file mode 100644 index 000000000000..9255f01a3514 --- /dev/null +++ b/libretro-common/vfs/vfs_implementation_nfs.h @@ -0,0 +1,70 @@ +#ifndef VFS_IMPLEMENTATION_NFS_H +#define VFS_IMPLEMENTATION_NFS_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct nfs_settings { + const char *server_address; + const char *export_path; + const char *subdir; + unsigned timeout; + unsigned num_contexts; +}; + +typedef struct nfs_settings nfs_settings_t; + +struct nfs_dirent { + char name[256]; + int type; /* file vs directory */ + int64_t size; /* file size */ +}; + +typedef struct { + struct nfs_context *ctx; + struct nfsdir *dir; +} nfs_dir_handle; + +bool nfs_init_cfg(const struct nfs_settings *new_cfg); + +/* File operations */ +bool retro_vfs_file_open_nfs(libretro_vfs_implementation_file *stream, + const char *path, unsigned mode, unsigned hints); +int64_t retro_vfs_file_read_nfs(libretro_vfs_implementation_file *stream, + void *s, uint64_t len); +int64_t retro_vfs_file_write_nfs(libretro_vfs_implementation_file *stream, + const void *s, uint64_t len); +int64_t retro_vfs_file_seek_nfs(libretro_vfs_implementation_file *stream, + int64_t offset, int whence); +int64_t retro_vfs_file_tell_nfs(libretro_vfs_implementation_file *stream); +int retro_vfs_file_close_nfs(libretro_vfs_implementation_file *stream); + +/* Directory operations */ +nfs_dir_handle* retro_vfs_opendir_nfs(const char *path, bool include_hidden); +struct nfs_dirent* retro_vfs_readdir_nfs(nfs_dir_handle* dh); +int retro_vfs_closedir_nfs(nfs_dir_handle* dh); + +/* Stat */ +int retro_vfs_stat_nfs(const char *path, int64_t *size); + +/* Errors */ +int retro_vfs_file_error_nfs(libretro_vfs_implementation_file *stream); + +/* Context management */ +void nfs_shutdown(void); + +/* Mount with current settings; returns false on failure. + * nfs_get_last_error() has a short reason after failure. */ +bool nfs_probe_connection(void); +const char *nfs_get_last_error(void); + +#ifdef __cplusplus +} +#endif + +#endif /* VFS_IMPLEMENTATION_NFS_H */ diff --git a/menu/cbs/menu_cbs_deferred_push.c b/menu/cbs/menu_cbs_deferred_push.c index 56cdcdee8fae..b633b2d97021 100644 --- a/menu/cbs/menu_cbs_deferred_push.c +++ b/menu/cbs/menu_cbs_deferred_push.c @@ -296,6 +296,10 @@ GENERIC_DEFERRED_PUSH(deferred_push_core_game_ai_options, DISPLAYLIS GENERIC_DEFERRED_PUSH(deferred_push_smb_client_settings_list, DISPLAYLIST_SMB_CLIENT_SETTINGS_LIST) GENERIC_DEFERRED_PUSH(deferred_push_smb_client_options, DISPLAYLIST_OPTIONS_SMB_CLIENT) #endif +#ifdef HAVE_NFSCLIENT +GENERIC_DEFERRED_PUSH(deferred_push_nfs_client_settings_list, DISPLAYLIST_NFS_CLIENT_SETTINGS_LIST) +GENERIC_DEFERRED_PUSH(deferred_push_nfs_client_options, DISPLAYLIST_OPTIONS_NFS_CLIENT) +#endif static int general_push(menu_displaylist_info_t *info, unsigned id, enum menu_displaylist_ctl_state state) @@ -808,6 +812,10 @@ static int menu_cbs_init_bind_deferred_push_compare_label( #ifdef HAVE_SMBCLIENT {MENU_ENUM_LABEL_DEFERRED_SMB_CLIENT_SETTINGS_LIST, deferred_push_smb_client_settings_list}, {MENU_ENUM_LABEL_SMB_CLIENT_SETTINGS, deferred_push_smb_client_options}, +#endif +#ifdef HAVE_NFSCLIENT + {MENU_ENUM_LABEL_DEFERRED_NFS_CLIENT_SETTINGS_LIST, deferred_push_nfs_client_settings_list}, + {MENU_ENUM_LABEL_NFS_CLIENT_SETTINGS, deferred_push_nfs_client_options}, #endif }; @@ -931,6 +939,12 @@ static int menu_cbs_init_bind_deferred_push_compare_label( { MENU_ENUM_LABEL_SIDELOAD_CORE_LIST, deferred_push_file_browser_select_sideload_core }, { MENU_ENUM_LABEL_DEFERRED_ADD_TO_PLAYLIST_LIST, deferred_push_add_to_playlist_list }, { MENU_ENUM_LABEL_DEFERRED_ADD_TO_PLAYLIST_QUICKMENU, deferred_push_add_to_playlist_quickmenu }, +#ifdef HAVE_SMBCLIENT + { MENU_ENUM_LABEL_DEFERRED_SMB_CLIENT_SETTINGS_LIST, deferred_push_smb_client_settings_list }, +#endif +#ifdef HAVE_NFSCLIENT + { MENU_ENUM_LABEL_DEFERRED_NFS_CLIENT_SETTINGS_LIST, deferred_push_nfs_client_settings_list }, +#endif }; { @@ -1020,6 +1034,11 @@ static int menu_cbs_init_bind_deferred_push_compare_label( case MENU_ENUM_LABEL_SMB_CLIENT_SETTINGS: BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_smb_client_options); break; +#endif +#ifdef HAVE_NFSCLIENT + case MENU_ENUM_LABEL_NFS_CLIENT_SETTINGS: + BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_nfs_client_options); + break; #endif default: break; /* Fall through to string-based lookup below */ diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index 6b46477f990b..5a6a27e85414 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -38,6 +38,9 @@ #ifdef HAVE_SMBCLIENT #include "../vfs/vfs_implementation_smb.h" #endif +#ifdef HAVE_NFSCLIENT +#include "../../libretro-common/vfs/vfs_implementation_nfs.h" +#endif #ifdef HAVE_DISCORD #include "../../network/discord.h" @@ -425,6 +428,10 @@ static enum msg_hash_enums action_ok_dl_to_enum(unsigned lbl) #ifdef HAVE_SMBCLIENT case ACTION_OK_DL_SMB_CLIENT_SETTINGS_LIST: return MENU_ENUM_LABEL_DEFERRED_SMB_CLIENT_SETTINGS_LIST; +#endif +#ifdef HAVE_NFSCLIENT + case ACTION_OK_DL_NFS_CLIENT_SETTINGS_LIST: + return MENU_ENUM_LABEL_DEFERRED_NFS_CLIENT_SETTINGS_LIST; #endif case ACTION_OK_DL_ACCESSIBILITY_SETTINGS_LIST: return MENU_ENUM_LABEL_DEFERRED_ACCESSIBILITY_SETTINGS_LIST; @@ -1810,6 +1817,9 @@ int generic_action_ok_displaylist_push( case ACTION_OK_DL_AI_SERVICE_SETTINGS_LIST: #ifdef HAVE_SMBCLIENT case ACTION_OK_DL_SMB_CLIENT_SETTINGS_LIST: +#endif +#ifdef HAVE_NFSCLIENT + case ACTION_OK_DL_NFS_CLIENT_SETTINGS_LIST: #endif case ACTION_OK_DL_ACCESSIBILITY_SETTINGS_LIST: case ACTION_OK_DL_POWER_MANAGEMENT_SETTINGS_LIST: @@ -6891,6 +6901,9 @@ STATIC_DEFAULT_ACTION_OK_FUNC(action_ok_push_audio_mixer_settings_list, ACTION_O #ifdef HAVE_SMBCLIENT STATIC_DEFAULT_ACTION_OK_FUNC(action_ok_push_smb_client_settings_list, ACTION_OK_DL_SMB_CLIENT_SETTINGS_LIST) #endif +#ifdef HAVE_NFSCLIENT +STATIC_DEFAULT_ACTION_OK_FUNC(action_ok_push_nfs_client_settings_list, ACTION_OK_DL_NFS_CLIENT_SETTINGS_LIST) +#endif STATIC_DEFAULT_ACTION_OK_FUNC(action_ok_push_user_binds_list, ACTION_OK_DL_USER_BINDS_LIST) STATIC_DEFAULT_ACTION_OK_FUNC(action_ok_push_accounts_cheevos_list, ACTION_OK_DL_ACCOUNTS_CHEEVOS_LIST) #ifdef HAVE_LAKKA @@ -9316,6 +9329,107 @@ static int action_ok_smb_browse(const char *path, } #endif +#ifdef HAVE_NFSCLIENT +static int action_ok_nfs_browse(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + settings_t *settings = config_get_ptr(); + char nfs_path[PATH_MAX_LENGTH]; + char *ptr = nfs_path; + size_t remaining = sizeof(nfs_path); + size_t len; + + if (!settings->bools.nfs_client_enable) + { + runloop_msg_queue_push( + "NFS is not enabled. Enable it in Network Settings.", + 0, 100, 180, true, NULL, + MESSAGE_QUEUE_ICON_DEFAULT, + MESSAGE_QUEUE_CATEGORY_INFO); + return -1; + } + + if (!*settings->arrays.nfs_client_server_address) + { + runloop_msg_queue_push( + "NFS server address not configured.", + 0, 100, 180, true, NULL, + MESSAGE_QUEUE_ICON_DEFAULT, + MESSAGE_QUEUE_CATEGORY_ERROR); + return -1; + } + + if (!*settings->arrays.nfs_client_export) + { + runloop_msg_queue_push( + "NFS export path not configured.", + 0, 100, 180, true, NULL, + MESSAGE_QUEUE_ICON_DEFAULT, + MESSAGE_QUEUE_CATEGORY_ERROR); + return -1; + } + + /* Fail early with a visible reason instead of "Directory Not Found". */ + if (!nfs_probe_connection()) + { + const char *err = nfs_get_last_error(); + runloop_msg_queue_push( + (err && *err) ? err : "NFS mount failed.", + 0, 100, 180, true, NULL, + MESSAGE_QUEUE_ICON_DEFAULT, + MESSAGE_QUEUE_CATEGORY_ERROR); + return -1; + } + + /* Build base NFS path: nfs:// */ + len = snprintf(ptr, remaining, "nfs://%s", + settings->arrays.nfs_client_server_address); + if (len >= remaining) + len = remaining - 1; + ptr += len; + remaining -= len; + + /* Append export path if set */ + if (remaining > 1 && *settings->arrays.nfs_client_export) + { + if (settings->arrays.nfs_client_export[0] != '/') + { + *ptr++ = '/'; + remaining--; + } + len = strlcpy(ptr, settings->arrays.nfs_client_export, remaining); + if (len >= remaining) + len = remaining - 1; + ptr += len; + remaining -= len; + } + + /* Append / if set */ + if (remaining > 1 && *settings->arrays.nfs_client_subdir) + { + if (settings->arrays.nfs_client_subdir[0] != '/') + { + *ptr++ = '/'; + remaining--; + } + len = strlcpy(ptr, settings->arrays.nfs_client_subdir, remaining); + if (len >= remaining) + len = remaining - 1; + ptr += len; + remaining -= len; + } + + return generic_action_ok_displaylist_push( + nfs_path, + nfs_path, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NFS_CLIENT_NFS_SHARE), + FILE_TYPE_DIRECTORY, + idx, + entry_idx, + ACTION_OK_DL_FILE_BROWSER_SELECT_DIR); +} +#endif + static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs, const char *label) { @@ -9516,6 +9630,10 @@ static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs, #ifdef HAVE_SMBCLIENT {MENU_ENUM_LABEL_SMB_CLIENT_SETTINGS, action_ok_push_smb_client_settings_list}, {MENU_ENUM_LABEL_SMB_CLIENT_BROWSE, action_ok_smb_browse}, +#endif +#ifdef HAVE_NFSCLIENT + {MENU_ENUM_LABEL_NFS_CLIENT_SETTINGS, action_ok_push_nfs_client_settings_list}, + {MENU_ENUM_LABEL_NFS_CLIENT_BROWSE, action_ok_nfs_browse}, #endif {MENU_ENUM_LABEL_CORE_DELETE, action_ok_core_delete}, {MENU_ENUM_LABEL_CORE_CREATE_BACKUP, action_ok_core_create_backup}, diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index 5f63f8a71e52..c0931bb97890 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -692,6 +692,17 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_smb_client_timeout, DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_smb_client_browse, MENU_ENUM_SUBLABEL_SMB_CLIENT_BROWSE) #endif +#ifdef HAVE_NFSCLIENT +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_nfs_client_settings, MENU_ENUM_SUBLABEL_NFS_CLIENT_SETTINGS) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_nfs_client_enable, MENU_ENUM_SUBLABEL_NFS_CLIENT_ENABLE) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_nfs_client_server, MENU_ENUM_SUBLABEL_NFS_CLIENT_SERVER) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_nfs_client_export, MENU_ENUM_SUBLABEL_NFS_CLIENT_EXPORT) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_nfs_client_subdir, MENU_ENUM_SUBLABEL_NFS_CLIENT_SUBDIR) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_nfs_client_num_contexts, MENU_ENUM_SUBLABEL_NFS_CLIENT_NUM_CONTEXTS) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_nfs_client_timeout, MENU_ENUM_SUBLABEL_NFS_CLIENT_TIMEOUT) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_nfs_client_browse, MENU_ENUM_SUBLABEL_NFS_CLIENT_BROWSE) +#endif + static int action_bind_sublabel_systeminfo_controller_entry( file_list_t *list, unsigned type, unsigned i, @@ -3662,6 +3673,32 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_SMB_CLIENT_BROWSE: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_smb_client_browse); break; +#endif +#ifdef HAVE_NFSCLIENT + case MENU_ENUM_LABEL_NFS_CLIENT_SETTINGS: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_nfs_client_settings); + break; + case MENU_ENUM_LABEL_NFS_CLIENT_ENABLE: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_nfs_client_enable); + break; + case MENU_ENUM_LABEL_NFS_CLIENT_SERVER: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_nfs_client_server); + break; + case MENU_ENUM_LABEL_NFS_CLIENT_EXPORT: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_nfs_client_export); + break; + case MENU_ENUM_LABEL_NFS_CLIENT_SUBDIR: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_nfs_client_subdir); + break; + case MENU_ENUM_LABEL_NFS_CLIENT_NUM_CONTEXTS: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_nfs_client_num_contexts); + break; + case MENU_ENUM_LABEL_NFS_CLIENT_TIMEOUT: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_nfs_client_timeout); + break; + case MENU_ENUM_LABEL_NFS_CLIENT_BROWSE: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_nfs_client_browse); + break; #endif default: return -1; diff --git a/menu/cbs/menu_cbs_title.c b/menu/cbs/menu_cbs_title.c index 4851473b7684..9ec9e4234198 100644 --- a/menu/cbs/menu_cbs_title.c +++ b/menu/cbs/menu_cbs_title.c @@ -890,6 +890,10 @@ DEFAULT_TITLE_SEARCH_FILTER_MACRO(action_get_core_game_ai_options_list, ME DEFAULT_TITLE_MACRO(action_get_smb_client_settings_list, MENU_ENUM_LABEL_VALUE_SMB_CLIENT_SETTINGS) #endif +#ifdef HAVE_NFSCLIENT +DEFAULT_TITLE_MACRO(action_get_nfs_client_settings_list, MENU_ENUM_LABEL_VALUE_NFS_CLIENT_SETTINGS) +#endif + static int action_get_title_deferred_database_manager_list( const char *path, const char *label, unsigned menu_type, char *s, size_t len) @@ -1069,6 +1073,9 @@ static int menu_cbs_init_bind_title_compare_label(menu_file_list_cbs_t *cbs, #ifdef HAVE_SMBCLIENT {MENU_ENUM_LABEL_DEFERRED_SMB_CLIENT_SETTINGS_LIST, action_get_smb_client_settings_list}, #endif +#ifdef HAVE_NFSCLIENT + {MENU_ENUM_LABEL_DEFERRED_NFS_CLIENT_SETTINGS_LIST, action_get_nfs_client_settings_list}, +#endif #ifdef HAVE_LAKKA {MENU_ENUM_LABEL_DEFERRED_LAKKA_SERVICES_LIST, action_get_lakka_services_list}, #endif @@ -1106,6 +1113,10 @@ static int menu_cbs_init_bind_title_compare_label(menu_file_list_cbs_t *cbs, #ifdef HAVE_SMBCLIENT {MENU_ENUM_LABEL_SMB_CLIENT_SETTINGS, action_get_smb_client_settings_list}, +#endif +#ifdef HAVE_NFSCLIENT + {MENU_ENUM_LABEL_NFS_CLIENT_SETTINGS, + action_get_nfs_client_settings_list}, #endif }; diff --git a/menu/drivers/materialui.c b/menu/drivers/materialui.c index 9e84a6d0fcf3..47b923a7f090 100644 --- a/menu/drivers/materialui.c +++ b/menu/drivers/materialui.c @@ -12412,6 +12412,9 @@ static void materialui_list_insert(void *userdata, || string_is_equal(label, MENU_ENUM_LABEL_AI_SERVICE_SETTINGS_STR) #ifdef HAVE_SMBCLIENT || string_is_equal(label, MENU_ENUM_LABEL_SMB_CLIENT_SETTINGS_STR) +#endif +#ifdef HAVE_NFSCLIENT + || string_is_equal(label, MENU_ENUM_LABEL_NFS_CLIENT_SETTINGS_STR) #endif || string_is_equal(label, MENU_ENUM_LABEL_ACCESSIBILITY_SETTINGS_STR) || string_is_equal(label, MENU_ENUM_LABEL_POWER_MANAGEMENT_SETTINGS_STR) diff --git a/menu/drivers/ozone.c b/menu/drivers/ozone.c index bd0d63d469c2..16ed031ea193 100644 --- a/menu/drivers/ozone.c +++ b/menu/drivers/ozone.c @@ -7353,20 +7353,22 @@ OZONE_NOINLINE static void ozone_draw_osk( if (!draw_placeholder && input_st->keyboard_line.buffer) { + char cursor_src[2048]; char cursor_message[2048]; size_t ptr = input_st->keyboard_line.ptr; if (ptr > input_st->keyboard_line.size) ptr = input_st->keyboard_line.size; - if (ptr >= sizeof(cursor_message)) - ptr = sizeof(cursor_message) - 1; + if (ptr >= sizeof(cursor_src)) + ptr = sizeof(cursor_src) - 1; - memcpy(cursor_message, input_st->keyboard_line.buffer, ptr); - cursor_message[ptr] = '\0'; + memcpy(cursor_src, input_st->keyboard_line.buffer, ptr); + cursor_src[ptr] = '\0'; + /* word_wrap src/dst must not overlap (fortified strlcpy on Darwin). */ (ozone->word_wrap)(cursor_message, sizeof(cursor_message), - cursor_message, - strlen(cursor_message), + cursor_src, + strlen(cursor_src), (video_width - (margin * 2) - (padding * 2)) / ozone->fonts.entries_label.glyph_width, ozone->fonts.entries_label.wideglyph_width, 0); diff --git a/menu/menu_cbs.h b/menu/menu_cbs.h index 34e8fd964f4a..b7212d70202a 100644 --- a/menu/menu_cbs.h +++ b/menu/menu_cbs.h @@ -208,6 +208,9 @@ enum ACTION_OK_DL_AI_SERVICE_SETTINGS_LIST, #ifdef HAVE_SMBCLIENT ACTION_OK_DL_SMB_CLIENT_SETTINGS_LIST, +#endif +#ifdef HAVE_NFSCLIENT + ACTION_OK_DL_NFS_CLIENT_SETTINGS_LIST, #endif ACTION_OK_DL_ACCESSIBILITY_SETTINGS_LIST, ACTION_OK_DL_USER_INTERFACE_SETTINGS_LIST, diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 77b78e3016f5..31ca02ee7270 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -3897,6 +3897,22 @@ static int menu_displaylist_parse_load_content_settings( MENU_SETTING_ACTION, 0, 0, NULL)) count++; } +#endif +#ifdef HAVE_NFSCLIENT + if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list, + MENU_ENUM_LABEL_NFS_CLIENT_SETTINGS, + PARSE_ONLY_BOOL, false) == 0) + count++; + + if (settings->bools.nfs_client_enable) + { + if (menu_entries_append(list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NFS_CLIENT_SETTINGS), + MENU_ENUM_LABEL_NFS_CLIENT_SETTINGS_STR, + MENU_ENUM_LABEL_NFS_CLIENT_SETTINGS, + MENU_SETTING_ACTION, 0, 0, NULL)) + count++; + } #endif } @@ -8501,12 +8517,26 @@ unsigned menu_displaylist_build_list( { if (menu_entries_append(list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SMB_CLIENT_BROWSE), - msg_hash_to_str(MENU_ENUM_SUBLABEL_SMB_CLIENT_BROWSE), + MENU_ENUM_LABEL_SMB_CLIENT_BROWSE_STR, MENU_ENUM_LABEL_SMB_CLIENT_BROWSE, FILE_TYPE_DIRECTORY, 0, 0, NULL)) count++; } } +#endif +#ifdef HAVE_NFSCLIENT + { + settings_t *settings = config_get_ptr(); + if (settings->bools.nfs_client_enable) + { + if (menu_entries_append(list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NFS_CLIENT_BROWSE), + MENU_ENUM_LABEL_NFS_CLIENT_BROWSE_STR, + MENU_ENUM_LABEL_NFS_CLIENT_BROWSE, + FILE_TYPE_DIRECTORY, 0, 0, NULL)) + count++; + } + } #endif if ( !settings->bools.kiosk_mode_enable && settings->bools.settings_show_file_browser) @@ -9579,6 +9609,9 @@ unsigned menu_displaylist_build_list( static menu_displaylist_build_info_selective_t build_list[] = { #ifdef HAVE_SMBCLIENT {MENU_ENUM_LABEL_SMB_CLIENT_SETTINGS, PARSE_ACTION, true}, +#endif +#ifdef HAVE_NFSCLIENT + {MENU_ENUM_LABEL_NFS_CLIENT_SETTINGS, PARSE_ACTION, true}, #endif {MENU_ENUM_LABEL_NETPLAY_PUBLIC_ANNOUNCE, PARSE_ONLY_BOOL, true}, {MENU_ENUM_LABEL_NETPLAY_USE_MITM_SERVER, PARSE_ONLY_BOOL, true}, @@ -12574,6 +12607,50 @@ unsigned menu_displaylist_build_list( } } break; +#endif +#ifdef HAVE_NFSCLIENT + case DISPLAYLIST_NFS_CLIENT_SETTINGS_LIST: + { + bool nfs_enable = settings->bools.nfs_client_enable; + + static menu_displaylist_build_info_selective_t build_list[] = { + {MENU_ENUM_LABEL_NFS_CLIENT_ENABLE, PARSE_ONLY_BOOL, true}, + {MENU_ENUM_LABEL_NFS_CLIENT_SERVER, PARSE_ONLY_STRING, false}, + {MENU_ENUM_LABEL_NFS_CLIENT_EXPORT, PARSE_ONLY_STRING, false}, + {MENU_ENUM_LABEL_NFS_CLIENT_SUBDIR, PARSE_ONLY_STRING, false}, + {MENU_ENUM_LABEL_NFS_CLIENT_NUM_CONTEXTS, PARSE_ONLY_UINT, false}, + {MENU_ENUM_LABEL_NFS_CLIENT_TIMEOUT, PARSE_ONLY_UINT, false}, + }; + + for (i = 0; i < ARRAY_SIZE(build_list); i++) + { + switch (build_list[i].enum_idx) + { + case MENU_ENUM_LABEL_NFS_CLIENT_SERVER: + case MENU_ENUM_LABEL_NFS_CLIENT_EXPORT: + case MENU_ENUM_LABEL_NFS_CLIENT_SUBDIR: + case MENU_ENUM_LABEL_NFS_CLIENT_NUM_CONTEXTS: + case MENU_ENUM_LABEL_NFS_CLIENT_TIMEOUT: + build_list[i].checked = nfs_enable; + break; + default: + break; + } + } + + for (i = 0; i < ARRAY_SIZE(build_list); i++) + { + if (!build_list[i].checked && !include_everything) + continue; + + if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list, + build_list[i].enum_idx, + build_list[i].parse_type, + false) == 0) + count++; + } + } + break; #endif default: break; @@ -15210,6 +15287,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, #ifdef HAVE_SMBCLIENT case DISPLAYLIST_SMB_CLIENT_SETTINGS_LIST: case DISPLAYLIST_OPTIONS_SMB_CLIENT: +#endif +#ifdef HAVE_NFSCLIENT + case DISPLAYLIST_NFS_CLIENT_SETTINGS_LIST: + case DISPLAYLIST_OPTIONS_NFS_CLIENT: #endif case DISPLAYLIST_OPTIONS_OVERRIDES: menu_entries_clear(info->list); diff --git a/menu/menu_displaylist.h b/menu/menu_displaylist.h index cb6ffe1edd8b..5c1780b2afcc 100644 --- a/menu/menu_displaylist.h +++ b/menu/menu_displaylist.h @@ -219,6 +219,9 @@ enum menu_displaylist_ctl_state DISPLAYLIST_AI_SERVICE_SETTINGS_LIST, #ifdef HAVE_SMBCLIENT DISPLAYLIST_SMB_CLIENT_SETTINGS_LIST, +#endif +#ifdef HAVE_NFSCLIENT + DISPLAYLIST_NFS_CLIENT_SETTINGS_LIST, #endif DISPLAYLIST_ACCESSIBILITY_SETTINGS_LIST, DISPLAYLIST_ONSCREEN_DISPLAY_SETTINGS_LIST, @@ -307,6 +310,9 @@ enum menu_displaylist_ctl_state #endif #ifdef HAVE_SMBCLIENT DISPLAYLIST_OPTIONS_SMB_CLIENT, +#endif +#ifdef HAVE_NFSCLIENT + DISPLAYLIST_OPTIONS_NFS_CLIENT, #endif DISPLAYLIST_PENDING_CLEAR }; diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 85fc90b23b2a..baa91be1ca43 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -396,6 +396,9 @@ enum settings_list_type #endif #ifdef HAVE_SMBCLIENT SETTINGS_LIST_SMBCLIENT, +#endif +#ifdef HAVE_NFSCLIENT + SETTINGS_LIST_NFSCLIENT, #endif SETTINGS_LIST_MANUAL_CONTENT_SCAN }; @@ -8032,6 +8035,9 @@ static const enum settings_list_type settings_list_build_order[] = #endif #ifdef HAVE_SMBCLIENT SETTINGS_LIST_SMBCLIENT, +#endif +#ifdef HAVE_NFSCLIENT + SETTINGS_LIST_NFSCLIENT, #endif SETTINGS_LIST_MANUAL_CONTENT_SCAN }; @@ -12536,6 +12542,13 @@ static const setting_desc_t ui_desc_9[] = { }; #endif +#ifdef HAVE_NFSCLIENT +static const setting_desc_t ui_desc_nfs_show[] = { +/* GENERATED: rows come from settings_def_settings_show_nfs.h in order. */ +#include "../settings/settings_def_settings_show_nfs.h" +}; +#endif + static const setting_desc_t ui_desc_10[] = { /* GENERATED: rows come from settings_def_menu_quick_views.h in order. */ #include "../settings/settings_def_menu_quick_views.h" @@ -12631,7 +12644,7 @@ static const setting_desc_t core_updater_desc_2[] = { #endif #endif -#ifdef HAVE_SMBCLIENT +#if defined(HAVE_SMBCLIENT) || defined(HAVE_NFSCLIENT) static const setting_desc_t np_desc_0[] = { /* GENERATED: rows come from settings_def_netplay_action.h in order. */ #include "../settings/settings_def_netplay_action.h" @@ -12827,6 +12840,22 @@ static const setting_desc_t smbclient_desc_1[] = { }; #endif +#ifdef HAVE_NFSCLIENT +#include "../settings/settings_def_menu_rows_begin.h" +static const setting_desc_t nfsclient_desc_0[] = { +/* GENERATED: rows come from settings_def_nfs_client.h in order. */ +#include "../settings/settings_def_nfs_client.h" +}; +#endif + +#ifdef HAVE_NFSCLIENT +static const setting_desc_t nfsclient_desc_1[] = { +/* GENERATED: rows come from settings_def_nfs_client_opts.h in order. */ +#include "../settings/settings_def_nfs_client_opts.h" +#include "../settings/settings_def_rows_end.h" +}; +#endif + /* --- Per-list build functions; the registry below replaces the old * monolithic switch. Adding a settings list means a build function * (or, for pure descriptor groups, only def-file rows) and one @@ -15855,6 +15884,10 @@ static void settings_build_user_interface( ADD_DESC(ui_desc_9); #endif +#ifdef HAVE_NFSCLIENT + ADD_DESC(ui_desc_nfs_show); +#endif + ADD_DESC(ui_desc_10); #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL) @@ -16233,8 +16266,17 @@ static void settings_build_netplay( parent_group = MENU_ENUM_LABEL_NETWORK_SETTINGS_STR; -#ifdef HAVE_SMBCLIENT - if (settings->bools.settings_show_smb_client) +#if defined(HAVE_SMBCLIENT) || defined(HAVE_NFSCLIENT) + if ( +#if defined(HAVE_SMBCLIENT) + settings->bools.settings_show_smb_client +#else + false +#endif +#if defined(HAVE_NFSCLIENT) + || settings->bools.settings_show_nfs_client +#endif + ) { ADD_DESC(np_desc_0); } @@ -17300,6 +17342,72 @@ static void settings_build_smbclient( } #endif +#ifdef HAVE_NFSCLIENT +static void settings_build_nfsclient( + settings_t *settings, global_t *global, + rarch_setting_t **list, rarch_setting_info_t *list_info, + const char *parent_group) +{ + rarch_setting_group_info_t group_info; + rarch_setting_group_info_t subgroup_info; + group_info.name = NULL; + subgroup_info.name = NULL; + (void)settings; (void)global; (void)group_info; (void)subgroup_info; + { + GROUP_STATE(MENU_ENUM_LABEL_VALUE_NFS_CLIENT_SETTINGS, MENU_ENUM_LABEL_NFS_CLIENT_SETTINGS); + + ADD_DESC(nfsclient_desc_0); + + /* Descriptor holdout: non-general read/write handler. */ + CONFIG_STRING( + list, list_info, + settings->arrays.nfs_client_server_address, + sizeof(settings->arrays.nfs_client_server_address), + MENU_ENUM_LABEL_NFS_CLIENT_SERVER, + MENU_ENUM_LABEL_VALUE_NFS_CLIENT_SERVER, + "", + &group_info, + &subgroup_info, + parent_group, + NULL, + NULL); + SETTINGS_DATA_LIST_CURRENT_ADD_FLAGS(list, list_info, SD_FLAG_ALLOW_INPUT); + + CONFIG_STRING( + list, list_info, + settings->arrays.nfs_client_export, + sizeof(settings->arrays.nfs_client_export), + MENU_ENUM_LABEL_NFS_CLIENT_EXPORT, + MENU_ENUM_LABEL_VALUE_NFS_CLIENT_EXPORT, + "", + &group_info, + &subgroup_info, + parent_group, + NULL, + NULL); + SETTINGS_DATA_LIST_CURRENT_ADD_FLAGS(list, list_info, SD_FLAG_ALLOW_INPUT); + + CONFIG_STRING( + list, list_info, + settings->arrays.nfs_client_subdir, + sizeof(settings->arrays.nfs_client_subdir), + MENU_ENUM_LABEL_NFS_CLIENT_SUBDIR, + MENU_ENUM_LABEL_VALUE_NFS_CLIENT_SUBDIR, + "", + &group_info, + &subgroup_info, + parent_group, + NULL, + NULL); + SETTINGS_DATA_LIST_CURRENT_ADD_FLAGS(list, list_info, SD_FLAG_ALLOW_INPUT); + + ADD_DESC(nfsclient_desc_1); + + GROUP_END(); + } +} +#endif + typedef struct settings_build_entry { enum settings_list_type type; @@ -17466,6 +17574,9 @@ static const settings_build_entry_t settings_build_registry[] = { #ifdef HAVE_SMBCLIENT { SETTINGS_LIST_SMBCLIENT, settings_build_smbclient, NULL, 0, MSG_UNKNOWN, MSG_UNKNOWN, MSG_UNKNOWN }, #endif +#ifdef HAVE_NFSCLIENT + { SETTINGS_LIST_NFSCLIENT, settings_build_nfsclient, NULL, 0, MSG_UNKNOWN, MSG_UNKNOWN, MSG_UNKNOWN }, +#endif }; static bool setting_append_list( @@ -18026,6 +18137,9 @@ static const settings_desc_table_t settings_desc_registry[] = { #endif #ifdef HAVE_SMBCLIENT { ui_desc_9, (uint16_t)ARRAY_SIZE(ui_desc_9) }, +#endif +#ifdef HAVE_NFSCLIENT + { ui_desc_nfs_show, (uint16_t)ARRAY_SIZE(ui_desc_nfs_show) }, #endif { ui_desc_10, (uint16_t)ARRAY_SIZE(ui_desc_10) }, #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL) @@ -18062,7 +18176,7 @@ static const settings_desc_table_t settings_desc_registry[] = { { core_updater_desc_2, (uint16_t)ARRAY_SIZE(core_updater_desc_2) }, #endif #endif -#ifdef HAVE_SMBCLIENT +#if defined(HAVE_SMBCLIENT) || defined(HAVE_NFSCLIENT) { np_desc_0, (uint16_t)ARRAY_SIZE(np_desc_0) }, #endif #if defined(HAVE_NETWORKING) @@ -18135,6 +18249,12 @@ static const settings_desc_table_t settings_desc_registry[] = { #ifdef HAVE_SMBCLIENT { smbclient_desc_1, (uint16_t)ARRAY_SIZE(smbclient_desc_1) }, #endif +#ifdef HAVE_NFSCLIENT + { nfsclient_desc_0, (uint16_t)ARRAY_SIZE(nfsclient_desc_0) }, +#endif +#ifdef HAVE_NFSCLIENT + { nfsclient_desc_1, (uint16_t)ARRAY_SIZE(nfsclient_desc_1) }, +#endif }; static const setting_desc_t *settings_master_find(enum msg_hash_enums e) diff --git a/msg_hash.h b/msg_hash.h index 27fb22867220..ef34cdb740cc 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -15358,6 +15358,7 @@ enum msg_hash_enums #undef SETTINGS_DEF_STRINGS_PASS #undef SETTINGS_DEF_ENUM_PASS MENU_LABEL(SETTINGS_SHOW_SMB_CLIENT), + MENU_LABEL(SETTINGS_SHOW_NFS_CLIENT), /* GENERATED REGION: menu quick views group enum rows (see settings/settings_def_menu_quick_views.h). */ #define SETTINGS_DEF_ENUM_PASS #define SETTINGS_DEF_STRINGS_PASS @@ -19154,6 +19155,9 @@ enum msg_hash_enums MENU_ENUM_LABEL_DEFERRED_AI_SERVICE_SETTINGS_LIST, #ifdef HAVE_SMBCLIENT MENU_ENUM_LABEL_DEFERRED_SMB_CLIENT_SETTINGS_LIST, +#endif +#ifdef HAVE_NFSCLIENT + MENU_ENUM_LABEL_DEFERRED_NFS_CLIENT_SETTINGS_LIST, #endif MENU_ENUM_LABEL_DEFERRED_ACCESSIBILITY_SETTINGS_LIST, MENU_ENUM_LABEL_DEFERRED_CHEAT_DETAILS_SETTINGS_LIST, @@ -33698,7 +33702,7 @@ enum msg_hash_enums MENU_LABEL(GAME_AI_MENU_OPTION), #endif -#ifdef HAVE_SMBCLIENT +#if defined(HAVE_SMBCLIENT) || defined(HAVE_NFSCLIENT) /* GENERATED REGION: netplay action enum rows (see settings/settings_def_netplay_action.h). */ #define SETTINGS_DEF_ENUM_PASS #define SETTINGS_DEF_STRINGS_PASS @@ -33825,6 +33829,8 @@ enum msg_hash_enums #undef S_FLOAT_NS_H #undef SETTINGS_DEF_STRINGS_PASS #undef SETTINGS_DEF_ENUM_PASS +#endif +#ifdef HAVE_SMBCLIENT /* GENERATED REGION: SMB client setting enum rows (see settings/settings_def_smb_client.h). */ #define SETTINGS_DEF_ENUM_PASS #define SETTINGS_DEF_STRINGS_PASS @@ -34087,6 +34093,266 @@ enum msg_hash_enums MENU_LABEL(SMB_CLIENT_SMB_SHARE), #endif +#ifdef HAVE_NFSCLIENT + /* GENERATED REGION: NFS client setting enum rows (see settings/settings_def_nfs_client.h). */ +#define SETTINGS_DEF_ENUM_PASS +#define SETTINGS_DEF_STRINGS_PASS +#define S_BOOL(f, T, n, d, sd, df, c, us, sub) MENU_LABEL(T), +#define S_BOOL_NS(f, T, n, d, sd, df, c, us) MENU_LABEL(T), +#define S_UINT(f, T, n, d, sd, df, c, mn, mx, st, ob, ok, rp, us, sub) MENU_LABEL(T), +#define S_UINT_NS(f, T, n, d, sd, df, c, mn, mx, st, ob, ok, rp, us) MENU_LABEL(T), +#define S_INT(f, T, n, d, sd, df, c, mn, mx, st, ob, ok, rp, us, sub) MENU_LABEL(T), +#define S_INT_NS(f, T, n, d, sd, df, c, mn, mx, st, ob, ok, rp, us) MENU_LABEL(T), +#define S_FLOAT(f, T, n, d, rnd, sd, df, c, mn, mx, st, ok, rp, us, sub) MENU_LABEL(T), +#define S_FLOAT_NS(f, T, n, d, rnd, sd, df, c, mn, mx, st, ok, rp, us) MENU_LABEL(T), +#define S_STRING(f, T, n, d, sd, c, ok, rp, sta, sel, lf, rt, ui, us, sub) MENU_LABEL(T), +#define S_STRING_NS(f, T, n, d, sd, c, ok, rp, sta, sel, lf, rt, ui, us) MENU_LABEL(T), +#define S_DIR(f, T, n, d, el, sd, c, sta, us, sub) MENU_LABEL(T), +#define S_DIR_NS(f, T, n, d, el, sd, c, sta, us) MENU_LABEL(T), +#define S_STRING_P(f, T, n, d, sd, c, ok, rp, sta, sel, lf, rt, ui, us, sub) MENU_LABEL(T), +#define S_STRING_P_NS(f, T, n, d, sd, c, ok, rp, sta, sel, lf, rt, ui, us) MENU_LABEL(T), +#define S_PATH(f, T, n, d, sd, c, vals, rp, ui, us, sub) MENU_LABEL(T), +#define S_PATH_NS(f, T, n, d, sd, c, vals, rp, ui, us) MENU_LABEL(T), +#define S_PATH_DS(f, T, n, df2, sd, c, vals, rp, ui, us, sub) MENU_LABEL(T), +#define S_PATH_DS_NS(f, T, n, df2, sd, c, vals, rp, ui, us) MENU_LABEL(T), +#define S_ACTION(T, n, us, sub) MENU_LABEL(T), +#define S_ACTION_NS(T, n, us) MENU_LABEL(T), +#define S_BOOL_EX(f, T, n, d, sd, df, c, ok, rp, sta, sel, lf, rt, ui, us, sub) MENU_LABEL(T), +#define S_BOOL_EX_NS(f, T, n, d, sd, df, c, ok, rp, sta, sel, lf, rt, ui, us) MENU_LABEL(T), +#define S_UINT_EX(f, T, n, d, sd, df, c, mn, mx, st, ob, ok, rp, sta, sel, lf, rt, ui, us, sub) MENU_LABEL(T), +#define S_UINT_EX_NS(f, T, n, d, sd, df, c, mn, mx, st, ob, ok, rp, sta, sel, lf, rt, ui, us) MENU_LABEL(T), +#define S_INT_EX(f, T, n, d, sd, df, c, mn, mx, st, ob, ok, rp, sta, sel, lf, rt, ui, us, sub) MENU_LABEL(T), +#define S_INT_EX_NS(f, T, n, d, sd, df, c, mn, mx, st, ob, ok, rp, sta, sel, lf, rt, ui, us) MENU_LABEL(T), +#define S_FLOAT_EX(f, T, n, d, rnd, sd, df, c, mn, mx, st, ok, rp, sta, sel, lf, rt, ui, us, sub) MENU_LABEL(T), +#define S_FLOAT_EX_NS(f, T, n, d, rnd, sd, df, c, mn, mx, st, ok, rp, sta, sel, lf, rt, ui, us) MENU_LABEL(T), +#define S_ACTION_EX(T, n, sd, ok, rp, c, us, sub) MENU_LABEL(T), +#define S_ACTION_EX_NS(T, n, sd, ok, rp, c, us) MENU_LABEL(T), +#define S_BOOL_H(f, T, n, d, sd, df, c, us, sub) MENU_LBL_H(T), +#define S_UINT_H(f, T, n, d, sd, df, c, mn, mx, st, ob, ok, rp, us, sub) MENU_LBL_H(T), +#define S_BOOL_NS_H(f, T, n, d, sd, df, c, us) MENU_LBL_H(T), +#define S_INT_H(f, T, n, d, sd, df, c, mn, mx, st, ob, ok, rp, us, sub) MENU_LBL_H(T), +#define S_FLOAT_H(f, T, n, d, rnd, sd, df, c, mn, mx, st, ok, rp, us, sub) MENU_LBL_H(T), +#define S_UINT_NS_H(f, T, n, d, sd, df, c, mn, mx, st, ob, ok, rp, us) MENU_LBL_H(T), +#define S_INT_NS_H(f, T, n, d, sd, df, c, mn, mx, st, ob, ok, rp, us) MENU_LBL_H(T), +#define S_FLOAT_NS_H(f, T, n, d, rnd, sd, df, c, mn, mx, st, ok, rp, us) MENU_LBL_H(T), +#define S_STRING_H(f, T, n, d, sd, c, ok, rp, sta, sel, lf, rt, ui, us, sub) MENU_LBL_H(T), +#define S_STRING_NS_H(f, T, n, d, sd, c, ok, rp, sta, sel, lf, rt, ui, us) MENU_LBL_H(T), +#define S_DIR_H(f, T, n, d, el, sd, c, sta, us, sub) MENU_LBL_H(T), +#define S_DIR_NS_H(f, T, n, d, el, sd, c, sta, us) MENU_LBL_H(T), +#define S_STRING_P_H(f, T, n, d, sd, c, ok, rp, sta, sel, lf, rt, ui, us, sub) MENU_LBL_H(T), +#define S_STRING_P_NS_H(f, T, n, d, sd, c, ok, rp, sta, sel, lf, rt, ui, us) MENU_LBL_H(T), +#define S_PATH_H(f, T, n, d, sd, c, vals, rp, ui, us, sub) MENU_LBL_H(T), +#define S_PATH_NS_H(f, T, n, d, sd, c, vals, rp, ui, us) MENU_LBL_H(T), +#define S_PATH_DS_H(f, T, n, df2, sd, c, vals, rp, ui, us, sub) MENU_LBL_H(T), +#define S_PATH_DS_NS_H(f, T, n, df2, sd, c, vals, rp, ui, us) MENU_LBL_H(T), +#define S_ACTION_H(T, n, us, sub) MENU_LBL_H(T), +#define S_ACTION_NS_H(T, n, us) MENU_LBL_H(T), +#define S_BOOL_EX_H(f, T, n, d, sd, df, c, ok, rp, sta, sel, lf, rt, ui, us, sub) MENU_LBL_H(T), +#define S_BOOL_EX_NS_H(f, T, n, d, sd, df, c, ok, rp, sta, sel, lf, rt, ui, us) MENU_LBL_H(T), +#define S_UINT_EX_H(f, T, n, d, sd, df, c, mn, mx, st, ob, ok, rp, sta, sel, lf, rt, ui, us, sub) MENU_LBL_H(T), +#define S_UINT_EX_NS_H(f, T, n, d, sd, df, c, mn, mx, st, ob, ok, rp, sta, sel, lf, rt, ui, us) MENU_LBL_H(T), +#define S_INT_EX_H(f, T, n, d, sd, df, c, mn, mx, st, ob, ok, rp, sta, sel, lf, rt, ui, us, sub) MENU_LBL_H(T), +#define S_INT_EX_NS_H(f, T, n, d, sd, df, c, mn, mx, st, ob, ok, rp, sta, sel, lf, rt, ui, us) MENU_LBL_H(T), +#define S_FLOAT_EX_H(f, T, n, d, rnd, sd, df, c, mn, mx, st, ok, rp, sta, sel, lf, rt, ui, us, sub) MENU_LBL_H(T), +#define S_FLOAT_EX_NS_H(f, T, n, d, rnd, sd, df, c, mn, mx, st, ok, rp, sta, sel, lf, rt, ui, us) MENU_LBL_H(T), +#define S_ACTION_EX_H(T, n, sd, ok, rp, c, us, sub) MENU_LBL_H(T), +#define S_ACTION_EX_NS_H(T, n, sd, ok, rp, c, us) MENU_LBL_H(T), +#include "settings/settings_def_nfs_client.h" +#undef S_BOOL +#undef S_BOOL_NS +#undef S_UINT +#undef S_UINT_NS +#undef S_INT +#undef S_INT_NS +#undef S_FLOAT +#undef S_FLOAT_NS +#undef S_STRING +#undef S_STRING_NS +#undef S_STRING_H +#undef S_STRING_NS_H +#undef S_DIR +#undef S_DIR_NS +#undef S_DIR_H +#undef S_DIR_NS_H +#undef S_STRING_P +#undef S_STRING_P_NS +#undef S_STRING_P_H +#undef S_STRING_P_NS_H +#undef S_PATH +#undef S_PATH_NS +#undef S_PATH_H +#undef S_PATH_NS_H +#undef S_PATH_DS +#undef S_PATH_DS_NS +#undef S_PATH_DS_H +#undef S_PATH_DS_NS_H +#undef S_ACTION +#undef S_ACTION_NS +#undef S_ACTION_H +#undef S_ACTION_NS_H +#undef S_BOOL_EX +#undef S_BOOL_EX_NS +#undef S_BOOL_EX_H +#undef S_BOOL_EX_NS_H +#undef S_UINT_EX +#undef S_UINT_EX_NS +#undef S_UINT_EX_H +#undef S_UINT_EX_NS_H +#undef S_INT_EX +#undef S_INT_EX_NS +#undef S_INT_EX_H +#undef S_INT_EX_NS_H +#undef S_FLOAT_EX +#undef S_FLOAT_EX_NS +#undef S_FLOAT_EX_H +#undef S_FLOAT_EX_NS_H +#undef S_ACTION_EX +#undef S_ACTION_EX_NS +#undef S_ACTION_EX_H +#undef S_ACTION_EX_NS_H +#undef S_BOOL_H +#undef S_UINT_H +#undef S_BOOL_NS_H +#undef S_INT_H +#undef S_FLOAT_H +#undef S_UINT_NS_H +#undef S_INT_NS_H +#undef S_FLOAT_NS_H +#undef SETTINGS_DEF_STRINGS_PASS +#undef SETTINGS_DEF_ENUM_PASS + /* GENERATED REGION: NFS client options group enum rows (see settings/settings_def_nfs_client_opts.h). */ +#define SETTINGS_DEF_ENUM_PASS +#define SETTINGS_DEF_STRINGS_PASS +#define S_BOOL(f, T, n, d, sd, df, c, us, sub) MENU_LABEL(T), +#define S_BOOL_NS(f, T, n, d, sd, df, c, us) MENU_LABEL(T), +#define S_UINT(f, T, n, d, sd, df, c, mn, mx, st, ob, ok, rp, us, sub) MENU_LABEL(T), +#define S_UINT_NS(f, T, n, d, sd, df, c, mn, mx, st, ob, ok, rp, us) MENU_LABEL(T), +#define S_INT(f, T, n, d, sd, df, c, mn, mx, st, ob, ok, rp, us, sub) MENU_LABEL(T), +#define S_INT_NS(f, T, n, d, sd, df, c, mn, mx, st, ob, ok, rp, us) MENU_LABEL(T), +#define S_FLOAT(f, T, n, d, rnd, sd, df, c, mn, mx, st, ok, rp, us, sub) MENU_LABEL(T), +#define S_FLOAT_NS(f, T, n, d, rnd, sd, df, c, mn, mx, st, ok, rp, us) MENU_LABEL(T), +#define S_STRING(f, T, n, d, sd, c, ok, rp, sta, sel, lf, rt, ui, us, sub) MENU_LABEL(T), +#define S_STRING_NS(f, T, n, d, sd, c, ok, rp, sta, sel, lf, rt, ui, us) MENU_LABEL(T), +#define S_DIR(f, T, n, d, el, sd, c, sta, us, sub) MENU_LABEL(T), +#define S_DIR_NS(f, T, n, d, el, sd, c, sta, us) MENU_LABEL(T), +#define S_STRING_P(f, T, n, d, sd, c, ok, rp, sta, sel, lf, rt, ui, us, sub) MENU_LABEL(T), +#define S_STRING_P_NS(f, T, n, d, sd, c, ok, rp, sta, sel, lf, rt, ui, us) MENU_LABEL(T), +#define S_PATH(f, T, n, d, sd, c, vals, rp, ui, us, sub) MENU_LABEL(T), +#define S_PATH_NS(f, T, n, d, sd, c, vals, rp, ui, us) MENU_LABEL(T), +#define S_PATH_DS(f, T, n, df2, sd, c, vals, rp, ui, us, sub) MENU_LABEL(T), +#define S_PATH_DS_NS(f, T, n, df2, sd, c, vals, rp, ui, us) MENU_LABEL(T), +#define S_ACTION(T, n, us, sub) MENU_LABEL(T), +#define S_ACTION_NS(T, n, us) MENU_LABEL(T), +#define S_BOOL_EX(f, T, n, d, sd, df, c, ok, rp, sta, sel, lf, rt, ui, us, sub) MENU_LABEL(T), +#define S_BOOL_EX_NS(f, T, n, d, sd, df, c, ok, rp, sta, sel, lf, rt, ui, us) MENU_LABEL(T), +#define S_UINT_EX(f, T, n, d, sd, df, c, mn, mx, st, ob, ok, rp, sta, sel, lf, rt, ui, us, sub) MENU_LABEL(T), +#define S_UINT_EX_NS(f, T, n, d, sd, df, c, mn, mx, st, ob, ok, rp, sta, sel, lf, rt, ui, us) MENU_LABEL(T), +#define S_INT_EX(f, T, n, d, sd, df, c, mn, mx, st, ob, ok, rp, sta, sel, lf, rt, ui, us, sub) MENU_LABEL(T), +#define S_INT_EX_NS(f, T, n, d, sd, df, c, mn, mx, st, ob, ok, rp, sta, sel, lf, rt, ui, us) MENU_LABEL(T), +#define S_FLOAT_EX(f, T, n, d, rnd, sd, df, c, mn, mx, st, ok, rp, sta, sel, lf, rt, ui, us, sub) MENU_LABEL(T), +#define S_FLOAT_EX_NS(f, T, n, d, rnd, sd, df, c, mn, mx, st, ok, rp, sta, sel, lf, rt, ui, us) MENU_LABEL(T), +#define S_ACTION_EX(T, n, sd, ok, rp, c, us, sub) MENU_LABEL(T), +#define S_ACTION_EX_NS(T, n, sd, ok, rp, c, us) MENU_LABEL(T), +#define S_BOOL_H(f, T, n, d, sd, df, c, us, sub) MENU_LBL_H(T), +#define S_UINT_H(f, T, n, d, sd, df, c, mn, mx, st, ob, ok, rp, us, sub) MENU_LBL_H(T), +#define S_BOOL_NS_H(f, T, n, d, sd, df, c, us) MENU_LBL_H(T), +#define S_INT_H(f, T, n, d, sd, df, c, mn, mx, st, ob, ok, rp, us, sub) MENU_LBL_H(T), +#define S_FLOAT_H(f, T, n, d, rnd, sd, df, c, mn, mx, st, ok, rp, us, sub) MENU_LBL_H(T), +#define S_UINT_NS_H(f, T, n, d, sd, df, c, mn, mx, st, ob, ok, rp, us) MENU_LBL_H(T), +#define S_INT_NS_H(f, T, n, d, sd, df, c, mn, mx, st, ob, ok, rp, us) MENU_LBL_H(T), +#define S_FLOAT_NS_H(f, T, n, d, rnd, sd, df, c, mn, mx, st, ok, rp, us) MENU_LBL_H(T), +#define S_STRING_H(f, T, n, d, sd, c, ok, rp, sta, sel, lf, rt, ui, us, sub) MENU_LBL_H(T), +#define S_STRING_NS_H(f, T, n, d, sd, c, ok, rp, sta, sel, lf, rt, ui, us) MENU_LBL_H(T), +#define S_DIR_H(f, T, n, d, el, sd, c, sta, us, sub) MENU_LBL_H(T), +#define S_DIR_NS_H(f, T, n, d, el, sd, c, sta, us) MENU_LBL_H(T), +#define S_STRING_P_H(f, T, n, d, sd, c, ok, rp, sta, sel, lf, rt, ui, us, sub) MENU_LBL_H(T), +#define S_STRING_P_NS_H(f, T, n, d, sd, c, ok, rp, sta, sel, lf, rt, ui, us) MENU_LBL_H(T), +#define S_PATH_H(f, T, n, d, sd, c, vals, rp, ui, us, sub) MENU_LBL_H(T), +#define S_PATH_NS_H(f, T, n, d, sd, c, vals, rp, ui, us) MENU_LBL_H(T), +#define S_PATH_DS_H(f, T, n, df2, sd, c, vals, rp, ui, us, sub) MENU_LBL_H(T), +#define S_PATH_DS_NS_H(f, T, n, df2, sd, c, vals, rp, ui, us) MENU_LBL_H(T), +#define S_ACTION_H(T, n, us, sub) MENU_LBL_H(T), +#define S_ACTION_NS_H(T, n, us) MENU_LBL_H(T), +#define S_BOOL_EX_H(f, T, n, d, sd, df, c, ok, rp, sta, sel, lf, rt, ui, us, sub) MENU_LBL_H(T), +#define S_BOOL_EX_NS_H(f, T, n, d, sd, df, c, ok, rp, sta, sel, lf, rt, ui, us) MENU_LBL_H(T), +#define S_UINT_EX_H(f, T, n, d, sd, df, c, mn, mx, st, ob, ok, rp, sta, sel, lf, rt, ui, us, sub) MENU_LBL_H(T), +#define S_UINT_EX_NS_H(f, T, n, d, sd, df, c, mn, mx, st, ob, ok, rp, sta, sel, lf, rt, ui, us) MENU_LBL_H(T), +#define S_INT_EX_H(f, T, n, d, sd, df, c, mn, mx, st, ob, ok, rp, sta, sel, lf, rt, ui, us, sub) MENU_LBL_H(T), +#define S_INT_EX_NS_H(f, T, n, d, sd, df, c, mn, mx, st, ob, ok, rp, sta, sel, lf, rt, ui, us) MENU_LBL_H(T), +#define S_FLOAT_EX_H(f, T, n, d, rnd, sd, df, c, mn, mx, st, ok, rp, sta, sel, lf, rt, ui, us, sub) MENU_LBL_H(T), +#define S_FLOAT_EX_NS_H(f, T, n, d, rnd, sd, df, c, mn, mx, st, ok, rp, sta, sel, lf, rt, ui, us) MENU_LBL_H(T), +#define S_ACTION_EX_H(T, n, sd, ok, rp, c, us, sub) MENU_LBL_H(T), +#define S_ACTION_EX_NS_H(T, n, sd, ok, rp, c, us) MENU_LBL_H(T), +#include "settings/settings_def_nfs_client_opts.h" +#undef S_BOOL +#undef S_BOOL_NS +#undef S_UINT +#undef S_UINT_NS +#undef S_INT +#undef S_INT_NS +#undef S_FLOAT +#undef S_FLOAT_NS +#undef S_STRING +#undef S_STRING_NS +#undef S_STRING_H +#undef S_STRING_NS_H +#undef S_DIR +#undef S_DIR_NS +#undef S_DIR_H +#undef S_DIR_NS_H +#undef S_STRING_P +#undef S_STRING_P_NS +#undef S_STRING_P_H +#undef S_STRING_P_NS_H +#undef S_PATH +#undef S_PATH_NS +#undef S_PATH_H +#undef S_PATH_NS_H +#undef S_PATH_DS +#undef S_PATH_DS_NS +#undef S_PATH_DS_H +#undef S_PATH_DS_NS_H +#undef S_ACTION +#undef S_ACTION_NS +#undef S_ACTION_H +#undef S_ACTION_NS_H +#undef S_BOOL_EX +#undef S_BOOL_EX_NS +#undef S_BOOL_EX_H +#undef S_BOOL_EX_NS_H +#undef S_UINT_EX +#undef S_UINT_EX_NS +#undef S_UINT_EX_H +#undef S_UINT_EX_NS_H +#undef S_INT_EX +#undef S_INT_EX_NS +#undef S_INT_EX_H +#undef S_INT_EX_NS_H +#undef S_FLOAT_EX +#undef S_FLOAT_EX_NS +#undef S_FLOAT_EX_H +#undef S_FLOAT_EX_NS_H +#undef S_ACTION_EX +#undef S_ACTION_EX_NS +#undef S_ACTION_EX_H +#undef S_ACTION_EX_NS_H +#undef S_BOOL_H +#undef S_UINT_H +#undef S_BOOL_NS_H +#undef S_INT_H +#undef S_FLOAT_H +#undef S_UINT_NS_H +#undef S_INT_NS_H +#undef S_FLOAT_NS_H +#undef SETTINGS_DEF_STRINGS_PASS +#undef SETTINGS_DEF_ENUM_PASS + MENU_LABEL(NFS_CLIENT_SERVER), + MENU_LABEL(NFS_CLIENT_EXPORT), + MENU_LABEL(NFS_CLIENT_SUBDIR), + MENU_LABEL(NFS_CLIENT_BROWSE), + MENU_LABEL(NFS_CLIENT_NFS_SHARE), +#endif + MSG_LAST, /* Ensure sizeof(enum) == sizeof(int) */ diff --git a/msg_hash_lbl_str.h b/msg_hash_lbl_str.h index 057e9b8baacc..0ff623f4cfd4 100644 --- a/msg_hash_lbl_str.h +++ b/msg_hash_lbl_str.h @@ -915,6 +915,7 @@ #define MENU_ENUM_LABEL_MIXER_ACTION_VOLUME_STR "mixer_action_volume" #define MENU_ENUM_LABEL_CORE_GAME_AI_OPTIONS_STR "core_game_ai_options" #define MENU_ENUM_LABEL_DEFERRED_SMB_CLIENT_SETTINGS_LIST_STR "deferred_smb_client_settings_list" +#define MENU_ENUM_LABEL_SMB_CLIENT_SETTINGS_STR "smb_client_settings" #define MENU_ENUM_LABEL_SMB_CLIENT_SERVER_STR "smb_client_server" #define MENU_ENUM_LABEL_SMB_CLIENT_SHARE_STR "smb_client_share" #define MENU_ENUM_LABEL_SMB_CLIENT_SUBDIR_STR "smb_client_subdir" @@ -922,6 +923,12 @@ #define MENU_ENUM_LABEL_SMB_CLIENT_PASSWORD_STR "smb_client_password" #define MENU_ENUM_LABEL_SMB_CLIENT_WORKGROUP_STR "smb_client_workgroup" #define MENU_ENUM_LABEL_SMB_CLIENT_BROWSE_STR "smb_client_browse" +#define MENU_ENUM_LABEL_DEFERRED_NFS_CLIENT_SETTINGS_LIST_STR "deferred_nfs_client_settings_list" +#define MENU_ENUM_LABEL_NFS_CLIENT_SETTINGS_STR "nfs_client_settings" +#define MENU_ENUM_LABEL_NFS_CLIENT_SERVER_STR "nfs_client_server" +#define MENU_ENUM_LABEL_NFS_CLIENT_EXPORT_STR "nfs_client_export" +#define MENU_ENUM_LABEL_NFS_CLIENT_SUBDIR_STR "nfs_client_subdir" +#define MENU_ENUM_LABEL_NFS_CLIENT_BROWSE_STR "nfs_client_browse" /* GENERATED REGION BEGIN: settings-definition label strings * diff --git a/pkg/android/phoenix-common/jni/Android.mk b/pkg/android/phoenix-common/jni/Android.mk index 81c5af59483d..7b33f52530af 100644 --- a/pkg/android/phoenix-common/jni/Android.mk +++ b/pkg/android/phoenix-common/jni/Android.mk @@ -12,6 +12,7 @@ HAVE_FILE_LOGGER := 1 HAVE_GFX_WIDGETS := 1 HAVE_SAF := 1 HAVE_BUILTINSMBCLIENT := 1 +HAVE_BUILTINNFSCLIENT := 1 INCFLAGS := DEFINES := @@ -59,6 +60,36 @@ LOCAL_MODULE := retroarch-activity LOCAL_SRC_FILES += $(RARCH_DIR)/griffin/griffin.c \ $(RARCH_DIR)/griffin/griffin_cpp.cpp +# libnfs cannot live inside griffin (symbol clashes); compile as separate TUs. +ifeq ($(HAVE_BUILTINNFSCLIENT),1) +LOCAL_SRC_FILES += \ + $(RARCH_DIR)/deps/libnfs/lib/init.c \ + $(RARCH_DIR)/deps/libnfs/lib/krb5-wrapper.c \ + $(RARCH_DIR)/deps/libnfs/lib/libnfs.c \ + $(RARCH_DIR)/deps/libnfs/lib/libnfs-sync.c \ + $(RARCH_DIR)/deps/libnfs/lib/libnfs-zdr.c \ + $(RARCH_DIR)/deps/libnfs/lib/multithreading.c \ + $(RARCH_DIR)/deps/libnfs/lib/nfs_v3.c \ + $(RARCH_DIR)/deps/libnfs/lib/nfs_v4.c \ + $(RARCH_DIR)/deps/libnfs/lib/pdu.c \ + $(RARCH_DIR)/deps/libnfs/lib/socket.c \ + $(RARCH_DIR)/deps/libnfs/mount/mount.c \ + $(RARCH_DIR)/deps/libnfs/mount/libnfs-raw-mount.c \ + $(RARCH_DIR)/deps/libnfs/nfs/nfs.c \ + $(RARCH_DIR)/deps/libnfs/nfs/nfsacl.c \ + $(RARCH_DIR)/deps/libnfs/nfs/libnfs-raw-nfs.c \ + $(RARCH_DIR)/deps/libnfs/nfs4/nfs4.c \ + $(RARCH_DIR)/deps/libnfs/nfs4/libnfs-raw-nfs4.c \ + $(RARCH_DIR)/deps/libnfs/nlm/nlm.c \ + $(RARCH_DIR)/deps/libnfs/nlm/libnfs-raw-nlm.c \ + $(RARCH_DIR)/deps/libnfs/nsm/nsm.c \ + $(RARCH_DIR)/deps/libnfs/nsm/libnfs-raw-nsm.c \ + $(RARCH_DIR)/deps/libnfs/portmap/portmap.c \ + $(RARCH_DIR)/deps/libnfs/portmap/libnfs-raw-portmap.c \ + $(RARCH_DIR)/deps/libnfs/rquota/rquota.c \ + $(RARCH_DIR)/deps/libnfs/rquota/libnfs-raw-rquota.c +endif + ifeq ($(HAVE_BUILTINSMBCLIENT),1) DEFINES += -DHAVE_BUILTINSMBCLIENT DEFINES += "-D_U_=__attribute__((unused))" @@ -73,6 +104,23 @@ ifeq ($(HAVE_BUILTINSMBCLIENT),1) DEFINES += -DHAVE_SMBCLIENT endif +ifeq ($(HAVE_BUILTINNFSCLIENT),1) + DEFINES += -DHAVE_BUILTINNFSCLIENT -DHAVE_NFSCLIENT + DEFINES += "-D_U_=__attribute__((unused))" + DEFINES += -DHAVE_ARPA_INET_H -DHAVE_DLFCN_H -DHAVE_INTTYPES_H + DEFINES += -DHAVE_MEMORY_H -DHAVE_NETDB_H -DHAVE_NETINET_IN_H + DEFINES += -DHAVE_NETINET_TCP_H -DHAVE_NET_IF_H -DHAVE_POLL_H + DEFINES += -DHAVE_PWD_H -DHAVE_SOCKADDR_STORAGE -DHAVE_STDINT_H + DEFINES += -DHAVE_STDLIB_H -DHAVE_STDATOMIC_H -DHAVE_STRINGS_H + DEFINES += -DHAVE_STRING_H -DHAVE_SYS_IOCTL_H -DHAVE_SYS_STATVFS_H + DEFINES += -DHAVE_SYS_STAT_H -DHAVE_SYS_TIME_H -DHAVE_SYS_TYPES_H + DEFINES += -DHAVE_SYS_UIO_H -DHAVE_UNISTD_H -DHAVE_UTIME_H + DEFINES += -DHAVE_SIGNAL_H -DHAVE_SYS_UTSNAME_H -DSTDC_HEADERS + DEFINES += -DHAVE_CLOCK_GETTIME -DHAVE_STRUCT_STAT_ST_MTIM_TV_NSEC + # Bionic provides major()/minor() via sys/sysmacros.h (needed by nfs_v3/nfs_v4). + DEFINES += -DHAVE_SYS_SYSMACROS_H +endif + ifeq ($(HAVE_LOGGER), 1) DEFINES += -DHAVE_LOGGER endif @@ -213,6 +261,21 @@ ifeq ($(HAVE_CHEEVOS),1) INCLUDE_DIRS += -I$(LOCAL_PATH)/$(DEPS_DIR)/rcheevos/include endif +ifeq ($(HAVE_BUILTINNFSCLIENT),1) + # Prefer libnfs slist.h over libsmb2 when both are on the include path. + INCLUDE_DIRS += \ + -I$(LOCAL_PATH)/$(DEPS_DIR)/libnfs/include \ + -I$(LOCAL_PATH)/$(DEPS_DIR)/libnfs/include/nfsc \ + -I$(LOCAL_PATH)/$(DEPS_DIR)/libnfs \ + -I$(LOCAL_PATH)/$(DEPS_DIR)/libnfs/mount \ + -I$(LOCAL_PATH)/$(DEPS_DIR)/libnfs/nfs \ + -I$(LOCAL_PATH)/$(DEPS_DIR)/libnfs/nfs4 \ + -I$(LOCAL_PATH)/$(DEPS_DIR)/libnfs/nlm \ + -I$(LOCAL_PATH)/$(DEPS_DIR)/libnfs/nsm \ + -I$(LOCAL_PATH)/$(DEPS_DIR)/libnfs/portmap \ + -I$(LOCAL_PATH)/$(DEPS_DIR)/libnfs/rquota +endif + ifeq ($(HAVE_BUILTINSMBCLIENT),1) INCLUDE_DIRS += \ -I$(LOCAL_PATH)/$(DEPS_DIR)/libsmb2/include \ diff --git a/pkg/apple/BaseConfig.xcconfig b/pkg/apple/BaseConfig.xcconfig index a5b0e9623eca..7ea92d78b227 100644 --- a/pkg/apple/BaseConfig.xcconfig +++ b/pkg/apple/BaseConfig.xcconfig @@ -59,6 +59,19 @@ OTHER_CFLAGS = $(inherited) -DHAVE_NETPLAYDISCOVERY_NSNET OTHER_CFLAGS = $(inherited) -DHAVE_NETWORKGAMEPAD OTHER_CFLAGS = $(inherited) -DHAVE_NETWORKING OTHER_CFLAGS = $(inherited) -DHAVE_NETWORK_CMD +// Bundled libnfs is compiled as separate sources in Metal + iOS13 Xcode projects. +OTHER_CFLAGS = $(inherited) -DHAVE_NFSCLIENT -DHAVE_BUILTINNFSCLIENT +OTHER_CFLAGS = $(inherited) -D_U_=__attribute__((unused)) +OTHER_CFLAGS = $(inherited) -DHAVE_ARPA_INET_H -DHAVE_DLFCN_H -DHAVE_INTTYPES_H +OTHER_CFLAGS = $(inherited) -DHAVE_MEMORY_H -DHAVE_NETDB_H -DHAVE_NETINET_IN_H +OTHER_CFLAGS = $(inherited) -DHAVE_NETINET_TCP_H -DHAVE_NET_IF_H -DHAVE_POLL_H +OTHER_CFLAGS = $(inherited) -DHAVE_PWD_H -DHAVE_SOCKADDR_STORAGE -DHAVE_STDINT_H +OTHER_CFLAGS = $(inherited) -DHAVE_STDLIB_H -DHAVE_STDATOMIC_H -DHAVE_STRINGS_H +OTHER_CFLAGS = $(inherited) -DHAVE_STRING_H -DHAVE_SYS_IOCTL_H -DHAVE_SYS_STATVFS_H +OTHER_CFLAGS = $(inherited) -DHAVE_SYS_STAT_H -DHAVE_SYS_TIME_H -DHAVE_SYS_TYPES_H +OTHER_CFLAGS = $(inherited) -DHAVE_SYS_UIO_H -DHAVE_UNISTD_H -DHAVE_UTIME_H +OTHER_CFLAGS = $(inherited) -DHAVE_SIGNAL_H -DHAVE_SYS_UTSNAME_H -DSTDC_HEADERS +OTHER_CFLAGS[sdk=macosx*] = $(inherited) -DHAVE_SOCKADDR_LEN -DHAVE_SYS_FILIO_H OTHER_CFLAGS = $(inherited) OTHER_CFLAGS = $(inherited) -DHAVE_OPENGL OTHER_CFLAGS = $(inherited) -DHAVE_OVERLAY @@ -172,10 +185,22 @@ HEADER_SEARCH_PATHS = $(inherited) $(GLSLANG_BUILTIN_HEADER_SEARCH_PATHS) HEADER_SEARCH_PATHS = $(inherited) $(DEPS_DIR)/rcheevos/include HEADER_SEARCH_PATHS = $(inherited) $(DEPS_DIR)/stb HEADER_SEARCH_PATHS = $(inherited) $(DEPS_DIR)/zstd/lib +HEADER_SEARCH_PATHS = $(inherited) $(DEPS_DIR)/libnfs/include +HEADER_SEARCH_PATHS = $(inherited) $(DEPS_DIR)/libnfs/include/nfsc +HEADER_SEARCH_PATHS = $(inherited) $(DEPS_DIR)/libnfs +HEADER_SEARCH_PATHS = $(inherited) $(DEPS_DIR)/libnfs/mount +HEADER_SEARCH_PATHS = $(inherited) $(DEPS_DIR)/libnfs/nfs +HEADER_SEARCH_PATHS = $(inherited) $(DEPS_DIR)/libnfs/nfs4 +HEADER_SEARCH_PATHS = $(inherited) $(DEPS_DIR)/libnfs/nlm +HEADER_SEARCH_PATHS = $(inherited) $(DEPS_DIR)/libnfs/nsm +HEADER_SEARCH_PATHS = $(inherited) $(DEPS_DIR)/libnfs/portmap +HEADER_SEARCH_PATHS = $(inherited) $(DEPS_DIR)/libnfs/rquota HEADER_SEARCH_PATHS = $(inherited) $(SRCBASE) HEADER_SEARCH_PATHS = $(inherited) $(SRCBASE)/gfx/include HEADER_SEARCH_PATHS = $(inherited) $(SRCBASE)/libretro-common/include +// libsmb2 griffin needs typeof (GNU C); Metal project previously used c99. +GCC_C_LANGUAGE_STANDARD = gnu99 CLANG_CXX_LANGUAGE_STANDARD=c++11 CLANG_ENABLE_OBJC_ARC=YES INFOPLIST_FILE[sdk=macosx*] = $(SRCROOT)/OSX/Info_Metal.plist diff --git a/pkg/apple/RetroArch_Metal.xcodeproj/project.pbxproj b/pkg/apple/RetroArch_Metal.xcodeproj/project.pbxproj index a00476c7f8a7..0d1d89a71f69 100644 --- a/pkg/apple/RetroArch_Metal.xcodeproj/project.pbxproj +++ b/pkg/apple/RetroArch_Metal.xcodeproj/project.pbxproj @@ -7,6 +7,31 @@ objects = { /* Begin PBXBuildFile section */ + CCF17BAC5FAE75FA1ADF9F0B /* init.c in Sources */ = {isa = PBXBuildFile; fileRef = ECBDC9AC2813EE2EBA0469FB /* init.c */; }; + 8568F9F8CFFE9F69F9FAA5D7 /* krb5-wrapper.c in Sources */ = {isa = PBXBuildFile; fileRef = C6AD76F7F56DC777A8B6EDAE /* krb5-wrapper.c */; }; + 62452F462BAB1E07961A8D79 /* libnfs.c in Sources */ = {isa = PBXBuildFile; fileRef = E943D456AB9CCEC8BFBF991B /* libnfs.c */; }; + 2D80D6D8F92EFFD084F5E3E3 /* libnfs-sync.c in Sources */ = {isa = PBXBuildFile; fileRef = D63B317B7CE22496A7B70CD1 /* libnfs-sync.c */; }; + 5C66F3E4CBB253CD8F3D01C8 /* libnfs-zdr.c in Sources */ = {isa = PBXBuildFile; fileRef = 5716EB128756B8E21BF437E1 /* libnfs-zdr.c */; }; + 2B37D85CEA471EE0FF8A18EE /* multithreading.c in Sources */ = {isa = PBXBuildFile; fileRef = A8DD6DADA4082CDB789A2AE2 /* multithreading.c */; }; + 8AE70AB4D0BED53ADC35FEB9 /* nfs_v3.c in Sources */ = {isa = PBXBuildFile; fileRef = 7DBD8A19FDBA553170DD7378 /* nfs_v3.c */; }; + ABF722C446785EECFD6AD129 /* nfs_v4.c in Sources */ = {isa = PBXBuildFile; fileRef = D58C8962D257184F5085EDD2 /* nfs_v4.c */; }; + BE57636517D8988DE69FBE6A /* pdu.c in Sources */ = {isa = PBXBuildFile; fileRef = 120029DDBBD268167878D777 /* pdu.c */; }; + 6985077789CCC8637BD8DFC2 /* socket.c in Sources */ = {isa = PBXBuildFile; fileRef = 41854C3DF8BA07453776C581 /* socket.c */; }; + AAB8FD314477E1F183AD7E76 /* mount.c in Sources */ = {isa = PBXBuildFile; fileRef = 8279AB18DDB557B50F328038 /* mount.c */; }; + C95238A33FFFA7DFBE6F1029 /* libnfs-raw-mount.c in Sources */ = {isa = PBXBuildFile; fileRef = 6479602196531BFEC7D14BB6 /* libnfs-raw-mount.c */; }; + B3F1A3EAD66E02320186E55B /* nfs.c in Sources */ = {isa = PBXBuildFile; fileRef = 4D483CD108E398D722275C3A /* nfs.c */; }; + D1C7B995FFEADDF6D86F9217 /* nfsacl.c in Sources */ = {isa = PBXBuildFile; fileRef = 1D75EC188F34484371CAECBA /* nfsacl.c */; }; + D3B6C6D7BD022B9F7CD1D856 /* libnfs-raw-nfs.c in Sources */ = {isa = PBXBuildFile; fileRef = 9D0E8F85884616E28ECE6DA4 /* libnfs-raw-nfs.c */; }; + 6052622F489C8A49038DDF42 /* nfs4.c in Sources */ = {isa = PBXBuildFile; fileRef = EE9EFFA7748E2029A2DF6F1A /* nfs4.c */; }; + B5D3C8B75AD0F389531EB492 /* libnfs-raw-nfs4.c in Sources */ = {isa = PBXBuildFile; fileRef = 11038DB847202921AC6D2058 /* libnfs-raw-nfs4.c */; }; + 892B9F8DFB264D976D51335C /* nlm.c in Sources */ = {isa = PBXBuildFile; fileRef = 72B1C067884958D102A12C49 /* nlm.c */; }; + ACEF6876CC58F30ABE779508 /* libnfs-raw-nlm.c in Sources */ = {isa = PBXBuildFile; fileRef = BA7AB15F877BCEB95F2AD16E /* libnfs-raw-nlm.c */; }; + 97C410CFD0389903D7A9C76D /* nsm.c in Sources */ = {isa = PBXBuildFile; fileRef = AD995D9BDD767D1DCA542FA3 /* nsm.c */; }; + 4C471E479DFA1FC79B215ADF /* libnfs-raw-nsm.c in Sources */ = {isa = PBXBuildFile; fileRef = 14E40989A3A0E011CE4EE18E /* libnfs-raw-nsm.c */; }; + 769A75E9F8590B95DE7B18BB /* portmap.c in Sources */ = {isa = PBXBuildFile; fileRef = 6E1FA1349F9855BE032E0037 /* portmap.c */; }; + 850A65ECBD6BF82B5C4A34D6 /* libnfs-raw-portmap.c in Sources */ = {isa = PBXBuildFile; fileRef = D472C56011026462DFA4F148 /* libnfs-raw-portmap.c */; }; + 5D85E37159419A6A890E4ADB /* rquota.c in Sources */ = {isa = PBXBuildFile; fileRef = BD5D36879215B3D8723D5723 /* rquota.c */; }; + BC842F834279D3E686163BDE /* libnfs-raw-rquota.c in Sources */ = {isa = PBXBuildFile; fileRef = 439817A721DFAE0C46BFC194 /* libnfs-raw-rquota.c */; }; 05269A6220ABF20500C29F1E /* MetalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 05269A6120ABF20500C29F1E /* MetalKit.framework */; }; 053FC26521433F2200D98D46 /* QtWidgets.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 053FC25721433F1800D98D46 /* QtWidgets.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 053FC270214340F500D98D46 /* QtGui.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 053FC25321433F1700D98D46 /* QtGui.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; @@ -164,6 +189,31 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + ECBDC9AC2813EE2EBA0469FB /* init.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = init.c; path = ../../deps/libnfs/lib/init.c; sourceTree = ""; }; + C6AD76F7F56DC777A8B6EDAE /* krb5-wrapper.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = krb5-wrapper.c; path = ../../deps/libnfs/lib/krb5-wrapper.c; sourceTree = ""; }; + E943D456AB9CCEC8BFBF991B /* libnfs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = libnfs.c; path = ../../deps/libnfs/lib/libnfs.c; sourceTree = ""; }; + D63B317B7CE22496A7B70CD1 /* libnfs-sync.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = libnfs-sync.c; path = ../../deps/libnfs/lib/libnfs-sync.c; sourceTree = ""; }; + 5716EB128756B8E21BF437E1 /* libnfs-zdr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = libnfs-zdr.c; path = ../../deps/libnfs/lib/libnfs-zdr.c; sourceTree = ""; }; + A8DD6DADA4082CDB789A2AE2 /* multithreading.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = multithreading.c; path = ../../deps/libnfs/lib/multithreading.c; sourceTree = ""; }; + 7DBD8A19FDBA553170DD7378 /* nfs_v3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = nfs_v3.c; path = ../../deps/libnfs/lib/nfs_v3.c; sourceTree = ""; }; + D58C8962D257184F5085EDD2 /* nfs_v4.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = nfs_v4.c; path = ../../deps/libnfs/lib/nfs_v4.c; sourceTree = ""; }; + 120029DDBBD268167878D777 /* pdu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pdu.c; path = ../../deps/libnfs/lib/pdu.c; sourceTree = ""; }; + 41854C3DF8BA07453776C581 /* socket.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = socket.c; path = ../../deps/libnfs/lib/socket.c; sourceTree = ""; }; + 8279AB18DDB557B50F328038 /* mount.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mount.c; path = ../../deps/libnfs/mount/mount.c; sourceTree = ""; }; + 6479602196531BFEC7D14BB6 /* libnfs-raw-mount.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = libnfs-raw-mount.c; path = ../../deps/libnfs/mount/libnfs-raw-mount.c; sourceTree = ""; }; + 4D483CD108E398D722275C3A /* nfs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = nfs.c; path = ../../deps/libnfs/nfs/nfs.c; sourceTree = ""; }; + 1D75EC188F34484371CAECBA /* nfsacl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = nfsacl.c; path = ../../deps/libnfs/nfs/nfsacl.c; sourceTree = ""; }; + 9D0E8F85884616E28ECE6DA4 /* libnfs-raw-nfs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = libnfs-raw-nfs.c; path = ../../deps/libnfs/nfs/libnfs-raw-nfs.c; sourceTree = ""; }; + EE9EFFA7748E2029A2DF6F1A /* nfs4.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = nfs4.c; path = ../../deps/libnfs/nfs4/nfs4.c; sourceTree = ""; }; + 11038DB847202921AC6D2058 /* libnfs-raw-nfs4.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = libnfs-raw-nfs4.c; path = ../../deps/libnfs/nfs4/libnfs-raw-nfs4.c; sourceTree = ""; }; + 72B1C067884958D102A12C49 /* nlm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = nlm.c; path = ../../deps/libnfs/nlm/nlm.c; sourceTree = ""; }; + BA7AB15F877BCEB95F2AD16E /* libnfs-raw-nlm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = libnfs-raw-nlm.c; path = ../../deps/libnfs/nlm/libnfs-raw-nlm.c; sourceTree = ""; }; + AD995D9BDD767D1DCA542FA3 /* nsm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = nsm.c; path = ../../deps/libnfs/nsm/nsm.c; sourceTree = ""; }; + 14E40989A3A0E011CE4EE18E /* libnfs-raw-nsm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = libnfs-raw-nsm.c; path = ../../deps/libnfs/nsm/libnfs-raw-nsm.c; sourceTree = ""; }; + 6E1FA1349F9855BE032E0037 /* portmap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = portmap.c; path = ../../deps/libnfs/portmap/portmap.c; sourceTree = ""; }; + D472C56011026462DFA4F148 /* libnfs-raw-portmap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = libnfs-raw-portmap.c; path = ../../deps/libnfs/portmap/libnfs-raw-portmap.c; sourceTree = ""; }; + BD5D36879215B3D8723D5723 /* rquota.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = rquota.c; path = ../../deps/libnfs/rquota/rquota.c; sourceTree = ""; }; + 439817A721DFAE0C46BFC194 /* libnfs-raw-rquota.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = libnfs-raw-rquota.c; path = ../../deps/libnfs/rquota/libnfs-raw-rquota.c; sourceTree = ""; }; 05269A6120ABF20500C29F1E /* MetalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MetalKit.framework; path = System/Library/Frameworks/MetalKit.framework; sourceTree = SDKROOT; }; 0538874D20DDD5C600769232 /* dxgi_common.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = dxgi_common.c; sourceTree = ""; }; 0538874E20DDD5C600769232 /* dxgi_common.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = dxgi_common.h; sourceTree = ""; }; @@ -600,6 +650,38 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + B8C809D291DF935ACD5B3AC7 /* libnfs */ = { + isa = PBXGroup; + children = ( + ECBDC9AC2813EE2EBA0469FB /* init.c */, + C6AD76F7F56DC777A8B6EDAE /* krb5-wrapper.c */, + E943D456AB9CCEC8BFBF991B /* libnfs.c */, + D63B317B7CE22496A7B70CD1 /* libnfs-sync.c */, + 5716EB128756B8E21BF437E1 /* libnfs-zdr.c */, + A8DD6DADA4082CDB789A2AE2 /* multithreading.c */, + 7DBD8A19FDBA553170DD7378 /* nfs_v3.c */, + D58C8962D257184F5085EDD2 /* nfs_v4.c */, + 120029DDBBD268167878D777 /* pdu.c */, + 41854C3DF8BA07453776C581 /* socket.c */, + 8279AB18DDB557B50F328038 /* mount.c */, + 6479602196531BFEC7D14BB6 /* libnfs-raw-mount.c */, + 4D483CD108E398D722275C3A /* nfs.c */, + 1D75EC188F34484371CAECBA /* nfsacl.c */, + 9D0E8F85884616E28ECE6DA4 /* libnfs-raw-nfs.c */, + EE9EFFA7748E2029A2DF6F1A /* nfs4.c */, + 11038DB847202921AC6D2058 /* libnfs-raw-nfs4.c */, + 72B1C067884958D102A12C49 /* nlm.c */, + BA7AB15F877BCEB95F2AD16E /* libnfs-raw-nlm.c */, + AD995D9BDD767D1DCA542FA3 /* nsm.c */, + 14E40989A3A0E011CE4EE18E /* libnfs-raw-nsm.c */, + 6E1FA1349F9855BE032E0037 /* portmap.c */, + D472C56011026462DFA4F148 /* libnfs-raw-portmap.c */, + BD5D36879215B3D8723D5723 /* rquota.c */, + 439817A721DFAE0C46BFC194 /* libnfs-raw-rquota.c */, + ); + name = libnfs; + sourceTree = ""; + }; 05366511213F8BE5007E7EA0 /* qt */ = { isa = PBXGroup; children = ( @@ -1330,6 +1412,7 @@ children = ( 509F0C9C1AA23AFC00619ECC /* griffin_objc.m */, 840222FB1A889EE2009AB261 /* griffin.c */, + B8C809D291DF935ACD5B3AC7 /* libnfs */, 05D7753320A5678300646447 /* griffin_cpp.cpp */, 05D7753420A5678400646447 /* griffin_glslang.cpp */, ); @@ -1655,6 +1738,31 @@ 05422E452140C8DB00F09961 /* griffin_cpp.cpp in Sources */, 05422E462140C8DB00F09961 /* griffin_objc.m in Sources */, 05422E472140C8DB00F09961 /* griffin.c in Sources */, + CCF17BAC5FAE75FA1ADF9F0B /* init.c in Sources */, + 8568F9F8CFFE9F69F9FAA5D7 /* krb5-wrapper.c in Sources */, + 62452F462BAB1E07961A8D79 /* libnfs.c in Sources */, + 2D80D6D8F92EFFD084F5E3E3 /* libnfs-sync.c in Sources */, + 5C66F3E4CBB253CD8F3D01C8 /* libnfs-zdr.c in Sources */, + 2B37D85CEA471EE0FF8A18EE /* multithreading.c in Sources */, + 8AE70AB4D0BED53ADC35FEB9 /* nfs_v3.c in Sources */, + ABF722C446785EECFD6AD129 /* nfs_v4.c in Sources */, + BE57636517D8988DE69FBE6A /* pdu.c in Sources */, + 6985077789CCC8637BD8DFC2 /* socket.c in Sources */, + AAB8FD314477E1F183AD7E76 /* mount.c in Sources */, + C95238A33FFFA7DFBE6F1029 /* libnfs-raw-mount.c in Sources */, + B3F1A3EAD66E02320186E55B /* nfs.c in Sources */, + D1C7B995FFEADDF6D86F9217 /* nfsacl.c in Sources */, + D3B6C6D7BD022B9F7CD1D856 /* libnfs-raw-nfs.c in Sources */, + 6052622F489C8A49038DDF42 /* nfs4.c in Sources */, + B5D3C8B75AD0F389531EB492 /* libnfs-raw-nfs4.c in Sources */, + 892B9F8DFB264D976D51335C /* nlm.c in Sources */, + ACEF6876CC58F30ABE779508 /* libnfs-raw-nlm.c in Sources */, + 97C410CFD0389903D7A9C76D /* nsm.c in Sources */, + 4C471E479DFA1FC79B215ADF /* libnfs-raw-nsm.c in Sources */, + 769A75E9F8590B95DE7B18BB /* portmap.c in Sources */, + 850A65ECBD6BF82B5C4A34D6 /* libnfs-raw-portmap.c in Sources */, + 5D85E37159419A6A890E4ADB /* rquota.c in Sources */, + BC842F834279D3E686163BDE /* libnfs-raw-rquota.c in Sources */, 05422E482140C8DB00F09961 /* Shaders.metal in Sources */, 0798404C2E0F218D0079E1A3 /* huf_decompress_amd64.S in Sources */, ); @@ -1670,6 +1778,31 @@ 0720994629B1258C001642BB /* griffin_cpp.cpp in Sources */, 0720994729B1258C001642BB /* griffin_objc.m in Sources */, 0720994829B1258C001642BB /* griffin.c in Sources */, + CCF17BAC5FAE75FA1ADF9F0B /* init.c in Sources */, + 8568F9F8CFFE9F69F9FAA5D7 /* krb5-wrapper.c in Sources */, + 62452F462BAB1E07961A8D79 /* libnfs.c in Sources */, + 2D80D6D8F92EFFD084F5E3E3 /* libnfs-sync.c in Sources */, + 5C66F3E4CBB253CD8F3D01C8 /* libnfs-zdr.c in Sources */, + 2B37D85CEA471EE0FF8A18EE /* multithreading.c in Sources */, + 8AE70AB4D0BED53ADC35FEB9 /* nfs_v3.c in Sources */, + ABF722C446785EECFD6AD129 /* nfs_v4.c in Sources */, + BE57636517D8988DE69FBE6A /* pdu.c in Sources */, + 6985077789CCC8637BD8DFC2 /* socket.c in Sources */, + AAB8FD314477E1F183AD7E76 /* mount.c in Sources */, + C95238A33FFFA7DFBE6F1029 /* libnfs-raw-mount.c in Sources */, + B3F1A3EAD66E02320186E55B /* nfs.c in Sources */, + D1C7B995FFEADDF6D86F9217 /* nfsacl.c in Sources */, + D3B6C6D7BD022B9F7CD1D856 /* libnfs-raw-nfs.c in Sources */, + 6052622F489C8A49038DDF42 /* nfs4.c in Sources */, + B5D3C8B75AD0F389531EB492 /* libnfs-raw-nfs4.c in Sources */, + 892B9F8DFB264D976D51335C /* nlm.c in Sources */, + ACEF6876CC58F30ABE779508 /* libnfs-raw-nlm.c in Sources */, + 97C410CFD0389903D7A9C76D /* nsm.c in Sources */, + 4C471E479DFA1FC79B215ADF /* libnfs-raw-nsm.c in Sources */, + 769A75E9F8590B95DE7B18BB /* portmap.c in Sources */, + 850A65ECBD6BF82B5C4A34D6 /* libnfs-raw-portmap.c in Sources */, + 5D85E37159419A6A890E4ADB /* rquota.c in Sources */, + BC842F834279D3E686163BDE /* libnfs-raw-rquota.c in Sources */, 0720994929B1258C001642BB /* Shaders.metal in Sources */, 0798404D2E0F21910079E1A3 /* huf_decompress_amd64.S in Sources */, ); @@ -1685,6 +1818,31 @@ 07F2BBCE2BE83A4700FD1295 /* griffin_cpp.cpp in Sources */, 07F2BBCF2BE83A4700FD1295 /* griffin_objc.m in Sources */, 07F2BBD02BE83A4700FD1295 /* griffin.c in Sources */, + CCF17BAC5FAE75FA1ADF9F0B /* init.c in Sources */, + 8568F9F8CFFE9F69F9FAA5D7 /* krb5-wrapper.c in Sources */, + 62452F462BAB1E07961A8D79 /* libnfs.c in Sources */, + 2D80D6D8F92EFFD084F5E3E3 /* libnfs-sync.c in Sources */, + 5C66F3E4CBB253CD8F3D01C8 /* libnfs-zdr.c in Sources */, + 2B37D85CEA471EE0FF8A18EE /* multithreading.c in Sources */, + 8AE70AB4D0BED53ADC35FEB9 /* nfs_v3.c in Sources */, + ABF722C446785EECFD6AD129 /* nfs_v4.c in Sources */, + BE57636517D8988DE69FBE6A /* pdu.c in Sources */, + 6985077789CCC8637BD8DFC2 /* socket.c in Sources */, + AAB8FD314477E1F183AD7E76 /* mount.c in Sources */, + C95238A33FFFA7DFBE6F1029 /* libnfs-raw-mount.c in Sources */, + B3F1A3EAD66E02320186E55B /* nfs.c in Sources */, + D1C7B995FFEADDF6D86F9217 /* nfsacl.c in Sources */, + D3B6C6D7BD022B9F7CD1D856 /* libnfs-raw-nfs.c in Sources */, + 6052622F489C8A49038DDF42 /* nfs4.c in Sources */, + B5D3C8B75AD0F389531EB492 /* libnfs-raw-nfs4.c in Sources */, + 892B9F8DFB264D976D51335C /* nlm.c in Sources */, + ACEF6876CC58F30ABE779508 /* libnfs-raw-nlm.c in Sources */, + 97C410CFD0389903D7A9C76D /* nsm.c in Sources */, + 4C471E479DFA1FC79B215ADF /* libnfs-raw-nsm.c in Sources */, + 769A75E9F8590B95DE7B18BB /* portmap.c in Sources */, + 850A65ECBD6BF82B5C4A34D6 /* libnfs-raw-portmap.c in Sources */, + 5D85E37159419A6A890E4ADB /* rquota.c in Sources */, + BC842F834279D3E686163BDE /* libnfs-raw-rquota.c in Sources */, 07F2BBD12BE83A4700FD1295 /* Shaders.metal in Sources */, 0798404E2E0F21960079E1A3 /* huf_decompress_amd64.S in Sources */, ); @@ -1700,6 +1858,31 @@ 05D7753520A567A400646447 /* griffin_cpp.cpp in Sources */, 509F0C9D1AA23AFC00619ECC /* griffin_objc.m in Sources */, 840222FC1A889EE2009AB261 /* griffin.c in Sources */, + CCF17BAC5FAE75FA1ADF9F0B /* init.c in Sources */, + 8568F9F8CFFE9F69F9FAA5D7 /* krb5-wrapper.c in Sources */, + 62452F462BAB1E07961A8D79 /* libnfs.c in Sources */, + 2D80D6D8F92EFFD084F5E3E3 /* libnfs-sync.c in Sources */, + 5C66F3E4CBB253CD8F3D01C8 /* libnfs-zdr.c in Sources */, + 2B37D85CEA471EE0FF8A18EE /* multithreading.c in Sources */, + 8AE70AB4D0BED53ADC35FEB9 /* nfs_v3.c in Sources */, + ABF722C446785EECFD6AD129 /* nfs_v4.c in Sources */, + BE57636517D8988DE69FBE6A /* pdu.c in Sources */, + 6985077789CCC8637BD8DFC2 /* socket.c in Sources */, + AAB8FD314477E1F183AD7E76 /* mount.c in Sources */, + C95238A33FFFA7DFBE6F1029 /* libnfs-raw-mount.c in Sources */, + B3F1A3EAD66E02320186E55B /* nfs.c in Sources */, + D1C7B995FFEADDF6D86F9217 /* nfsacl.c in Sources */, + D3B6C6D7BD022B9F7CD1D856 /* libnfs-raw-nfs.c in Sources */, + 6052622F489C8A49038DDF42 /* nfs4.c in Sources */, + B5D3C8B75AD0F389531EB492 /* libnfs-raw-nfs4.c in Sources */, + 892B9F8DFB264D976D51335C /* nlm.c in Sources */, + ACEF6876CC58F30ABE779508 /* libnfs-raw-nlm.c in Sources */, + 97C410CFD0389903D7A9C76D /* nsm.c in Sources */, + 4C471E479DFA1FC79B215ADF /* libnfs-raw-nsm.c in Sources */, + 769A75E9F8590B95DE7B18BB /* portmap.c in Sources */, + 850A65ECBD6BF82B5C4A34D6 /* libnfs-raw-portmap.c in Sources */, + 5D85E37159419A6A890E4ADB /* rquota.c in Sources */, + BC842F834279D3E686163BDE /* libnfs-raw-rquota.c in Sources */, 05A8C7B420DB75A500FF7857 /* Shaders.metal in Sources */, 0798404B2E0F21380079E1A3 /* huf_decompress_amd64.S in Sources */, ); @@ -1908,7 +2091,7 @@ ENABLE_HARDENED_RUNTIME = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = c99; + GCC_C_LANGUAGE_STANDARD = gnu99; GCC_MODEL_TUNING = G5; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; @@ -1988,7 +2171,7 @@ DEVELOPMENT_TEAM = UK699V5ZS8; ENABLE_HARDENED_RUNTIME = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = c99; + GCC_C_LANGUAGE_STANDARD = gnu99; GCC_MODEL_TUNING = G5; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 3; diff --git a/pkg/apple/RetroArch_iOS13.xcodeproj/project.pbxproj b/pkg/apple/RetroArch_iOS13.xcodeproj/project.pbxproj index 799078794cf3..975a6a0c9073 100644 --- a/pkg/apple/RetroArch_iOS13.xcodeproj/project.pbxproj +++ b/pkg/apple/RetroArch_iOS13.xcodeproj/project.pbxproj @@ -21,6 +21,56 @@ /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ + DCA144C1F2D0669C4F8615A8 /* init.c in Sources */ = {isa = PBXBuildFile; fileRef = 37409E73AF4D2A7313805071 /* init.c */; }; + 89F6FA3282CC1AB62E51EE33 /* krb5-wrapper.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5E88148F17A4D04FC6290E /* krb5-wrapper.c */; }; + D26FDEBB2C87A3A8AE5B3AC5 /* libnfs.c in Sources */ = {isa = PBXBuildFile; fileRef = 545E1C54835F0C9466747BFD /* libnfs.c */; }; + 041B1BC56F626891766D9083 /* libnfs-sync.c in Sources */ = {isa = PBXBuildFile; fileRef = EC88DFF5AF97A4609C577863 /* libnfs-sync.c */; }; + 418020E21A59481CE75C3728 /* libnfs-zdr.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C531BC14A9F4A2989AEF07A /* libnfs-zdr.c */; }; + DF50F27A06FD677977D40575 /* multithreading.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A871E15A332DD97395DDDCF /* multithreading.c */; }; + 5CC20C7F47DAABE4BC701782 /* nfs_v3.c in Sources */ = {isa = PBXBuildFile; fileRef = 8D614F075482BDFFBDD74AB0 /* nfs_v3.c */; }; + C94F3B7AC904063AC38CBCAF /* nfs_v4.c in Sources */ = {isa = PBXBuildFile; fileRef = 71D0FCC74D9B4466506512D6 /* nfs_v4.c */; }; + 7A536987DA7775A1A9748656 /* pdu.c in Sources */ = {isa = PBXBuildFile; fileRef = B12C2A0F2307A8FCE2FFCEF4 /* pdu.c */; }; + C8182809F45E6C523693B8D9 /* socket.c in Sources */ = {isa = PBXBuildFile; fileRef = 8C8E159EF44B056138D00F34 /* socket.c */; }; + EF71BDF9277DC80E468EDF72 /* mount.c in Sources */ = {isa = PBXBuildFile; fileRef = 0F31C03F2498645681C90418 /* mount.c */; }; + 1162D1ABE19B0F9C531AAFF0 /* libnfs-raw-mount.c in Sources */ = {isa = PBXBuildFile; fileRef = F0F9D8060F15213897A5162D /* libnfs-raw-mount.c */; }; + 0F09608340640B30796D86B7 /* nfs.c in Sources */ = {isa = PBXBuildFile; fileRef = 48BD13171876EEE72F4A88ED /* nfs.c */; }; + 0ADB1372000910DC48F6EF20 /* nfsacl.c in Sources */ = {isa = PBXBuildFile; fileRef = A114EEE68059D5FA1643289F /* nfsacl.c */; }; + DC84BC69FCCC792B4DE15031 /* libnfs-raw-nfs.c in Sources */ = {isa = PBXBuildFile; fileRef = CCA3A9C801DDFF74E4BB42CC /* libnfs-raw-nfs.c */; }; + 989A1AA91C0411610F80B78A /* nfs4.c in Sources */ = {isa = PBXBuildFile; fileRef = E08369CC0F41405AD973F3ED /* nfs4.c */; }; + 39A8F3361B503ECF77B6C017 /* libnfs-raw-nfs4.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B4C49D06B9F13B7EA0F2F24 /* libnfs-raw-nfs4.c */; }; + 2C1BAEA5A6BE170549F862D5 /* nlm.c in Sources */ = {isa = PBXBuildFile; fileRef = 706E99A264F1571BB02F25B6 /* nlm.c */; }; + 317CDE8E134F77BCD9BC4A65 /* libnfs-raw-nlm.c in Sources */ = {isa = PBXBuildFile; fileRef = 29FD8205A478A6E4054E6561 /* libnfs-raw-nlm.c */; }; + 3BB4913DD1C6BFAA2559339C /* nsm.c in Sources */ = {isa = PBXBuildFile; fileRef = 9B9A3C5364EC6312EB6DD58F /* nsm.c */; }; + D8FCADC70C6613761C04D74B /* libnfs-raw-nsm.c in Sources */ = {isa = PBXBuildFile; fileRef = 06245C5082B4C280FF2AA008 /* libnfs-raw-nsm.c */; }; + B7A577B77C7C8E97A90A55CC /* portmap.c in Sources */ = {isa = PBXBuildFile; fileRef = 67326B7F9BE081ACCE736946 /* portmap.c */; }; + 553019B6E138785D5644B255 /* libnfs-raw-portmap.c in Sources */ = {isa = PBXBuildFile; fileRef = 8B21CEA0A0AE6F808C9922A1 /* libnfs-raw-portmap.c */; }; + 5C011FFD85E2EEA1A46828D9 /* rquota.c in Sources */ = {isa = PBXBuildFile; fileRef = C8AA87DBE34ECD2F80074EAF /* rquota.c */; }; + A07BC8706552BBF254892BA6 /* libnfs-raw-rquota.c in Sources */ = {isa = PBXBuildFile; fileRef = C5E1410D2342740F67D4F105 /* libnfs-raw-rquota.c */; }; + 1E3143E3071829B8E99A460B /* init.c in Sources */ = {isa = PBXBuildFile; fileRef = 37409E73AF4D2A7313805071 /* init.c */; }; + 4A5845FE2A51CB04A3962910 /* krb5-wrapper.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B5E88148F17A4D04FC6290E /* krb5-wrapper.c */; }; + EAFDB3636DD05A6813D6801B /* libnfs.c in Sources */ = {isa = PBXBuildFile; fileRef = 545E1C54835F0C9466747BFD /* libnfs.c */; }; + 423A4A494CDC5267A8952A26 /* libnfs-sync.c in Sources */ = {isa = PBXBuildFile; fileRef = EC88DFF5AF97A4609C577863 /* libnfs-sync.c */; }; + 3B9050BAF91B39DC0D2679F4 /* libnfs-zdr.c in Sources */ = {isa = PBXBuildFile; fileRef = 7C531BC14A9F4A2989AEF07A /* libnfs-zdr.c */; }; + 10560F2B181CC2FE5CD2049D /* multithreading.c in Sources */ = {isa = PBXBuildFile; fileRef = 2A871E15A332DD97395DDDCF /* multithreading.c */; }; + DE822A062BAD7FBCE06FD02D /* nfs_v3.c in Sources */ = {isa = PBXBuildFile; fileRef = 8D614F075482BDFFBDD74AB0 /* nfs_v3.c */; }; + 3C302C234A3511A6DB74CC00 /* nfs_v4.c in Sources */ = {isa = PBXBuildFile; fileRef = 71D0FCC74D9B4466506512D6 /* nfs_v4.c */; }; + 312244FA8202464BC6A435DD /* pdu.c in Sources */ = {isa = PBXBuildFile; fileRef = B12C2A0F2307A8FCE2FFCEF4 /* pdu.c */; }; + 359795FDDCF5EA12561D311F /* socket.c in Sources */ = {isa = PBXBuildFile; fileRef = 8C8E159EF44B056138D00F34 /* socket.c */; }; + A7A77A9C00DE2F59F044B588 /* mount.c in Sources */ = {isa = PBXBuildFile; fileRef = 0F31C03F2498645681C90418 /* mount.c */; }; + DB0388A4F55D7933878B4B3A /* libnfs-raw-mount.c in Sources */ = {isa = PBXBuildFile; fileRef = F0F9D8060F15213897A5162D /* libnfs-raw-mount.c */; }; + 58F7010852490D04C83B5FBE /* nfs.c in Sources */ = {isa = PBXBuildFile; fileRef = 48BD13171876EEE72F4A88ED /* nfs.c */; }; + 19B16DA32B274DCB10744503 /* nfsacl.c in Sources */ = {isa = PBXBuildFile; fileRef = A114EEE68059D5FA1643289F /* nfsacl.c */; }; + 6F827C6D27DE0A32B7232F6A /* libnfs-raw-nfs.c in Sources */ = {isa = PBXBuildFile; fileRef = CCA3A9C801DDFF74E4BB42CC /* libnfs-raw-nfs.c */; }; + ACDA3D87E3A5A3AFE8C65FF4 /* nfs4.c in Sources */ = {isa = PBXBuildFile; fileRef = E08369CC0F41405AD973F3ED /* nfs4.c */; }; + E6AD16E846FC068C2A6ECEB8 /* libnfs-raw-nfs4.c in Sources */ = {isa = PBXBuildFile; fileRef = 5B4C49D06B9F13B7EA0F2F24 /* libnfs-raw-nfs4.c */; }; + C3454B1DA238B2BD135CFD00 /* nlm.c in Sources */ = {isa = PBXBuildFile; fileRef = 706E99A264F1571BB02F25B6 /* nlm.c */; }; + B9A0082C1E0D088F4E520561 /* libnfs-raw-nlm.c in Sources */ = {isa = PBXBuildFile; fileRef = 29FD8205A478A6E4054E6561 /* libnfs-raw-nlm.c */; }; + C9A7439FB97B081176DBCFBE /* nsm.c in Sources */ = {isa = PBXBuildFile; fileRef = 9B9A3C5364EC6312EB6DD58F /* nsm.c */; }; + 11EE97CEA7FF1F4CA6F453E3 /* libnfs-raw-nsm.c in Sources */ = {isa = PBXBuildFile; fileRef = 06245C5082B4C280FF2AA008 /* libnfs-raw-nsm.c */; }; + B430D3F33791D7B3AA2D6832 /* portmap.c in Sources */ = {isa = PBXBuildFile; fileRef = 67326B7F9BE081ACCE736946 /* portmap.c */; }; + 86C4E149E925052F607B8B70 /* libnfs-raw-portmap.c in Sources */ = {isa = PBXBuildFile; fileRef = 8B21CEA0A0AE6F808C9922A1 /* libnfs-raw-portmap.c */; }; + 7E625403A58C1D5F1384AD8A /* rquota.c in Sources */ = {isa = PBXBuildFile; fileRef = C8AA87DBE34ECD2F80074EAF /* rquota.c */; }; + 2346BC25B0F1997FFFCEB0DC /* libnfs-raw-rquota.c in Sources */ = {isa = PBXBuildFile; fileRef = C5E1410D2342740F67D4F105 /* libnfs-raw-rquota.c */; }; 07019B932CD24FF200D6C3FD /* GCDWebDAVServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 07C5C63E2CD167470030FBEC /* GCDWebDAVServer.m */; }; 070672FB2D1723A10099FC74 /* GCDWebUploader.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 92CC059F21FE3C1700FF79F0 /* GCDWebUploader.bundle */; }; 070A88432A4E7AA9003161C0 /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 070A88422A4E7AA9003161C0 /* OpenAL.framework */; }; @@ -163,6 +213,31 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 37409E73AF4D2A7313805071 /* init.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = init.c; path = ../../deps/libnfs/lib/init.c; sourceTree = ""; }; + 5B5E88148F17A4D04FC6290E /* krb5-wrapper.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = krb5-wrapper.c; path = ../../deps/libnfs/lib/krb5-wrapper.c; sourceTree = ""; }; + 545E1C54835F0C9466747BFD /* libnfs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = libnfs.c; path = ../../deps/libnfs/lib/libnfs.c; sourceTree = ""; }; + EC88DFF5AF97A4609C577863 /* libnfs-sync.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = libnfs-sync.c; path = ../../deps/libnfs/lib/libnfs-sync.c; sourceTree = ""; }; + 7C531BC14A9F4A2989AEF07A /* libnfs-zdr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = libnfs-zdr.c; path = ../../deps/libnfs/lib/libnfs-zdr.c; sourceTree = ""; }; + 2A871E15A332DD97395DDDCF /* multithreading.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = multithreading.c; path = ../../deps/libnfs/lib/multithreading.c; sourceTree = ""; }; + 8D614F075482BDFFBDD74AB0 /* nfs_v3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = nfs_v3.c; path = ../../deps/libnfs/lib/nfs_v3.c; sourceTree = ""; }; + 71D0FCC74D9B4466506512D6 /* nfs_v4.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = nfs_v4.c; path = ../../deps/libnfs/lib/nfs_v4.c; sourceTree = ""; }; + B12C2A0F2307A8FCE2FFCEF4 /* pdu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pdu.c; path = ../../deps/libnfs/lib/pdu.c; sourceTree = ""; }; + 8C8E159EF44B056138D00F34 /* socket.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = socket.c; path = ../../deps/libnfs/lib/socket.c; sourceTree = ""; }; + 0F31C03F2498645681C90418 /* mount.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mount.c; path = ../../deps/libnfs/mount/mount.c; sourceTree = ""; }; + F0F9D8060F15213897A5162D /* libnfs-raw-mount.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = libnfs-raw-mount.c; path = ../../deps/libnfs/mount/libnfs-raw-mount.c; sourceTree = ""; }; + 48BD13171876EEE72F4A88ED /* nfs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = nfs.c; path = ../../deps/libnfs/nfs/nfs.c; sourceTree = ""; }; + A114EEE68059D5FA1643289F /* nfsacl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = nfsacl.c; path = ../../deps/libnfs/nfs/nfsacl.c; sourceTree = ""; }; + CCA3A9C801DDFF74E4BB42CC /* libnfs-raw-nfs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = libnfs-raw-nfs.c; path = ../../deps/libnfs/nfs/libnfs-raw-nfs.c; sourceTree = ""; }; + E08369CC0F41405AD973F3ED /* nfs4.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = nfs4.c; path = ../../deps/libnfs/nfs4/nfs4.c; sourceTree = ""; }; + 5B4C49D06B9F13B7EA0F2F24 /* libnfs-raw-nfs4.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = libnfs-raw-nfs4.c; path = ../../deps/libnfs/nfs4/libnfs-raw-nfs4.c; sourceTree = ""; }; + 706E99A264F1571BB02F25B6 /* nlm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = nlm.c; path = ../../deps/libnfs/nlm/nlm.c; sourceTree = ""; }; + 29FD8205A478A6E4054E6561 /* libnfs-raw-nlm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = libnfs-raw-nlm.c; path = ../../deps/libnfs/nlm/libnfs-raw-nlm.c; sourceTree = ""; }; + 9B9A3C5364EC6312EB6DD58F /* nsm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = nsm.c; path = ../../deps/libnfs/nsm/nsm.c; sourceTree = ""; }; + 06245C5082B4C280FF2AA008 /* libnfs-raw-nsm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = libnfs-raw-nsm.c; path = ../../deps/libnfs/nsm/libnfs-raw-nsm.c; sourceTree = ""; }; + 67326B7F9BE081ACCE736946 /* portmap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = portmap.c; path = ../../deps/libnfs/portmap/portmap.c; sourceTree = ""; }; + 8B21CEA0A0AE6F808C9922A1 /* libnfs-raw-portmap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = libnfs-raw-portmap.c; path = ../../deps/libnfs/portmap/libnfs-raw-portmap.c; sourceTree = ""; }; + C8AA87DBE34ECD2F80074EAF /* rquota.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = rquota.c; path = ../../deps/libnfs/rquota/rquota.c; sourceTree = ""; }; + C5E1410D2342740F67D4F105 /* libnfs-raw-rquota.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = libnfs-raw-rquota.c; path = ../../deps/libnfs/rquota/libnfs-raw-rquota.c; sourceTree = ""; }; 070A88422A4E7AA9003161C0 /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = System/Library/Frameworks/OpenAL.framework; sourceTree = SDKROOT; }; 071212C72C6FD65B00F1B4B0 /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = ""; }; 0712A7702B807AE400C9765F /* RetroArchTopShelfExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = RetroArchTopShelfExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -512,6 +587,38 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + F2B87FF9E192F75FD4F0329B /* libnfs */ = { + isa = PBXGroup; + children = ( + 37409E73AF4D2A7313805071 /* init.c */, + 5B5E88148F17A4D04FC6290E /* krb5-wrapper.c */, + 545E1C54835F0C9466747BFD /* libnfs.c */, + EC88DFF5AF97A4609C577863 /* libnfs-sync.c */, + 7C531BC14A9F4A2989AEF07A /* libnfs-zdr.c */, + 2A871E15A332DD97395DDDCF /* multithreading.c */, + 8D614F075482BDFFBDD74AB0 /* nfs_v3.c */, + 71D0FCC74D9B4466506512D6 /* nfs_v4.c */, + B12C2A0F2307A8FCE2FFCEF4 /* pdu.c */, + 8C8E159EF44B056138D00F34 /* socket.c */, + 0F31C03F2498645681C90418 /* mount.c */, + F0F9D8060F15213897A5162D /* libnfs-raw-mount.c */, + 48BD13171876EEE72F4A88ED /* nfs.c */, + A114EEE68059D5FA1643289F /* nfsacl.c */, + CCA3A9C801DDFF74E4BB42CC /* libnfs-raw-nfs.c */, + E08369CC0F41405AD973F3ED /* nfs4.c */, + 5B4C49D06B9F13B7EA0F2F24 /* libnfs-raw-nfs4.c */, + 706E99A264F1571BB02F25B6 /* nlm.c */, + 29FD8205A478A6E4054E6561 /* libnfs-raw-nlm.c */, + 9B9A3C5364EC6312EB6DD58F /* nsm.c */, + 06245C5082B4C280FF2AA008 /* libnfs-raw-nsm.c */, + 67326B7F9BE081ACCE736946 /* portmap.c */, + 8B21CEA0A0AE6F808C9922A1 /* libnfs-raw-portmap.c */, + C8AA87DBE34ECD2F80074EAF /* rquota.c */, + C5E1410D2342740F67D4F105 /* libnfs-raw-rquota.c */, + ); + name = libnfs; + sourceTree = ""; + }; 0712A7732B807AE400C9765F /* RetroArchTopShelfExtension */ = { isa = PBXGroup; children = ( @@ -1154,6 +1261,7 @@ 9210C2FB24B4CB4900E6FE7C /* Shaders.metal */, 83D632D719ECFCC4009E3161 /* iOS */, 926C77D821FD1E6500103EDE /* tvOS */, + F2B87FF9E192F75FD4F0329B /* libnfs */, 92CC05CC21FF782C00FF79F0 /* WebServer */, 07649B662E1C47220003184B /* AppIntents */, 9292D6E628F549D100E47A75 /* RetroArchWidgetExtension */, @@ -1530,6 +1638,31 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + DCA144C1F2D0669C4F8615A8 /* init.c in Sources */, + 89F6FA3282CC1AB62E51EE33 /* krb5-wrapper.c in Sources */, + D26FDEBB2C87A3A8AE5B3AC5 /* libnfs.c in Sources */, + 041B1BC56F626891766D9083 /* libnfs-sync.c in Sources */, + 418020E21A59481CE75C3728 /* libnfs-zdr.c in Sources */, + DF50F27A06FD677977D40575 /* multithreading.c in Sources */, + 5CC20C7F47DAABE4BC701782 /* nfs_v3.c in Sources */, + C94F3B7AC904063AC38CBCAF /* nfs_v4.c in Sources */, + 7A536987DA7775A1A9748656 /* pdu.c in Sources */, + C8182809F45E6C523693B8D9 /* socket.c in Sources */, + EF71BDF9277DC80E468EDF72 /* mount.c in Sources */, + 1162D1ABE19B0F9C531AAFF0 /* libnfs-raw-mount.c in Sources */, + 0F09608340640B30796D86B7 /* nfs.c in Sources */, + 0ADB1372000910DC48F6EF20 /* nfsacl.c in Sources */, + DC84BC69FCCC792B4DE15031 /* libnfs-raw-nfs.c in Sources */, + 989A1AA91C0411610F80B78A /* nfs4.c in Sources */, + 39A8F3361B503ECF77B6C017 /* libnfs-raw-nfs4.c in Sources */, + 2C1BAEA5A6BE170549F862D5 /* nlm.c in Sources */, + 317CDE8E134F77BCD9BC4A65 /* libnfs-raw-nlm.c in Sources */, + 3BB4913DD1C6BFAA2559339C /* nsm.c in Sources */, + D8FCADC70C6613761C04D74B /* libnfs-raw-nsm.c in Sources */, + B7A577B77C7C8E97A90A55CC /* portmap.c in Sources */, + 553019B6E138785D5644B255 /* libnfs-raw-portmap.c in Sources */, + 5C011FFD85E2EEA1A46828D9 /* rquota.c in Sources */, + A07BC8706552BBF254892BA6 /* libnfs-raw-rquota.c in Sources */, 92CC05B821FE3C1700FF79F0 /* GCDWebServerDataRequest.m in Sources */, 92CC05A421FE3C1700FF79F0 /* GCDWebServerRequest.m in Sources */, 92CC05AA21FE3C1700FF79F0 /* GCDWebServerConnection.m in Sources */, @@ -1562,6 +1695,31 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 1E3143E3071829B8E99A460B /* init.c in Sources */, + 4A5845FE2A51CB04A3962910 /* krb5-wrapper.c in Sources */, + EAFDB3636DD05A6813D6801B /* libnfs.c in Sources */, + 423A4A494CDC5267A8952A26 /* libnfs-sync.c in Sources */, + 3B9050BAF91B39DC0D2679F4 /* libnfs-zdr.c in Sources */, + 10560F2B181CC2FE5CD2049D /* multithreading.c in Sources */, + DE822A062BAD7FBCE06FD02D /* nfs_v3.c in Sources */, + 3C302C234A3511A6DB74CC00 /* nfs_v4.c in Sources */, + 312244FA8202464BC6A435DD /* pdu.c in Sources */, + 359795FDDCF5EA12561D311F /* socket.c in Sources */, + A7A77A9C00DE2F59F044B588 /* mount.c in Sources */, + DB0388A4F55D7933878B4B3A /* libnfs-raw-mount.c in Sources */, + 58F7010852490D04C83B5FBE /* nfs.c in Sources */, + 19B16DA32B274DCB10744503 /* nfsacl.c in Sources */, + 6F827C6D27DE0A32B7232F6A /* libnfs-raw-nfs.c in Sources */, + ACDA3D87E3A5A3AFE8C65FF4 /* nfs4.c in Sources */, + E6AD16E846FC068C2A6ECEB8 /* libnfs-raw-nfs4.c in Sources */, + C3454B1DA238B2BD135CFD00 /* nlm.c in Sources */, + B9A0082C1E0D088F4E520561 /* libnfs-raw-nlm.c in Sources */, + C9A7439FB97B081176DBCFBE /* nsm.c in Sources */, + 11EE97CEA7FF1F4CA6F453E3 /* libnfs-raw-nsm.c in Sources */, + B430D3F33791D7B3AA2D6832 /* portmap.c in Sources */, + 86C4E149E925052F607B8B70 /* libnfs-raw-portmap.c in Sources */, + 7E625403A58C1D5F1384AD8A /* rquota.c in Sources */, + 2346BC25B0F1997FFFCEB0DC /* libnfs-raw-rquota.c in Sources */, 92CC05B921FE3C1700FF79F0 /* GCDWebServerDataRequest.m in Sources */, 92CC05A521FE3C1700FF79F0 /* GCDWebServerRequest.m in Sources */, 92CC05AB21FE3C1700FF79F0 /* GCDWebServerConnection.m in Sources */, diff --git a/pkg/msvc-uwp/RetroArch-msvcUWP/RetroArch-msvcUWP.vcxproj b/pkg/msvc-uwp/RetroArch-msvcUWP/RetroArch-msvcUWP.vcxproj index bc3615516ba0..c83812df5315 100644 --- a/pkg/msvc-uwp/RetroArch-msvcUWP/RetroArch-msvcUWP.vcxproj +++ b/pkg/msvc-uwp/RetroArch-msvcUWP/RetroArch-msvcUWP.vcxproj @@ -99,10 +99,10 @@ - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include\compat\zlib;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\lib;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\common;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\compress;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\decompress;$(MSBuildProjectDirectory)\..\..\..\deps\7zip;$(MSBuildProjectDirectory)\..\..\..\deps\dr;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\libsmb2\include\smb2;$(MSBuildProjectDirectory)\..\..\..\deps\libsmb2\include;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include\compat\zlib;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\lib;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\common;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\compress;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\decompress;$(MSBuildProjectDirectory)\..\..\..\deps\7zip;$(MSBuildProjectDirectory)\..\..\..\deps\dr;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps\libsmb2\include\smb2;$(MSBuildProjectDirectory)\..\..\..\deps\libsmb2\include;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) /utf-8 4453;28204 - WIN32;HAVE_XDELTA;HAVE_MAIN;HAVE_DYNAMIC;HAVE_DYLIB;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_D3D;HAVE_D3D11;HAVE_D3D12;HAVE_BUILTINSMBCLIENT;HAVE_SMBCLIENT;_U_=/**/;HAVE_FCNTL_H;HAVE_STDINT_H;HAVE_LINGER;NEED_RANDOM;NEED_SRANDOM;NEED_GETLOGIN_R;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_CHD;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_RZSTD;HAVE_7ZIP;HAVE_TRANSLATE;HAVE_ACCESSIBILITY;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_CORE_INFO_CACHE;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_RVORBIS;HAVE_RMODTRACKER;HAVE_DR_FLAC;HAVE_DR_MP3;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS;HAVE_CLOUDSYNC;_SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING + WIN32;HAVE_XDELTA;HAVE_MAIN;HAVE_DYNAMIC;HAVE_DYLIB;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_D3D;HAVE_D3D11;HAVE_D3D12;HAVE_BUILTINSMBCLIENT;HAVE_SMBCLIENT;HAVE_BUILTINNFSCLIENT;HAVE_NFSCLIENT;_U_=/**/;HAVE_FCNTL_H;HAVE_STDINT_H;HAVE_LINGER;NEED_RANDOM;NEED_SRANDOM;NEED_GETLOGIN_R;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_CHD;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_RZSTD;HAVE_7ZIP;HAVE_TRANSLATE;HAVE_ACCESSIBILITY;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_CORE_INFO_CACHE;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_RVORBIS;HAVE_RMODTRACKER;HAVE_DR_FLAC;HAVE_DR_MP3;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS;HAVE_CLOUDSYNC;_SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING @@ -114,10 +114,10 @@ - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include\compat\zlib;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\lib;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\common;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\compress;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\decompress;$(MSBuildProjectDirectory)\..\..\..\deps\7zip;$(MSBuildProjectDirectory)\..\..\..\deps\dr;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\libsmb2\include\smb2;$(MSBuildProjectDirectory)\..\..\..\deps\libsmb2\include;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\ANGLE;%(AdditionalIncludeDirectories) + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include\compat\zlib;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\lib;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\common;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\compress;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\decompress;$(MSBuildProjectDirectory)\..\..\..\deps\7zip;$(MSBuildProjectDirectory)\..\..\..\deps\dr;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps\libsmb2\include\smb2;$(MSBuildProjectDirectory)\..\..\..\deps\libsmb2\include;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\ANGLE;%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) /utf-8 4453;28204 - WIN32;HAVE_XDELTA;HAVE_MAIN;HAVE_DYNAMIC;HAVE_DYLIB;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_D3D;HAVE_D3D11;HAVE_D3D12;HAVE_BUILTINSMBCLIENT;HAVE_SMBCLIENT;_U_=/**/;HAVE_FCNTL_H;HAVE_STDINT_H;HAVE_LINGER;NEED_RANDOM;NEED_SRANDOM;NEED_GETLOGIN_R;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_CHD;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_RZSTD;HAVE_7ZIP;HAVE_TRANSLATE;HAVE_ACCESSIBILITY;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_CORE_INFO_CACHE;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_RVORBIS;HAVE_RMODTRACKER;HAVE_DR_FLAC;HAVE_DR_MP3;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS;HAVE_ANGLE;HAVE_OPENGL;HAVE_OPENGLES;HAVE_OPENGLES2;HAVE_GLSL;HAVE_CLOUDSYNC;_SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING + WIN32;HAVE_XDELTA;HAVE_MAIN;HAVE_DYNAMIC;HAVE_DYLIB;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_D3D;HAVE_D3D11;HAVE_D3D12;HAVE_BUILTINSMBCLIENT;HAVE_SMBCLIENT;HAVE_BUILTINNFSCLIENT;HAVE_NFSCLIENT;_U_=/**/;HAVE_FCNTL_H;HAVE_STDINT_H;HAVE_LINGER;NEED_RANDOM;NEED_SRANDOM;NEED_GETLOGIN_R;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_CHD;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_RZSTD;HAVE_7ZIP;HAVE_TRANSLATE;HAVE_ACCESSIBILITY;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_CORE_INFO_CACHE;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_RVORBIS;HAVE_RMODTRACKER;HAVE_DR_FLAC;HAVE_DR_MP3;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS;HAVE_ANGLE;HAVE_OPENGL;HAVE_OPENGLES;HAVE_OPENGLES2;HAVE_GLSL;HAVE_CLOUDSYNC;_SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING @@ -129,10 +129,10 @@ - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include\compat\zlib;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\lib;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\common;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\compress;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\decompress;$(MSBuildProjectDirectory)\..\..\..\deps\7zip;$(MSBuildProjectDirectory)\..\..\..\deps\dr;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\libsmb2\include\smb2;$(MSBuildProjectDirectory)\..\..\..\deps\libsmb2\include;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include\compat\zlib;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\lib;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\common;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\compress;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\decompress;$(MSBuildProjectDirectory)\..\..\..\deps\7zip;$(MSBuildProjectDirectory)\..\..\..\deps\dr;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps\libsmb2\include\smb2;$(MSBuildProjectDirectory)\..\..\..\deps\libsmb2\include;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) /utf-8 4453;28204 - WIN32;HAVE_XDELTA;HAVE_MAIN;HAVE_DYNAMIC;HAVE_DYLIB;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_D3D;HAVE_D3D11;HAVE_D3D12;HAVE_BUILTINSMBCLIENT;HAVE_SMBCLIENT;_U_=/**/;HAVE_FCNTL_H;HAVE_STDINT_H;HAVE_LINGER;NEED_RANDOM;NEED_SRANDOM;NEED_GETLOGIN_R;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_CHD;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_RZSTD;HAVE_7ZIP;HAVE_TRANSLATE;HAVE_ACCESSIBILITY;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_CORE_INFO_CACHE;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_RVORBIS;HAVE_RMODTRACKER;HAVE_DR_FLAC;HAVE_DR_MP3;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS;HAVE_CLOUDSYNC;_SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING + WIN32;HAVE_XDELTA;HAVE_MAIN;HAVE_DYNAMIC;HAVE_DYLIB;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_D3D;HAVE_D3D11;HAVE_D3D12;HAVE_BUILTINSMBCLIENT;HAVE_SMBCLIENT;HAVE_BUILTINNFSCLIENT;HAVE_NFSCLIENT;_U_=/**/;HAVE_FCNTL_H;HAVE_STDINT_H;HAVE_LINGER;NEED_RANDOM;NEED_SRANDOM;NEED_GETLOGIN_R;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_CHD;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_RZSTD;HAVE_7ZIP;HAVE_TRANSLATE;HAVE_ACCESSIBILITY;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_CORE_INFO_CACHE;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_RVORBIS;HAVE_RMODTRACKER;HAVE_DR_FLAC;HAVE_DR_MP3;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS;HAVE_CLOUDSYNC;_SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING @@ -144,10 +144,10 @@ - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include\compat\zlib;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\lib;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\common;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\compress;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\decompress;$(MSBuildProjectDirectory)\..\..\..\deps\7zip;$(MSBuildProjectDirectory)\..\..\..\deps\dr;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\libsmb2\include\smb2;$(MSBuildProjectDirectory)\..\..\..\deps\libsmb2\include;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\ANGLE;%(AdditionalIncludeDirectories) + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include\compat\zlib;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\lib;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\common;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\compress;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\decompress;$(MSBuildProjectDirectory)\..\..\..\deps\7zip;$(MSBuildProjectDirectory)\..\..\..\deps\dr;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps\libsmb2\include\smb2;$(MSBuildProjectDirectory)\..\..\..\deps\libsmb2\include;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\ANGLE;%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) /utf-8 4453;28204 - WIN32;HAVE_XDELTA;HAVE_MAIN;HAVE_DYNAMIC;HAVE_DYLIB;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_D3D;HAVE_D3D11;HAVE_D3D12;HAVE_BUILTINSMBCLIENT;HAVE_SMBCLIENT;_U_=/**/;HAVE_FCNTL_H;HAVE_STDINT_H;HAVE_LINGER;NEED_RANDOM;NEED_SRANDOM;NEED_GETLOGIN_R;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_CHD;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_RZSTD;HAVE_7ZIP;HAVE_TRANSLATE;HAVE_ACCESSIBILITY;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_CORE_INFO_CACHE;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_RVORBIS;HAVE_RMODTRACKER;HAVE_DR_FLAC;HAVE_DR_MP3;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS;HAVE_ANGLE;HAVE_OPENGL;HAVE_OPENGLES;HAVE_OPENGLES2;HAVE_GLSL;HAVE_CLOUDSYNC;_SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING + WIN32;HAVE_XDELTA;HAVE_MAIN;HAVE_DYNAMIC;HAVE_DYLIB;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_D3D;HAVE_D3D11;HAVE_D3D12;HAVE_BUILTINSMBCLIENT;HAVE_SMBCLIENT;HAVE_BUILTINNFSCLIENT;HAVE_NFSCLIENT;_U_=/**/;HAVE_FCNTL_H;HAVE_STDINT_H;HAVE_LINGER;NEED_RANDOM;NEED_SRANDOM;NEED_GETLOGIN_R;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_CHD;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_RZSTD;HAVE_7ZIP;HAVE_TRANSLATE;HAVE_ACCESSIBILITY;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_CORE_INFO_CACHE;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_RVORBIS;HAVE_RMODTRACKER;HAVE_DR_FLAC;HAVE_DR_MP3;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS;HAVE_ANGLE;HAVE_OPENGL;HAVE_OPENGLES;HAVE_OPENGLES2;HAVE_GLSL;HAVE_CLOUDSYNC;_SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING @@ -159,10 +159,10 @@ - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include\compat\zlib;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\lib;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\common;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\compress;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\decompress;$(MSBuildProjectDirectory)\..\..\..\deps\7zip;$(MSBuildProjectDirectory)\..\..\..\deps\dr;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\libsmb2\include\smb2;$(MSBuildProjectDirectory)\..\..\..\deps\libsmb2\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\MESA;%(AdditionalIncludeDirectories) + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include\compat\zlib;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\lib;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\common;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\compress;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\decompress;$(MSBuildProjectDirectory)\..\..\..\deps\7zip;$(MSBuildProjectDirectory)\..\..\..\deps\dr;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps\libsmb2\include\smb2;$(MSBuildProjectDirectory)\..\..\..\deps\libsmb2\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\MESA;%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) /utf-8 4453;28204 - WIN32;HAVE_XDELTA;HAVE_MAIN;HAVE_DYNAMIC;HAVE_DYLIB;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_D3D;HAVE_D3D11;HAVE_D3D12;HAVE_BUILTINSMBCLIENT;HAVE_SMBCLIENT;_U_=/**/;HAVE_FCNTL_H;HAVE_STDINT_H;HAVE_LINGER;NEED_RANDOM;NEED_SRANDOM;NEED_GETLOGIN_R;HAVE_OPENGL;HAVE_GLSL;HAVE_HLSL;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_CHD;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_RZSTD;HAVE_7ZIP;HAVE_TRANSLATE;HAVE_ACCESSIBILITY;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_CORE_INFO_CACHE;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_RVORBIS;HAVE_RMODTRACKER;HAVE_DR_FLAC;HAVE_DR_MP3;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS;HAVE_CLOUDSYNC;_SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING + WIN32;HAVE_XDELTA;HAVE_MAIN;HAVE_DYNAMIC;HAVE_DYLIB;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_D3D;HAVE_D3D11;HAVE_D3D12;HAVE_BUILTINSMBCLIENT;HAVE_SMBCLIENT;HAVE_BUILTINNFSCLIENT;HAVE_NFSCLIENT;_U_=/**/;HAVE_FCNTL_H;HAVE_STDINT_H;HAVE_LINGER;NEED_RANDOM;NEED_SRANDOM;NEED_GETLOGIN_R;HAVE_OPENGL;HAVE_GLSL;HAVE_HLSL;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_CHD;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_RZSTD;HAVE_7ZIP;HAVE_TRANSLATE;HAVE_ACCESSIBILITY;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_CORE_INFO_CACHE;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_RVORBIS;HAVE_RMODTRACKER;HAVE_DR_FLAC;HAVE_DR_MP3;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS;HAVE_CLOUDSYNC;_SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING ProgramDatabase @@ -175,10 +175,10 @@ - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include\compat\zlib;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\lib;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\common;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\compress;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\decompress;$(MSBuildProjectDirectory)\..\..\..\deps\7zip;$(MSBuildProjectDirectory)\..\..\..\deps\dr;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\libsmb2\include\smb2;$(MSBuildProjectDirectory)\..\..\..\deps\libsmb2\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\MESA;%(AdditionalIncludeDirectories) + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include\compat\zlib;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\lib;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\common;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\compress;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\decompress;$(MSBuildProjectDirectory)\..\..\..\deps\7zip;$(MSBuildProjectDirectory)\..\..\..\deps\dr;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps\libsmb2\include\smb2;$(MSBuildProjectDirectory)\..\..\..\deps\libsmb2\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\MESA;%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) /utf-8 4453;28204 - WIN32;HAVE_XDELTA;HAVE_MAIN;HAVE_DYNAMIC;HAVE_DYLIB;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_D3D;HAVE_D3D11;HAVE_D3D12;HAVE_BUILTINSMBCLIENT;HAVE_SMBCLIENT;_U_=/**/;HAVE_FCNTL_H;HAVE_STDINT_H;HAVE_LINGER;NEED_RANDOM;NEED_SRANDOM;NEED_GETLOGIN_R;HAVE_OPENGL;HAVE_GLSL;HAVE_HLSL;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_CHD;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_RZSTD;HAVE_7ZIP;HAVE_TRANSLATE;HAVE_ACCESSIBILITY;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_CORE_INFO_CACHE;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_RVORBIS;HAVE_RMODTRACKER;HAVE_DR_FLAC;HAVE_DR_MP3;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS;HAVE_CLOUDSYNC;_SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING + WIN32;HAVE_XDELTA;HAVE_MAIN;HAVE_DYNAMIC;HAVE_DYLIB;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_D3D;HAVE_D3D11;HAVE_D3D12;HAVE_BUILTINSMBCLIENT;HAVE_SMBCLIENT;HAVE_BUILTINNFSCLIENT;HAVE_NFSCLIENT;_U_=/**/;HAVE_FCNTL_H;HAVE_STDINT_H;HAVE_LINGER;NEED_RANDOM;NEED_SRANDOM;NEED_GETLOGIN_R;HAVE_OPENGL;HAVE_GLSL;HAVE_HLSL;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_CHD;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_RZSTD;HAVE_7ZIP;HAVE_TRANSLATE;HAVE_ACCESSIBILITY;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_CORE_INFO_CACHE;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_RVORBIS;HAVE_RMODTRACKER;HAVE_DR_FLAC;HAVE_DR_MP3;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS;HAVE_CLOUDSYNC;_SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING @@ -190,10 +190,10 @@ - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include\compat\zlib;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\lib;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\common;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\compress;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\decompress;$(MSBuildProjectDirectory)\..\..\..\deps\7zip;$(MSBuildProjectDirectory)\..\..\..\deps\dr;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\libsmb2\include\smb2;$(MSBuildProjectDirectory)\..\..\..\deps\libsmb2\include;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\ANGLE;%(AdditionalIncludeDirectories) + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include\compat\zlib;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\lib;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\common;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\compress;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\decompress;$(MSBuildProjectDirectory)\..\..\..\deps\7zip;$(MSBuildProjectDirectory)\..\..\..\deps\dr;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps\libsmb2\include\smb2;$(MSBuildProjectDirectory)\..\..\..\deps\libsmb2\include;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\ANGLE;%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) /utf-8 4453;28204 - WIN32;HAVE_XDELTA;HAVE_MAIN;HAVE_DYNAMIC;HAVE_DYLIB;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_D3D;HAVE_D3D11;HAVE_D3D12;HAVE_BUILTINSMBCLIENT;HAVE_SMBCLIENT;_U_=/**/;HAVE_FCNTL_H;HAVE_STDINT_H;HAVE_LINGER;NEED_RANDOM;NEED_SRANDOM;NEED_GETLOGIN_R;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_CHD;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_RZSTD;HAVE_7ZIP;HAVE_TRANSLATE;HAVE_ACCESSIBILITY;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_CORE_INFO_CACHE;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_RVORBIS;HAVE_RMODTRACKER;HAVE_DR_FLAC;HAVE_DR_MP3;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS;HAVE_ANGLE;HAVE_OPENGL;HAVE_OPENGLES;HAVE_OPENGLES2;HAVE_GLSL;HAVE_HLSL;HAVE_EGL;HAVE_CLOUDSYNC;_SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING + WIN32;HAVE_XDELTA;HAVE_MAIN;HAVE_DYNAMIC;HAVE_DYLIB;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_D3D;HAVE_D3D11;HAVE_D3D12;HAVE_BUILTINSMBCLIENT;HAVE_SMBCLIENT;HAVE_BUILTINNFSCLIENT;HAVE_NFSCLIENT;_U_=/**/;HAVE_FCNTL_H;HAVE_STDINT_H;HAVE_LINGER;NEED_RANDOM;NEED_SRANDOM;NEED_GETLOGIN_R;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_CHD;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_RZSTD;HAVE_7ZIP;HAVE_TRANSLATE;HAVE_ACCESSIBILITY;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_CORE_INFO_CACHE;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_RVORBIS;HAVE_RMODTRACKER;HAVE_DR_FLAC;HAVE_DR_MP3;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS;HAVE_ANGLE;HAVE_OPENGL;HAVE_OPENGLES;HAVE_OPENGLES2;HAVE_GLSL;HAVE_HLSL;HAVE_EGL;HAVE_CLOUDSYNC;_SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING @@ -220,10 +220,10 @@ - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include\compat\zlib;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\lib;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\common;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\compress;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\decompress;$(MSBuildProjectDirectory)\..\..\..\deps\7zip;$(MSBuildProjectDirectory)\..\..\..\deps\dr;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\libsmb2\include\smb2;$(MSBuildProjectDirectory)\..\..\..\deps\libsmb2\include;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\ANGLE;%(AdditionalIncludeDirectories) + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include\compat\zlib;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\lib;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\common;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\compress;$(MSBuildProjectDirectory)\..\..\..\deps\zstd\decompress;$(MSBuildProjectDirectory)\..\..\..\deps\7zip;$(MSBuildProjectDirectory)\..\..\..\deps\dr;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps\libsmb2\include\smb2;$(MSBuildProjectDirectory)\..\..\..\deps\libsmb2\include;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\ANGLE;%(AdditionalIncludeDirectories) /bigobj %(AdditionalOptions) /utf-8 4453;28204 - WIN32;HAVE_XDELTA;HAVE_MAIN;HAVE_DYNAMIC;HAVE_DYLIB;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_D3D;HAVE_D3D11;HAVE_D3D12;HAVE_BUILTINSMBCLIENT;HAVE_SMBCLIENT;_U_=/**/;HAVE_FCNTL_H;HAVE_STDINT_H;HAVE_LINGER;NEED_RANDOM;NEED_SRANDOM;NEED_GETLOGIN_R;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_CHD;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_RZSTD;HAVE_7ZIP;HAVE_TRANSLATE;HAVE_ACCESSIBILITY;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_CORE_INFO_CACHE;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_RVORBIS;HAVE_RMODTRACKER;HAVE_DR_FLAC;HAVE_DR_MP3;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS;HAVE_ANGLE;HAVE_OPENGL;HAVE_OPENGLES;HAVE_OPENGLES2;HAVE_GLSL;HAVE_HLSL;HAVE_CLOUDSYNC;_SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING + WIN32;HAVE_XDELTA;HAVE_MAIN;HAVE_DYNAMIC;HAVE_DYLIB;HAVE_XAUDIO2;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_D3D;HAVE_D3D11;HAVE_D3D12;HAVE_BUILTINSMBCLIENT;HAVE_SMBCLIENT;HAVE_BUILTINNFSCLIENT;HAVE_NFSCLIENT;_U_=/**/;HAVE_FCNTL_H;HAVE_STDINT_H;HAVE_LINGER;NEED_RANDOM;NEED_SRANDOM;NEED_GETLOGIN_R;RC_DISABLE_LUA;HAVE_CHEEVOS;HAVE_CHD;HAVE_RUNAHEAD;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_RZSTD;HAVE_7ZIP;HAVE_TRANSLATE;HAVE_ACCESSIBILITY;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_CORE_INFO_CACHE;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XINPUT2;HAVE_XAUDIO;HAVE_RVORBIS;HAVE_RMODTRACKER;HAVE_DR_FLAC;HAVE_DR_MP3;HAVE_DIRECTX;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_STB_FONT;HAVE_STATIC_DUMMY;HAVE_STATIC_VIDEO_FILTERS;HAVE_STATIC_AUDIO_FILTERS;HAVE_ANGLE;HAVE_OPENGL;HAVE_OPENGLES;HAVE_OPENGLES2;HAVE_GLSL;HAVE_HLSL;HAVE_CLOUDSYNC;_SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING ProgramDatabase @@ -231,6 +231,84 @@ false + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + diff --git a/pkg/msvc/msvc-2019/RetroArch-msvc2019.vcxproj b/pkg/msvc/msvc-2019/RetroArch-msvc2019.vcxproj index 112fabced1d7..b0dba1ad22f6 100644 --- a/pkg/msvc/msvc-2019/RetroArch-msvc2019.vcxproj +++ b/pkg/msvc/msvc-2019/RetroArch-msvc2019.vcxproj @@ -197,8 +197,8 @@ Level3 Disabled - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_ASIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_ASIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast @@ -219,8 +219,8 @@ Level3 Disabled - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_HLSL;RC_DISABLE_LUA;HAVE_DSOUND;HAVE_WASAPI;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XAUDIO;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_HLSL;RC_DISABLE_LUA;HAVE_DSOUND;HAVE_WASAPI;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XAUDIO;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast @@ -242,8 +242,8 @@ Level3 Disabled - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_HLSL;RC_DISABLE_LUA;HAVE_DSOUND;HAVE_WASAPI;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_HLSL;RC_DISABLE_LUA;HAVE_DSOUND;HAVE_WASAPI;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast @@ -265,8 +265,8 @@ Level3 Disabled - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast @@ -288,8 +288,8 @@ Level3 Disabled - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast @@ -311,8 +311,8 @@ Level3 Disabled - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast @@ -334,8 +334,8 @@ Level3 Disabled - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast @@ -357,8 +357,8 @@ Level3 Disabled - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast @@ -380,8 +380,8 @@ Level3 Disabled - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast @@ -403,8 +403,8 @@ Level3 Disabled - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast @@ -426,8 +426,8 @@ Level3 Disabled - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast @@ -449,8 +449,8 @@ Level3 Disabled - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast @@ -472,8 +472,8 @@ Level3 Disabled - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast @@ -493,8 +493,8 @@ Level3 Disabled - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast @@ -515,8 +515,8 @@ Level3 Disabled - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast @@ -537,8 +537,8 @@ Level3 Disabled - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast @@ -561,8 +561,8 @@ MaxSpeed true true - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast @@ -588,8 +588,8 @@ MaxSpeed true true - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_HLSL;RC_DISABLE_LUA;HAVE_DSOUND;HAVE_WASAPI;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XAUDIO;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_HLSL;RC_DISABLE_LUA;HAVE_DSOUND;HAVE_WASAPI;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XAUDIO;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast @@ -616,8 +616,8 @@ MaxSpeed true true - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_HLSL;RC_DISABLE_LUA;HAVE_DSOUND;HAVE_WASAPI;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_HLSL;RC_DISABLE_LUA;HAVE_DSOUND;HAVE_WASAPI;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast @@ -644,8 +644,8 @@ MaxSpeed true true - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast @@ -672,8 +672,8 @@ MaxSpeed true true - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast @@ -700,8 +700,8 @@ MaxSpeed true true - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast @@ -728,8 +728,8 @@ MaxSpeed true true - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast @@ -756,8 +756,8 @@ MaxSpeed true true - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast @@ -784,8 +784,8 @@ MaxSpeed true true - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast @@ -812,8 +812,8 @@ MaxSpeed true true - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast @@ -840,8 +840,8 @@ MaxSpeed true true - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast @@ -868,8 +868,8 @@ MaxSpeed true true - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast @@ -896,8 +896,8 @@ MaxSpeed true true - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast @@ -923,8 +923,8 @@ MaxSpeed true true - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast @@ -950,8 +950,8 @@ MaxSpeed true true - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast @@ -977,8 +977,8 @@ MaxSpeed true true - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast @@ -1003,6 +1003,84 @@ CompileAsC + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + /bigobj %(AdditionalOptions) diff --git a/pkg/msvc/msvc-2022/RetroArch-msvc2022.vcxproj b/pkg/msvc/msvc-2022/RetroArch-msvc2022.vcxproj index 783a3d8319ef..ab1e9375a353 100644 --- a/pkg/msvc/msvc-2022/RetroArch-msvc2022.vcxproj +++ b/pkg/msvc/msvc-2022/RetroArch-msvc2022.vcxproj @@ -198,8 +198,8 @@ Level3 Disabled - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_ASIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_ASIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast @@ -220,8 +220,8 @@ Level3 Disabled - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_HLSL;RC_DISABLE_LUA;HAVE_DSOUND;HAVE_WASAPI;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XAUDIO;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_HLSL;RC_DISABLE_LUA;HAVE_DSOUND;HAVE_WASAPI;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XAUDIO;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast @@ -243,8 +243,8 @@ Level3 Disabled - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_HLSL;RC_DISABLE_LUA;HAVE_DSOUND;HAVE_WASAPI;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_HLSL;RC_DISABLE_LUA;HAVE_DSOUND;HAVE_WASAPI;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast @@ -266,8 +266,8 @@ Level3 Disabled - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast @@ -289,8 +289,8 @@ Level3 Disabled - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast @@ -312,8 +312,8 @@ Level3 Disabled - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast @@ -335,8 +335,8 @@ Level3 Disabled - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast @@ -358,8 +358,8 @@ Level3 Disabled - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast @@ -381,8 +381,8 @@ Level3 Disabled - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast @@ -404,8 +404,8 @@ Level3 Disabled - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast @@ -427,8 +427,8 @@ Level3 Disabled - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast @@ -450,8 +450,8 @@ Level3 Disabled - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast @@ -473,8 +473,8 @@ Level3 Disabled - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast @@ -494,8 +494,8 @@ Level3 Disabled - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast @@ -516,8 +516,8 @@ Level3 Disabled - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast @@ -538,8 +538,8 @@ Level3 Disabled - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;DEBUG;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp Fast @@ -562,8 +562,8 @@ MaxSpeed true true - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast @@ -589,8 +589,8 @@ MaxSpeed true true - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_HLSL;RC_DISABLE_LUA;HAVE_DSOUND;HAVE_WASAPI;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XAUDIO;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_HLSL;RC_DISABLE_LUA;HAVE_DSOUND;HAVE_WASAPI;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_XINPUT;HAVE_XAUDIO;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast @@ -617,8 +617,8 @@ MaxSpeed true true - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_HLSL;RC_DISABLE_LUA;HAVE_DSOUND;HAVE_WASAPI;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_HLSL;RC_DISABLE_LUA;HAVE_DSOUND;HAVE_WASAPI;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;HAVE_OVERLAY;HAVE_RGUI;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast @@ -645,8 +645,8 @@ MaxSpeed true true - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast @@ -673,8 +673,8 @@ MaxSpeed true true - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast @@ -701,8 +701,8 @@ MaxSpeed true true - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast @@ -729,8 +729,8 @@ MaxSpeed true true - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast @@ -757,8 +757,8 @@ MaxSpeed true true - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast @@ -785,8 +785,8 @@ MaxSpeed true true - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast @@ -813,8 +813,8 @@ MaxSpeed true true - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast @@ -841,8 +841,8 @@ MaxSpeed true true - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast @@ -869,8 +869,8 @@ MaxSpeed true true - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast @@ -897,8 +897,8 @@ MaxSpeed true true - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast @@ -924,8 +924,8 @@ MaxSpeed true true - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast @@ -951,8 +951,8 @@ MaxSpeed true true - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast @@ -978,8 +978,8 @@ MaxSpeed true true - WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) + WIN32;HAVE_XDELTA;RARCH_INTERNAL;HAVE_CC_RESAMPLER;WANT_GLSLANG;HAVE_SLANG;HAVE_GLSLANG;HAVE_BUILTINGLSLANG;HAVE_SPIRV_CROSS;HAVE_ONLINE_UPDATER;HAVE_UPDATE_ASSETS;HAVE_UPDATE_CORES;HAVE_UPDATE_CORE_INFO;HAVE_CORE_INFO_CACHE;HAVE_D3D;HAVE_D3D9;HAVE_D3D10;HAVE_D3D11;HAVE_D3D12;HAVE_MICROPHONE;HAVE_VULKAN;HAVE_HLSL;RC_DISABLE_LUA;HAVE_WASAPI;HAVE_CG;HAVE_GLSL;HAVE_CHEEVOS;HAVE_RUNAHEAD;HAVE_TRANSLATE;HAVE_CDROM;HAVE_GRIFFIN;HAVE_GDI;HAVE_LANGEXTRA;HAVE_QT;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;HAVE_XMB;HAVE_OZONE;HAVE_SHADERPIPELINE;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_OPENGL_CORE;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NFSCLIENT;HAVE_BUILTINNFSCLIENT;_U_=/**/;HAVE_IFINFO;HAVE_NETWORK_CMD;HAVE_NETPLAYDISCOVERY;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RWEBP;HAVE_RDDS;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_GFX_WIDGETS;HAVE_CONFIGFILE;HAVE_PATCH;HAVE_DSP_FILTER;HAVE_VIDEO_FILTER;HAVE_REWIND;HAVE_SCREENSHOTS;HAVE_CHEATS;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_AUDIOMIXER;HAVE_RWAV;HAVE_RVORBIS;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\rcheevos\include;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\win32;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\include\nfsc;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\mount;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nfs4;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nlm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\nsm;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\portmap;$(MSBuildProjectDirectory)\..\..\..\deps\libnfs\rquota;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;$(MSBuildProjectDirectory)\..\..\..\gfx\include\d3d9;%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp Fast @@ -1004,6 +1004,84 @@ CompileAsC + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + + + CompileAsC + /bigobj %(AdditionalOptions) diff --git a/qb/config.libs.sh b/qb/config.libs.sh index 2c942bc8e06c..3f0e2a7ebd29 100644 --- a/qb/config.libs.sh +++ b/qb/config.libs.sh @@ -906,6 +906,7 @@ fi # First try system libsmb2 check_pkgconf SMBCLIENT libsmb2 0.0 check_enabled NETWORKING SMBCLIENT libsmb2 'SMB client support is' false +check_enabled NETWORKING BUILTINSMBCLIENT libsmb2 'SMB client support is' false if [ "$HAVE_SMBCLIENT" = "yes" ]; then echo "SMB support enabled (system libsmb2)" @@ -914,3 +915,16 @@ elif [ "$HAVE_BUILTINSMBCLIENT" = "yes" ] || [ "$HAVE_BUILTINSMBCLIENT" = "auto" echo "SMB support - building bundled libsmb2" add_dirs INCLUDE ./deps/libsmb2/include fi + +# First try system libnfs +check_pkgconf NFSCLIENT libnfs 0.0 +check_enabled NETWORKING NFSCLIENT libnfs 'NFS client support is' false +check_enabled NETWORKING BUILTINNFSCLIENT libnfs 'NFS client support is' false + +if [ "$HAVE_NFSCLIENT" = "yes" ]; then + echo "NFS support enabled (system libnfs)" +elif [ "$HAVE_BUILTINNFSCLIENT" = "yes" ] || [ "$HAVE_BUILTINNFSCLIENT" = "auto" ]; then + HAVE_BUILTINNFSCLIENT=yes + echo "NFS support - building bundled libnfs" + add_dirs INCLUDE ./deps/libnfs/include +fi diff --git a/qb/config.params.sh b/qb/config.params.sh index 8db13d9ebb5f..855ec0dfa6c3 100644 --- a/qb/config.params.sh +++ b/qb/config.params.sh @@ -225,6 +225,8 @@ HAVE_TEST_DRIVERS=yes # Test input driver HAVE_GAME_AI=no HAVE_SMBCLIENT=auto # SMB client support HAVE_BUILTINSMBCLIENT=no # Use builtin libsmb2 +HAVE_NFSCLIENT=auto # NFS client support +HAVE_BUILTINNFSCLIENT=auto # Use builtin libnfs when system libnfs is unavailable HAVE_COCOA=auto # Cocoa support (Darwin/Apple) HAVE_RETROARCH_PLAYLIST_MANAGER=auto # iOS/tvOS + macOS 10.11+ playlist helper (see qb/config.libs.sh) HAVE_MFI=auto # GameController.framework joypad support (Apple) diff --git a/retroarch.c b/retroarch.c index 55cc648add96..ebf84e5cfa05 100644 --- a/retroarch.c +++ b/retroarch.c @@ -78,6 +78,9 @@ #ifdef HAVE_SMBCLIENT #include "libretro-common/vfs/vfs_implementation_smb.h" #endif +#ifdef HAVE_NFSCLIENT +#include "libretro-common/vfs/vfs_implementation_nfs.h" +#endif #include @@ -402,6 +405,23 @@ void retroarch_smb_init(void) } #endif +#ifdef HAVE_NFSCLIENT +static struct nfs_settings nfs_global_cfg; + +void retroarch_nfs_init(void) +{ + settings_t *settings = config_get_ptr(); + + nfs_global_cfg.server_address = settings->arrays.nfs_client_server_address; + nfs_global_cfg.export_path = settings->arrays.nfs_client_export; + nfs_global_cfg.subdir = settings->arrays.nfs_client_subdir; + nfs_global_cfg.timeout = settings->uints.nfs_client_timeout; + nfs_global_cfg.num_contexts = settings->uints.nfs_client_num_contexts; + + nfs_init_cfg(&nfs_global_cfg); +} +#endif + static location_driver_t location_null = { NULL, NULL, @@ -6526,6 +6546,10 @@ int rarch_main(int argc, char *argv[], void *data) retroarch_smb_init(); #endif +#ifdef HAVE_NFSCLIENT + retroarch_nfs_init(); +#endif + ui_companion_driver_init_first( #ifdef HAVE_QT settings->bools.desktop_menu_enable, @@ -9386,6 +9410,10 @@ bool retroarch_main_quit(void) smb_shutdown(); #endif +#ifdef HAVE_NFSCLIENT + nfs_shutdown(); +#endif + return true; } diff --git a/settings/settings_def_netplay_action.h b/settings/settings_def_netplay_action.h index 838e5970972d..c4f39995efdf 100644 --- a/settings/settings_def_netplay_action.h +++ b/settings/settings_def_netplay_action.h @@ -10,3 +10,9 @@ S_ACTION(SMB_CLIENT_SETTINGS, "SMB Network Settings", "Configure SMB network share settings.") #endif +#ifdef HAVE_NFSCLIENT +S_ACTION(NFS_CLIENT_SETTINGS, + "nfs_client_settings", + "NFS Network Settings", + "Configure NFS network share settings.") +#endif diff --git a/settings/settings_def_nfs_client.h b/settings/settings_def_nfs_client.h new file mode 100644 index 000000000000..9b12c13f2999 --- /dev/null +++ b/settings/settings_def_nfs_client.h @@ -0,0 +1,13 @@ +/* Single-source definitions: NFS client setting. + * Grammar identical to settings_def_video_sync.h plus S_FLOAT and + * the _NS no-sublabel variants; the descriptor argument span + * matches SDESC__ROW; row order is menu display order; + * h2json.py parses these rows for the Crowdin source upload. */ + +#ifdef HAVE_NFSCLIENT +S_BOOL_EX(nfs_client_enable, NFS_CLIENT_ENABLE, + "nfs_client_enable", + false, SD_FLAG_ADVANCED, 0, 0, setting_bool_action_left_with_refresh, NULL, NULL, NULL, setting_bool_action_left_with_refresh, setting_bool_action_right_with_refresh, 0, + "Enable NFS Client", + "Enable NFS network share access. Ethernet is strongly recommended over Wi-Fi for a more reliable connection. Note: changing these settings requires a restart of RetroArch.") +#endif diff --git a/settings/settings_def_nfs_client_opts.h b/settings/settings_def_nfs_client_opts.h new file mode 100644 index 000000000000..b8b6fca721bc --- /dev/null +++ b/settings/settings_def_nfs_client_opts.h @@ -0,0 +1,20 @@ +/* Single-source definitions: NFS client options group. + * Grammar identical to settings_def_video_sync.h plus S_FLOAT and + * the _NS no-sublabel variants; the descriptor argument span + * matches SDESC__ROW; row order is menu display order; + * h2json.py parses these rows for the Crowdin source upload. */ + +#ifdef HAVE_NFSCLIENT +S_UINT_EX(nfs_client_num_contexts, NFS_CLIENT_NUM_CONTEXTS, + "nfs_client_num_contexts", + DEFAULT_NFS_CLIENT_NUM_CONTEXTS, SD_FLAG_ADVANCED, SDESC_RANGE_MINMAX, 0, 1, DEFAULT_NFS_CLIENT_MAX_CONTEXTS, 1, 0, setting_action_ok_uint, NULL, NULL, NULL, NULL, NULL, 0, + "NFS Maximum connections", + "Select the maximum connections used in your environment.") +#endif +#ifdef HAVE_NFSCLIENT +S_UINT_EX(nfs_client_timeout, NFS_CLIENT_TIMEOUT, + "nfs_client_timeout", + DEFAULT_NFS_CLIENT_TIMEOUT, SD_FLAG_ADVANCED, SDESC_RANGE_MINMAX, 0, 1, DEFAULT_NFS_CLIENT_MAX_TIMEOUT, 1, 0, setting_action_ok_uint, NULL, NULL, NULL, NULL, NULL, 0, + "NFS Timeout", + "Select the default timeout in seconds.") +#endif diff --git a/settings/settings_def_settings_show_nfs.h b/settings/settings_def_settings_show_nfs.h new file mode 100644 index 000000000000..f6104105ae96 --- /dev/null +++ b/settings/settings_def_settings_show_nfs.h @@ -0,0 +1,13 @@ +/* Single-source definitions: NFS client settings visibility setting. + * Grammar identical to settings_def_video_sync.h plus S_FLOAT and + * the _NS no-sublabel variants; the descriptor argument span + * matches SDESC__ROW; row order is menu display order; + * h2json.py parses these rows for the Crowdin source upload. */ + +#if defined(HAVE_MENU) && defined(HAVE_NFSCLIENT) +S_BOOL(settings_show_nfs_client, SETTINGS_SHOW_NFS_CLIENT, + "settings_show_nfs_client", + DEFAULT_SETTINGS_SHOW_NFS_CLIENT, SD_FLAG_NONE, 0, 0, + "Show 'NFS Client'", + "Show 'NFS Client' settings.") +#endif diff --git a/tasks/task_content.c b/tasks/task_content.c index 15fd4b0e989e..2dd8fd1e13cc 100644 --- a/tasks/task_content.c +++ b/tasks/task_content.c @@ -63,6 +63,9 @@ #include #include #include +#ifdef HAVE_NFSCLIENT +#include "../libretro-common/vfs/vfs_implementation_nfs.h" +#endif #include #include "../msg_hash_lbl_str.h" @@ -1235,6 +1238,252 @@ static bool content_file_extract_from_archive( } #endif +/* Whether content_path must be staged to a local cache file before + * memory load / archive extract / core open. + * + * Local paths never stage here (extract handles archives separately). + * Network VFS URLs stage when: + * - nfs:// or smb:// with archive#entry (those VFS backends cannot + * open #entry — stage the archive, then reattach #entry), or + * - need_fullpath && core does not support VFS (any :// scheme). + * + * Cores with supports_vfs + need_fullpath may open nfs/smb URLs + * directly (stream CHD etc.). In-memory loads use frontend + * filestream/VFS without a disk stage. */ +static bool content_path_needs_stage( + const char *content_path, + bool need_fullpath, + bool supports_vfs) +{ + bool is_nfs_or_smb; + + if (!content_path || !*content_path) + return false; + if (!strstr(content_path, "://")) + return false; + + is_nfs_or_smb = + string_starts_with_case_insensitive(content_path, "nfs://") + || string_starts_with_case_insensitive(content_path, "smb://"); + + if (is_nfs_or_smb && path_get_archive_delim(content_path)) + return true; + + return need_fullpath && !supports_vfs; +} + +/* Shared stage path for VFS URLs (nfs://, smb://, and other :// schemes). + * Copies to a local cache file when content_path_needs_stage() says so. + * Keeps the file in cache (not temporary_files) so a failed load still + * leaves evidence, and Settings → Cache is the place to look. */ +static bool content_file_copy_vfs_url_to_cache( + content_information_ctx_t *content_ctx, + content_state_t *p_content, + const char **content_path, + char **err_string) +{ + RFILE *fp_src = NULL; + RFILE *fp_dst = NULL; + char new_path[PATH_MAX_LENGTH]; + char new_basedir[DIR_MAX_LENGTH]; + char archive_path[PATH_MAX_LENGTH]; + char staged_with_entry[PATH_MAX_LENGTH]; + char buf[64 * 1024]; + const char *basename_ptr; + const char *open_path; + const char *archive_delim; + const char *result_path; + int64_t n; + int64_t total = 0; + static char *staged_path = NULL; + + (void)p_content; + + if (!content_path || !*content_path || !**content_path) + return false; + + if (!strstr(*content_path, "://")) + return true; + + /* nfs/smb cannot open archive#entry paths — stage the archive only, + * then reattach #entry so local extract/load can run. */ + open_path = *content_path; + archive_delim = path_get_archive_delim(*content_path); + archive_path[0] = '\0'; + if (archive_delim) + { + size_t archive_len = (size_t)(archive_delim - *content_path); + if (archive_len == 0 || archive_len >= sizeof(archive_path)) + { + char msg[PATH_MAX_LENGTH]; + snprintf(msg, sizeof(msg), + "%s: bad archive path \"%.200s\"\n", + msg_hash_to_str(MSG_COULD_NOT_READ_CONTENT_FILE), + *content_path); + *err_string = strdup(msg); + return false; + } + memcpy(archive_path, *content_path, archive_len); + archive_path[archive_len] = '\0'; + open_path = archive_path; + } + + new_basedir[0] = '\0'; + if (content_ctx->directory_cache && *content_ctx->directory_cache) + strlcpy(new_basedir, content_ctx->directory_cache, sizeof(new_basedir)); +#if defined(WEBOS) + if (!*new_basedir) + { + const char *home = getenv("HOME"); + if (home && *home) + fill_pathname_join_special(new_basedir, home, "cache", + sizeof(new_basedir)); + } +#endif +#if !defined(_WIN32) && !defined(__WINRT__) + if (!*new_basedir) + strlcpy(new_basedir, "/tmp", sizeof(new_basedir)); +#endif + + if (!*new_basedir) + { + char msg[PATH_MAX_LENGTH]; + snprintf(msg, sizeof(msg), + "%s: \"%.160s\". (cache directory not set — set Directories → Cache)\n", + msg_hash_to_str(MSG_COULD_NOT_READ_CONTENT_FILE), + *content_path); + *err_string = strdup(msg); + return false; + } + + if (!path_is_directory(new_basedir) && !path_mkdir(new_basedir)) + { + char msg[PATH_MAX_LENGTH]; + snprintf(msg, sizeof(msg), + "%s: cannot create cache dir \"%.200s\".\n", + msg_hash_to_str(MSG_COULD_NOT_READ_CONTENT_FILE), + new_basedir); + *err_string = strdup(msg); + return false; + } + + /* Keep network staged files under a dedicated subdir. */ + { + char staged_dir[DIR_MAX_LENGTH]; + fill_pathname_join_special(staged_dir, new_basedir, "vfs_stage", + sizeof(staged_dir)); + strlcpy(new_basedir, staged_dir, sizeof(new_basedir)); + } + + if (!path_is_directory(new_basedir) && !path_mkdir(new_basedir)) + { + char msg[PATH_MAX_LENGTH]; + snprintf(msg, sizeof(msg), + "%s: cannot create \"%.200s\".\n", + msg_hash_to_str(MSG_COULD_NOT_READ_CONTENT_FILE), + new_basedir); + *err_string = strdup(msg); + return false; + } + + basename_ptr = path_basename(open_path); + if (!basename_ptr || !*basename_ptr) + basename_ptr = "content.bin"; + + fill_pathname_join_special(new_path, new_basedir, + basename_ptr, sizeof(new_path)); + + RARCH_LOG("[Content] Staging VFS URL to cache: \"%s\" -> \"%s\"\n", + open_path, new_path); + + fp_src = filestream_open(open_path, + RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE); + if (!fp_src) + { + char msg[PATH_MAX_LENGTH]; +#if defined(HAVE_NFSCLIENT) + const char *nfs_err = NULL; + if (string_starts_with_case_insensitive(open_path, "nfs://")) + nfs_err = nfs_get_last_error(); + if (nfs_err && *nfs_err) + snprintf(msg, sizeof(msg), + "%s: open \"%.160s\" failed (%.80s)\n", + msg_hash_to_str(MSG_COULD_NOT_READ_CONTENT_FILE), + open_path, nfs_err); + else +#endif + snprintf(msg, sizeof(msg), + "%s: open \"%.200s\" failed\n", + msg_hash_to_str(MSG_COULD_NOT_READ_CONTENT_FILE), + open_path); + *err_string = strdup(msg); + return false; + } + + fp_dst = filestream_open(new_path, + RETRO_VFS_FILE_ACCESS_WRITE, RETRO_VFS_FILE_ACCESS_HINT_NONE); + if (!fp_dst) + { + char msg[PATH_MAX_LENGTH]; + filestream_close(fp_src); + snprintf(msg, sizeof(msg), + "%s: cannot write \"%.200s\"\n", + msg_hash_to_str(MSG_COULD_NOT_READ_CONTENT_FILE), + new_path); + *err_string = strdup(msg); + return false; + } + + while ((n = filestream_read(fp_src, buf, sizeof(buf))) > 0) + { + if (filestream_write(fp_dst, buf, n) != n) + { + char msg[PATH_MAX_LENGTH]; + filestream_close(fp_src); + filestream_close(fp_dst); + snprintf(msg, sizeof(msg), + "%s: write failed at %lld bytes -> \"%.180s\"\n", + msg_hash_to_str(MSG_COULD_NOT_READ_CONTENT_FILE), + (long long)total, new_path); + *err_string = strdup(msg); + return false; + } + total += n; + } + + filestream_close(fp_src); + filestream_close(fp_dst); + + if (total <= 0) + { + char msg[PATH_MAX_LENGTH]; + snprintf(msg, sizeof(msg), + "%s: read 0 bytes from \"%.200s\"\n", + msg_hash_to_str(MSG_COULD_NOT_READ_CONTENT_FILE), + open_path); + *err_string = strdup(msg); + return false; + } + + result_path = new_path; + if (archive_delim) + { + strlcpy(staged_with_entry, new_path, sizeof(staged_with_entry)); + strlcat(staged_with_entry, archive_delim, sizeof(staged_with_entry)); + result_path = staged_with_entry; + } + + free(staged_path); + staged_path = strdup(result_path); + if (!staged_path) + return false; + + *content_path = staged_path; + RARCH_LOG("[Content] Staged %lld bytes at \"%s\".\n", + (long long)total, result_path); + return true; +} + static void content_file_get_path( struct string_list *content, size_t idx, @@ -1384,9 +1633,7 @@ static bool content_file_load( size_t i; retro_ctx_load_content_info_t load_info; bool used_vfs_fallback_copy = false; -#ifdef __WINRT__ rarch_system_info_t *sys_info = &runloop_state_get_ptr()->system; -#endif enum rarch_content_type first_content_type = RARCH_CONTENT_NONE; for (i = 0; i < content->size; i++) @@ -1425,6 +1672,30 @@ static bool content_file_load( if (p_content->content_override_list) content_file_apply_overrides(p_content, content, i, content_path); + /* One stage path for local+nfs+smb (and other :// schemes): + * decide via content_path_needs_stage(), then either continue + * with the (possibly remote) path or a local cache copy. + * After staging, local extract/memory load runs unchanged. */ + { + bool need_fullpath = ((content->elems[i].attr.i + & BLCK_NEED_FULLPATH) != 0); + bool supports_vfs = (sys_info && sys_info->supports_vfs); + + if (content_path_needs_stage(content_path, + need_fullpath, supports_vfs)) + { + if (!content_file_copy_vfs_url_to_cache(content_ctx, p_content, + &content_path, err_string)) + return false; + /* Match prior fallback-copy error reporting: only when + * staging was required because the core lacks VFS. */ + if (need_fullpath && !supports_vfs) + used_vfs_fallback_copy = true; + content_compressed = path_is_compressed_file(content_path) + || path_contains_compressed_file(content_path); + } + } + /* If core does not require 'fullpath', load * the content into memory */ @@ -2727,6 +2998,12 @@ static bool task_content_defer_menu_load(content_state_t *p_content, * ("foo.zip#rom") is stable and may defer. */ if (!strncmp(fullpath, "content://", STRLEN_CONST("content://"))) return false; + /* Network VFS URLs need synchronous staging in content_file_load; + * prefetch reads them raw and skips on size/open failure, which + * leaves a confusing "core failed" style load. */ + if (string_starts_with_case_insensitive(fullpath, "nfs://") + || string_starts_with_case_insensitive(fullpath, "smb://")) + return false; if ( path_is_compressed_file(fullpath) && !path_contains_compressed_file(fullpath)) return false; /* bare archive: load picks entry */