Merge branch 'win32' into win32-3
authorRonnie Sahlberg <ronniesahlberg@gmail.com>
Sat, 3 Sep 2011 00:57:42 +0000 (10:57 +1000)
committerRonnie Sahlberg <ronniesahlberg@gmail.com>
Sat, 3 Sep 2011 00:57:42 +0000 (10:57 +1000)
README
configure.ac
include/libnfs-raw.h
include/libnfs.h
lib/libnfs-sync.c
lib/libnfs.c
lib/socket.c
nfs/nfs.c

diff --git a/README b/README
index cab6aa646a563dd53c50120bdd4cf549bc067721..cd1600f94d35ce7fff726ab540a1cda365bd437d 100644 (file)
--- a/README
+++ b/README
@@ -44,6 +44,7 @@ Cygwin: - tested under 64bit win2k8.
 MacOSX: - tested with SDK 10.4 (under Snow Leopard) - should also work with later SDKs and 64Bit
 iOS:    - tested with iOS SDK 4.2 - running on iOS 4.3.x
 FreeBSD:- tested with 8.2
+OpenSolaris
 
 
 Cygwin
index a569f7016d914ac7839d69a0f61a138c0e0e1c38..1b21947fcd9ab8266bdc9b1914ca36dab854d24f 100644 (file)
@@ -49,6 +49,7 @@ case $host in
     ;;
   *solaris*)
     AC_CHECK_HEADERS([sys/filio.h])
+    AC_CHECK_HEADERS([sys/sockio.h])
     if test x$ENABLE_EXAMPLES = xyes; then
       AC_CHECK_LIB([socket], [main], , [AC_MSG_ERROR([Can not find required library])])
       AC_CHECK_LIB([nsl],    [main], , [AC_MSG_ERROR([Can not find required library])])
index 1650a8a18406621702f04c4bf0cc3bbacfddc033..573205c9c876c9ca48d38377806ea68369e0f1b4 100644 (file)
@@ -444,7 +444,7 @@ int rpc_nfs_remove_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh,
 
 
 /*
- * Call NFS/REMOVE
+ * Call NFS/READDIR
  * Function returns
  *  0 : The call was initiated. The callback will be invoked when the call completes.
  * <0 : An error occured when trying to set up the call. The callback will not be invoked.
@@ -459,6 +459,22 @@ int rpc_nfs_remove_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh,
  */
 int rpc_nfs_readdir_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, uint64_t cookie, char *cookieverf, int count, void *private_data);
 
