X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=lib%2Flibnfs.c;h=a70e6ac57e6ad7a68bf938f2dc01eb4c30538900;hb=a3d6cf111ed6c756b4483eb02486c046a3d0195b;hp=8d27a816b0fa079b6a28a090aa764a99767b08f1;hpb=2e4db0d14597fdb0013fb16f24b3f872d1217397;p=deb_libnfs.git diff --git a/lib/libnfs.c b/lib/libnfs.c index 8d27a81..a70e6ac 100644 --- a/lib/libnfs.c +++ b/lib/libnfs.c @@ -19,17 +19,27 @@ */ #define _GNU_SOURCE + +#if defined(WIN32) +#include +#define DllExport +#define O_SYNC 0 +typedef int uid_t; +typedef int gid_t; +#else +#include +#include +#include +#include +#endif + #include #include #include #include -#include #include #include #include -#include -#include -#include #include #include "libnfs.h" #include "libnfs-raw.h" @@ -107,7 +117,7 @@ static int nfs_lookup_path_async_internal(struct nfs_context *nfs, struct nfs_cb void nfs_set_auth(struct nfs_context *nfs, struct AUTH *auth) { - return rpc_set_auth(nfs->rpc, auth); + rpc_set_auth(nfs->rpc, auth); } int nfs_get_fd(struct nfs_context *nfs) @@ -144,6 +154,12 @@ struct nfs_context *nfs_init_context(void) return NULL; } + nfs->server = NULL; + nfs->export = NULL; + + nfs->rootfh.data.data_len = 0; + nfs->rootfh.data.data_val = NULL; + return nfs; } @@ -470,15 +486,26 @@ static void nfs_mount_1_cb(struct rpc_context *rpc, int status, void *command_da int nfs_mount_async(struct nfs_context *nfs, const char *server, const char *export, nfs_cb cb, void *private_data) { struct nfs_cb_data *data; + char *new_server, *new_export; data = malloc(sizeof(struct nfs_cb_data)); if (data == NULL) { rpc_set_error(nfs->rpc, "out of memory. failed to allocate memory for nfs mount data"); return -1; } - bzero(data, sizeof(struct nfs_cb_data)); - nfs->server = strdup(server); - nfs->export = strdup(export); + bzero((char *)data, sizeof(struct nfs_cb_data)); + new_server = strdup(server); + new_export = strdup(export); + if (nfs->server != NULL) { + free(nfs->server); + nfs->server = NULL; + } + nfs->server = new_server; + if (nfs->export != NULL) { + free(nfs->export); + nfs->export = NULL; + } + nfs->export = new_export; data->nfs = nfs; data->cb = cb; data->private_data = private_data; @@ -540,7 +567,7 @@ static int nfs_lookup_path_async_internal(struct nfs_context *nfs, struct nfs_cb } path = data->path; - str = index(path, '/'); + str = strchr(path, '/'); if (str != NULL) { *str = 0; data->path = str+1; @@ -587,7 +614,7 @@ static int nfs_lookuppath_async(struct nfs_context *nfs, const char *path, nfs_c rpc_set_error(nfs->rpc, "out of memory: failed to allocate nfs_cb_data structure"); return -1; } - bzero(data, sizeof(struct nfs_cb_data)); + bzero((char *)data, sizeof(struct nfs_cb_data)); data->nfs = nfs; data->cb = cb; data->continue_cb = continue_cb; @@ -654,8 +681,10 @@ static void nfs_stat_1_cb(struct rpc_context *rpc _U_, int status, void *command st.st_gid = res->GETATTR3res_u.resok.obj_attributes.gid; st.st_rdev = 0; st.st_size = res->GETATTR3res_u.resok.obj_attributes.size; +#if !defined(WIN32) st.st_blksize = 4096; st.st_blocks = res->GETATTR3res_u.resok.obj_attributes.size / 4096; +#endif st.st_atime = res->GETATTR3res_u.resok.obj_attributes.atime.seconds; st.st_mtime = res->GETATTR3res_u.resok.obj_attributes.mtime.seconds; st.st_ctime = res->GETATTR3res_u.resok.obj_attributes.ctime.seconds; @@ -750,7 +779,7 @@ static void nfs_open_cb(struct rpc_context *rpc _U_, int status, void *command_d free_nfs_cb_data(data); return; } - bzero(nfsfh, sizeof(struct nfsfh)); + bzero((char *)nfsfh, sizeof(struct nfsfh)); if (data->continue_int & O_SYNC) { nfsfh->is_sync = 1; @@ -904,7 +933,7 @@ int nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, rpc_set_error(nfs->rpc, "out of memory: failed to allocate nfs_cb_data structure"); return -1; } - bzero(data, sizeof(struct nfs_cb_data)); + bzero((char *)data, sizeof(struct nfs_cb_data)); data->nfs = nfs; data->cb = cb; data->private_data = private_data; @@ -950,7 +979,7 @@ int nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, rpc_set_error(nfs->rpc, "out of memory: failed to allocate nfs_mcb_data structure"); return -1; } - bzero(mdata, sizeof(struct nfs_mcb_data)); + bzero((char *)mdata, sizeof(struct nfs_mcb_data)); mdata->data = data; mdata->offset = offset; mdata->count = readcount; @@ -1021,7 +1050,7 @@ int nfs_pwrite_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, rpc_set_error(nfs->rpc, "out of memory: failed to allocate nfs_cb_data structure"); return -1; } - bzero(data, sizeof(struct nfs_cb_data)); + bzero((char *)data, sizeof(struct nfs_cb_data)); data->nfs = nfs; data->cb = cb; data->private_data = private_data; @@ -1080,7 +1109,7 @@ int nfs_fstat_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, voi rpc_set_error(nfs->rpc, "out of memory: failed to allocate nfs_cb_data structure"); return -1; } - bzero(data, sizeof(struct nfs_cb_data)); + bzero((char *)data, sizeof(struct nfs_cb_data)); data->nfs = nfs; data->cb = cb; data->private_data = private_data; @@ -1137,7 +1166,7 @@ int nfs_fsync_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, voi rpc_set_error(nfs->rpc, "out of memory: failed to allocate nfs_cb_data structure"); return -1; } - bzero(data, sizeof(struct nfs_cb_data)); + bzero((char *)data, sizeof(struct nfs_cb_data)); data->nfs = nfs; data->cb = cb; data->private_data = private_data; @@ -1196,12 +1225,12 @@ int nfs_ftruncate_async(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t leng rpc_set_error(nfs->rpc, "out of memory: failed to allocate nfs_cb_data structure"); return -1; } - bzero(data, sizeof(struct nfs_cb_data)); + bzero((char *)data, sizeof(struct nfs_cb_data)); data->nfs = nfs; data->cb = cb; data->private_data = private_data; - bzero(&args, sizeof(SETATTR3args)); + bzero((char *)&args, sizeof(SETATTR3args)); args.object.data.data_len = nfsfh->fh.data.data_len; args.object.data.data_val = nfsfh->fh.data.data_val; args.new_attributes.size.set_it = 1; @@ -1316,7 +1345,7 @@ int nfs_mkdir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void * return -1; } - ptr = rindex(new_path, '/'); + ptr = strrchr(new_path, '/'); if (ptr == NULL) { rpc_set_error(nfs->rpc, "Invalid path %s", path); return -1; @@ -1397,7 +1426,7 @@ int nfs_rmdir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void * return -1; } - ptr = rindex(new_path, '/'); + ptr = strrchr(new_path, '/'); if (ptr == NULL) { rpc_set_error(nfs->rpc, "Invalid path %s", path); return -1; @@ -1454,7 +1483,7 @@ static void nfs_create_2_cb(struct rpc_context *rpc _U_, int status, void *comma free_nfs_cb_data(data); return; } - bzero(nfsfh, sizeof(struct nfsfh)); + bzero((char *)nfsfh, sizeof(struct nfsfh)); /* steal the filehandle */ nfsfh->fh.data.data_len = data->fh.data.data_len; @@ -1529,7 +1558,7 @@ int nfs_creat_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb return -1; } - ptr = rindex(new_path, '/'); + ptr = strrchr(new_path, '/'); if (ptr == NULL) { rpc_set_error(nfs->rpc, "Invalid path %s", path); return -1; @@ -1609,7 +1638,7 @@ int nfs_unlink_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void return -1; } - ptr = rindex(new_path, '/'); + ptr = strrchr(new_path, '/'); if (ptr == NULL) { rpc_set_error(nfs->rpc, "Invalid path %s", path); return -1; @@ -1634,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 nfsdir *nfsdir = data->continue_data; + struct entryplus3 *entry; uint64_t cookie; - + if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); nfs_free_nfsdir(nfsdir); @@ -1666,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; @@ -1678,7 +1707,7 @@ static void nfs_opendir_cb(struct rpc_context *rpc _U_, int status, void *comman free_nfs_cb_data(data); return; } - bzero(nfsdirent, sizeof(struct nfsdirent)); + bzero((char *)nfsdirent, sizeof(struct nfsdirent)); nfsdirent->name = strdup(entry->name); if (nfsdirent->name == NULL) { data->cb(-ENOMEM, nfs, "Failed to allocate dirent->name", data->private_data); @@ -1688,6 +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; @@ -1695,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; @@ -1719,9 +1761,9 @@ static int nfs_opendir_continue_internal(struct nfs_context *nfs, struct nfs_cb_ { cookieverf3 cv; - bzero(cv, sizeof(cookieverf3)); - if (rpc_nfs_readdir_async(nfs->rpc, nfs_opendir_cb, &data->fh, 0, (char *)&cv, 20000, data) != 0) { - rpc_set_error(nfs->rpc, "RPC error: Failed to send READDIR call for %s", data->path); + bzero((char *)cv, sizeof(cookieverf3)); + if (rpc_nfs_readdirplus_async(nfs->rpc, nfs_opendir_cb, &data->fh, 0, (char *)&cv, 8192, data) != 0) { + rpc_set_error(nfs->rpc, "RPC error: Failed to send READDIRPLUS call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; @@ -1738,7 +1780,7 @@ int nfs_opendir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void rpc_set_error(nfs->rpc, "failed to allocate buffer for nfsdir"); return -1; } - bzero(nfsdir, sizeof(struct nfsdir)); + bzero((char *)nfsdir, sizeof(struct nfsdir)); if (nfs_lookuppath_async(nfs, path, cb, private_data, nfs_opendir_continue_internal, nfsdir, free, 0) != 0) { rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); @@ -2012,7 +2054,7 @@ static int nfs_chmod_continue_internal(struct nfs_context *nfs, struct nfs_cb_da { SETATTR3args args; - bzero(&args, sizeof(SETATTR3args)); + bzero((char *)&args, sizeof(SETATTR3args)); args.object.data.data_len = data->fh.data.data_len; args.object.data.data_val = data->fh.data.data_val; args.new_attributes.mode.set_it = 1; @@ -2050,7 +2092,7 @@ int nfs_fchmod_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int mode, nfs rpc_set_error(nfs->rpc, "out of memory. failed to allocate memory for nfs mount data"); return -1; } - bzero(data, sizeof(struct nfs_cb_data)); + bzero((char *)data, sizeof(struct nfs_cb_data)); data->nfs = nfs; data->cb = cb; data->private_data = private_data; @@ -2116,7 +2158,7 @@ static int nfs_chown_continue_internal(struct nfs_context *nfs, struct nfs_cb_da SETATTR3args args; struct nfs_chown_data *chown_data = data->continue_data; - bzero(&args, sizeof(SETATTR3args)); + bzero((char *)&args, sizeof(SETATTR3args)); args.object.data.data_len = data->fh.data.data_len; args.object.data.data_val = data->fh.data.data_val; if (chown_data->uid != (uid_t)-1) { @@ -2183,7 +2225,7 @@ int nfs_fchown_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int uid, int rpc_set_error(nfs->rpc, "out of memory. failed to allocate memory for fchown data"); return -1; } - bzero(data, sizeof(struct nfs_cb_data)); + bzero((char *)data, sizeof(struct nfs_cb_data)); data->nfs = nfs; data->cb = cb; data->private_data = private_data; @@ -2247,7 +2289,7 @@ static int nfs_utimes_continue_internal(struct nfs_context *nfs, struct nfs_cb_d SETATTR3args args; struct timeval *utimes_data = data->continue_data; - bzero(&args, sizeof(SETATTR3args)); + bzero((char *)&args, sizeof(SETATTR3args)); args.object.data.data_len = data->fh.data.data_len; args.object.data.data_val = data->fh.data.data_val; if (utimes_data != NULL) { @@ -2495,7 +2537,7 @@ int nfs_symlink_async(struct nfs_context *nfs, const char *oldpath, const char * rpc_set_error(nfs->rpc, "Out of memory, failed to allocate buffer for symlink data"); return -1; } - bzero(symlink_data, sizeof(struct nfs_symlink_data)); + bzero((char *)symlink_data, sizeof(struct nfs_symlink_data)); symlink_data->oldpath = strdup(oldpath); if (symlink_data->oldpath == NULL) { @@ -2511,7 +2553,7 @@ int nfs_symlink_async(struct nfs_context *nfs, const char *oldpath, const char * return -1; } - ptr = rindex(symlink_data->newpathparent, '/'); + ptr = strrchr(symlink_data->newpathparent, '/'); if (ptr == NULL) { rpc_set_error(nfs->rpc, "Invalid path %s", oldpath); free_nfs_symlink_data(symlink_data); @@ -2649,7 +2691,7 @@ int nfs_rename_async(struct nfs_context *nfs, const char *oldpath, const char *n rpc_set_error(nfs->rpc, "Out of memory, failed to allocate buffer for rename data"); return -1; } - bzero(rename_data, sizeof(struct nfs_rename_data)); + bzero((char *)rename_data, sizeof(struct nfs_rename_data)); rename_data->oldpath = strdup(oldpath); if (rename_data->oldpath == NULL) { @@ -2657,7 +2699,7 @@ int nfs_rename_async(struct nfs_context *nfs, const char *oldpath, const char *n free_nfs_rename_data(rename_data); return -1; } - ptr = rindex(rename_data->oldpath, '/'); + ptr = strrchr(rename_data->oldpath, '/'); if (ptr == NULL) { rpc_set_error(nfs->rpc, "Invalid path %s", oldpath); free_nfs_rename_data(rename_data); @@ -2674,7 +2716,7 @@ int nfs_rename_async(struct nfs_context *nfs, const char *oldpath, const char *n free_nfs_rename_data(rename_data); return -1; } - ptr = rindex(rename_data->newpath, '/'); + ptr = strrchr(rename_data->newpath, '/'); if (ptr == NULL) { rpc_set_error(nfs->rpc, "Invalid path %s", newpath); free_nfs_rename_data(rename_data); @@ -2805,7 +2847,7 @@ int nfs_link_async(struct nfs_context *nfs, const char *oldpath, const char *new rpc_set_error(nfs->rpc, "Out of memory, failed to allocate buffer for link data"); return -1; } - bzero(link_data, sizeof(struct nfs_link_data)); + bzero((char *)link_data, sizeof(struct nfs_link_data)); link_data->oldpath = strdup(oldpath); if (link_data->oldpath == NULL) { @@ -2820,7 +2862,7 @@ int nfs_link_async(struct nfs_context *nfs, const char *oldpath, const char *new free_nfs_link_data(link_data); return -1; } - ptr = rindex(link_data->newpath, '/'); + ptr = strrchr(link_data->newpath, '/'); if (ptr == NULL) { rpc_set_error(nfs->rpc, "Invalid path %s", newpath); free_nfs_link_data(link_data); @@ -2870,7 +2912,8 @@ void nfs_set_error(struct nfs_context *nfs, char *error_string, ...) char *str = NULL; va_start(ap, error_string); - vasprintf(&str, error_string, ap); + str = malloc(1024); + vsnprintf(str, 1024, error_string, ap); if (nfs->rpc->error_string != NULL) { free(nfs->rpc->error_string); } @@ -3024,7 +3067,7 @@ int mount_getexports_async(struct rpc_context *rpc, const char *server, rpc_cb c if (data == NULL) { return -1; } - bzero(data, sizeof(struct mount_cb_data)); + bzero((char *)data, sizeof(struct mount_cb_data)); data->cb = cb; data->private_data = private_data; data->server = strdup(server); @@ -3045,3 +3088,43 @@ struct rpc_context *nfs_get_rpc_context(struct nfs_context *nfs) return nfs->rpc; } +const char *nfs_get_server(struct nfs_context *nfs) { + return nfs->server; +} + +const char *nfs_get_export(struct nfs_context *nfs) { + return nfs->export; +} + + +#if defined(WIN32) +int poll(struct pollfd *fds, int nfsd, int timeout) +{ + fd_set rfds, wfds, efds; + int ret; + + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_ZERO(&efds); + if (fds->events & POLLIN) { + FD_SET(fds->fd, &rfds); + } + if (fds->events & POLLOUT) { + FD_SET(fds->fd, &wfds); + } + FD_SET(fds->fd, &efds); + select(fds->fd + 1, &rfds, &wfds, &efds, NULL); + fds->revents = 0; + if (FD_ISSET(fds->fd, &rfds)) { + fds->revents |= POLLIN; + } + if (FD_ISSET(fds->fd, &wfds)) { + fds->revents |= POLLOUT; + } + if (FD_ISSET(fds->fd, &efds)) { + fds->revents |= POLLHUP; + } + return 1; +} +#endif +