ZDR: New builtin replacement for RPC/XDR called ZDR
[deb_libnfs.git] / lib / libnfs.c
index 71c6e9cb1b2ad78b3a3783ff0a962810fafd349d..5754bfbc6489ad097050f204531e96e663a70a7a 100644 (file)
@@ -37,6 +37,8 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <netinet/in.h>
+#include "libnfs-zdr.h"
 #include "libnfs.h"
 #include "libnfs-raw.h"
 #include "libnfs-raw-mount.h"
@@ -51,7 +53,7 @@ struct nfsdir {
 struct nfsfh {
        struct nfs_fh3 fh;
        int is_sync;
-       off_t offset;
+       uint64_t offset;
 };
 
 struct nfs_context {
@@ -59,8 +61,8 @@ struct nfs_context {
        char *server;
        char *export;
        struct nfs_fh3 rootfh;
-       size_t readmax;
-       size_t writemax;
+       uint64_t readmax;
+       uint64_t writemax;
 };
 
 void nfs_free_nfsdir(struct nfsdir *nfsdir)
@@ -98,14 +100,14 @@ struct nfs_cb_data {
        int error;
        int cancel;
        int num_calls;
-       off_t start_offset, max_offset;
+       uint64_t start_offset, max_offset;
        char *buffer;
 };
 
 struct nfs_mcb_data {
        struct nfs_cb_data *data;
-       off_t offset;
-       size_t count;
+       uint64_t offset;
+       uint64_t count;
 };
 
 static int nfs_lookup_path_async_internal(struct nfs_context *nfs, struct nfs_cb_data *data, struct nfs_fh3 *fh);
@@ -459,7 +461,7 @@ static void nfs_mount_2_cb(struct rpc_context *rpc, int status, void *command_da
                return;
        }
 
-       if (rpc_pmap_getport_async(rpc, MOUNT_PROGRAM, MOUNT_V3, nfs_mount_3_cb, private_data) != 0) {
+       if (rpc_pmap_getport_async(rpc, MOUNT_PROGRAM, MOUNT_V3, IPPROTO_TCP, nfs_mount_3_cb, private_data) != 0) {
                data->cb(-ENOMEM, nfs, command_data, data->private_data);
                free_nfs_cb_data(data);
                return;
@@ -686,6 +688,9 @@ static void nfs_stat_1_cb(struct rpc_context *rpc _U_, int status, void *command
        if (res->GETATTR3res_u.resok.obj_attributes.type == NF3DIR) {
                st.st_mode |= S_IFDIR ;
        }
+       if (res->GETATTR3res_u.resok.obj_attributes.type == NF3REG) {
+               st.st_mode |= S_IFREG ;
+       }
         st.st_nlink   = res->GETATTR3res_u.resok.obj_attributes.nlink;
         st.st_uid     = res->GETATTR3res_u.resok.obj_attributes.uid;
         st.st_gid     = res->GETATTR3res_u.resok.obj_attributes.gid;
@@ -934,7 +939,7 @@ static void nfs_pread_mcb(struct rpc_context *rpc _U_, int status, void *command
        free(mdata);
 }
 
-int nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, size_t count, nfs_cb cb, void *private_data)
+int nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset, uint64_t count, nfs_cb cb, void *private_data)
 {
        struct nfs_cb_data *data;
 
@@ -977,7 +982,7 @@ int nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset,
        }
 
        while (count > 0) {
-               size_t readcount = count;
+               uint64_t readcount = count;
                struct nfs_mcb_data *mdata;
 
                if (readcount > nfs_get_readmax(nfs)) {
@@ -1011,7 +1016,7 @@ int nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset,
 /*
  * Async read()
  */
-int nfs_read_async(struct nfs_context *nfs, struct nfsfh *nfsfh, size_t count, nfs_cb cb, void *private_data)
+int nfs_read_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t count, nfs_cb cb, void *private_data)
 {
        return nfs_pread_async(nfs, nfsfh, nfsfh->offset, count, cb, private_data);
 }
@@ -1110,7 +1115,7 @@ static void nfs_pwrite_mcb(struct rpc_context *rpc _U_, int status, void *comman
 }
 
 
-int nfs_pwrite_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, size_t count, char *buf, nfs_cb cb, void *private_data)
+int nfs_pwrite_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset, uint64_t count, char *buf, nfs_cb cb, void *private_data)
 {
        struct nfs_cb_data *data;
 
@@ -1145,7 +1150,7 @@ int nfs_pwrite_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset,
        data->start_offset = offset;
 
        while (count > 0) {
-               size_t writecount = count;
+               uint64_t writecount = count;
                struct nfs_mcb_data *mdata;
 
                if (writecount > nfs_get_writemax(nfs)) {
@@ -1180,7 +1185,7 @@ int nfs_pwrite_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset,
 /*
  * Async write()
  */
-int nfs_write_async(struct nfs_context *nfs, struct nfsfh *nfsfh, size_t count, char *buf, nfs_cb cb, void *private_data)
+int nfs_write_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t count, char *buf, nfs_cb cb, void *private_data)
 {
        return nfs_pwrite_async(nfs, nfsfh, nfsfh->offset, count, buf, cb, private_data);
 }
@@ -1326,7 +1331,7 @@ static void nfs_ftruncate_cb(struct rpc_context *rpc _U_, int status, void *comm
        free_nfs_cb_data(data);
 }
 
-int nfs_ftruncate_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t length, nfs_cb cb, void *private_data)
+int nfs_ftruncate_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t length, nfs_cb cb, void *private_data)
 {
        struct nfs_cb_data *data;
        SETATTR3args args;
@@ -1362,7 +1367,7 @@ int nfs_ftruncate_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t leng
  */
 static int nfs_truncate_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data)
 {
-       off_t offset = data->continue_int;
+       uint64_t offset = data->continue_int;
        struct nfsfh nfsfh;
 
        nfsfh.fh.data.data_val = data->fh.data.data_val;
@@ -1378,9 +1383,9 @@ static int nfs_truncate_continue_internal(struct nfs_context *nfs, struct nfs_cb
        return 0;
 }
 
-int nfs_truncate_async(struct nfs_context *nfs, const char *path, off_t length, nfs_cb cb, void *private_data)
+int nfs_truncate_async(struct nfs_context *nfs, const char *path, uint64_t length, nfs_cb cb, void *private_data)
 {
-       off_t offset;
+       uint64_t offset;
 
        offset = length;
 
@@ -1433,10 +1438,18 @@ static void nfs_mkdir_cb(struct rpc_context *rpc _U_, int status, void *command_
 static int nfs_mkdir_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data)
 {
        char *str = data->continue_data;
-       
+       MKDIR3args args;
+
        str = &str[strlen(str) + 1];
 
-       if (rpc_nfs_mkdir_async(nfs->rpc, nfs_mkdir_cb, &data->fh, str, data) != 0) {
+       memset(&args, 0, sizeof(MKDIR3args));
+       args.where.dir.data.data_len = data->fh.data.data_len;
+       args.where.dir.data.data_val = data->fh.data.data_val;
+       args.where.name = str;
+       args.attributes.mode.set_it = 1;
+       args.attributes.mode.set_mode3_u.mode = 0755;
+
+       if (rpc_nfs_mkdir_async(nfs->rpc, nfs_mkdir_cb, &args, data) != 0) {
                rpc_set_error(nfs->rpc, "RPC error: Failed to send MKDIR call for %s", data->path);
                data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data);
                free_nfs_cb_data(data);
@@ -1646,10 +1659,20 @@ static void nfs_creat_1_cb(struct rpc_context *rpc _U_, int status, void *comman
 static int nfs_creat_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data)
 {
        char *str = data->continue_data;
-       
+       CREATE3args args;
+
        str = &str[strlen(str) + 1];
 
-       if (rpc_nfs_create_async(nfs->rpc, nfs_creat_1_cb, &data->fh, str, data->continue_int, data) != 0) {
+
+       memset(&args, 0, sizeof(CREATE3args));
+       args.where.dir.data.data_len = data->fh.data.data_len;
+       args.where.dir.data.data_val = data->fh.data.data_val;
+       args.where.name = str;
+       args.how.mode = UNCHECKED;
+       args.how.createhow3_u.obj_attributes.mode.set_it = 1;
+       args.how.createhow3_u.obj_attributes.mode.set_mode3_u.mode = data->continue_int;
+
+       if (rpc_nfs_create_async(nfs->rpc, nfs_creat_1_cb, &args, data) != 0) {
                rpc_set_error(nfs->rpc, "RPC error: Failed to send CREATE call for %s/%s", data->path, str);
                data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data);
                free_nfs_cb_data(data);
@@ -2222,7 +2245,7 @@ void nfs_closedir(struct nfs_context *nfs _U_, struct nfsdir *nfsdir)
 struct lseek_cb_data {
        struct nfs_context *nfs;
        struct nfsfh *nfsfh;
-       off_t offset;
+       uint64_t offset;
        nfs_cb cb;
        void *private_data;
 };
@@ -2257,7 +2280,7 @@ static void nfs_lseek_1_cb(struct rpc_context *rpc _U_, int status, void *comman
        free(data);
 }
 
-int nfs_lseek_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, int whence, nfs_cb cb, void *private_data)
+int nfs_lseek_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset, int whence, nfs_cb cb, void *private_data)
 {
        struct lseek_cb_data *data;
 
@@ -2399,7 +2422,12 @@ static void nfs_readlink_1_cb(struct rpc_context *rpc _U_, int status, void *com
 
 static int nfs_readlink_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data)
 {
-       if (rpc_nfs_readlink_async(nfs->rpc, nfs_readlink_1_cb, &data->fh, data) != 0) {
+       READLINK3args args;
+
+       args.symlink.data.data_len = data->fh.data.data_len; 
+       args.symlink.data.data_val = data->fh.data.data_val; 
+
+       if (rpc_nfs_readlink_async(nfs->rpc, nfs_readlink_1_cb, &args, data) != 0) {
                rpc_set_error(nfs->rpc, "RPC error: Failed to send READLINK call for %s", data->path);
                data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data);
                free_nfs_cb_data(data);
@@ -2920,8 +2948,17 @@ static void nfs_symlink_cb(struct rpc_context *rpc _U_, int status, void *comman
 static int nfs_symlink_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data)
 {
        struct nfs_symlink_data *symlink_data = data->continue_data;
+       SYMLINK3args sa;
+
+       memset(&sa, 0, sizeof(SYMLINK3args));
+       sa.where.dir.data.data_len = data->fh.data.data_len;
+       sa.where.dir.data.data_val = data->fh.data.data_val;
+       sa.where.name = symlink_data->newpathobject;
+       sa.symlink.symlink_attributes.mode.set_it = 1;
+       sa.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;
+       sa.symlink.symlink_data = symlink_data->oldpath;
 
-       if (rpc_nfs_symlink_async(nfs->rpc, nfs_symlink_cb, &data->fh, symlink_data->newpathobject, symlink_data->oldpath, data) != 0) {
+       if (rpc_nfs_symlink_async(nfs->rpc, nfs_symlink_cb, &sa, data) != 0) {
                rpc_set_error(nfs->rpc, "RPC error: Failed to send SYMLINK call for %s", data->path);
                data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data);
                free_nfs_cb_data(data);
@@ -3286,7 +3323,7 @@ int nfs_link_async(struct nfs_context *nfs, const char *oldpath, const char *new
 
 
 //qqq replace later with lseek()
-off_t nfs_get_current_offset(struct nfsfh *nfsfh)
+uint64_t nfs_get_current_offset(struct nfsfh *nfsfh)
 {
        return nfsfh->offset;
 }
@@ -3296,7 +3333,7 @@ off_t nfs_get_current_offset(struct nfsfh *nfsfh)
 /*
  * Get the maximum supported READ3 size by the server
  */
-size_t nfs_get_readmax(struct nfs_context *nfs)
+uint64_t nfs_get_readmax(struct nfs_context *nfs)
 {
        return nfs->readmax;
 }
@@ -3304,9 +3341,9 @@ size_t nfs_get_readmax(struct nfs_context *nfs)
 /*
  * Get the maximum supported WRITE3 size by the server
  */
-size_t nfs_get_writemax(struct nfs_context *nfs)
+uint64_t nfs_get_writemax(struct nfs_context *nfs)
 {
-       /* Some XDR libraries can not marshall PDUs bigger than this */
+       /* Some ZDR libraries can not marshall PDUs bigger than this */
         if (nfs->writemax < 32768) {
                return nfs->writemax;
        }
@@ -3440,7 +3477,7 @@ static void mount_export_2_cb(struct rpc_context *rpc, int status, void *command
                return;
        }
 
-       if (rpc_pmap_getport_async(rpc, MOUNT_PROGRAM, MOUNT_V3, mount_export_3_cb, private_data) != 0) {
+       if (rpc_pmap_getport_async(rpc, MOUNT_PROGRAM, MOUNT_V3, IPPROTO_TCP, mount_export_3_cb, private_data) != 0) {
                data->cb(rpc, -ENOMEM, command_data, data->private_data);
                free_mount_cb_data(data);
                return;
@@ -3509,3 +3546,10 @@ const char *nfs_get_export(struct nfs_context *nfs) {
        return nfs->export;
 }
 
+const struct nfs_fh3 *nfs_get_rootfh(struct nfs_context *nfs) {
+      return &nfs->rootfh;
+}
+
+struct nfs_fh3 *nfs_get_fh(struct nfsfh *nfsfh) {
+       return &nfsfh->fh;
+}