+/*
+ * Call NFS/READDIRPLUS
+ * Function returns
+ *  0 : The call was initiated. The callback will be invoked when the call completes.
+ * <0 : An error occured when trying to set up the call. The callback will not be invoked.
+ *
+ * When the callback is invoked, status indicates the result:
+ * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon.
+ *                      data is READDIRPLUS3res *
+ * RPC_STATUS_ERROR   : An error occured when trying to contact the nfs daemon.
+ *                      data is the error string.
+ * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete.
+ *                     data is NULL.
+ */
+int rpc_nfs_readdirplus_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, uint64_t cookie, char *cookieverf, int count, void *private_data);
+
 /*
  * Call NFS/FSSTAT
  * Function returns
index c72b7cf537622ed29ea9a2b981d1d4d44fae6c3f..dd63f9623816f8b4a3d67b28ed89555e7af5048e 100644 (file)
@@ -611,6 +611,14 @@ struct nfsdirent  {
        struct nfsdirent *next;
        char *name;
        uint64_t inode;
+
+       /* some extra fields we get for free through the READDIRPLUS3 call. You need libnfs-raw-nfs.h for these */
+       uint32_t type; /* NF3REG, NF3DIR, NF3BLK, ... */
+       uint32_t mode;
+       uint64_t size;
+       struct timeval atime;
+       struct timeval mtime;
+       struct timeval ctime;
 };
 /*
  * nfs_readdir() never blocks, so no special sync/async versions are available
index 3d3692b403ebcf18c1d117b890f3984bb1b50cd9..cfeb5759989ae3835172001e6719efca138758e0 100644 (file)
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <errno.h>
+#include <poll.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netdb.h>
+#ifdef HAVE_SYS_SOCKIO_H
+#include <sys/sockio.h>
+#endif
 #include "libnfs.h"
 #include "libnfs-raw.h"
 #include "libnfs-raw-mount.h"
index df8ae802cf6149537c73ced356bff11e8406fa5b..eee5d5a6dbb8e4b6c8f755f7adbe2129289d35e6 100644 (file)
@@ -1663,13 +1663,13 @@ int nfs_unlink_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void
  */
 static void nfs_opendir_cb(struct rpc_context *rpc _U_, int status, void *command_data, void *private_data)
 {
-       READDIR3res *res;
+       READDIRPLUS3res *res;
        struct nfs_cb_data *data = private_data;
        struct nfs_context *nfs = data->nfs;
        struct nfsdir *nfsdir = data->continue_data;
-       struct entry3 *entry;
+       struct entryplus3 *entry;
        uint64_t cookie;
-       
+
        if (status == RPC_STATUS_ERROR) {
                data->cb(-EFAULT, nfs, command_data, data->private_data);
                nfs_free_nfsdir(nfsdir);
@@ -1695,7 +1695,7 @@ static void nfs_opendir_cb(struct rpc_context *rpc _U_, int status, void *comman
                return;
        }
 
-       entry =res->READDIR3res_u.resok.reply.entries;
+       entry =res->READDIRPLUS3res_u.resok.reply.entries;
        while (entry != NULL) {
                struct nfsdirent *nfsdirent;
 
@@ -1717,6 +1717,19 @@ static void nfs_opendir_cb(struct rpc_context *rpc _U_, int status, void *comman
                        return;
                }
                nfsdirent->inode = entry->fileid;
+               if (entry->name_attributes.attributes_follow) {
+                       nfsdirent->type = entry->name_attributes.post_op_attr_u.attributes.type;
+                       nfsdirent->mode = entry->name_attributes.post_op_attr_u.attributes.mode;
+                       nfsdirent->size = entry->name_attributes.post_op_attr_u.attributes.size;
+
+                       nfsdirent->atime.tv_sec  = entry->name_attributes.post_op_attr_u.attributes.atime.seconds;
+                       nfsdirent->atime.tv_usec = entry->name_attributes.post_op_attr_u.attributes.atime.nseconds/1000;
+                       nfsdirent->mtime.tv_sec  = entry->name_attributes.post_op_attr_u.attributes.mtime.seconds;
+                       nfsdirent->mtime.tv_usec = entry->name_attributes.post_op_attr_u.attributes.mtime.nseconds/1000;
+                       nfsdirent->ctime.tv_sec  = entry->name_attributes.post_op_attr_u.attributes.ctime.seconds;
+                       nfsdirent->ctime.tv_usec = entry->name_attributes.post_op_attr_u.attributes.ctime.nseconds/1000;
+               }
+
                nfsdirent->next  = nfsdir->entries;
                nfsdir->entries  = nfsdirent;
 
@@ -1724,9 +1737,9 @@ static void nfs_opendir_cb(struct rpc_context *rpc _U_, int status, void *comman
                entry  = entry->nextentry;
        }
 
-       if (res->READDIR3res_u.resok.reply.eof == 0) {
-               if (rpc_nfs_readdir_async(nfs->rpc, nfs_opendir_cb, &data->fh, cookie, res->READDIR3res_u.resok.cookieverf, 20000, data) != 0) {
-                       rpc_set_error(nfs->rpc, "RPC error: Failed to send READDIR call for %s", data->path);
+       if (res->READDIRPLUS3res_u.resok.reply.eof == 0) {
+               if (rpc_nfs_readdirplus_async(nfs->rpc, nfs_opendir_cb, &data->fh, cookie, res->READDIRPLUS3res_u.resok.cookieverf, 8192, data) != 0) {
+                       rpc_set_error(nfs->rpc, "RPC error: Failed to send READDIRPLUS call for %s", data->path);
                        data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data);
                        nfs_free_nfsdir(nfsdir);
                        data->continue_data = NULL;
@@ -1749,8 +1762,8 @@ static int nfs_opendir_continue_internal(struct nfs_context *nfs, struct nfs_cb_
        cookieverf3 cv;
 
        bzero(cv, sizeof(cookieverf3));
-       if (rpc_nfs_readdir_async(nfs->rpc, nfs_opendir_cb, &data->fh, 0, (char *)&cv, 20000, data) != 0) {
-               rpc_set_error(nfs->rpc, "RPC error: Failed to send READDIR call for %s", data->path);
+       if (rpc_nfs_readdirplus_async(nfs->rpc, nfs_opendir_cb, &data->fh, 0, (char *)&cv, 8192, data) != 0) {
+               rpc_set_error(nfs->rpc, "RPC error: Failed to send READDIRPLUS call for %s", data->path);
                data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data);
                free_nfs_cb_data(data);
                return -1;
@@ -3111,6 +3124,7 @@ int poll(struct pollfd *fds, int nfsd, int timeout)
        if (FD_ISSET(fds->fd, &efds)) {
                fds->revents |= POLLHUP;
        }
+       return 1;
 }
 #endif
 
index 4d4859edf3aa151ad23dea11e0072475870c1ee0..e9c103e55b0cd124ce04baaeef1721fb43d5e5fd 100644 (file)
@@ -43,6 +43,9 @@
 #ifdef HAVE_SYS_FILIO_H
 #include <sys/filio.h>
 #endif
+#ifdef HAVE_SYS_SOCKIO_H
+#include <sys/sockio.h>
+#endif
 #include <sys/types.h>
 #include "libnfs.h"
 #include "libnfs-raw.h"
index a32521e4a8b1e6d24ab1b21ce978586ec89b0264..0c8ff79857f84670e2f9dc48891d4f03c7f88c8b 100644 (file)
--- a/nfs/nfs.c
+++ b/nfs/nfs.c
@@ -489,7 +489,6 @@ int rpc_nfs_remove_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh,
        return 0;
 }
 
-
 int rpc_nfs_readdir_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, uint64_t cookie, char *cookieverf, int count, void *private_data)
 {
        struct rpc_pdu *pdu;
@@ -523,6 +522,40 @@ int rpc_nfs_readdir_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh
        return 0;
 }
 
+int rpc_nfs_readdirplus_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, uint64_t cookie, char *cookieverf, int count, void *private_data)
+{
+       struct rpc_pdu *pdu;
+       READDIRPLUS3args args;
+
+       pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_READDIRPLUS, cb, private_data, (xdrproc_t)xdr_READDIRPLUS3res, sizeof(READDIRPLUS3res));
+       if (pdu == NULL) {
+               rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nfs/readdirplus call");
+               return -1;
+       }
+
+       bzero(&args, sizeof(READDIRPLUS3args));
+       args.dir.data.data_len = fh->data.data_len;
+       args.dir.data.data_val = fh->data.data_val;
+       args.cookie = cookie;
+       memcpy(&args.cookieverf, cookieverf, sizeof(cookieverf3)); 
+       args.dircount = count;
+       args.maxcount = count;
+
+       if (xdr_READDIRPLUS3args(&pdu->xdr, &args) == 0) {
+               rpc_set_error(rpc, "XDR error: Failed to encode READDIRPLUS3args");
+               rpc_free_pdu(rpc, pdu);
+               return -2;
+       }
+
+       if (rpc_queue_pdu(rpc, pdu) != 0) {
+               rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nfs/readdirplus call");
+               rpc_free_pdu(rpc, pdu);
+               return -3;
+       }
+
+       return 0;
+}
+
 int rpc_nfs_fsstat_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data)
 {
        struct rpc_pdu *pdu;