From: Ronnie Sahlberg Date: Sun, 12 Jan 2014 23:18:59 +0000 (-0800) Subject: Merge pull request #47 from Memphiz/win32fix3 X-Git-Tag: upstream/1.9.6^2~135 X-Git-Url: https://git.piment-noir.org/?p=deb_libnfs.git;a=commitdiff_plain;h=c9cc77a538b9062f0b00a26019c6658ca003492e;hp=be184101ca7251c15184e6af3880680018011e32 Merge pull request #47 from Memphiz/win32fix3 [win32] - fixed bad number casting when using libnfs on 64bit win8 syste... --- diff --git a/Makefile.am b/Makefile.am index 18277c0..3dec343 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = mount nfs nlm portmap rquota lib include . $(MAYBE_EXAMPLES) +SUBDIRS = mount nfs nlm nsm portmap rquota lib include . $(MAYBE_EXAMPLES) pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libnfs.pc diff --git a/README b/README index 4115911..6d3eb73 100644 --- a/README +++ b/README @@ -23,6 +23,21 @@ stat(), read(), ... examples/nfsclient-sync.c provides examples on how to use this API +URL-FORMAT: +=========== +Libnfs uses RFC2224 style URLs extended with libnfs specific url arguments some minor extensions. +The basic syntax of these URLs is : + +nfs:///path[?arg=val[&arg=val]*] + +Arguments supported by libnfs are : + tcp-syncnt= : Number of SYNs to send during the seccion establish + before failing settin 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. ROOT vs NON-ROOT @@ -47,6 +62,14 @@ This is highly non-portable so IF this works on your linux system, count yourself lucky. +FUSE +==== +A simple FUSE filesystem built on libnfs can be found in +examples/fuse_nfs.c + +Compile using : gcc fuse_nfs.c -o fuse_nfs -lfuse -lnfs +Mount using : sudo ./fuse_nfs -n nfs:/// -m + PLATFORM support ================= diff --git a/aros/Makefile.AROS b/aros/Makefile.AROS index 6d39137..9c97dc0 100755 --- a/aros/Makefile.AROS +++ b/aros/Makefile.AROS @@ -21,6 +21,18 @@ lib/libnfs.a: $(OBJS) echo $(CC) $(CFLAGS) -c -o $@ $< $(CC) $(CFLAGS) -c -o $@ $< +install: all + cp lib/libnfs.a GCC:lib + mkdir -p INCLUDE:nfsc + cp include/nfsc/libnfs.h INCLUDE:nfsc + cp include/nfsc/libnfs-raw.h INCLUDE:nfsc + cp include/nfsc/libnfs-zdr.h INCLUDE:nfsc + cp mount/libnfs-raw-mount.h INCLUDE:nfsc + cp nlm/libnfs-raw-nlm.h INCLUDE:nfsc + cp nfs/libnfs-raw-nfs.h INCLUDE:nfsc + cp portmap/libnfs-raw-portmap.h INCLUDE:nfsc + cp rquota/libnfs-raw-rquota.h INCLUDE:nfsc + examples/nfsclient-listservers: examples/nfsclient-listservers.c lib/libnfs.a $(CC) $(CFLAGS) -o $@ $< lib/libnfs.a diff --git a/configure.ac b/configure.ac index e5b170e..98599ee 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ AC_PREREQ(2.50) -AC_INIT([libnfs], [1.6.0], [ronniesahlberg@gmail.com]) +AC_INIT([libnfs], [1.8.90], [ronniesahlberg@gmail.com]) AC_CONFIG_HEADERS([config.h]) AM_INIT_AUTOMAKE([foreign]) AC_CANONICAL_HOST @@ -121,6 +121,10 @@ AC_CHECK_HEADERS([sys/statvfs.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]) @@ -156,6 +160,7 @@ AC_CONFIG_FILES([Makefile] [mount/Makefile] [nfs/Makefile] [nlm/Makefile] + [nsm/Makefile] [portmap/Makefile] [rquota/Makefile] [examples/Makefile] diff --git a/examples/Makefile.am b/examples/Makefile.am index 200ba11..39f5a17 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -1,12 +1,12 @@ -noinst_PROGRAMS = nfsclient-async nfsclient-raw nfsclient-sync nfsclient-bcast nfsclient-listservers nfs-ls nfs-cp +noinst_PROGRAMS = nfsclient-async nfsclient-raw nfsclient-sync nfsclient-bcast nfsclient-listservers nfs-ls nfs-cp nfs-io AM_CPPFLAGS = \ -I$(abs_top_srcdir)/include \ -I$(abs_top_srcdir)/include/nfsc \ - -I../mount \ - -I../nfs \ - -I../rquota \ - -I../portmap \ + -I$(abs_top_srcdir)/mount \ + -I$(abs_top_srcdir)/nfs \ + -I$(abs_top_srcdir)/rquota \ + -I$(abs_top_srcdir)/portmap \ "-D_U_=__attribute__((unused))" AM_LDFLAGS = ../lib/.libs/libnfs.la -lpopt @@ -15,6 +15,8 @@ nfs_ls_SOURCES = nfs-ls.c nfs_cp_SOURCES = nfs-cp.c +nfs_io_SOURCES = nfs-io.c + nfsclient_async_SOURCES = nfsclient-async.c nfsclient_raw_SOURCES = nfsclient-raw.c diff --git a/examples/fuse_nfs.c b/examples/fuse_nfs.c new file mode 100644 index 0000000..261a6aa --- /dev/null +++ b/examples/fuse_nfs.c @@ -0,0 +1,321 @@ +/* + Copyright (C) by Ronnie Sahlberg 2013 + + 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 . +*/ +/* A FUSE filesystem based on libnfs. */ + +#define FUSE_USE_VERSION 26 +#define _FILE_OFFSET_BITS 64 + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define discard_const(ptr) ((void *)((intptr_t)(ptr))) + +struct nfs_context *nfs = NULL; + +static int fuse_nfs_getattr(const char *path, struct stat *stbuf) +{ + int ret = 0; + + memset(stbuf, 0, sizeof(struct stat)); + ret = nfs_stat(nfs, path, stbuf); + + return ret; +} + +static int fuse_nfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, + off_t offset, struct fuse_file_info *fi) +{ + struct nfsdir *nfsdir; + struct nfsdirent *nfsdirent; + + int ret = 0; + + ret = nfs_opendir(nfs, path, &nfsdir); + if (ret < 0) { + return ret; + } + while ((nfsdirent = nfs_readdir(nfs, nfsdir)) != NULL) { + filler(buf, nfsdirent->name, NULL, 0); + } + + return ret; +} + +static int fuse_nfs_open(const char *path, struct fuse_file_info *fi) +{ + int ret = 0; + struct nfsfh *nfsfh; + + fi->fh = 0; + ret = nfs_open(nfs, path, fi->flags, &nfsfh); + if (ret < 0) { + return ret; + } + + fi->fh = (uint64_t)nfsfh; + + return ret; +} + +static int fuse_nfs_release(const char *path, struct fuse_file_info *fi) +{ + struct nfsfh *nfsfh = (struct nfsfh *)fi->fh; + + nfs_close(nfs, nfsfh); + return 0; +} + +static int fuse_nfs_read(const char *path, char *buf, size_t size, + off_t offset, struct fuse_file_info *fi) +{ + int ret = 0; + struct nfsfh *nfsfh = (struct nfsfh *)fi->fh; + + ret = nfs_pread(nfs, nfsfh, offset, size, buf); + + return ret; +} + +static int fuse_nfs_write(const char *path, const char *buf, size_t size, + off_t offset, struct fuse_file_info *fi) +{ + int ret = 0; + struct nfsfh *nfsfh = (struct nfsfh *)fi->fh; + + ret = nfs_pwrite(nfs, nfsfh, offset, size, discard_const(buf)); + + return ret; +} + +static int fuse_nfs_create(const char *path, mode_t mode, struct fuse_file_info *fi) +{ + int ret = 0; + struct nfsfh *nfsfh; + + ret = nfs_creat(nfs, path, mode, &nfsfh); + if (ret < 0) { + return ret; + } + + fi->fh = (uint64_t)nfsfh; + + return ret; +} + +static int fuse_nfs_utime(const char *path, struct utimbuf *times) +{ + int ret = 0; + + ret = nfs_utime(nfs, path, times); + if (ret < 0) { + return ret; + } + + return ret; +} + +static int fuse_nfs_unlink(const char *path) +{ + int ret = 0; + + ret = nfs_unlink(nfs, path); + if (ret < 0) { + return ret; + } + + return ret; +} + +static int fuse_nfs_rmdir(const char *path) +{ + int ret = 0; + + ret = nfs_rmdir(nfs, path); + if (ret < 0) { + return ret; + } + + return ret; +} + +static int fuse_nfs_mkdir(const char *path, mode_t mode) +{ + int ret = 0; + + ret = nfs_mkdir(nfs, path); + if (ret < 0) { + return ret; + } + ret = nfs_chmod(nfs, path, mode); + if (ret < 0) { + return ret; + } + + return ret; +} + +static struct fuse_operations nfs_oper = { + .create = fuse_nfs_create, + .getattr = fuse_nfs_getattr, + .mkdir = fuse_nfs_mkdir, + .open = fuse_nfs_open, + .read = fuse_nfs_read, + .readdir = fuse_nfs_readdir, + .release = fuse_nfs_release, + .rmdir = fuse_nfs_rmdir, + .unlink = fuse_nfs_unlink, + .utime = fuse_nfs_utime, + .write = fuse_nfs_write, +}; + +void print_usage(char *name) +{ + printf("Usage: %s [-?|--help] [-n|--nfs-share=nfs-url] mountpoint\n", + name); + exit(0); +} + +int main(int argc, char *argv[]) +{ + int ret = 0; + static struct option long_opts[] = { + { "help", no_argument, 0, '?' }, + { "nfs-share", required_argument, 0, 'n' }, + { "mountpoint", required_argument, 0, 'm' }, + { NULL, 0, 0, 0 } + }; + int c; + int opt_idx = 0; + char *url = NULL; + char *mnt = NULL; + char *server = NULL, *export = NULL, *strp; + int fuse_nfs_argc = 5; + char *fuse_nfs_argv[16] = { + "fuse-nfs", + "", + "-oallow_other", + "-odefault_permissions", + "-omax_write=32768", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + }; + + while ((c = getopt_long(argc, argv, "?hm:n:", long_opts, + &opt_idx)) > 0) { + switch (c) { + case 'h': + case '?': + print_usage(argv[0]); + return 0; + case 'm': + mnt = strdup(optarg); + break; + case 'n': + url = strdup(optarg); + break; + } + } + + if (url == NULL) { + fprintf(stderr, "-n was not specified.\n"); + ret = 10; + goto finished; + } + if (mnt == NULL) { + fprintf(stderr, "-m was not specified.\n"); + ret = 10; + goto finished; + } + + + if (strncmp(url, "nfs://", 6)) { + fprintf(stderr, "Invalid URL specified.\n"); + ret = 10; + goto finished; + } + server = strdup(url + 6); + if (server == NULL) { + fprintf(stderr, "Failed to strdup server string\n"); + ret = 10; + goto finished; + } + if (server[0] == '/' || server[0] == '\0') { + fprintf(stderr, "Invalid server string.\n"); + ret = 10; + goto finished; + } + strp = strchr(server, '/'); + if (strp == NULL) { + fprintf(stderr, "Invalid URL specified.\n"); + ret = 10; + goto finished; + } + export = strdup(strp); + if (export == NULL) { + fprintf(stderr, "Failed to strdup server string\n"); + ret = 10; + goto finished; + } + if (export[0] != '/') { + fprintf(stderr, "Invalid export.\n"); + ret = 10; + goto finished; + } + *strp = 0; + + nfs = nfs_init_context(); + if (nfs == NULL) { + printf("failed to init context\n"); + goto finished; + } + + ret = nfs_mount(nfs, server, export); + if (ret != 0) { + printf("Failed to mount nfs share : %s\n", nfs_get_error(nfs)); + goto finished; + } + + + fuse_nfs_argv[1] = mnt; + return fuse_main(fuse_nfs_argc, fuse_nfs_argv, &nfs_oper, NULL); + +finished: + if (nfs != NULL) { + nfs_destroy_context(nfs); + } + free(server); + free(export); + free(url); + free(mnt); + return ret; +} diff --git a/examples/nfs-cp.c b/examples/nfs-cp.c index 3d25189..fe9911d 100644 --- a/examples/nfs-cp.c +++ b/examples/nfs-cp.c @@ -59,6 +59,7 @@ struct file_context { int fd; struct nfs_context *nfs; struct nfsfh *nfsfh; + struct nfs_url *url; }; void usage(void) @@ -81,6 +82,7 @@ free_file_context(struct file_context *file_context) if (file_context->nfs != NULL) { nfs_destroy_context(file_context->nfs); } + nfs_destroy_url(file_context->url); free(file_context); } @@ -120,7 +122,6 @@ static struct file_context * open_file(const char *url, int flags) { struct file_context *file_context; - char *server = NULL, *path = NULL, *file = NULL, *strp; file_context = malloc(sizeof(struct file_context)); if (file_context == NULL) { @@ -131,8 +132,8 @@ open_file(const char *url, int flags) file_context->fd = -1; file_context->nfs = NULL; file_context->nfsfh = NULL; + file_context->url = NULL; - if (strncmp(url, "nfs://", 6)) { file_context->is_nfs = 0; file_context->fd = open(url, flags, 0660); @@ -153,77 +154,40 @@ open_file(const char *url, int flags) return NULL; } - server = strdup(url + 6); - if (server == NULL) { - fprintf(stderr, "Failed to strdup server string\n"); - free_file_context(file_context); - return NULL; - } - if (server[0] == '/' || server[0] == '\0') { - fprintf(stderr, "Invalid server string.\n"); - free(server); - free_file_context(file_context); - return NULL; - } - strp = strchr(server, '/'); - path = strdup(strp); - *strp = 0; - if (path == NULL) { - fprintf(stderr, "Invalid URL specified.\n"); - free(server); + file_context->url = nfs_parse_url_full(file_context->nfs, url); + if (file_context->url == NULL) { + fprintf(stderr, "%s\n", nfs_get_error(file_context->nfs)); free_file_context(file_context); return NULL; } - strp = strrchr(path, '/'); - if (strp == NULL) { - fprintf(stderr, "Invalid URL specified.\n"); - free(path); - free(server); - free_file_context(file_context); - return NULL; - } - file = strdup(strp); - *strp = 0; - - if (nfs_mount(file_context->nfs, server, path) != 0) { - fprintf(stderr, "Failed to mount nfs share : %s\n", + if (nfs_mount(file_context->nfs, file_context->url->server, + file_context->url->path) != 0) { + fprintf(stderr, "Failed to mount nfs share : %s\n", nfs_get_error(file_context->nfs)); - free(file); - free(path); - free(server); free_file_context(file_context); return NULL; } if (flags == O_RDONLY) { - if (nfs_open(file_context->nfs, file, flags, + if (nfs_open(file_context->nfs, file_context->url->file, flags, &file_context->nfsfh) != 0) { - fprintf(stderr, "Failed to open file : %s\n", + fprintf(stderr, "Failed to open file %s: %s\n", + file_context->url->file, nfs_get_error(file_context->nfs)); - free(file); - free(path); - free(server); free_file_context(file_context); return NULL; } } else { - if (nfs_creat(file_context->nfs, file, 0660, + if (nfs_creat(file_context->nfs, file_context->url->file, 0660, &file_context->nfsfh) != 0) { - fprintf(stderr, "Failed to creat file %s %s\n", file, + fprintf(stderr, "Failed to creat file %s: %s\n", + file_context->url->file, nfs_get_error(file_context->nfs)); - free(file); - free(path); - free(server); free_file_context(file_context); return NULL; } } - - free(file); - free(path); - free(server); - return file_context; } @@ -297,7 +261,7 @@ int main(int argc, char *argv[]) off += count; } - printf("copied %d bytes\n", (int)count); + printf("copied %d bytes\n", (int)off); free_file_context(src); free_file_context(dst); diff --git a/examples/nfs-io.c b/examples/nfs-io.c new file mode 100644 index 0000000..bda05d5 --- /dev/null +++ b/examples/nfs-io.c @@ -0,0 +1,177 @@ +/* + Copyright (C) by Peter Lieven 2013 + + 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 . +*/ + +#define _FILE_OFFSET_BITS 64 +#define _GNU_SOURCE + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef AROS +#include "aros_compat.h" +#endif + +#ifdef WIN32 +#include "win32_compat.h" +#pragma comment(lib, "ws2_32.lib") +WSADATA wsaData; +#define PRId64 "ll" +#else +#include +#include +#include +#include +#ifndef AROS +#include +#endif +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include "libnfs-zdr.h" +#include "libnfs.h" +#include "libnfs-raw.h" +#include "libnfs-raw-mount.h" + +void print_usage(void) +{ + fprintf(stderr, "Usage: nfs-io [-?|--help|--usage] [stat|creat|unlink|mkdir|rmdir] \n"); +} + +int main(int argc, char *argv[]) +{ + int ret = 1; + struct nfs_context *nfs = NULL; + struct nfsfh *nfsfh = NULL; + struct nfs_url *url = NULL; + +#ifdef WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) { + printf("Failed to start Winsock2\n"); + exit(10); + } +#endif + +#ifdef AROS + aros_init_socket(); +#endif + + if (argc < 3) { + fprintf(stderr, "No URL specified.\n"); + goto finished; + } + + nfs = nfs_init_context(); + if (nfs == NULL) { + printf("failed to init context\n"); + goto finished; + } + + url = nfs_parse_url_full(nfs, argv[argc - 1]); + if (url == NULL) { + fprintf(stderr, "%s\n", nfs_get_error(nfs)); + goto finished; + } + + if (nfs_mount(nfs, url->server, url->path) != 0) { + fprintf(stderr, "Failed to mount nfs share : %s\n", nfs_get_error(nfs)); + goto finished; + } + + if (!strncmp(argv[1], "creat", 5)) { + ret = nfs_creat(nfs, url->file, 0600, &nfsfh); + } else if (!strncmp(argv[1], "unlink", 6)) { + ret = nfs_unlink(nfs, url->file); + } else if (!strncmp(argv[1], "mkdir", 5)) { + ret = nfs_mkdir(nfs, url->file); + } else if (!strncmp(argv[1], "rmdir", 5)) { + ret = nfs_rmdir(nfs, url->file); + } else if (!strncmp(argv[1], "stat", 4)) { + struct stat st; + ret = nfs_stat(nfs, url->file, &st); + if (!ret) { + switch (st.st_mode & S_IFMT) { + #ifndef WIN32 + case S_IFLNK: + printf("l"); + break; + #endif + case S_IFREG: + printf("-"); + break; + case S_IFDIR: + printf("d"); + break; + case S_IFCHR: + printf("c"); + break; + case S_IFBLK: + printf("b"); + break; + } + printf("%c%c%c", + "-r"[!!(st.st_mode & S_IRUSR)], + "-w"[!!(st.st_mode & S_IWUSR)], + "-x"[!!(st.st_mode & S_IXUSR)] + ); + printf("%c%c%c", + "-r"[!!(st.st_mode & S_IRGRP)], + "-w"[!!(st.st_mode & S_IWGRP)], + "-x"[!!(st.st_mode & S_IXGRP)] + ); + printf("%c%c%c", + "-r"[!!(st.st_mode & S_IROTH)], + "-w"[!!(st.st_mode & S_IWOTH)], + "-x"[!!(st.st_mode & S_IXOTH)] + ); + printf(" %2d", (int) st.st_nlink); + printf(" %5d", st.st_uid); + printf(" %5d", st.st_gid); + printf(" %12" PRId64, st.st_size); + printf("\n"); + } + } else { + goto finished; + } + + if (ret) { + fprintf(stderr, "ERROR: %s\n", nfs_get_error(nfs)); + } + +finished: + if (ret > 0) { + print_usage(); + } + nfs_destroy_url(url); + if (nfs != NULL) { + if (nfsfh) { + nfs_close(nfs, nfsfh); + } + nfs_destroy_context(nfs); + } + return !!ret; +} + diff --git a/examples/nfs-ls.c b/examples/nfs-ls.c index e0131c8..e87ffa8 100644 --- a/examples/nfs-ls.c +++ b/examples/nfs-ls.c @@ -35,6 +35,7 @@ WSADATA wsaData; #include #include #include +#include #ifndef AROS #include #endif @@ -62,103 +63,44 @@ struct client { int is_finished; }; +int recursive = 0, summary = 0, discovery = 0; + void print_usage(void) { - fprintf(stderr, "Usage: nfs-ls [-?|--help] [--usage] \n"); + fprintf(stderr, "Usage: nfs-ls [-?|--help|--usage] [-R|--recursive] [-s|--summary] [-D|--discovery] \n"); } -int main(int argc, char *argv[]) -{ - struct nfs_context *nfs = NULL; - int i, ret, res; - uint64_t offset; - struct client client; - struct stat st; - struct nfsfh *nfsfh; - struct nfsdir *nfsdir; - struct nfsdirent *nfsdirent; - struct statvfs svfs; - exports export, tmp; - const char *url = NULL; - char *server = NULL, *path = NULL, *strp; +int process_server(const char *server) { + struct exportnode *exports; + struct exportnode *export; -#ifdef WIN32 - if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) { - printf("Failed to start Winsock2\n"); - exit(10); - } -#endif - -#ifdef AROS - aros_init_socket(); -#endif - - url = argv[1]; - - if (url == NULL) { - fprintf(stderr, "No URL specified.\n"); - print_usage(); - exit(0); + exports = mount_getexports(server); + if (exports == NULL) { + fprintf(stderr, "Failed to get exports for server %s.\n", server); + return -1; } - - if (strncmp(url, "nfs://", 6)) { - fprintf(stderr, "Invalid URL specified.\n"); - print_usage(); - exit(0); + for (export=exports; export; export = export->ex_next) { + printf("nfs://%s%s\n", server, export->ex_dir); } + mount_free_export_list(exports); + return 0; +} - server = strdup(url + 6); - if (server == NULL) { - fprintf(stderr, "Failed to strdup server string\n"); - exit(10); - } - if (server[0] == '/' || server[0] == '\0') { - fprintf(stderr, "Invalid server string.\n"); - free(server); - exit(10); - } - strp = strchr(server, '/'); - if (strp == NULL) { - fprintf(stderr, "Invalid URL specified.\n"); - print_usage(); - free(server); - exit(0); - } - path = strdup(strp); - if (path == NULL) { - fprintf(stderr, "Failed to strdup server string\n"); - free(server); - exit(10); - } - if (path[0] != '/') { - fprintf(stderr, "Invalid path.\n"); - free(server); - free(path); +void process_dir(struct nfs_context *nfs, char *dir, int level) { + int ret; + struct nfsdirent *nfsdirent; + struct statvfs svfs; + struct nfsdir *nfsdir; + struct stat st; + + if (!level) { + printf("Recursion detected!\n"); exit(10); } - *strp = 0; - client.server = server; - client.export = path; - client.is_finished = 0; - - - nfs = nfs_init_context(); - if (nfs == NULL) { - printf("failed to init context\n"); - goto finished; - } - - ret = nfs_mount(nfs, client.server, client.export); - if (ret != 0) { - printf("Failed to mount nfs share : %s\n", nfs_get_error(nfs)); - goto finished; - } - - - ret = nfs_opendir(nfs, "/", &nfsdir); + ret = nfs_opendir(nfs, dir, &nfsdir); if (ret != 0) { - printf("Failed to opendir(\"/\")\n", nfs_get_error(nfs)); + printf("Failed to opendir(\"%s\") %s\n", dir, nfs_get_error(nfs)); exit(10); } while((nfsdirent = nfs_readdir(nfs, nfsdir)) != NULL) { @@ -168,7 +110,7 @@ int main(int argc, char *argv[]) continue; } - sprintf(path, "%s/%s", "/", nfsdirent->name); + snprintf(path, 1024, "%s/%s", dir, nfsdirent->name); ret = nfs_stat(nfs, path, &st); if (ret != 0) { fprintf(stderr, "Failed to stat(%s) %s\n", path, nfs_get_error(nfs)); @@ -178,6 +120,8 @@ int main(int argc, char *argv[]) switch (st.st_mode & S_IFMT) { #ifndef WIN32 case S_IFLNK: + printf("l"); + break; #endif case S_IFREG: printf("-"); @@ -207,22 +151,130 @@ int main(int argc, char *argv[]) "-w"[!!(st.st_mode & S_IWOTH)], "-x"[!!(st.st_mode & S_IXOTH)] ); - printf(" %2d", st.st_nlink); + printf(" %2d", (int) st.st_nlink); printf(" %5d", st.st_uid); printf(" %5d", st.st_gid); printf(" %12" PRId64, st.st_size); - printf(" %s\n", nfsdirent->name); + printf(" %s\n", path + 1); + + if (recursive && (st.st_mode & S_IFMT) == S_IFDIR) { + process_dir(nfs, path, level - 1); + } } nfs_closedir(nfs, nfsdir); +} +int main(int argc, char *argv[]) +{ + struct nfs_context *nfs = NULL; + int i, ret = 1, res; + uint64_t offset; + struct client client; + struct statvfs stvfs; + struct nfs_url *url; + exports export, tmp; +#ifdef WIN32 + if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) { + printf("Failed to start Winsock2\n"); + exit(10); + } +#endif + +#ifdef AROS + aros_init_socket(); +#endif + + if (argc < 2) { + fprintf(stderr, "No URL specified.\n"); + goto finished; + } + + for (i=1; i < argc -1; i++) { + if (!strcmp(argv[i], "-R") || !strcmp(argv[i], "--recursive")) { + recursive++; + } else if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "--summary")) { + summary++; + } else if (!strcmp(argv[i], "-D") || !strcmp(argv[i], "--discovery")) { + discovery++; + } else{ + goto finished; + } + } + + nfs = nfs_init_context(); + if (nfs == NULL) { + printf("failed to init context\n"); + goto finished; + } + + if (discovery) { + url = nfs_parse_url_incomplete(nfs, argv[argc - 1]); + if (url == NULL) { + fprintf(stderr, "%s\n", nfs_get_error(nfs)); + goto finished; + } + if (!url->server) { + struct nfs_server_list *srvrs; + struct nfs_server_list *srv; + + srvrs = nfs_find_local_servers(); + if (srvrs == NULL) { + fprintf(stderr, "Failed to find local servers.\n"); + goto finished; + } + for (srv=srvrs; srv; srv = srv->next) { + if (recursive) { + process_server(srv->addr); + } else { + printf("nfs://%s\n", srv->addr); + } + } + free_nfs_srvr_list(srvrs); + ret = 0; + goto finished; + } + if (url->server && !url->path) { + ret = process_server(url->server); + goto finished; + } + nfs_destroy_url(url); + } + + url = nfs_parse_url_dir(nfs, argv[argc - 1]); + if (url == NULL) { + fprintf(stderr, "%s\n", nfs_get_error(nfs)); + goto finished; + } + + client.server = url->server; + client.export = url->path; + client.is_finished = 0; + + if ((ret = nfs_mount(nfs, client.server, client.export)) != 0) { + fprintf(stderr, "Failed to mount nfs share : %s\n", nfs_get_error(nfs)); + goto finished; + } + + process_dir(nfs, "", 16); + + if (summary) { + if (nfs_statvfs(nfs, "/", &stvfs) != 0) { + goto finished; + } + printf("\n%12" PRId64 " of %12" PRId64 " bytes free.\n", + stvfs.f_frsize * stvfs.f_bfree, stvfs.f_frsize * stvfs.f_blocks); + } + + ret = 0; finished: - free(server); - free(path); - if (nfs != NULL) { + if (ret > 0) { + print_usage(); + } + nfs_destroy_url(url); + if (nfs != NULL) { nfs_destroy_context(nfs); } - return 0; + return ret; } - diff --git a/examples/nfsclient-raw.c b/examples/nfsclient-raw.c index 80a38f0..28dd45c 100644 --- a/examples/nfsclient-raw.c +++ b/examples/nfsclient-raw.c @@ -85,7 +85,7 @@ void rquota_connect_cb(struct rpc_context *rpc, int status, void *data _U_, void printf("Connected to RPC.RQUOTAD on %s:%d\n", client->server, client->rquota_port); printf("Send GETQUOTA request for uid 100\n"); if (rpc_rquota1_getquota_async(rpc, rquota_getquota_cb, EXPORT, 100, client) != 0) { - printf("Failed to send fsinfo request\n"); + printf("Failed to send getquota request\n"); exit(10); } } @@ -170,6 +170,7 @@ void nfs_fsinfo_cb(struct rpc_context *rpc _U_, int status, void *data, void *pr void nfs_connect_cb(struct rpc_context *rpc, int status, void *data _U_, void *private_data) { struct client *client = private_data; + struct FSINFO3args args; if (status != RPC_STATUS_SUCCESS) { printf("connection to RPC.MOUNTD on server %s failed\n", client->server); @@ -178,7 +179,8 @@ void nfs_connect_cb(struct rpc_context *rpc, int status, void *data _U_, void *p printf("Connected to RPC.NFSD on %s:%d\n", client->server, client->mount_port); printf("Send FSINFO request\n"); - if (rpc_nfs_fsinfo_async(rpc, nfs_fsinfo_cb, &client->rootfh, client) != 0) { + args.fsroot = client->rootfh; + if (rpc_nfs3_fsinfo_async(rpc, nfs_fsinfo_cb, &args, client) != 0) { printf("Failed to send fsinfo request\n"); exit(10); } diff --git a/examples/nfsclient-sync.c b/examples/nfsclient-sync.c index 9ca58b4..29a4daf 100644 --- a/examples/nfsclient-sync.c +++ b/examples/nfsclient-sync.c @@ -163,7 +163,7 @@ int main(int argc, char *argv[]) ret = nfs_opendir(nfs, "/", &nfsdir); if (ret != 0) { - printf("Failed to opendir(\"/\")\n", nfs_get_error(nfs)); + printf("Failed to opendir(\"/\") %s\n", nfs_get_error(nfs)); exit(10); } while((nfsdirent = nfs_readdir(nfs, nfsdir)) != NULL) { @@ -212,7 +212,7 @@ int main(int argc, char *argv[]) "-w"[!!(st.st_mode & S_IWOTH)], "-x"[!!(st.st_mode & S_IXOTH)] ); - printf(" %2d", st.st_nlink); + printf(" %2d", (int)st.st_nlink); printf(" %5d", st.st_uid); printf(" %5d", st.st_gid); printf(" %12" PRId64, st.st_size); diff --git a/include/Makefile.am b/include/Makefile.am index d757d2b..e1e65dc 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -7,4 +7,5 @@ dist_nfsc_HEADERS = \ ${abs_top_srcdir}/portmap/libnfs-raw-portmap.h \ ${abs_top_srcdir}/nfs/libnfs-raw-nfs.h \ ${abs_top_srcdir}/nlm/libnfs-raw-nlm.h \ + ${abs_top_srcdir}/nsm/libnfs-raw-nsm.h \ ${abs_top_srcdir}/rquota/libnfs-raw-rquota.h diff --git a/include/libnfs-private.h b/include/libnfs-private.h index 79ac411..a2f3e1a 100644 --- a/include/libnfs-private.h +++ b/include/libnfs-private.h @@ -56,9 +56,10 @@ struct rpc_fragment { }; #define RPC_CONTEXT_MAGIC 0xc6e46435 +#define RPC_PARAM_UNDEFINED -1 struct rpc_context { - uint32_t magic; + uint32_t magic; int fd; int is_connected; @@ -68,37 +69,42 @@ struct rpc_context { void *connect_data; struct AUTH *auth; - unsigned long xid; + uint32_t xid; - /* buffer used for encoding RPC PDU */ - char *encodebuf; - int encodebuflen; + /* buffer used for encoding RPC PDU */ + char *encodebuf; + int encodebuflen; - struct rpc_pdu *outqueue; - struct sockaddr_storage udp_src; - struct rpc_pdu *waitpdu; + struct rpc_pdu *outqueue; + struct sockaddr_storage udp_src; + struct rpc_pdu *waitpdu; - uint32_t inpos; - uint32_t insize; - char *inbuf; + uint32_t inpos; + uint32_t insize; + char *inbuf; - /* special fields for UDP, which can sometimes be BROADCASTed */ - int is_udp; - struct sockaddr *udp_dest; - int is_broadcast; + /* special fields for UDP, which can sometimes be BROADCASTed */ + int is_udp; + struct sockaddr *udp_dest; + int is_broadcast; - /* track the address we connect to so we can auto-reconnect on session failure */ - struct sockaddr_storage s; - int auto_reconnect; + /* track the address we connect to so we can auto-reconnect on session failure */ + struct sockaddr_storage s; + int auto_reconnect; /* fragment reassembly */ struct rpc_fragment *fragments; + + /* parameters passable via URL */ + int tcp_syncnt; + int uid; + int gid; }; struct rpc_pdu { struct rpc_pdu *next; - unsigned long xid; + uint32_t xid; ZDR zdr; uint32_t written; @@ -135,6 +141,10 @@ struct sockaddr *rpc_get_recv_sockaddr(struct rpc_context *rpc); void rpc_set_autoreconnect(struct rpc_context *rpc); void rpc_unset_autoreconnect(struct rpc_context *rpc); +void rpc_set_tcp_syncnt(struct rpc_context *rpc, int v); +void rpc_set_uid(struct rpc_context *rpc, int uid); +void rpc_set_gid(struct rpc_context *rpc, int gid); + int rpc_add_fragment(struct rpc_context *rpc, char *data, uint64_t size); void rpc_free_all_fragments(struct rpc_context *rpc); diff --git a/include/nfsc/libnfs-raw.h b/include/nfsc/libnfs-raw.h index b71e6b0..b62ea70 100644 --- a/include/nfsc/libnfs-raw.h +++ b/include/nfsc/libnfs-raw.h @@ -53,6 +53,12 @@ struct rpc_context *nfs_get_rpc_context(struct nfs_context *nfs); */ struct nfs_fh3 *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. + */ +void rpc_set_next_xid(struct rpc_context *rpc, uint32_t xid); + #define RPC_STATUS_SUCCESS 0 #define RPC_STATUS_ERROR 1 #define RPC_STATUS_CANCEL 2 @@ -72,6 +78,21 @@ struct nfs_fh3 *nfs_get_fh(struct nfsfh *nfsfh); * : data is NULL. */ 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. Once the connection establish finishes, the callback will be invoked. + * <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 erro string. + * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. + * : data is NULL. + */ +int rpc_connect_program_async(struct rpc_context *rpc, char *server, int program, int version, rpc_cb cb, void *private_data); /* * When disconnecting a connection in flight. All commands in flight will be called with the callback * and status RPC_STATUS_ERROR. Data will be the error string for the disconnection. @@ -97,7 +118,7 @@ int rpc_disconnect(struct rpc_context *rpc, char *error); * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ -int rpc_pmap_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); +EXTERN int rpc_pmap_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); /* @@ -114,7 +135,7 @@ int rpc_pmap_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ -int rpc_pmap_getport_async(struct rpc_context *rpc, int program, int version, int protocol, rpc_cb cb, void *private_data); +EXTERN int rpc_pmap_getport_async(struct rpc_context *rpc, int program, int version, int protocol, rpc_cb cb, void *private_data); /* * Call PORTMAPPER/SET @@ -130,7 +151,7 @@ int rpc_pmap_getport_async(struct rpc_context *rpc, int program, int version, in * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ -int rpc_pmap_set_async(struct rpc_context *rpc, int program, int version, int protocol, int port, rpc_cb cb, void *private_data); +EXTERN int rpc_pmap_set_async(struct rpc_context *rpc, int program, int version, int protocol, int port, rpc_cb cb, void *private_data); /* * Call PORTMAPPER/UNSET @@ -146,7 +167,7 @@ int rpc_pmap_set_async(struct rpc_context *rpc, int program, int version, int pr * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ -int rpc_pmap_unset_async(struct rpc_context *rpc, int program, int version, int protocol, int port, rpc_cb cb, void *private_data); +EXTERN int rpc_pmap_unset_async(struct rpc_context *rpc, int program, int version, int protocol, int port, rpc_cb cb, void *private_data); /* * Call PORTMAPPER/CALLIT. @@ -162,16 +183,16 @@ int rpc_pmap_unset_async(struct rpc_context *rpc, int program, int version, int * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ -int rpc_pmap_callit_async(struct rpc_context *rpc, int program, int version, int procedure, char *data, int datalen, rpc_cb cb, void *private_data); +EXTERN int rpc_pmap_callit_async(struct rpc_context *rpc, int program, int version, int procedure, char *data, int datalen, rpc_cb cb, void *private_data); /* - * MOUNT FUNCTIONS + * MOUNT v3 FUNCTIONS */ char *mountstat3_to_str(int stat); int mountstat3_to_errno(int error); /* - * Call MOUNT/NULL + * Call MOUNT3/NULL * 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. @@ -184,10 +205,11 @@ int mountstat3_to_errno(int error); * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ -int rpc_mount_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); +EXTERN int rpc_mount3_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); +EXTERN int rpc_mount_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); /* - * Call MOUNT/MNT + * Call MOUNT3/MNT * 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. @@ -200,10 +222,11 @@ int rpc_mount_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ -int rpc_mount_mnt_async(struct rpc_context *rpc, rpc_cb cb, char *export, void *private_data); +EXTERN int rpc_mount3_mnt_async(struct rpc_context *rpc, rpc_cb cb, char *export, void *private_data); +EXTERN int rpc_mount_mnt_async(struct rpc_context *rpc, rpc_cb cb, char *export, void *private_data); /* - * Call MOUNT/DUMP + * Call MOUNT3/DUMP * 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. @@ -216,10 +239,11 @@ int rpc_mount_mnt_async(struct rpc_context *rpc, rpc_cb cb, char *export, void * * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ -int rpc_mount_dump_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); +EXTERN int rpc_mount3_dump_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); +EXTERN int rpc_mount_dump_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); /* - * Call MOUNT/UMNT + * Call MOUNT3/UMNT * 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. @@ -232,10 +256,11 @@ int rpc_mount_dump_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ -int rpc_mount_umnt_async(struct rpc_context *rpc, rpc_cb cb, char *export, void *private_data); +EXTERN int rpc_mount3_umnt_async(struct rpc_context *rpc, rpc_cb cb, char *export, void *private_data); +EXTERN int rpc_mount_umnt_async(struct rpc_context *rpc, rpc_cb cb, char *export, void *private_data); /* - * Call MOUNT/UMNTALL + * Call MOUNT3/UMNTALL * 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. @@ -248,10 +273,11 @@ int rpc_mount_umnt_async(struct rpc_context *rpc, rpc_cb cb, char *export, void * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ -int rpc_mount_umntall_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); +EXTERN int rpc_mount3_umntall_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); +EXTERN int rpc_mount_umntall_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); /* - * Call MOUNT/EXPORT + * Call MOUNT3/EXPORT * NOTE: You must include 'libnfs-raw-mount.h' to get the definitions of the * returned structures. * @@ -268,20 +294,122 @@ int rpc_mount_umntall_async(struct rpc_context *rpc, rpc_cb cb, void *private_da * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ -int rpc_mount_export_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); +EXTERN int rpc_mount3_export_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); +EXTERN int rpc_mount_export_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); +/* + * MOUNT v1 FUNCTIONS (Used with NFSv2) + */ +/* + * Call MOUNT1/NULL + * 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 mount daemon. + * data is NULL. + * RPC_STATUS_ERROR : An error occured when trying to contact the mount daemon. + * data is the error string. + * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. + * data is NULL. + */ +EXTERN int rpc_mount1_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); +/* + * Call MOUNT1/MNT + * 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 mount daemon. + * data is union mountres1. + * RPC_STATUS_ERROR : An error occured when trying to contact the mount daemon. + * data is the error string. + * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. + * data is NULL. + */ +EXTERN int rpc_mount1_mnt_async(struct rpc_context *rpc, rpc_cb cb, char *export, void *private_data); + +/* + * Call MOUNT1/DUMP + * 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 mount daemon. + * data is a mountlist. + * RPC_STATUS_ERROR : An error occured when trying to contact the mount daemon. + * data is the error string. + * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. + * data is NULL. + */ +EXTERN int rpc_mount1_dump_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); + +/* + * Call MOUNT1/UMNT + * 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 mount daemon. + * data NULL. + * RPC_STATUS_ERROR : An error occured when trying to contact the mount daemon. + * data is the error string. + * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. + * data is NULL. + */ +EXTERN int rpc_mount1_umnt_async(struct rpc_context *rpc, rpc_cb cb, char *export, void *private_data); + +/* + * Call MOUNT1/UMNTALL + * 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 mount daemon. + * data NULL. + * RPC_STATUS_ERROR : An error occured when trying to contact the mount daemon. + * data is the error string. + * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. + * data is NULL. + */ +EXTERN int rpc_mount1_umntall_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); + +/* + * Call MOUNT1/EXPORT + * NOTE: You must include 'libnfs-raw-mount.h' to get the definitions of the + * returned structures. + * + * 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 mount daemon. + * data is a pointer to an exports pointer: + * exports export = *(exports *)data; + * RPC_STATUS_ERROR : An error occured when trying to contact the mount daemon. + * data is the error string. + * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. + * data is NULL. + */ +EXTERN int rpc_mount1_export_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); /* - * NFS FUNCTIONS + * NFS v3 FUNCTIONS */ struct nfs_fh3; char *nfsstat3_to_str(int error); int nfsstat3_to_errno(int error); /* - * Call NFS/NULL + * Call NFS3/NULL * 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. @@ -294,10 +422,11 @@ int nfsstat3_to_errno(int error); * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ -int rpc_nfs_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); +EXTERN int rpc_nfs3_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); +EXTERN int rpc_nfs_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); /* - * Call NFS/GETATTR + * Call NFS3/GETATTR * 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. @@ -310,10 +439,30 @@ int rpc_nfs_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ -int rpc_nfs_getattr_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data); +struct GETATTR3args; +EXTERN int rpc_nfs3_getattr_async(struct rpc_context *rpc, rpc_cb cb, struct GETATTR3args *args, void *private_data); +EXTERN int rpc_nfs_getattr_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data); /* - * Call NFS/LOOKUP + * Call NFS3/PATHCONF + * 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 PATHCONF3res + * 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. + */ +struct PATHCONF3args; +EXTERN int rpc_nfs3_pathconf_async(struct rpc_context *rpc, rpc_cb cb, struct PATHCONF3args *args, void *private_data); +EXTERN int rpc_nfs_pathconf_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data); + +/* + * Call NFS3/LOOKUP * 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. @@ -326,10 +475,12 @@ int rpc_nfs_getattr_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ -int rpc_nfs_lookup_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *name, void *private_data); +struct LOOKUP3args; +EXTERN int rpc_nfs3_lookup_async(struct rpc_context *rpc, rpc_cb cb, struct LOOKUP3args *args, void *private_data); +EXTERN int rpc_nfs_lookup_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *name, void *private_data); /* - * Call NFS/ACCESS + * Call NFS3/ACCESS * 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. @@ -342,10 +493,12 @@ int rpc_nfs_lookup_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ -int rpc_nfs_access_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, int access, void *private_data); +struct ACCESS3args; +EXTERN int rpc_nfs3_access_async(struct rpc_context *rpc, rpc_cb cb, struct ACCESS3args *args, void *private_data); +EXTERN int rpc_nfs_access_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, int access, void *private_data); /* - * Call NFS/READ + * Call NFS3/READ * 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. @@ -358,10 +511,12 @@ int rpc_nfs_access_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ -int rpc_nfs_read_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, uint64_t offset, uint64_t count, void *private_data); +struct READ3args; +EXTERN int rpc_nfs3_read_async(struct rpc_context *rpc, rpc_cb cb, struct READ3args *args, void *private_data); +EXTERN int rpc_nfs_read_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, uint64_t offset, uint64_t count, void *private_data); /* - * Call NFS/WRITE + * Call NFS3/WRITE * 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. @@ -374,10 +529,12 @@ int rpc_nfs_read_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, u * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ -int rpc_nfs_write_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *buf, uint64_t offset, uint64_t count, int stable_how, void *private_data); +struct WRITE3args; +EXTERN int rpc_nfs3_write_async(struct rpc_context *rpc, rpc_cb cb, struct WRITE3args *args, void *private_data); +EXTERN int rpc_nfs_write_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *buf, uint64_t offset, uint64_t count, int stable_how, void *private_data); /* - * Call NFS/COMMIT + * Call NFS3/COMMIT * 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. @@ -390,11 +547,12 @@ int rpc_nfs_write_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ -int rpc_nfs_commit_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data); - +struct COMMIT3args; +EXTERN int rpc_nfs3_commit_async(struct rpc_context *rpc, rpc_cb cb, struct COMMIT3args *args, void *private_data); +EXTERN int rpc_nfs_commit_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data); /* - * Call NFS/SETATTR + * Call NFS3/SETATTR * 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. @@ -408,12 +566,11 @@ int rpc_nfs_commit_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, * data is NULL. */ struct SETATTR3args; -int rpc_nfs_setattr_async(struct rpc_context *rpc, rpc_cb cb, struct SETATTR3args *args, void *private_data); - - +EXTERN int rpc_nfs3_setattr_async(struct rpc_context *rpc, rpc_cb cb, struct SETATTR3args *args, void *private_data); +EXTERN int rpc_nfs_setattr_async(struct rpc_context *rpc, rpc_cb cb, struct SETATTR3args *args, void *private_data); /* - * Call NFS/MKDIR + * Call NFS3/MKDIR * 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. @@ -427,14 +584,11 @@ int rpc_nfs_setattr_async(struct rpc_context *rpc, rpc_cb cb, struct SETATTR3arg * data is NULL. */ struct MKDIR3args; -int rpc_nfs_mkdir_async(struct rpc_context *rpc, rpc_cb cb, struct MKDIR3args *args, void *private_data); - - - - +EXTERN int rpc_nfs3_mkdir_async(struct rpc_context *rpc, rpc_cb cb, struct MKDIR3args *args, void *private_data); +EXTERN int rpc_nfs_mkdir_async(struct rpc_context *rpc, rpc_cb cb, struct MKDIR3args *args, void *private_data); /* - * Call NFS/RMDIR + * Call NFS3/RMDIR * 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. @@ -447,13 +601,12 @@ int rpc_nfs_mkdir_async(struct rpc_context *rpc, rpc_cb cb, struct MKDIR3args *a * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ -int rpc_nfs_rmdir_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *dir, void *private_data); - - - +struct RMDIR3args; +EXTERN int rpc_nfs3_rmdir_async(struct rpc_context *rpc, rpc_cb cb, struct RMDIR3args *args, void *private_data); +EXTERN int rpc_nfs_rmdir_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *dir, void *private_data); /* - * Call NFS/CREATE + * Call NFS3/CREATE * 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. @@ -467,11 +620,11 @@ int rpc_nfs_rmdir_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, * data is NULL. */ struct CREATE3args; -int rpc_nfs_create_async(struct rpc_context *rpc, rpc_cb cb, struct CREATE3args *args, void *private_data); - +EXTERN int rpc_nfs3_create_async(struct rpc_context *rpc, rpc_cb cb, struct CREATE3args *args, void *private_data); +EXTERN int rpc_nfs_create_async(struct rpc_context *rpc, rpc_cb cb, struct CREATE3args *args, void *private_data); /* - * Call NFS/MKNOD + * Call NFS3/MKNOD * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. @@ -484,11 +637,12 @@ int rpc_nfs_create_async(struct rpc_context *rpc, rpc_cb cb, struct CREATE3args * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ -int rpc_nfs_mknod_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *file, int mode, int major, int minor, void *private_data); - +struct MKNOD3args; +EXTERN int rpc_nfs3_mknod_async(struct rpc_context *rpc, rpc_cb cb, struct MKNOD3args *args, void *private_data); +EXTERN int rpc_nfs_mknod_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *file, int mode, int major, int minor, void *private_data); /* - * Call NFS/REMOVE + * Call NFS3/REMOVE * 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. @@ -501,12 +655,12 @@ int rpc_nfs_mknod_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ -int rpc_nfs_remove_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *name, void *private_data); - - +struct REMOVE3args; +EXTERN int rpc_nfs3_remove_async(struct rpc_context *rpc, rpc_cb cb, struct REMOVE3args *args, void *private_data); +EXTERN int rpc_nfs_remove_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *name, void *private_data); /* - * Call NFS/READDIR + * Call NFS3/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. @@ -519,10 +673,12 @@ int rpc_nfs_remove_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ -int rpc_nfs_readdir_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, uint64_t cookie, char *cookieverf, int count, void *private_data); +struct READDIR3args; +EXTERN int rpc_nfs3_readdir_async(struct rpc_context *rpc, rpc_cb cb, struct READDIR3args *args, void *private_data); +EXTERN 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 + * Call NFS3/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. @@ -535,10 +691,12 @@ int rpc_nfs_readdir_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ -int rpc_nfs_readdirplus_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, uint64_t cookie, char *cookieverf, int count, void *private_data); +struct READDIRPLUS3args; +EXTERN int rpc_nfs3_readdirplus_async(struct rpc_context *rpc, rpc_cb cb, struct READDIRPLUS3args *args, void *private_data); +EXTERN 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 + * Call NFS3/FSSTAT * 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. @@ -551,101 +709,374 @@ int rpc_nfs_readdirplus_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ -int rpc_nfs_fsstat_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data); +struct FSSTAT3args; +EXTERN int rpc_nfs3_fsstat_async(struct rpc_context *rpc, rpc_cb cb, struct FSSTAT3args *args, void *private_data); +EXTERN int rpc_nfs_fsstat_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data); +/* + * Call NFS3/FSINFO + * 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 FSINFO3res + * 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. + */ +struct FSINFO3args; +EXTERN int rpc_nfs3_fsinfo_async(struct rpc_context *rpc, rpc_cb cb, struct FSINFO3args *args, void *private_data); +EXTERN int rpc_nfs_fsinfo_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data); +/* + * Call NFS3/READLINK + * 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 READLINK3res * + * 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. + */ +struct READLINK3args; +EXTERN int rpc_nfs3_readlink_async(struct rpc_context *rpc, rpc_cb cb, struct READLINK3args *args, void *private_data); +EXTERN int rpc_nfs_readlink_async(struct rpc_context *rpc, rpc_cb cb, struct READLINK3args *args, void *private_data); /* - * Call NFS/FSINFO + * Call NFS3/SYMLINK * 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 FSINFO3res + * data is SYMLINK3res * + * 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. + */ +struct SYMLINK3args; +EXTERN int rpc_nfs3_symlink_async(struct rpc_context *rpc, rpc_cb cb, struct SYMLINK3args *args, void *private_data); +EXTERN int rpc_nfs_symlink_async(struct rpc_context *rpc, rpc_cb cb, struct SYMLINK3args *args, void *private_data); + +/* + * Call NFS3/RENAME + * 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 RENAME3res * * 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_fsinfo_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data); +struct RENAME3args; +EXTERN int rpc_nfs3_rename_async(struct rpc_context *rpc, rpc_cb cb, struct RENAME3args *args, void *private_data); +EXTERN int rpc_nfs_rename_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *olddir, char *oldname, struct nfs_fh3 *newdir, char *newname, void *private_data); +/* + * Call NFS3/LINK + * 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 LINK3res * + * 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. + */ +struct LINK3args; +EXTERN int rpc_nfs3_link_async(struct rpc_context *rpc, rpc_cb cb, struct LINK3args *args, void *private_data); +EXTERN int rpc_nfs_link_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *file, struct nfs_fh3 *newdir, char *newname, void *private_data); +/* + * NFS v2 FUNCTIONS + */ /* - * Call NFS/READLINK + * Call NFS2/NULL * 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 READLINK3res * + * data is NULL. * 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. */ -struct READLINK3args; -int rpc_nfs_readlink_async(struct rpc_context *rpc, rpc_cb cb, struct READLINK3args *args, void *private_data); +EXTERN int rpc_nfs2_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); +/* + * Call NFS2/GETATTR + * 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 GETATTR2res + * 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. + */ +struct GETATTR2args; +EXTERN int rpc_nfs2_getattr_async(struct rpc_context *rpc, rpc_cb cb, struct GETATTR2args *args, void *private_data); +/* + * Call NFS2/SETATTR + * 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 SETATTR2res * + * 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. + */ +struct SETATTR2args; +EXTERN int rpc_nfs2_setattr_async(struct rpc_context *rpc, rpc_cb cb, struct SETATTR2args *args, void *private_data); /* - * Call NFS/SYMLINK + * Call NFS2/LOOKUP * 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 SYMLINK3res * + * data is LOOKUP2res * 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. */ -struct SYMLINK3args; -int rpc_nfs_symlink_async(struct rpc_context *rpc, rpc_cb cb, struct SYMLINK3args *args, void *private_data); +struct LOOKUP2args; +EXTERN int rpc_nfs2_lookup_async(struct rpc_context *rpc, rpc_cb cb, struct LOOKUP2args *args, void *private_data); +/* + * Call NFS2/READLINK + * 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 READLINK2res * + * 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. + */ +struct READLINK2args; +EXTERN int rpc_nfs32_readlink_async(struct rpc_context *rpc, rpc_cb cb, struct READLINK2args *args, void *private_data); /* - * Call NFS/RENAME + * Call NFS2/READ * 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 RENAME3res * + * data is READ2res * 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_rename_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *olddir, char *oldname, struct nfs_fh3 *newdir, char *newname, void *private_data); +struct READ2args; +EXTERN int rpc_nfs2_read_async(struct rpc_context *rpc, rpc_cb cb, struct READ2args *args, void *private_data); +/* + * Call NFS2/WRITE + * 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 WRITE2res * + * 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. + */ +struct WRITE2args; +EXTERN int rpc_nfs2_write_async(struct rpc_context *rpc, rpc_cb cb, struct WRITE2args *args, void *private_data); + +/* + * Call NFS2/CREATE + * 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 CREATE2res * + * 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. + */ +struct CREATE2args; +EXTERN int rpc_nfs2_create_async(struct rpc_context *rpc, rpc_cb cb, struct CREATE2args *args, void *private_data); +/* + * Call NFS2/REMOVE + * 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 REMOVE2res * + * 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. + */ +struct REMOVE2args; +EXTERN int rpc_nfs2_remove_async(struct rpc_context *rpc, rpc_cb cb, struct REMOVE2args *args, void *private_data); /* - * Call NFS/LINK + * Call NFS2/RENAME * 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 LINK3res * + * data is RENAME2res * + * 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. + */ +struct RENAME2args; +EXTERN int rpc_nfs2_rename_async(struct rpc_context *rpc, rpc_cb cb, struct RENAME2args *args, void *private_data); + +/* + * Call NFS2/LINK + * 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 LINK2res * + * 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. + */ +struct LINK2args; +EXTERN int rpc_nfs2_link_async(struct rpc_context *rpc, rpc_cb cb, struct LINK2args *args, void *private_data); + +/* + * Call NFS2/SYMLINK + * 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 SYMLINK2res * + * 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. + */ +struct SYMLINK2args; +EXTERN int rpc_nfs2_symlink_async(struct rpc_context *rpc, rpc_cb cb, struct SYMLINK2args *args, void *private_data); + +/* + * Call NFS2/MKDIR + * 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 MKDIR2res * * 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_link_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *file, struct nfs_fh3 *newdir, char *newname, void *private_data); +struct MKDIR2args; +EXTERN int rpc_nfs2_mkdir_async(struct rpc_context *rpc, rpc_cb cb, struct MKDIR2args *args, void *private_data); +/* + * Call NFS2/RMDIR + * 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 RMDIR2res * + * 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. + */ +struct RMDIR2args; +EXTERN int rpc_nfs2_rmdir_async(struct rpc_context *rpc, rpc_cb cb, struct RMDIR2args *args, void *private_data); +/* + * Call NFS2/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. + * + * When the callback is invoked, status indicates the result: + * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. + * data is READDIR2res * + * 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. + */ +struct READDIR2args; +EXTERN int rpc_nfs2_readdir_async(struct rpc_context *rpc, rpc_cb cb, struct READDIR2args *args, void *private_data); +/* + * Call NFS2/STATFS + * 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 STATFS2res * + * 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. + */ +struct STATFS2args; +EXTERN int rpc_nfs2_statfs_async(struct rpc_context *rpc, rpc_cb cb, struct STATFS2args *args, void *private_data); /* * RQUOTA FUNCTIONS @@ -667,7 +1098,7 @@ int rquotastat_to_errno(int error); * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ -int rpc_rquota1_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); +EXTERN int rpc_rquota1_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); /* * Call RQUOTA1/GETQUOTA @@ -683,7 +1114,7 @@ int rpc_rquota1_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_dat * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ -int rpc_rquota1_getquota_async(struct rpc_context *rpc, rpc_cb cb, char *export, int uid, void *private_data); +EXTERN int rpc_rquota1_getquota_async(struct rpc_context *rpc, rpc_cb cb, char *export, int uid, void *private_data); /* * Call RQUOTA1/GETACTIVEQUOTA @@ -699,7 +1130,7 @@ int rpc_rquota1_getquota_async(struct rpc_context *rpc, rpc_cb cb, char *export, * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ -int rpc_rquota1_getactivequota_async(struct rpc_context *rpc, rpc_cb cb, char *export, int uid, void *private_data); +EXTERN int rpc_rquota1_getactivequota_async(struct rpc_context *rpc, rpc_cb cb, char *export, int uid, void *private_data); @@ -777,7 +1208,7 @@ int rpc_rquota2_getactivequota_async(struct rpc_context *rpc, rpc_cb cb, char *e * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ -int rpc_nfsacl_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); +EXTERN int rpc_nfsacl_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); /* * Call NFSACL/GETACL @@ -795,7 +1226,7 @@ int rpc_nfsacl_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data * data is NULL. */ struct GETACL3args; -int rpc_nfsacl_getacl_async(struct rpc_context *rpc, rpc_cb cb, struct GETACL3args *args, void *private_data); +EXTERN int rpc_nfsacl_getacl_async(struct rpc_context *rpc, rpc_cb cb, struct GETACL3args *args, void *private_data); @@ -815,7 +1246,7 @@ int rpc_nfsacl_getacl_async(struct rpc_context *rpc, rpc_cb cb, struct GETACL3ar * data is NULL. */ struct SETACL3args; -int rpc_nfsacl_setacl_async(struct rpc_context *rpc, rpc_cb cb, struct SETACL3args *args, void *private_data); +EXTERN int rpc_nfsacl_setacl_async(struct rpc_context *rpc, rpc_cb cb, struct SETACL3args *args, void *private_data); @@ -841,7 +1272,7 @@ char *nlmstat4_to_str(int stat); * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ -int rpc_nlm4_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); +EXTERN int rpc_nlm4_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); /* * Call NLM/TEST @@ -860,7 +1291,7 @@ int rpc_nlm4_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); * data is NULL. */ struct NLM4_TESTargs; -int rpc_nlm4_test_async(struct rpc_context *rpc, rpc_cb cb, struct NLM4_TESTargs *args, void *private_data); +EXTERN int rpc_nlm4_test_async(struct rpc_context *rpc, rpc_cb cb, struct NLM4_TESTargs *args, void *private_data); /* * Call NLM/LOCK @@ -879,7 +1310,7 @@ int rpc_nlm4_test_async(struct rpc_context *rpc, rpc_cb cb, struct NLM4_TESTargs * data is NULL. */ struct NLM4_LOCKargs; -int rpc_nlm4_lock_async(struct rpc_context *rpc, rpc_cb cb, struct NLM4_LOCKargs *args, void *private_data); +EXTERN int rpc_nlm4_lock_async(struct rpc_context *rpc, rpc_cb cb, struct NLM4_LOCKargs *args, void *private_data); /* * Call NLM/CANCEL @@ -898,7 +1329,7 @@ int rpc_nlm4_lock_async(struct rpc_context *rpc, rpc_cb cb, struct NLM4_LOCKargs * data is NULL. */ struct NLM4_CANCargs; -int rpc_nlm4_cancel_async(struct rpc_context *rpc, rpc_cb cb, struct NLM4_CANCargs *args, void *private_data); +EXTERN int rpc_nlm4_cancel_async(struct rpc_context *rpc, rpc_cb cb, struct NLM4_CANCargs *args, void *private_data); /* * Call NLM/UNLOCK @@ -917,6 +1348,142 @@ int rpc_nlm4_cancel_async(struct rpc_context *rpc, rpc_cb cb, struct NLM4_CANCar * data is NULL. */ struct NLM4_UNLOCKargs; -int rpc_nlm4_unlock_async(struct rpc_context *rpc, rpc_cb cb, struct NLM4_UNLOCKargs *args, void *private_data); +EXTERN int rpc_nlm4_unlock_async(struct rpc_context *rpc, rpc_cb cb, struct NLM4_UNLOCKargs *args, void *private_data); + +/* + * NSM functions + */ +char *nsmstat1_to_str(int stat); + +/* + * Call NSM/NULL + * Call the NULL procedure for the NSM protocol + * + * 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 nsm daemon. + * data is NULL + * RPC_STATUS_ERROR : An error occured when trying to contact the nsm daemon. + * data is the error string. + * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. + * data is NULL. + */ +EXTERN int rpc_nsm1_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); + +/* + * Call NSM/STAT + * Call the STAT procedure for the NSM protocol + * + * 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 nsm daemon. + * data is NSM1_STATres + * RPC_STATUS_ERROR : An error occured when trying to contact the nsm daemon. + * data is the error string. + * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. + * data is NULL. + */ +struct NSM1_STATargs; +EXTERN int rpc_nsm1_stat_async(struct rpc_context *rpc, rpc_cb cb, struct NSM1_STATargs *args, void *private_data); + +/* + * Call NSM/MON + * Call the MON procedure for the NSM protocol + * + * 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 nsm daemon. + * data is NSM1_MONres + * RPC_STATUS_ERROR : An error occured when trying to contact the nsm daemon. + * data is the error string. + * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. + * data is NULL. + */ +struct NSM1_MONargs; +EXTERN int rpc_nsm1_mon_async(struct rpc_context *rpc, rpc_cb cb, struct NSM1_MONargs *args, void *private_data); + +/* + * Call NSM/UNMON + * Call the UNMON procedure for the NSM protocol + * + * 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 nsm daemon. + * data is NSM1_UNMONres + * RPC_STATUS_ERROR : An error occured when trying to contact the nsm daemon. + * data is the error string. + * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. + * data is NULL. + */ +struct NSM1_UNMONargs; +EXTERN int rpc_nsm1_unmon_async(struct rpc_context *rpc, rpc_cb cb, struct NSM1_UNMONargs *args, void *private_data); + +/* + * Call NSM/UNMONALL + * Call the UNMONALL procedure for the NSM protocol + * + * 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 nsm daemon. + * data is NSM1_UNMONALLres + * RPC_STATUS_ERROR : An error occured when trying to contact the nsm daemon. + * data is the error string. + * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. + * data is NULL. + */ +struct NSM1_UNMONALLargs; +EXTERN int rpc_nsm1_unmonall_async(struct rpc_context *rpc, rpc_cb cb, struct NSM1_UNMONALLargs *args, void *private_data); + +/* + * Call NSM/SIMUCRASH + * Call the SIMUCRASH procedure for the NSM protocol + * + * 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 nsm daemon. + * data is NULL + * RPC_STATUS_ERROR : An error occured when trying to contact the nsm daemon. + * data is the error string. + * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. + * data is NULL. + */ +EXTERN int rpc_nsm1_simucrash_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); + +/* + * Call NSM/NOTIFY + * Call the NOTIFY procedure for the NSM protocol + * + * 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 nsm daemon. + * data is NULL + * RPC_STATUS_ERROR : An error occured when trying to contact the nsm daemon. + * data is the error string. + * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. + * data is NULL. + */ +struct NSM1_NOTIFYargs; +EXTERN int rpc_nsm1_notify_async(struct rpc_context *rpc, rpc_cb cb, struct NSM1_NOTIFYargs *args, void *private_data); #endif diff --git a/include/nfsc/libnfs.h b/include/nfsc/libnfs.h index 82b4a06..388ea78 100644 --- a/include/nfsc/libnfs.h +++ b/include/nfsc/libnfs.h @@ -28,6 +28,12 @@ struct nfs_context; struct rpc_context; +struct nfs_url { + char *server; + char *path; + char *file; +}; + #if defined(WIN32) #define EXTERN __declspec( dllexport ) #else @@ -71,7 +77,6 @@ EXTERN int nfs_queue_length(struct nfs_context *nfs); struct AUTH; EXTERN void nfs_set_auth(struct nfs_context *nfs, struct AUTH *auth); - /* * When an operation failed, this function can extract a detailed error string. */ @@ -106,6 +111,49 @@ EXTERN struct nfs_context *nfs_init_context(void); EXTERN void nfs_destroy_context(struct nfs_context *nfs); +/* + * 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 seccion establish + * before failing settin 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. + */ +/* + * 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; /* @@ -649,13 +697,16 @@ struct nfsdirent { char *name; uint64_t inode; - /* some extra fields we get for free through the READDIRPLUS3 call. You need libnfs-raw-nfs.h for these */ + /* 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; }; /* * nfs_readdir() never blocks, so no special sync/async versions are available diff --git a/lib/Makefile.am b/lib/Makefile.am index 30efafe..de4fc58 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -2,11 +2,12 @@ lib_LTLIBRARIES = libnfs.la libnfs_la_CPPFLAGS = -I$(abs_top_srcdir)/include \ -I$(abs_top_srcdir)/include/nfsc \ - -I../mount \ - -I../nfs \ - -I../nlm \ - -I../portmap \ - -I../rquota \ + -I$(abs_top_srcdir)/mount \ + -I$(abs_top_srcdir)/nfs \ + -I$(abs_top_srcdir)/nlm \ + -I$(abs_top_srcdir)/nsm \ + -I$(abs_top_srcdir)/portmap \ + -I$(abs_top_srcdir)/rquota \ "-D_U_=__attribute__((unused))" libnfs_la_SOURCES = \ @@ -17,11 +18,15 @@ libnfs_la_SOURCES = \ pdu.c \ socket.c -libnfs_la_LDFLAGS = -version-info 1:6:0 +SOCURRENT=1 +SOREVISION=8 +SOAGE=0 +libnfs_la_LDFLAGS = -version-info $(SOCURRENT):$(SOREVISION):$(SOAGE) libnfs_la_LIBADD = \ ../mount/libmount.la \ ../nfs/libnfs.la \ ../nlm/libnlm.la \ + ../nsm/libnsm.la \ ../portmap/libportmap.la \ ../rquota/librquota.la diff --git a/lib/init.c b/lib/init.c index 62a8f81..93d1db8 100644 --- a/lib/init.c +++ b/lib/init.c @@ -57,7 +57,9 @@ struct rpc_context *rpc_init_context(void) memset(rpc, 0, sizeof(struct rpc_context)); rpc->magic = RPC_CONTEXT_MAGIC; - rpc->encodebuflen = 65536; + + /* Allow 1M of data (for writes) and some */ + rpc->encodebuflen = 1024 * 1024 + 4096; rpc->encodebuf = malloc(rpc->encodebuflen); if (rpc->encodebuf == NULL) { free(rpc); @@ -70,9 +72,17 @@ struct rpc_context *rpc_init_context(void) free(rpc); return NULL; } - rpc->xid = salt + time(NULL); + rpc->xid = salt + time(NULL) + getpid() << 16; salt += 0x01000000; rpc->fd = -1; + rpc->tcp_syncnt = RPC_PARAM_UNDEFINED; +#ifdef WIN32 + rpc->uid = 65534; + rpc->gid = 65534; +#else + rpc->uid = getuid(); + rpc->gid = getgid(); +#endif return rpc; } @@ -100,6 +110,24 @@ void rpc_set_auth(struct rpc_context *rpc, struct AUTH *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_error(struct rpc_context *rpc, char *error_string, ...) { diff --git a/lib/libnfs-win32.def b/lib/libnfs-win32.def index 25ddfe8..7d7e108 100644 --- a/lib/libnfs-win32.def +++ b/lib/libnfs-win32.def @@ -46,6 +46,10 @@ nfs_open nfs_open_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 @@ -79,20 +83,112 @@ nfs_which_events nfs_write nfs_write_async win32_poll -rpc_which_events -rpc_service -rpc_init_context -rpc_get_fd -rpc_get_error +rpc_connect_async rpc_destroy_context -rpc_rquota1_getquota_async +rpc_disconnect +rpc_get_error +rpc_get_fd +rpc_init_context rpc_pmap_null_async rpc_pmap_getport_async -rpc_nfsacl_null_async -rpc_nfsacl_getacl_async +rpc_pmap_set_async +rpc_pmap_unset_async +rpc_pmap_callit_async rpc_mount_null_async rpc_mount_mnt_async +rpc_mount_dump_async +rpc_mount_umnt_async +rpc_mount_umntall_async rpc_mount_export_async -rpc_disconnect -rpc_connect_async +rpc_mount1_null_async +rpc_mount1_mnt_async +rpc_mount1_dump_async +rpc_mount1_umnt_async +rpc_mount1_umntall_async +rpc_mount1_export_async +rpc_mount3_null_async +rpc_mount3_mnt_async +rpc_mount3_dump_async +rpc_mount3_umnt_async +rpc_mount3_umntall_async +rpc_mount3_export_async +rpc_nfsacl_null_async +rpc_nfsacl_getacl_async +rpc_nfsacl_setacl_async +rpc_nfs_null_async +rpc_nfs_getattr_async +rpc_nfs_pathconf_async +rpc_nfs_lookup_async +rpc_nfs_access_async +rpc_nfs_read_async +rpc_nfs_write_async +rpc_nfs_commit_async +rpc_nfs_setattr_async +rpc_nfs_mkdir_async +rpc_nfs_rmdir_async +rpc_nfs_create_async +rpc_nfs_mknod_async +rpc_nfs_remove_async +rpc_nfs_readdir_async +rpc_nfs_readdirplus_async +rpc_nfs_fsstat_async rpc_nfs_fsinfo_async +rpc_nfs_readlink_async +rpc_nfs_symlink_async +rpc_nfs_rename_async +rpc_nfs_link_async +rpc_nfs2_null_async +rpc_nfs2_getattr_async +rpc_nfs2_setattr_async +rpc_nfs2_lookup_async +rpc_nfs2_readlink_async +rpc_nfs2_read_async +rpc_nfs2_write_async +rpc_nfs2_create_async +rpc_nfs2_remove_async +rpc_nfs2_rename_async +rpc_nfs2_link_async +rpc_nfs2_symlink_async +rpc_nfs2_mkdir_async +rpc_nfs2_rmdir_async +rpc_nfs2_readdir_async +rpc_nfs2_statfs_async +rpc_nfs3_null_async +rpc_nfs3_getattr_async +rpc_nfs3_pathconf_async +rpc_nfs3_lookup_async +rpc_nfs3_access_async +rpc_nfs3_read_async +rpc_nfs3_write_async +rpc_nfs3_commit_async +rpc_nfs3_setattr_async +rpc_nfs3_mkdir_async +rpc_nfs3_rmdir_async +rpc_nfs3_create_async +rpc_nfs3_mknod_async +rpc_nfs3_remove_async +rpc_nfs3_readdir_async +rpc_nfs3_readdirplus_async +rpc_nfs3_fsstat_async +rpc_nfs3_fsinfo_async +rpc_nfs3_readlink_async +rpc_nfs3_symlink_async +rpc_nfs3_rename_async +rpc_nfs3_link_async +rpc_nlm4_null_async +rpc_nlm4_test_async +rpc_nlm4_lock_async +rpc_nlm4_cancel_async +rpc_nlm4_unlock_async +rpc_nsm1_null_async +rpc_nsm1_stat_async +rpc_nsm1_mon_async +rpc_nsm1_unmon_async +rpc_nsm1_unmonall_async +rpc_nsm1_simucrash_async +rpc_nsm1_notify_async +rpc_rquota1_null_async +rpc_rquota1_getquota_async +rpc_rquota1_getactivequota_async +rpc_service +rpc_which_events diff --git a/lib/libnfs-zdr.c b/lib/libnfs-zdr.c index 5d98706..7539b08 100644 --- a/lib/libnfs-zdr.c +++ b/lib/libnfs-zdr.c @@ -124,7 +124,7 @@ bool_t libnfs_zdr_u_quad_t(ZDR *zdrs, uint64_t *u) *u = ntohl(*(uint32_t *)&zdrs->buf[zdrs->pos]); zdrs->pos += 4; *u <<= 32; - *u |= ntohl(*(uint32_t *)&zdrs->buf[zdrs->pos]); + *u |= (uint32_t)ntohl(*(uint32_t *)&zdrs->buf[zdrs->pos]); zdrs->pos += 4; return TRUE; break; @@ -219,6 +219,9 @@ bool_t libnfs_zdr_opaque(ZDR *zdrs, char *objp, uint32_t size) 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: @@ -476,10 +479,12 @@ struct AUTH *libnfs_authunix_create(char *host, uint32_t uid, uint32_t gid, uint size = 4 + 4 + ((strlen(host) + 3) & ~3) + 4 + 4 + 4 + len * 4; auth = malloc(sizeof(struct AUTH)); + memset(auth, 0x00, sizeof(struct AUTH)); auth->ah_cred.oa_flavor = AUTH_UNIX; auth->ah_cred.oa_length = size; auth->ah_cred.oa_base = malloc(size); + memset(auth->ah_cred.oa_base, 0x00, size); buf = (uint32_t *)auth->ah_cred.oa_base; idx = 0; buf[idx++] = htonl(time(NULL)); @@ -506,7 +511,7 @@ struct AUTH *libnfs_authunix_create(char *host, uint32_t uid, uint32_t gid, uint struct AUTH *libnfs_authunix_create_default(void) { #ifdef WIN32 - return libnfs_authunix_create("libnfs", 65535, 65535, 0, NULL); + return libnfs_authunix_create("libnfs", 65534, 65534, 0, NULL); #else return libnfs_authunix_create("libnfs", getuid(), getgid(), 0, NULL); #endif diff --git a/lib/libnfs.c b/lib/libnfs.c index a1a62bb..ca8ed37 100644 --- a/lib/libnfs.c +++ b/lib/libnfs.c @@ -173,6 +173,159 @@ char *nfs_get_error(struct nfs_context *nfs) return rpc_get_error(nfs->rpc); }; +static int nfs_set_context_args(struct nfs_context *nfs, char *arg, char *val) +{ + if (!strncmp(arg, "tcp-syncnt", 10)) { + rpc_set_tcp_syncnt(nfs_get_rpc_context(nfs), atoi(val)); + } else if (!strncmp(arg, "uid", 3)) { + rpc_set_uid(nfs_get_rpc_context(nfs), atoi(val)); + } else if (!strncmp(arg, "gid", 3)) { + rpc_set_gid(nfs_get_rpc_context(nfs), atoi(val)); + } + return 0; +} + +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; + + if (strncmp(url, "nfs://", 6)) { + rpc_set_error(nfs->rpc, "Invalid URL specified"); + return NULL; + } + + urls = malloc(sizeof(struct nfs_url)); + if (urls == NULL) { + rpc_set_error(nfs->rpc, "Out of memory"); + return NULL; + } + + memset(urls, 0x00, sizeof(struct nfs_url)); + urls->server = strdup(url + 6); + if (urls->server == NULL) { + nfs_destroy_url(urls); + rpc_set_error(nfs->rpc, "Out of memory"); + return NULL; + } + + if (urls->server[0] == '/' || urls->server[0] == '\0' || + urls->server[0] == '?') { + if (incomplete) { + flagsp = strchr(urls->server, '?'); + goto flags; + } + nfs_destroy_url(urls); + rpc_set_error(nfs->rpc, "Invalid server string"); + return NULL; + } + + strp = strchr(urls->server, '/'); + if (strp == NULL) { + if (incomplete) { + flagsp = strchr(urls->server, '?'); + goto flags; + } + nfs_destroy_url(urls); + rpc_set_error(nfs->rpc, "Incomplete or invalid URL specified."); + return NULL; + } + + urls->path = strdup(strp); + if (urls->path == NULL) { + nfs_destroy_url(urls); + rpc_set_error(nfs->rpc, "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); + rpc_set_error(nfs->rpc, "Incomplete or invalid URL specified."); + return NULL; + } + urls->file = strdup(strp); + if (urls->path == NULL) { + nfs_destroy_url(urls); + rpc_set_error(nfs->rpc, "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); + rpc_set_error(nfs->rpc, "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++; + nfs_set_context_args(nfs, strp, strp2); + } + } + + if (urls->server && strlen(urls->server) <= 1) { + free(urls->server); + urls->server = NULL; + } + + 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); +} + struct nfs_context *nfs_init_context(void) { struct nfs_context *nfs; @@ -219,6 +372,155 @@ void nfs_destroy_context(struct nfs_context *nfs) 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 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_ERROR) { + data->cb(rpc, status, command_data, data->private_data); + free_rpc_cb_data(data); + return; + } + if (status == RPC_STATUS_CANCEL) { + data->cb(rpc, status, "Command was cancelled", data->private_data); + free_rpc_cb_data(data); + return; + } + + data->cb(rpc, status, NULL, data->private_data); + free_rpc_cb_data(data); +} + +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; + uint32_t rpc_port; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (status == RPC_STATUS_ERROR) { + data->cb(rpc, status, command_data, data->private_data); + free_rpc_cb_data(data); + return; + } + if (status == RPC_STATUS_CANCEL) { + data->cb(rpc, status, "Command was cancelled", data->private_data); + free_rpc_cb_data(data); + return; + } + + rpc_port = *(uint32_t *)command_data; + 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"); + if (rpc_connect_async(rpc, data->server, rpc_port, rpc_connect_program_4_cb, data) != 0) { + data->cb(rpc, status, 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; + + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + if (status == RPC_STATUS_ERROR) { + data->cb(rpc, status, command_data, data->private_data); + free_rpc_cb_data(data); + return; + } + if (status == RPC_STATUS_CANCEL) { + data->cb(rpc, status, "Command was cancelled", data->private_data); + free_rpc_cb_data(data); + return; + } + + if (rpc_pmap_getport_async(rpc, data->program, data->version, IPPROTO_TCP, rpc_connect_program_3_cb, private_data) != 0) { + data->cb(rpc, status, command_data, data->private_data); + free_rpc_cb_data(data); + return; + } +} + +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_ERROR) { + data->cb(rpc, status, command_data, data->private_data); + free_rpc_cb_data(data); + return; + } + if (status == RPC_STATUS_CANCEL) { + data->cb(rpc, status, "Command was cancelled", data->private_data); + free_rpc_cb_data(data); + return; + } + + if (rpc_pmap_null_async(rpc, rpc_connect_program_2_cb, data) != 0) { + data->cb(rpc, status, command_data, data->private_data); + free_rpc_cb_data(data); + return; + } +} + +int rpc_connect_program_async(struct rpc_context *rpc, char *server, int program, int version, rpc_cb cb, void *private_data) +{ + struct rpc_cb_data *data; + + data = malloc(sizeof(struct rpc_cb_data)); + if (data == NULL) { + return -1; + } + memset(data, 0, sizeof(struct rpc_cb_data)); + data->server = strdup(server); + data->program = program; + data->version = version; + + data->cb = cb; + data->private_data = private_data; + + if (rpc_connect_async(rpc, server, 111, rpc_connect_program_1_cb, data) != 0) { + rpc_set_error(rpc, "Failed to start connection"); + free_rpc_cb_data(data); + return -1; + } + return 0; +} + void free_nfs_cb_data(struct nfs_cb_data *data) { if (data->saved_path != NULL) { @@ -275,6 +577,7 @@ static void nfs_mount_9_cb(struct rpc_context *rpc, int status, void *command_da struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; FSINFO3res *res = command_data; + struct GETATTR3args args; assert(rpc->magic == RPC_CONTEXT_MAGIC); @@ -292,7 +595,10 @@ static void nfs_mount_9_cb(struct rpc_context *rpc, int status, void *command_da nfs->readmax = res->FSINFO3res_u.resok.rtmax; nfs->writemax = res->FSINFO3res_u.resok.wtmax; - if (rpc_nfs_getattr_async(rpc, nfs_mount_10_cb, &nfs->rootfh, data) != 0) { + memset(&args, 0, sizeof(GETATTR3args)); + args.object = nfs->rootfh; + + if (rpc_nfs3_getattr_async(rpc, nfs_mount_10_cb, &args, data) != 0) { data->cb(-ENOMEM, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; @@ -303,6 +609,7 @@ static void nfs_mount_8_cb(struct rpc_context *rpc, int status, void *command_da { struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; + struct FSINFO3args args; assert(rpc->magic == RPC_CONTEXT_MAGIC); @@ -317,7 +624,8 @@ static void nfs_mount_8_cb(struct rpc_context *rpc, int status, void *command_da return; } - if (rpc_nfs_fsinfo_async(rpc, nfs_mount_9_cb, &nfs->rootfh, data) != 0) { + args.fsroot = nfs->rootfh; + if (rpc_nfs3_fsinfo_async(rpc, nfs_mount_9_cb, &args, data) != 0) { data->cb(-ENOMEM, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; @@ -346,7 +654,7 @@ static void nfs_mount_7_cb(struct rpc_context *rpc, int status, void *command_da return; } - if (rpc_nfs_null_async(rpc, nfs_mount_8_cb, data) != 0) { + if (rpc_nfs3_null_async(rpc, nfs_mount_8_cb, data) != 0) { data->cb(-ENOMEM, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; @@ -420,7 +728,7 @@ static void nfs_mount_5_cb(struct rpc_context *rpc, int status, void *command_da return; } - if (rpc_mount_mnt_async(rpc, nfs_mount_6_cb, nfs->export, data) != 0) { + if (rpc_mount3_mnt_async(rpc, nfs_mount_6_cb, nfs->export, data) != 0) { data->cb(-ENOMEM, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; @@ -448,7 +756,7 @@ static void nfs_mount_4_cb(struct rpc_context *rpc, int status, void *command_da return; } - if (rpc_mount_null_async(rpc, nfs_mount_5_cb, data) != 0) { + if (rpc_mount3_null_async(rpc, nfs_mount_5_cb, data) != 0) { data->cb(-ENOMEM, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; @@ -625,6 +933,7 @@ static void nfs_lookup_path_1_cb(struct rpc_context *rpc, int status, void *comm static int nfs_lookup_path_async_internal(struct nfs_context *nfs, struct nfs_cb_data *data, struct nfs_fh3 *fh) { char *path, *str; + LOOKUP3args args; while (*data->path == '/') { data->path++; @@ -655,7 +964,12 @@ static int nfs_lookup_path_async_internal(struct nfs_context *nfs, struct nfs_cb return 0; } - if (rpc_nfs_lookup_async(nfs->rpc, nfs_lookup_path_1_cb, fh, path, data) != 0) { + + memset(&args, 0, sizeof(LOOKUP3args)); + args.what.dir = *fh; + args.what.name = path; + + if (rpc_nfs3_lookup_async(nfs->rpc, nfs_lookup_path_1_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send lookup call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -768,7 +1082,12 @@ static void nfs_stat_1_cb(struct rpc_context *rpc, int status, void *command_dat static int nfs_stat_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data) { - if (rpc_nfs_getattr_async(nfs->rpc, nfs_stat_1_cb, &data->fh, data) != 0) { + struct GETATTR3args args; + + memset(&args, 0, sizeof(GETATTR3args)); + args.object = data->fh; + + if (rpc_nfs3_getattr_async(nfs->rpc, nfs_stat_1_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send STAT GETATTR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -861,8 +1180,7 @@ static void nfs_open_cb(struct rpc_context *rpc, int status, void *command_data, } /* steal the filehandle */ - nfsfh->fh.data.data_len = data->fh.data.data_len; - nfsfh->fh.data.data_val = data->fh.data.data_val; + nfsfh->fh = data->fh; data->fh.data.data_val = NULL; data->cb(0, nfs, nfsfh, data->private_data); @@ -872,6 +1190,7 @@ static void nfs_open_cb(struct rpc_context *rpc, int status, void *command_data, static int nfs_open_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data) { int nfsmode = 0; + ACCESS3args args; if (data->continue_int & O_WRONLY) { nfsmode |= ACCESS3_MODIFY; @@ -883,7 +1202,11 @@ static int nfs_open_continue_internal(struct nfs_context *nfs, struct nfs_cb_dat nfsmode |= ACCESS3_READ; } - if (rpc_nfs_access_async(nfs->rpc, nfs_open_cb, &data->fh, nfsmode, data) != 0) { + memset(&args, 0, sizeof(ACCESS3args)); + args.object = data->fh; + args.access = nfsmode; + + if (rpc_nfs3_access_async(nfs->rpc, nfs_open_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send OPEN ACCESS call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -1021,7 +1344,14 @@ int nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offse nfsfh->offset = offset; if (count <= nfs_get_readmax(nfs)) { - if (rpc_nfs_read_async(nfs->rpc, nfs_pread_cb, &nfsfh->fh, offset, count, data) != 0) { + READ3args args; + + memset(&args, 0, sizeof(READ3args)); + args.file = nfsfh->fh; + args.offset = offset; + args.count = count; + + if (rpc_nfs3_read_async(nfs->rpc, nfs_pread_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send READ call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -1032,7 +1362,7 @@ int nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offse /* trying to read more than maximum server read size, we has to chop it up into smaller * reads and collect into a reassembly buffer. - * we send all reads in parallell so that performance is still good. + * we send all reads in parallel so that performance is still good. */ data->max_offset = offset; data->start_offset = offset; @@ -1048,6 +1378,7 @@ int nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offse while (count > 0) { uint64_t readcount = count; struct nfs_mcb_data *mdata; + READ3args args; if (readcount > nfs_get_readmax(nfs)) { readcount = nfs_get_readmax(nfs); @@ -1062,7 +1393,13 @@ int nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offse mdata->data = data; mdata->offset = offset; mdata->count = readcount; - if (rpc_nfs_read_async(nfs->rpc, nfs_pread_mcb, &nfsfh->fh, offset, readcount, mdata) != 0) { + + memset(&args, 0, sizeof(READ3args)); + args.file = nfsfh->fh; + args.offset = offset; + args.count = readcount; + + if (rpc_nfs3_read_async(nfs->rpc, nfs_pread_mcb, &args, mdata) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send READ call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free(mdata); @@ -1201,7 +1538,17 @@ int nfs_pwrite_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offs nfsfh->offset = offset; if (count <= nfs_get_writemax(nfs)) { - if (rpc_nfs_write_async(nfs->rpc, nfs_pwrite_cb, &nfsfh->fh, buf, offset, count, nfsfh->is_sync?FILE_SYNC:UNSTABLE, data) != 0) { + WRITE3args args; + + memset(&args, 0, sizeof(WRITE3args)); + args.file = nfsfh->fh; + args.offset = offset; + args.count = count; + args.stable = nfsfh->is_sync?FILE_SYNC:UNSTABLE; + args.data.data_len = count; + args.data.data_val = buf; + + if (rpc_nfs3_write_async(nfs->rpc, nfs_pwrite_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send WRITE call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -1212,7 +1559,7 @@ int nfs_pwrite_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offs /* trying to write more than maximum server write size, we has to chop it up into smaller * chunks. - * we send all writes in parallell so that performance is still good. + * we send all writes in parallel so that performance is still good. */ data->max_offset = offset; data->start_offset = offset; @@ -1220,6 +1567,7 @@ int nfs_pwrite_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offs while (count > 0) { uint64_t writecount = count; struct nfs_mcb_data *mdata; + WRITE3args args; if (writecount > nfs_get_writemax(nfs)) { writecount = nfs_get_writemax(nfs); @@ -1235,7 +1583,15 @@ int nfs_pwrite_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offs mdata->offset = offset; mdata->count = writecount; - if (rpc_nfs_write_async(nfs->rpc, nfs_pwrite_mcb, &nfsfh->fh, &buf[offset - data->start_offset], offset, writecount, nfsfh->is_sync?FILE_SYNC:UNSTABLE, mdata) != 0) { + memset(&args, 0, sizeof(WRITE3args)); + args.file = nfsfh->fh; + args.offset = offset; + args.count = writecount; + args.stable = nfsfh->is_sync?FILE_SYNC:UNSTABLE; + args.data.data_len = writecount; + args.data.data_val = &buf[offset - data->start_offset]; + + if (rpc_nfs3_write_async(nfs->rpc, nfs_pwrite_mcb, &args, mdata) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send WRITE call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free(mdata); @@ -1287,6 +1643,7 @@ int nfs_close_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, voi int nfs_fstat_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, void *private_data) { struct nfs_cb_data *data; + struct GETATTR3args args; data = malloc(sizeof(struct nfs_cb_data)); if (data == NULL) { @@ -1298,7 +1655,10 @@ int nfs_fstat_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, voi data->cb = cb; data->private_data = private_data; - if (rpc_nfs_getattr_async(nfs->rpc, nfs_stat_1_cb, &nfsfh->fh, data) != 0) { + memset(&args, 0, sizeof(GETATTR3args)); + args.object = nfsfh->fh; + + if (rpc_nfs3_getattr_async(nfs->rpc, nfs_stat_1_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send STAT GETATTR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -1346,6 +1706,7 @@ static void nfs_fsync_cb(struct rpc_context *rpc, int status, void *command_data int nfs_fsync_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, void *private_data) { struct nfs_cb_data *data; + struct COMMIT3args args; data = malloc(sizeof(struct nfs_cb_data)); if (data == NULL) { @@ -1357,7 +1718,10 @@ int nfs_fsync_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, voi data->cb = cb; data->private_data = private_data; - if (rpc_nfs_commit_async(nfs->rpc, nfs_fsync_cb, &nfsfh->fh, data) != 0) { + args.file = nfsfh->fh; + args.offset = 0; + args.count = 0; + if (rpc_nfs3_commit_async(nfs->rpc, nfs_fsync_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send COMMIT call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -1419,12 +1783,11 @@ int nfs_ftruncate_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t l data->private_data = private_data; memset(&args, 0, sizeof(SETATTR3args)); - args.object.data.data_len = nfsfh->fh.data.data_len; - args.object.data.data_val = nfsfh->fh.data.data_val; + args.object = nfsfh->fh; args.new_attributes.size.set_it = 1; args.new_attributes.size.set_size3_u.size = length; - if (rpc_nfs_setattr_async(nfs->rpc, nfs_ftruncate_cb, &args, data) != 0) { + if (rpc_nfs3_setattr_async(nfs->rpc, nfs_ftruncate_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send SETATTR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -1442,8 +1805,7 @@ static int nfs_truncate_continue_internal(struct nfs_context *nfs, struct nfs_cb uint64_t offset = data->continue_int; struct nfsfh nfsfh; - nfsfh.fh.data.data_val = data->fh.data.data_val; - nfsfh.fh.data.data_len = data->fh.data.data_len; + nfsfh.fh = data->fh; if (nfs_ftruncate_async(nfs, &nfsfh, offset, data->cb, data->private_data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send SETATTR call for %s", data->path); @@ -1517,13 +1879,12 @@ static int nfs_mkdir_continue_internal(struct nfs_context *nfs, struct nfs_cb_da str = &str[strlen(str) + 1]; 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.dir = data->fh; 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) { + if (rpc_nfs3_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); @@ -1603,10 +1964,13 @@ static void nfs_rmdir_cb(struct rpc_context *rpc, int status, void *command_data static int nfs_rmdir_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data) { char *str = data->continue_data; - + RMDIR3args args; + str = &str[strlen(str) + 1]; - if (rpc_nfs_rmdir_async(nfs->rpc, nfs_rmdir_cb, &data->fh, str, data) != 0) { + args.object.dir = data->fh; + args.object.name = str; + if (rpc_nfs3_rmdir_async(nfs->rpc, nfs_rmdir_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send RMDIR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -1704,6 +2068,7 @@ static void nfs_creat_1_cb(struct rpc_context *rpc, int status, void *command_da struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; char *str = data->continue_data; + LOOKUP3args args; assert(rpc->magic == RPC_CONTEXT_MAGIC); @@ -1723,11 +2088,15 @@ static void nfs_creat_1_cb(struct rpc_context *rpc, int status, void *command_da if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: CREATE of %s/%s failed with %s(%d)", data->saved_path, str, nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); - + free_nfs_cb_data(data); return; } - if (rpc_nfs_lookup_async(nfs->rpc, nfs_create_2_cb, &data->fh, str, data) != 0) { + memset(&args, 0, sizeof(LOOKUP3args)); + args.what.dir = data->fh; + args.what.name = str; + + if (rpc_nfs3_lookup_async(nfs->rpc, nfs_create_2_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send lookup call for %s/%s", data->saved_path, str); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -1744,14 +2113,13 @@ static int nfs_creat_continue_internal(struct nfs_context *nfs, struct nfs_cb_da str = &str[strlen(str) + 1]; 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.dir = data->fh; 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) { + if (rpc_nfs3_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); @@ -1830,10 +2198,13 @@ static void nfs_unlink_cb(struct rpc_context *rpc, int status, void *command_dat static int nfs_unlink_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data) { char *str = data->continue_data; - + struct REMOVE3args args; + str = &str[strlen(str) + 1]; - if (rpc_nfs_remove_async(nfs->rpc, nfs_unlink_cb, &data->fh, str, data) != 0) { + args.object.dir = data->fh; + args.object.name = str; + if (rpc_nfs3_remove_async(nfs->rpc, nfs_unlink_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send REMOVE call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -1926,10 +2297,44 @@ static int nfs_mknod_continue_internal(struct nfs_context *nfs, struct nfs_cb_da { struct mknod_cb_data *cb_data = data->continue_data; char *str = cb_data->path; + MKNOD3args args; str = &str[strlen(str) + 1]; - if (rpc_nfs_mknod_async(nfs->rpc, nfs_mknod_cb, &data->fh, str, cb_data->mode, cb_data->major, cb_data->minor, data) != 0) { + args.where.dir = data->fh; + 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; + 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: + rpc_set_error(nfs->rpc, "Invalid file type for NFS3/MKNOD call"); + data->cb(-EINVAL, nfs, rpc_get_error(nfs->rpc), data->private_data); + free_nfs_cb_data(data); + return -1; + } + + if (rpc_nfs3_mknod_async(nfs->rpc, nfs_mknod_cb, &args, data) != 0) { data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; @@ -2033,6 +2438,8 @@ static void nfs_opendir3_cb(struct rpc_context *rpc, int status, void *command_d nfsdirent->mtime.tv_usec = attributes->mtime.nseconds/1000; nfsdirent->ctime.tv_sec = attributes->ctime.seconds; nfsdirent->ctime.tv_usec = attributes->ctime.nseconds/1000; + nfsdirent->uid = attributes->uid; + nfsdirent->gid = attributes->gid; } } @@ -2117,7 +2524,14 @@ static void nfs_opendir2_cb(struct rpc_context *rpc, int status, void *command_d } if (res->READDIR3res_u.resok.reply.eof == 0) { - if (rpc_nfs_readdir_async(nfs->rpc, nfs_opendir2_cb, &data->fh, cookie, res->READDIR3res_u.resok.cookieverf, 8192, data) != 0) { + READDIR3args args; + + args.dir = data->fh; + args.cookie = cookie; + memcpy(&args.cookieverf, res->READDIR3res_u.resok.cookieverf, sizeof(cookieverf3)); + args.count = 8192; + + if (rpc_nfs3_readdir_async(nfs->rpc, nfs_opendir2_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send READDIR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); nfs_free_nfsdir(nfsdir); @@ -2137,12 +2551,17 @@ static void nfs_opendir2_cb(struct rpc_context *rpc, int status, void *command_d rdpe_cb_data->data = data; for (nfsdirent = nfsdir->entries; nfsdirent; nfsdirent = nfsdirent->next) { struct rdpe_lookup_cb_data *rdpe_lookup_cb_data; + LOOKUP3args args; rdpe_lookup_cb_data = malloc(sizeof(struct rdpe_lookup_cb_data)); rdpe_lookup_cb_data->rdpe_cb_data = rdpe_cb_data; rdpe_lookup_cb_data->nfsdirent = nfsdirent; - if (rpc_nfs_lookup_async(nfs->rpc, nfs_opendir3_cb, &data->fh, nfsdirent->name, rdpe_lookup_cb_data) != 0) { + memset(&args, 0, sizeof(LOOKUP3args)); + args.what.dir = data->fh; + args.what.name = nfsdirent->name; + + if (rpc_nfs3_lookup_async(nfs->rpc, nfs_opendir3_cb, &args, rdpe_lookup_cb_data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send READDIR LOOKUP call"); /* if we have already commands in flight, we cant just stop, we have to wait for the @@ -2179,9 +2598,14 @@ static void nfs_opendir_cb(struct rpc_context *rpc, int status, void *command_da assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR || (status == RPC_STATUS_SUCCESS && res->status == NFS3ERR_NOTSUPP) ){ - cookieverf3 cv; + READDIR3args args; + + args.dir = data->fh; + args.cookie = cookie; + memset(&args.cookieverf, 0, sizeof(cookieverf3)); + args.count = 8192; - if (rpc_nfs_readdir_async(nfs->rpc, nfs_opendir2_cb, &data->fh, 0, (char *)&cv, 8192, data) != 0) { + if (rpc_nfs3_readdir_async(nfs->rpc, nfs_opendir2_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send READDIR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); nfs_free_nfsdir(nfsdir); @@ -2242,6 +2666,8 @@ static void nfs_opendir_cb(struct rpc_context *rpc, int status, void *command_da 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->uid = entry->name_attributes.post_op_attr_u.attributes.uid; + nfsdirent->gid = entry->name_attributes.post_op_attr_u.attributes.gid; } nfsdirent->next = nfsdir->entries; @@ -2252,7 +2678,15 @@ static void nfs_opendir_cb(struct rpc_context *rpc, int status, void *command_da } 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) { + READDIRPLUS3args args; + + args.dir = data->fh; + args.cookie = cookie; + memcpy(&args.cookieverf, res->READDIRPLUS3res_u.resok.cookieverf, sizeof(cookieverf3)); + args.dircount = 8192; + args.maxcount = 8192; + + if (rpc_nfs3_readdirplus_async(nfs->rpc, nfs_opendir_cb, &args, 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); @@ -2273,10 +2707,14 @@ static void nfs_opendir_cb(struct rpc_context *rpc, int status, void *command_da static int nfs_opendir_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data) { - cookieverf3 cv; - - memset(cv, 0, sizeof(cookieverf3)); - if (rpc_nfs_readdirplus_async(nfs->rpc, nfs_opendir_cb, &data->fh, 0, (char *)&cv, 8192, data) != 0) { + READDIRPLUS3args args; + + args.dir = data->fh; + args.cookie = 0; + memset(&args.cookieverf, 0, sizeof(cookieverf3)); + args.dircount = 8192; + args.maxcount = 8192; + if (rpc_nfs3_readdirplus_async(nfs->rpc, nfs_opendir_cb, &args, 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); @@ -2373,6 +2811,7 @@ static void nfs_lseek_1_cb(struct rpc_context *rpc, int status, void *command_da 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; + struct GETATTR3args args; if (whence == SEEK_SET) { nfsfh->offset = offset; @@ -2397,7 +2836,10 @@ int nfs_lseek_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offse data->cb = cb; data->private_data = private_data; - if (rpc_nfs_getattr_async(nfs->rpc, nfs_lseek_1_cb, &nfsfh->fh, data) != 0) { + memset(&args, 0, sizeof(GETATTR3args)); + args.object = nfsfh->fh; + + if (rpc_nfs3_getattr_async(nfs->rpc, nfs_lseek_1_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send LSEEK GETATTR call"); free(data); return -1; @@ -2459,7 +2901,10 @@ static void nfs_statvfs_1_cb(struct rpc_context *rpc, int status, void *command_ static int nfs_statvfs_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data) { - if (rpc_nfs_fsstat_async(nfs->rpc, nfs_statvfs_1_cb, &data->fh, data) != 0) { + FSSTAT3args args; + + args.fsroot = data->fh; + if (rpc_nfs3_fsstat_async(nfs->rpc, nfs_statvfs_1_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send FSSTAT call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -2520,10 +2965,9 @@ static int nfs_readlink_continue_internal(struct nfs_context *nfs, struct nfs_cb { READLINK3args args; - args.symlink.data.data_len = data->fh.data.data_len; - args.symlink.data.data_val = data->fh.data.data_val; + args.symlink = data->fh; - if (rpc_nfs_readlink_async(nfs->rpc, nfs_readlink_1_cb, &args, data) != 0) { + if (rpc_nfs3_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); @@ -2584,12 +3028,11 @@ static int nfs_chmod_continue_internal(struct nfs_context *nfs, struct nfs_cb_da SETATTR3args args; memset(&args, 0, sizeof(SETATTR3args)); - args.object.data.data_len = data->fh.data.data_len; - args.object.data.data_val = data->fh.data.data_val; + args.object = data->fh; args.new_attributes.mode.set_it = 1; args.new_attributes.mode.set_mode3_u.mode = data->continue_int; - if (rpc_nfs_setattr_async(nfs->rpc, nfs_chmod_cb, &args, data) != 0) { + if (rpc_nfs3_setattr_async(nfs->rpc, nfs_chmod_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send SETATTR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -2690,8 +3133,7 @@ static int nfs_chown_continue_internal(struct nfs_context *nfs, struct nfs_cb_da struct nfs_chown_data *chown_data = data->continue_data; memset(&args, 0, sizeof(SETATTR3args)); - args.object.data.data_len = data->fh.data.data_len; - args.object.data.data_val = data->fh.data.data_val; + args.object = data->fh; 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; @@ -2701,7 +3143,7 @@ static int nfs_chown_continue_internal(struct nfs_context *nfs, struct nfs_cb_da args.new_attributes.gid.set_gid3_u.gid = chown_data->gid; } - if (rpc_nfs_setattr_async(nfs->rpc, nfs_chown_cb, &args, data) != 0) { + if (rpc_nfs3_setattr_async(nfs->rpc, nfs_chown_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send SETATTR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -2823,8 +3265,7 @@ static int nfs_utimes_continue_internal(struct nfs_context *nfs, struct nfs_cb_d struct timeval *utimes_data = data->continue_data; memset(&args, 0, sizeof(SETATTR3args)); - args.object.data.data_len = data->fh.data.data_len; - args.object.data.data_val = data->fh.data.data_val; + args.object = data->fh; 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; @@ -2837,7 +3278,7 @@ static int nfs_utimes_continue_internal(struct nfs_context *nfs, struct nfs_cb_d args.new_attributes.mtime.set_it = SET_TO_SERVER_TIME; } - if (rpc_nfs_setattr_async(nfs->rpc, nfs_utimes_cb, &args, data) != 0) { + if (rpc_nfs3_setattr_async(nfs->rpc, nfs_utimes_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send SETATTR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -2959,6 +3400,7 @@ static void nfs_access_cb(struct rpc_context *rpc, int status, void *command_dat static int nfs_access_continue_internal(struct nfs_context *nfs, struct nfs_cb_data *data) { int nfsmode = 0; + ACCESS3args args; if (data->continue_int & R_OK) { nfsmode |= ACCESS3_READ; @@ -2970,7 +3412,11 @@ static int nfs_access_continue_internal(struct nfs_context *nfs, struct nfs_cb_d nfsmode |= ACCESS3_EXECUTE; } - if (rpc_nfs_access_async(nfs->rpc, nfs_access_cb, &data->fh, nfsmode, data) != 0) { + memset(&args, 0, sizeof(ACCESS3args)); + args.object = data->fh; + args.access = nfsmode; + + if (rpc_nfs3_access_async(nfs->rpc, nfs_access_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send OPEN ACCESS call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -3051,17 +3497,16 @@ static void nfs_symlink_cb(struct rpc_context *rpc, int status, void *command_da 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; + SYMLINK3args args; - 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; + memset(&args, 0, sizeof(SYMLINK3args)); + args.where.dir = data->fh; + args.where.name = symlink_data->newpathobject; + 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->oldpath; - if (rpc_nfs_symlink_async(nfs->rpc, nfs_symlink_cb, &sa, data) != 0) { + if (rpc_nfs3_symlink_async(nfs->rpc, nfs_symlink_cb, &args, 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); @@ -3188,13 +3633,17 @@ static void nfs_rename_cb(struct rpc_context *rpc, int status, void *command_dat static int nfs_rename_continue_2_internal(struct nfs_context *nfs, struct nfs_cb_data *data) { struct nfs_rename_data *rename_data = data->continue_data; + RENAME3args args; /* steal the filehandle */ - rename_data->newdir.data.data_len = data->fh.data.data_len; - rename_data->newdir.data.data_val = data->fh.data.data_val; + rename_data->newdir = data->fh; data->fh.data.data_val = NULL; - if (rpc_nfs_rename_async(nfs->rpc, nfs_rename_cb, &rename_data->olddir, rename_data->oldobject, &rename_data->newdir, rename_data->newobject, data) != 0) { + args.from.dir = rename_data->olddir; + args.from.name = rename_data->oldobject; + args.to.dir = rename_data->newdir; + args.to.name = rename_data->newobject; + if (rpc_nfs3_rename_async(nfs->rpc, nfs_rename_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send RENAME call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -3209,8 +3658,7 @@ static int nfs_rename_continue_1_internal(struct nfs_context *nfs, struct nfs_cb struct nfs_rename_data *rename_data = data->continue_data; /* steal the filehandle */ - rename_data->olddir.data.data_len = data->fh.data.data_len; - rename_data->olddir.data.data_val = data->fh.data.data_val; + rename_data->olddir = data->fh; data->fh.data.data_val = NULL; if (nfs_lookuppath_async(nfs, rename_data->newpath, data->cb, data->private_data, nfs_rename_continue_2_internal, rename_data, free_nfs_rename_data, 0) != 0) { @@ -3346,13 +3794,17 @@ static void nfs_link_cb(struct rpc_context *rpc, int status, void *command_data, static int nfs_link_continue_2_internal(struct nfs_context *nfs, struct nfs_cb_data *data) { struct nfs_link_data *link_data = data->continue_data; + LINK3args args; /* steal the filehandle */ - link_data->newdir.data.data_len = data->fh.data.data_len; - link_data->newdir.data.data_val = data->fh.data.data_val; + link_data->newdir = data->fh; data->fh.data.data_val = NULL; - if (rpc_nfs_link_async(nfs->rpc, nfs_link_cb, &link_data->oldfh, &link_data->newdir, link_data->newobject, data) != 0) { + memset(&args, 0, sizeof(LINK3args)); + args.file = link_data->oldfh; + args.link.dir = link_data->newdir; + args.link.name = link_data->newobject; + if (rpc_nfs3_link_async(nfs->rpc, nfs_link_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send LINK call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); @@ -3367,8 +3819,7 @@ static int nfs_link_continue_1_internal(struct nfs_context *nfs, struct nfs_cb_d struct nfs_link_data *link_data = data->continue_data; /* steal the filehandle */ - link_data->oldfh.data.data_len = data->fh.data.data_len; - link_data->oldfh.data.data_val = data->fh.data.data_val; + link_data->oldfh = data->fh; data->fh.data.data_val = NULL; if (nfs_lookuppath_async(nfs, link_data->newpath, data->cb, data->private_data, nfs_link_continue_2_internal, link_data, free_nfs_link_data, 0) != 0) { @@ -3450,11 +3901,7 @@ uint64_t nfs_get_readmax(struct nfs_context *nfs) */ uint64_t nfs_get_writemax(struct nfs_context *nfs) { - /* Some ZDR libraries can not marshall PDUs bigger than this */ - if (nfs->writemax < 32768) { - return nfs->writemax; - } - return 32768; + return nfs->writemax; } void nfs_set_error(struct nfs_context *nfs, char *error_string, ...) @@ -3534,7 +3981,7 @@ static void mount_export_4_cb(struct rpc_context *rpc, int status, void *command return; } - if (rpc_mount_export_async(rpc, mount_export_5_cb, data) != 0) { + if (rpc_mount3_export_async(rpc, mount_export_5_cb, data) != 0) { data->cb(rpc, -ENOMEM, command_data, data->private_data); free_mount_cb_data(data); return; diff --git a/lib/pdu.c b/lib/pdu.c index eca054c..c2538ef 100644 --- a/lib/pdu.c +++ b/lib/pdu.c @@ -113,6 +113,10 @@ void rpc_free_pdu(struct rpc_context *rpc, struct rpc_pdu *pdu) free(pdu); } +void rpc_set_next_xid(struct rpc_context *rpc, uint32_t xid) +{ + rpc->xid = xid; +} int rpc_queue_pdu(struct rpc_context *rpc, struct rpc_pdu *pdu) { @@ -230,7 +234,7 @@ int rpc_process_pdu(struct rpc_context *rpc, char *buf, int size) struct rpc_pdu *pdu; ZDR zdr; int pos, recordmarker = 0; - unsigned int xid; + uint32_t xid; char *reasbuf = NULL; assert(rpc->magic == RPC_CONTEXT_MAGIC); diff --git a/lib/socket.c b/lib/socket.c index 8dc3ed2..1676084 100644 --- a/lib/socket.c +++ b/lib/socket.c @@ -46,6 +46,10 @@ #include #endif +#ifdef HAVE_NETINET_TCP_H +#include +#endif + #ifdef HAVE_NETDB_H #include #endif @@ -92,6 +96,26 @@ static void set_nonblocking(int fd) #endif //FIXME } +#ifdef HAVE_NETINET_TCP_H +int set_tcp_sockopt(int sockfd, int optname, int value) +{ + int level; + + #if defined(__FreeBSD__) || 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)); +} +#endif + int rpc_get_fd(struct rpc_context *rpc) { assert(rpc->magic == RPC_CONTEXT_MAGIC); @@ -163,8 +187,6 @@ static int rpc_read_from_socket(struct rpc_context *rpc) assert(rpc->magic == RPC_CONTEXT_MAGIC); - assert(rpc->magic == RPC_CONTEXT_MAGIC); - if (ioctl(rpc->fd, FIONREAD, &available) != 0) { rpc_set_error(rpc, "Ioctl FIONREAD returned error : %d. Closing socket.", errno); return -1; @@ -258,14 +280,17 @@ static int rpc_read_from_socket(struct rpc_context *rpc) rpc->inpos += count; if (rpc->inpos == rpc->insize) { - if (rpc_process_pdu(rpc, rpc->inbuf, pdu_size) != 0) { - rpc_set_error(rpc, "Invalid/garbage pdu received from server. Closing socket"); - return -1; - } - free(rpc->inbuf); + char *buf = rpc->inbuf; + rpc->inbuf = NULL; rpc->insize = 0; rpc->inpos = 0; + + if (rpc_process_pdu(rpc, buf, pdu_size) != 0) { + rpc_set_error(rpc, "Invalid/garbage pdu received from server. Closing socket"); + return -1; + } + free(buf); } return 0; @@ -367,6 +392,13 @@ void rpc_unset_autoreconnect(struct rpc_context *rpc) rpc->auto_reconnect = 0; } +void rpc_set_tcp_syncnt(struct rpc_context *rpc, int v) +{ + assert(rpc->magic == RPC_CONTEXT_MAGIC); + + rpc->tcp_syncnt = v; +} + static int rpc_connect_sockaddr_async(struct rpc_context *rpc, struct sockaddr_storage *s) { int socksize; @@ -377,6 +409,11 @@ static int rpc_connect_sockaddr_async(struct rpc_context *rpc, struct sockaddr_s case AF_INET: socksize = sizeof(struct sockaddr_in); rpc->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); +#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); diff --git a/libnfs.pc.in b/libnfs.pc.in index e7e3a91..fdc012c 100644 --- a/libnfs.pc.in +++ b/libnfs.pc.in @@ -12,4 +12,3 @@ Requires: Conflicts: Libs: -L${libdir} -lnfs Cflags: -I${includedir} -Requires.private: @LIBNFS_PC_REQ_PRIVATE@ diff --git a/mount/mount.c b/mount/mount.c index 1f520cd..b3f87ff 100644 --- a/mount/mount.c +++ b/mount/mount.c @@ -27,7 +27,7 @@ #include "libnfs-private.h" #include "libnfs-raw-mount.h" -int rpc_mount_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) +int rpc_mount3_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; @@ -46,7 +46,12 @@ int rpc_mount_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) return 0; } -int rpc_mount_mnt_async(struct rpc_context *rpc, rpc_cb cb, char *export, void *private_data) +int rpc_mount_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) +{ + return rpc_mount3_null_async(rpc, cb, private_data); +} + +int rpc_mount3_mnt_async(struct rpc_context *rpc, rpc_cb cb, char *export, void *private_data) { struct rpc_pdu *pdu; @@ -71,7 +76,12 @@ int rpc_mount_mnt_async(struct rpc_context *rpc, rpc_cb cb, char *export, void * return 0; } -int rpc_mount_dump_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) +int rpc_mount_mnt_async(struct rpc_context *rpc, rpc_cb cb, char *export, void *private_data) +{ + return rpc_mount3_mnt_async(rpc, cb, export, private_data); +} + +int rpc_mount3_dump_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; @@ -90,7 +100,12 @@ int rpc_mount_dump_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) return 0; } -int rpc_mount_umnt_async(struct rpc_context *rpc, rpc_cb cb, char *export, void *private_data) +int rpc_mount_dump_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) +{ + return rpc_mount3_dump_async(rpc, cb, private_data); +} + +int rpc_mount3_umnt_async(struct rpc_context *rpc, rpc_cb cb, char *export, void *private_data) { struct rpc_pdu *pdu; @@ -115,7 +130,12 @@ int rpc_mount_umnt_async(struct rpc_context *rpc, rpc_cb cb, char *export, void return 0; } -int rpc_mount_umntall_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) +int rpc_mount_umnt_async(struct rpc_context *rpc, rpc_cb cb, char *export, void *private_data) +{ + return rpc_mount3_umnt_async(rpc, cb, export, private_data); +} + +int rpc_mount3_umntall_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; @@ -134,7 +154,12 @@ int rpc_mount_umntall_async(struct rpc_context *rpc, rpc_cb cb, void *private_da return 0; } -int rpc_mount_export_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) +int rpc_mount_umntall_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) +{ + return rpc_mount3_umntall_async(rpc, cb, private_data); +} + +int rpc_mount3_export_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; @@ -153,6 +178,11 @@ int rpc_mount_export_async(struct rpc_context *rpc, rpc_cb cb, void *private_dat return 0; } +int rpc_mount_export_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) +{ + return rpc_mount3_export_async(rpc, cb, private_data); +} + char *mountstat3_to_str(int st) { enum mountstat3 stat = st; @@ -193,5 +223,129 @@ int mountstat3_to_errno(int st) return -ERANGE; } +int rpc_mount1_null_async(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 -1; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for MOUNT1/NULL call"); + rpc_free_pdu(rpc, pdu); + return -1; + } + + return 0; +} + +int rpc_mount1_mnt_async(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 -1; + } + + 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 -1; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for MOUNT1/MNT call"); + rpc_free_pdu(rpc, pdu); + return -1; + } + + return 0; +} + +int rpc_mount1_dump_async(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 -1; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue MOUNT1/DUMP pdu"); + rpc_free_pdu(rpc, pdu); + return -1; + } + + return 0; +} + +int rpc_mount1_umnt_async(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 -1; + } + + if (zdr_dirpath(&pdu->zdr, &export) == 0) { + rpc_set_error(rpc, "failed to encode dirpath for MOUNT1/UMNT"); + rpc_free_pdu(rpc, pdu); + return -1; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue MOUNT1/UMNT pdu"); + rpc_free_pdu(rpc, pdu); + return -1; + } + + return 0; +} + +int rpc_mount1_umntall_async(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 -1; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue MOUNT1/UMNTALL pdu"); + rpc_free_pdu(rpc, pdu); + return -1; + } + + return 0; +} + +int rpc_mount1_export_async(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 -1; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Failed to queue MOUNT1/EXPORT pdu"); + rpc_free_pdu(rpc, pdu); + return -1; + } + return 0; +} diff --git a/nfs/Makefile.am b/nfs/Makefile.am index d6f75a0..82e60c5 100644 --- a/nfs/Makefile.am +++ b/nfs/Makefile.am @@ -18,5 +18,5 @@ nfs-stamp : nfs.x touch nfs-stamp compile_rpc: - rpcgen -h nfs.x | sed -e "s/#include //" | sed -e "s/xdr/zdr/g" -e "s/XDR/ZDR/g" > libnfs-raw-nfs.h + rpcgen -h nfs.x | sed -e "s/#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#if defined(ANDROID)\ntypedef long long int quad_t;\ntypedef long long unsigned u_quad_t;\n#endif\n#if defined(WIN32)\ntypedef long long int quad_t;\ntypedef long long unsigned u_quad_t;\n#endif/g" > libnfs-raw-nfs.h 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;/" > libnfs-raw-nfs.c diff --git a/nfs/libnfs-raw-nfs.c b/nfs/libnfs-raw-nfs.c index ce319ec..04e914d 100644 --- a/nfs/libnfs-raw-nfs.c +++ b/nfs/libnfs-raw-nfs.c @@ -2094,6 +2094,960 @@ zdr_SETATTR3res (ZDR *zdrs, SETATTR3res *objp) return TRUE; } +bool_t +zdr_fhandle2 (ZDR *zdrs, fhandle2 objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_opaque (zdrs, objp, FHSIZE2)) + return FALSE; + return TRUE; +} + +bool_t +zdr_ftype2 (ZDR *zdrs, ftype2 *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +bool_t +zdr_fattr2 (ZDR *zdrs, fattr2 *objp) +{ + register int32_t *buf; + buf = NULL; + + + 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; +} + +bool_t +zdr_sattr2 (ZDR *zdrs, sattr2 *objp) +{ + register int32_t *buf; + buf = NULL; + + + 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; +} + +bool_t +zdr_filename2 (ZDR *zdrs, filename2 *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_string (zdrs, objp, MAXNAMLEN2)) + return FALSE; + return TRUE; +} + +bool_t +zdr_path2 (ZDR *zdrs, path2 *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_string (zdrs, objp, MAXPATHLEN2)) + return FALSE; + return TRUE; +} + +bool_t +zdr_nfsdata2 (ZDR *zdrs, nfsdata2 *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_bytes (zdrs, (char **)&objp->nfsdata2_val, (u_int *) &objp->nfsdata2_len, NFSMAXDATA2)) + return FALSE; + return TRUE; +} + +bool_t +zdr_nfscookie2 (ZDR *zdrs, nfscookie2 objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_opaque (zdrs, objp, NFSCOOKIESIZE2)) + return FALSE; + return TRUE; +} + +bool_t +zdr_entry2 (ZDR *zdrs, entry2 *objp) +{ + register int32_t *buf; + buf = NULL; + + 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; +} + +bool_t +zdr_diropargs2 (ZDR *zdrs, diropargs2 *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_fhandle2 (zdrs, objp->dir)) + return FALSE; + if (!zdr_filename2 (zdrs, &objp->name)) + return FALSE; + return TRUE; +} + +bool_t +zdr_GETATTR2args (ZDR *zdrs, GETATTR2args *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_fhandle2 (zdrs, objp->fhandle)) + return FALSE; + return TRUE; +} + +bool_t +zdr_GETATTR2resok (ZDR *zdrs, GETATTR2resok *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_fattr2 (zdrs, &objp->attributes)) + return FALSE; + return TRUE; +} + +bool_t +zdr_GETATTR2res (ZDR *zdrs, GETATTR2res *objp) +{ + register int32_t *buf; + buf = NULL; + + 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; +} + +bool_t +zdr_SETATTR2args (ZDR *zdrs, SETATTR2args *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_fhandle2 (zdrs, objp->fhandle)) + return FALSE; + if (!zdr_sattr2 (zdrs, &objp->attributes)) + return FALSE; + return TRUE; +} + +bool_t +zdr_SETATTR2resok (ZDR *zdrs, SETATTR2resok *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_fattr2 (zdrs, &objp->attributes)) + return FALSE; + return TRUE; +} + +bool_t +zdr_SETATTR2res (ZDR *zdrs, SETATTR2res *objp) +{ + register int32_t *buf; + buf = NULL; + + 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; +} + +bool_t +zdr_LOOKUP2args (ZDR *zdrs, LOOKUP2args *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_diropargs2 (zdrs, &objp->what)) + return FALSE; + return TRUE; +} + +bool_t +zdr_LOOKUP2resok (ZDR *zdrs, LOOKUP2resok *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_fhandle2 (zdrs, objp->file)) + return FALSE; + if (!zdr_fattr2 (zdrs, &objp->attributes)) + return FALSE; + return TRUE; +} + +bool_t +zdr_LOOKUP2res (ZDR *zdrs, LOOKUP2res *objp) +{ + register int32_t *buf; + buf = NULL; + + 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; +} + +bool_t +zdr_READLINK2args (ZDR *zdrs, READLINK2args *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_fhandle2 (zdrs, objp->file)) + return FALSE; + return TRUE; +} + +bool_t +zdr_READLINK2resok (ZDR *zdrs, READLINK2resok *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_path2 (zdrs, &objp->data)) + return FALSE; + return TRUE; +} + +bool_t +zdr_READLINK2res (ZDR *zdrs, READLINK2res *objp) +{ + register int32_t *buf; + buf = NULL; + + 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; +} + +bool_t +zdr_READ2args (ZDR *zdrs, READ2args *objp) +{ + register int32_t *buf; + buf = NULL; + + 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; +} + +bool_t +zdr_READ2resok (ZDR *zdrs, READ2resok *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_fattr2 (zdrs, &objp->attributes)) + return FALSE; + if (!zdr_nfsdata2 (zdrs, &objp->data)) + return FALSE; + return TRUE; +} + +bool_t +zdr_READ2res (ZDR *zdrs, READ2res *objp) +{ + register int32_t *buf; + buf = NULL; + + 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; +} + +bool_t +zdr_WRITE2args (ZDR *zdrs, WRITE2args *objp) +{ + register int32_t *buf; + buf = NULL; + + + 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; +} + +bool_t +zdr_WRITE2resok (ZDR *zdrs, WRITE2resok *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_fattr2 (zdrs, &objp->attributes)) + return FALSE; + return TRUE; +} + +bool_t +zdr_WRITE2res (ZDR *zdrs, WRITE2res *objp) +{ + register int32_t *buf; + buf = NULL; + + 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; +} + +bool_t +zdr_CREATE2args (ZDR *zdrs, CREATE2args *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_diropargs2 (zdrs, &objp->where)) + return FALSE; + if (!zdr_sattr2 (zdrs, &objp->attributes)) + return FALSE; + return TRUE; +} + +bool_t +zdr_CREATE2resok (ZDR *zdrs, CREATE2resok *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_fhandle2 (zdrs, objp->file)) + return FALSE; + if (!zdr_fattr2 (zdrs, &objp->attributes)) + return FALSE; + return TRUE; +} + +bool_t +zdr_CREATE2res (ZDR *zdrs, CREATE2res *objp) +{ + register int32_t *buf; + buf = NULL; + + 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; +} + +bool_t +zdr_REMOVE2args (ZDR *zdrs, REMOVE2args *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_diropargs2 (zdrs, &objp->what)) + return FALSE; + return TRUE; +} + +bool_t +zdr_REMOVE2res (ZDR *zdrs, REMOVE2res *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +bool_t +zdr_RENAME2args (ZDR *zdrs, RENAME2args *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_diropargs2 (zdrs, &objp->from)) + return FALSE; + if (!zdr_diropargs2 (zdrs, &objp->to)) + return FALSE; + return TRUE; +} + +bool_t +zdr_RENAME2res (ZDR *zdrs, RENAME2res *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +bool_t +zdr_LINK2args (ZDR *zdrs, LINK2args *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_fhandle2 (zdrs, objp->from)) + return FALSE; + if (!zdr_diropargs2 (zdrs, &objp->to)) + return FALSE; + return TRUE; +} + +bool_t +zdr_LINK2res (ZDR *zdrs, LINK2res *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +bool_t +zdr_SYMLINK2args (ZDR *zdrs, SYMLINK2args *objp) +{ + register int32_t *buf; + buf = NULL; + + 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; +} + +bool_t +zdr_SYMLINK2res (ZDR *zdrs, SYMLINK2res *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +bool_t +zdr_MKDIR2args (ZDR *zdrs, MKDIR2args *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_diropargs2 (zdrs, &objp->where)) + return FALSE; + if (!zdr_sattr2 (zdrs, &objp->attributes)) + return FALSE; + return TRUE; +} + +bool_t +zdr_MKDIR2resok (ZDR *zdrs, MKDIR2resok *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_fhandle2 (zdrs, objp->file)) + return FALSE; + if (!zdr_fattr2 (zdrs, &objp->attributes)) + return FALSE; + return TRUE; +} + +bool_t +zdr_MKDIR2res (ZDR *zdrs, MKDIR2res *objp) +{ + register int32_t *buf; + buf = NULL; + + 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; +} + +bool_t +zdr_RMDIR2args (ZDR *zdrs, RMDIR2args *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_diropargs2 (zdrs, &objp->what)) + return FALSE; + return TRUE; +} + +bool_t +zdr_RMDIR2res (ZDR *zdrs, RMDIR2res *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_nfsstat3 (zdrs, &objp->status)) + return FALSE; + return TRUE; +} + +bool_t +zdr_READDIR2args (ZDR *zdrs, READDIR2args *objp) +{ + register int32_t *buf; + buf = NULL; + + 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; +} + +bool_t +zdr_READDIR2resok (ZDR *zdrs, READDIR2resok *objp) +{ + register int32_t *buf; + buf = NULL; + + 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; +} + +bool_t +zdr_READDIR2res (ZDR *zdrs, READDIR2res *objp) +{ + register int32_t *buf; + buf = NULL; + + 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; +} + +bool_t +zdr_STATFS2args (ZDR *zdrs, STATFS2args *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_fhandle2 (zdrs, objp->dir)) + return FALSE; + return TRUE; +} + +bool_t +zdr_STATFS2resok (ZDR *zdrs, STATFS2resok *objp) +{ + register int32_t *buf; + buf = NULL; + + + 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; +} + +bool_t +zdr_STATFS2res (ZDR *zdrs, STATFS2res *objp) +{ + register int32_t *buf; + buf = NULL; + + 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; +} + bool_t zdr_nfsacl_type (ZDR *zdrs, nfsacl_type *objp) { diff --git a/nfs/libnfs-raw-nfs.h b/nfs/libnfs-raw-nfs.h index dc47c05..8eb3b2e 100644 --- a/nfs/libnfs-raw-nfs.h +++ b/nfs/libnfs-raw-nfs.h @@ -5,9 +5,11 @@ #ifndef _NFS_H_RPCGEN #define _NFS_H_RPCGEN - #include + + + #ifdef __cplusplus extern "C" { #endif @@ -915,6 +917,331 @@ struct SETATTR3res { } 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; + u_int mode; + u_int nlink; + u_int uid; + u_int gid; + u_int size; + u_int blocksize; + u_int rdev; + u_int blocks; + u_int fsid; + u_int fileid; + nfstime3 atime; + nfstime3 mtime; + nfstime3 ctime; +}; +typedef struct fattr2 fattr2; + +struct sattr2 { + u_int mode; + u_int uid; + u_int gid; + u_int 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 { + u_int nfsdata2_len; + char *nfsdata2_val; +} nfsdata2; +#define NFSCOOKIESIZE2 4 + +typedef char nfscookie2[NFSCOOKIESIZE2]; + +struct entry2 { + u_int 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; + u_int offset; + u_int count; + u_int 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; + u_int beginoffset; + u_int offset; + u_int 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; + u_int count; +}; +typedef struct READDIR2args READDIR2args; + +struct READDIR2resok { + entry2 *entries; + bool_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 { + u_int tsize; + u_int bsize; + u_int blocks; + u_int bfree; + u_int 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, @@ -1007,6 +1334,110 @@ struct SETACL3res { 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 *, CLIENT *); +extern void * nfs2_null_2_svc(void *, struct svc_req *); +#define NFS2_GETATTR 1 +extern GETATTR2res * nfs2_getattr_2(GETATTR2args *, CLIENT *); +extern GETATTR2res * nfs2_getattr_2_svc(GETATTR2args *, struct svc_req *); +#define NFS2_SETATTR 2 +extern SETATTR2res * nfs2_setattr_2(SETATTR2args *, CLIENT *); +extern SETATTR2res * nfs2_setattr_2_svc(SETATTR2args *, struct svc_req *); +#define NFS2_LOOKUP 4 +extern LOOKUP2res * nfs2_lookup_2(LOOKUP2args *, CLIENT *); +extern LOOKUP2res * nfs2_lookup_2_svc(LOOKUP2args *, struct svc_req *); +#define NFS2_READLINK 5 +extern READLINK2res * nfs2_readlink_2(READLINK2args *, CLIENT *); +extern READLINK2res * nfs2_readlink_2_svc(READLINK2args *, struct svc_req *); +#define NFS2_READ 6 +extern READ2res * nfs2_read_2(READ2args *, CLIENT *); +extern READ2res * nfs2_read_2_svc(READ2args *, struct svc_req *); +#define NFS2_WRITE 8 +extern WRITE2res * nfs2_write_2(WRITE2args *, CLIENT *); +extern WRITE2res * nfs2_write_2_svc(WRITE2args *, struct svc_req *); +#define NFS2_CREATE 9 +extern CREATE2res * nfs2_create_2(CREATE2args *, CLIENT *); +extern CREATE2res * nfs2_create_2_svc(CREATE2args *, struct svc_req *); +#define NFS2_REMOVE 10 +extern REMOVE2res * nfs2_remove_2(REMOVE2args *, CLIENT *); +extern REMOVE2res * nfs2_remove_2_svc(REMOVE2args *, struct svc_req *); +#define NFS2_RENAME 11 +extern RENAME2res * nfs2_rename_2(RENAME2args *, CLIENT *); +extern RENAME2res * nfs2_rename_2_svc(RENAME2args *, struct svc_req *); +#define NFS2_LINK 12 +extern LINK2res * nfs2_link_2(LINK2args *, CLIENT *); +extern LINK2res * nfs2_link_2_svc(LINK2args *, struct svc_req *); +#define NFS2_SYMLINK 13 +extern SYMLINK2res * nfs2_symlink_2(SYMLINK2args *, CLIENT *); +extern SYMLINK2res * nfs2_symlink_2_svc(SYMLINK2args *, struct svc_req *); +#define NFS2_MKDIR 14 +extern MKDIR2res * nfs2_mkdir_2(MKDIR2args *, CLIENT *); +extern MKDIR2res * nfs2_mkdir_2_svc(MKDIR2args *, struct svc_req *); +#define NFS2_RMDIR 15 +extern RMDIR2res * nfs2_rmdir_2(RMDIR2args *, CLIENT *); +extern RMDIR2res * nfs2_rmdir_2_svc(RMDIR2args *, struct svc_req *); +#define NFS2_READDIR 16 +extern READDIR2res * nfs2_readdir_2(READDIR2args *, CLIENT *); +extern READDIR2res * nfs2_readdir_2_svc(READDIR2args *, struct svc_req *); +#define NFS2_STATFS 17 +extern STATFS2res * nfs2_statfs_2(STATFS2args *, CLIENT *); +extern STATFS2res * nfs2_statfs_2_svc(STATFS2args *, struct svc_req *); +extern int nfs_program_2_freeresult (SVCXPRT *, 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) @@ -1307,6 +1738,56 @@ extern bool_t zdr_SETATTR3args (ZDR *, SETATTR3args*); extern bool_t zdr_SETATTR3resok (ZDR *, SETATTR3resok*); extern bool_t zdr_SETATTR3resfail (ZDR *, SETATTR3resfail*); extern bool_t zdr_SETATTR3res (ZDR *, SETATTR3res*); +extern bool_t zdr_fhandle2 (ZDR *, fhandle2); +extern bool_t zdr_ftype2 (ZDR *, ftype2*); +extern bool_t zdr_fattr2 (ZDR *, fattr2*); +extern bool_t zdr_sattr2 (ZDR *, sattr2*); +extern bool_t zdr_filename2 (ZDR *, filename2*); +extern bool_t zdr_path2 (ZDR *, path2*); +extern bool_t zdr_nfsdata2 (ZDR *, nfsdata2*); +extern bool_t zdr_nfscookie2 (ZDR *, nfscookie2); +extern bool_t zdr_entry2 (ZDR *, entry2*); +extern bool_t zdr_diropargs2 (ZDR *, diropargs2*); +extern bool_t zdr_GETATTR2args (ZDR *, GETATTR2args*); +extern bool_t zdr_GETATTR2resok (ZDR *, GETATTR2resok*); +extern bool_t zdr_GETATTR2res (ZDR *, GETATTR2res*); +extern bool_t zdr_SETATTR2args (ZDR *, SETATTR2args*); +extern bool_t zdr_SETATTR2resok (ZDR *, SETATTR2resok*); +extern bool_t zdr_SETATTR2res (ZDR *, SETATTR2res*); +extern bool_t zdr_LOOKUP2args (ZDR *, LOOKUP2args*); +extern bool_t zdr_LOOKUP2resok (ZDR *, LOOKUP2resok*); +extern bool_t zdr_LOOKUP2res (ZDR *, LOOKUP2res*); +extern bool_t zdr_READLINK2args (ZDR *, READLINK2args*); +extern bool_t zdr_READLINK2resok (ZDR *, READLINK2resok*); +extern bool_t zdr_READLINK2res (ZDR *, READLINK2res*); +extern bool_t zdr_READ2args (ZDR *, READ2args*); +extern bool_t zdr_READ2resok (ZDR *, READ2resok*); +extern bool_t zdr_READ2res (ZDR *, READ2res*); +extern bool_t zdr_WRITE2args (ZDR *, WRITE2args*); +extern bool_t zdr_WRITE2resok (ZDR *, WRITE2resok*); +extern bool_t zdr_WRITE2res (ZDR *, WRITE2res*); +extern bool_t zdr_CREATE2args (ZDR *, CREATE2args*); +extern bool_t zdr_CREATE2resok (ZDR *, CREATE2resok*); +extern bool_t zdr_CREATE2res (ZDR *, CREATE2res*); +extern bool_t zdr_REMOVE2args (ZDR *, REMOVE2args*); +extern bool_t zdr_REMOVE2res (ZDR *, REMOVE2res*); +extern bool_t zdr_RENAME2args (ZDR *, RENAME2args*); +extern bool_t zdr_RENAME2res (ZDR *, RENAME2res*); +extern bool_t zdr_LINK2args (ZDR *, LINK2args*); +extern bool_t zdr_LINK2res (ZDR *, LINK2res*); +extern bool_t zdr_SYMLINK2args (ZDR *, SYMLINK2args*); +extern bool_t zdr_SYMLINK2res (ZDR *, SYMLINK2res*); +extern bool_t zdr_MKDIR2args (ZDR *, MKDIR2args*); +extern bool_t zdr_MKDIR2resok (ZDR *, MKDIR2resok*); +extern bool_t zdr_MKDIR2res (ZDR *, MKDIR2res*); +extern bool_t zdr_RMDIR2args (ZDR *, RMDIR2args*); +extern bool_t zdr_RMDIR2res (ZDR *, RMDIR2res*); +extern bool_t zdr_READDIR2args (ZDR *, READDIR2args*); +extern bool_t zdr_READDIR2resok (ZDR *, READDIR2resok*); +extern bool_t zdr_READDIR2res (ZDR *, READDIR2res*); +extern bool_t zdr_STATFS2args (ZDR *, STATFS2args*); +extern bool_t zdr_STATFS2resok (ZDR *, STATFS2resok*); +extern bool_t zdr_STATFS2res (ZDR *, STATFS2res*); extern bool_t zdr_nfsacl_type (ZDR *, nfsacl_type*); extern bool_t zdr_nfsacl_ace (ZDR *, nfsacl_ace*); extern bool_t zdr_GETACL3args (ZDR *, GETACL3args*); @@ -1445,6 +1926,56 @@ extern bool_t zdr_SETATTR3args (); extern bool_t zdr_SETATTR3resok (); extern bool_t zdr_SETATTR3resfail (); extern bool_t zdr_SETATTR3res (); +extern bool_t zdr_fhandle2 (); +extern bool_t zdr_ftype2 (); +extern bool_t zdr_fattr2 (); +extern bool_t zdr_sattr2 (); +extern bool_t zdr_filename2 (); +extern bool_t zdr_path2 (); +extern bool_t zdr_nfsdata2 (); +extern bool_t zdr_nfscookie2 (); +extern bool_t zdr_entry2 (); +extern bool_t zdr_diropargs2 (); +extern bool_t zdr_GETATTR2args (); +extern bool_t zdr_GETATTR2resok (); +extern bool_t zdr_GETATTR2res (); +extern bool_t zdr_SETATTR2args (); +extern bool_t zdr_SETATTR2resok (); +extern bool_t zdr_SETATTR2res (); +extern bool_t zdr_LOOKUP2args (); +extern bool_t zdr_LOOKUP2resok (); +extern bool_t zdr_LOOKUP2res (); +extern bool_t zdr_READLINK2args (); +extern bool_t zdr_READLINK2resok (); +extern bool_t zdr_READLINK2res (); +extern bool_t zdr_READ2args (); +extern bool_t zdr_READ2resok (); +extern bool_t zdr_READ2res (); +extern bool_t zdr_WRITE2args (); +extern bool_t zdr_WRITE2resok (); +extern bool_t zdr_WRITE2res (); +extern bool_t zdr_CREATE2args (); +extern bool_t zdr_CREATE2resok (); +extern bool_t zdr_CREATE2res (); +extern bool_t zdr_REMOVE2args (); +extern bool_t zdr_REMOVE2res (); +extern bool_t zdr_RENAME2args (); +extern bool_t zdr_RENAME2res (); +extern bool_t zdr_LINK2args (); +extern bool_t zdr_LINK2res (); +extern bool_t zdr_SYMLINK2args (); +extern bool_t zdr_SYMLINK2res (); +extern bool_t zdr_MKDIR2args (); +extern bool_t zdr_MKDIR2resok (); +extern bool_t zdr_MKDIR2res (); +extern bool_t zdr_RMDIR2args (); +extern bool_t zdr_RMDIR2res (); +extern bool_t zdr_READDIR2args (); +extern bool_t zdr_READDIR2resok (); +extern bool_t zdr_READDIR2res (); +extern bool_t zdr_STATFS2args (); +extern bool_t zdr_STATFS2resok (); +extern bool_t zdr_STATFS2res (); extern bool_t zdr_nfsacl_type (); extern bool_t zdr_nfsacl_ace (); extern bool_t zdr_GETACL3args (); diff --git a/nfs/nfs.c b/nfs/nfs.c index 44b7538..a97d40a 100644 --- a/nfs/nfs.c +++ b/nfs/nfs.c @@ -103,18 +103,21 @@ int nfsstat3_to_errno(int error) } -int rpc_nfs_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) +/* + * NFSv3 + */ +int rpc_nfs3_null_async(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 nfs/null call"); + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/NULL call"); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { - rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nfs/null call"); + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/NULL call"); rpc_free_pdu(rpc, pdu); return -2; } @@ -122,28 +125,673 @@ int rpc_nfs_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) return 0; } -int rpc_nfs_getattr_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data) +int rpc_nfs_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) +{ + return rpc_nfs3_null_async(rpc, cb, private_data); +} + +int rpc_nfs3_getattr_async(struct rpc_context *rpc, rpc_cb cb, struct GETATTR3args *args, void *private_data) { struct rpc_pdu *pdu; - GETATTR3args args; 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 nfs/null call"); + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/GETATTR call"); + return -1; + } + + if (zdr_GETATTR3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode GETATTR3args"); + 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 NFS3/GETATTR call"); + rpc_free_pdu(rpc, pdu); + return -3; + } + + return 0; +} + +int rpc_nfs_getattr_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data) +{ + GETATTR3args args; + + memset(&args, 0, sizeof(GETATTR3args)); + args.object.data.data_len = fh->data.data_len; + args.object.data.data_val = fh->data.data_val; + + return rpc_nfs3_getattr_async(rpc, cb, &args, private_data); +} + +int rpc_nfs3_pathconf_async(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 -1; + } + + if (zdr_PATHCONF3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode PATHCONF3args"); + 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 NFS3/PATHCONF call"); + rpc_free_pdu(rpc, pdu); + return -3; + } + + return 0; +} + +int rpc_nfs_pathconf_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data) +{ + PATHCONF3args args; + + memset(&args, 0, sizeof(PATHCONF3args)); + args.object.data.data_len = fh->data.data_len; + args.object.data.data_val = fh->data.data_val; + + return rpc_nfs3_pathconf_async(rpc, cb, &args, private_data); +} + +int rpc_nfs3_lookup_async(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 -1; + } + + if (zdr_LOOKUP3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode LOOKUP3args"); + 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 NFS3/LOOKUP call"); + rpc_free_pdu(rpc, pdu); + return -3; + } + + return 0; +} + +int rpc_nfs_lookup_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *name, void *private_data) +{ + LOOKUP3args args; + + memset(&args, 0, sizeof(LOOKUP3args)); + args.what.dir.data.data_len = fh->data.data_len; + args.what.dir.data.data_val = fh->data.data_val; + args.what.name = name; + + return rpc_nfs3_lookup_async(rpc, cb, &args, private_data); +} + +int rpc_nfs3_access_async(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 -1; + } + + if (zdr_ACCESS3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode ACCESS3args"); + 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 NFS3/ACCESS call"); + rpc_free_pdu(rpc, pdu); + return -3; + } + + return 0; +} + +int rpc_nfs_access_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, int access, void *private_data) +{ + ACCESS3args args; + + memset(&args, 0, sizeof(ACCESS3args)); + args.object.data.data_len = fh->data.data_len; + args.object.data.data_val = fh->data.data_val; + args.access = access; + + return rpc_nfs3_access_async(rpc, cb, &args, private_data); +} + +int rpc_nfs3_read_async(struct rpc_context *rpc, rpc_cb cb, struct READ3args *args, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_READ, cb, private_data, (zdrproc_t)zdr_READ3res, sizeof(READ3res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/READ call"); + return -1; + } + + if (zdr_READ3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode READ3args"); + 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 NFS3/READ call"); + rpc_free_pdu(rpc, pdu); + return -3; + } + + return 0; +} + +int rpc_nfs_read_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, uint64_t offset, uint64_t count, void *private_data) +{ + READ3args args; + + memset(&args, 0, sizeof(READ3args)); + args.file.data.data_len = fh->data.data_len; + args.file.data.data_val = fh->data.data_val; + args.offset = offset; + args.count = count; + + return rpc_nfs3_read_async(rpc, cb, &args, private_data); +} + +int rpc_nfs3_write_async(struct rpc_context *rpc, rpc_cb cb, struct WRITE3args *args, void *private_data) +{ + struct rpc_pdu *pdu; + + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_WRITE, cb, private_data, (zdrproc_t)zdr_WRITE3res, sizeof(WRITE3res)); + if (pdu == NULL) { + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/WRITE call"); + return -1; + } + + if (zdr_WRITE3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode WRITE3args"); + 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 NFS3/WRITE call"); + rpc_free_pdu(rpc, pdu); + return -3; + } + + return 0; +} + +int rpc_nfs_write_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *buf, uint64_t offset, uint64_t count, int stable_how, void *private_data) +{ + WRITE3args args; + + memset(&args, 0, sizeof(WRITE3args)); + args.file.data.data_len = fh->data.data_len; + args.file.data.data_val = fh->data.data_val; + args.offset = offset; + args.count = count; + args.stable = stable_how; + args.data.data_len = count; + args.data.data_val = buf; + + return rpc_nfs3_write_async(rpc, cb, &args, private_data); +} + +int rpc_nfs3_commit_async(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 -1; + } + + if (zdr_COMMIT3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode COMMIT3args"); + 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 NFS3/COMMIT call"); + rpc_free_pdu(rpc, pdu); + return -3; + } + + return 0; +} + +int rpc_nfs_commit_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data) +{ + COMMIT3args args; + + memset(&args, 0, sizeof(COMMIT3args)); + args.file.data.data_len = fh->data.data_len; + args.file.data.data_val = fh->data.data_val; + args.offset = 0; + args.count = 0; + + return rpc_nfs3_commit_async(rpc, cb, &args, private_data); +} + +int rpc_nfs3_setattr_async(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 -1; + } + + if (zdr_SETATTR3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode SETATTR3args"); + 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 NFS3/SETATTR call"); + rpc_free_pdu(rpc, pdu); + return -3; + } + + return 0; +} + +int rpc_nfs_setattr_async(struct rpc_context *rpc, rpc_cb cb, SETATTR3args *args, void *private_data) +{ + return rpc_nfs3_setattr_async(rpc, cb, args, private_data); +} + +int rpc_nfs3_mkdir_async(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 -1; + } + + if (zdr_MKDIR3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode MKDIR3args"); + 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 NFS3/MKDIR call"); + rpc_free_pdu(rpc, pdu); + return -3; + } + + return 0; +} + +int rpc_nfs_mkdir_async(struct rpc_context *rpc, rpc_cb cb, MKDIR3args *args, void *private_data) +{ + return rpc_nfs3_mkdir_async(rpc, cb, args, private_data); +} + +int rpc_nfs3_rmdir_async(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 -1; + } + + if (zdr_RMDIR3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode RMDIR3args"); + 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 NFS3/RMDIR call"); + rpc_free_pdu(rpc, pdu); + return -3; + } + + return 0; +} + +int rpc_nfs_rmdir_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *dir, void *private_data) +{ + RMDIR3args args; + + memset(&args, 0, sizeof(RMDIR3args)); + args.object.dir.data.data_len = fh->data.data_len; + args.object.dir.data.data_val = fh->data.data_val; + args.object.name = dir; + + return rpc_nfs3_rmdir_async(rpc, cb, &args, private_data); +} + +int rpc_nfs3_create_async(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 -1; + } + + if (zdr_CREATE3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode CREATE3args"); + 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 NFS3/CREATE call"); + rpc_free_pdu(rpc, pdu); + return -3; + } + + return 0; +} + +int rpc_nfs_create_async(struct rpc_context *rpc, rpc_cb cb, CREATE3args *args, void *private_data) +{ + return rpc_nfs3_create_async(rpc, cb, args, private_data); +} + +int rpc_nfs3_mknod_async(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 -1; + } + + if (zdr_MKNOD3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode MKNOD3args"); + rpc_free_pdu(rpc, pdu); + return -2; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/MKNOD call"); + rpc_free_pdu(rpc, pdu); + return -3; + } + + return 0; +} + +int rpc_nfs_mknod_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *file, int mode, int major, int minor, void *private_data) +{ + MKNOD3args args; + + memset(&args, 0, sizeof(MKNOD3args)); + args.where.dir.data.data_len = fh->data.data_len; + args.where.dir.data.data_val = fh->data.data_val; + args.where.name = file; + + switch (mode & S_IFMT) { + case S_IFCHR: + args.what.type = NF3CHR; + args.what.mknoddata3_u.chr_device.dev_attributes.mode.set_it = 1; + args.what.mknoddata3_u.chr_device.dev_attributes.mode.set_mode3_u.mode = mode & (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH); + args.what.mknoddata3_u.chr_device.spec.specdata1 = major; + args.what.mknoddata3_u.chr_device.spec.specdata2 = minor; + break; + case S_IFBLK: + args.what.type = NF3BLK; + args.what.mknoddata3_u.blk_device.dev_attributes.mode.set_it = 1; + args.what.mknoddata3_u.blk_device.dev_attributes.mode.set_mode3_u.mode = mode & (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH); + args.what.mknoddata3_u.blk_device.spec.specdata1 = major; + args.what.mknoddata3_u.blk_device.spec.specdata2 = minor; + case S_IFSOCK: + args.what.type = NF3SOCK; + args.what.mknoddata3_u.sock_attributes.mode.set_it = 1; + args.what.mknoddata3_u.sock_attributes.mode.set_mode3_u.mode = mode & (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH); + break; + case S_IFIFO: + args.what.type = NF3FIFO; + args.what.mknoddata3_u.pipe_attributes.mode.set_it = 1; + args.what.mknoddata3_u.pipe_attributes.mode.set_mode3_u.mode = mode & (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH); + break; + default: + rpc_set_error(rpc, "Invalid file type for NFS3/MKNOD call"); + return -1; + } + + return rpc_nfs3_mknod_async(rpc, cb, &args, private_data); +} + +int rpc_nfs3_remove_async(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 -1; + } + + if (zdr_REMOVE3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode REMOVE3args"); + 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 NFS3/REMOVE call"); + rpc_free_pdu(rpc, pdu); + return -3; + } + + return 0; +} + +int rpc_nfs_remove_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *file, void *private_data) +{ + REMOVE3args args; + + memset(&args, 0, sizeof(REMOVE3args)); + args.object.dir.data.data_len = fh->data.data_len; + args.object.dir.data.data_val = fh->data.data_val; + args.object.name = file; + + return rpc_nfs3_remove_async(rpc, cb, &args, private_data); +} + +int rpc_nfs3_readdir_async(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 -1; + } + + if (zdr_READDIR3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode READDIR3args"); + 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 NFS3/READDIR call"); + rpc_free_pdu(rpc, pdu); + return -3; + } + + 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) +{ + READDIR3args args; + + memset(&args, 0, sizeof(READDIR3args)); + args.dir.data.data_len = fh->data.data_len; + args.dir.data.data_val = fh->data.data_val; + args.cookie = cookie; + memcpy(&args.cookieverf, cookieverf, sizeof(cookieverf3)); + args.count = count; + + return rpc_nfs3_readdir_async(rpc, cb, &args, private_data); +} + +int rpc_nfs3_readdirplus_async(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 -1; + } + + if (zdr_READDIRPLUS3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR 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 NFS3/READDIRPLUS call"); + rpc_free_pdu(rpc, pdu); + return -3; + } + + 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) +{ + READDIRPLUS3args args; + + memset(&args, 0, sizeof(READDIRPLUS3args)); + args.dir.data.data_len = fh->data.data_len; + args.dir.data.data_val = fh->data.data_val; + args.cookie = cookie; + memcpy(&args.cookieverf, cookieverf, sizeof(cookieverf3)); + args.dircount = count; + args.maxcount = count; + + return rpc_nfs3_readdirplus_async(rpc, cb, &args, private_data); +} + +int rpc_nfs3_fsstat_async(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 -1; + } + + if (zdr_FSSTAT3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode FSSTAT3args"); + 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 NFS3/FSSTAT 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) +{ + FSSTAT3args args; + + memset(&args, 0, sizeof(FSSTAT3args)); + args.fsroot.data.data_len = fh->data.data_len; + args.fsroot.data.data_val = fh->data.data_val; + + return rpc_nfs3_fsstat_async(rpc, cb, &args, private_data); +} + +int rpc_nfs3_fsinfo_async(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 -1; + } + + if (zdr_FSINFO3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode FSINFO3args"); + 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 NFS3/FSINFO call"); + rpc_free_pdu(rpc, pdu); + return -3; + } + + return 0; +} + +int rpc_nfs_fsinfo_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data) +{ + FSINFO3args args; + + memset(&args, 0, sizeof(FSINFO3args)); + args.fsroot.data.data_len = fh->data.data_len; + args.fsroot.data.data_val = fh->data.data_val; + + return rpc_nfs3_fsinfo_async(rpc, cb, &args, private_data); +} + +int rpc_nfs3_readlink_async(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 -1; } - args.object.data.data_len = fh->data.data_len; - args.object.data.data_val = fh->data.data_val; - - if (zdr_GETATTR3args(&pdu->zdr, &args) == 0) { - rpc_set_error(rpc, "ZDR error: Failed to encode GETATTR3args"); + if (zdr_READLINK3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode READLINK3args"); 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/null call"); + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/READLINK call"); rpc_free_pdu(rpc, pdu); return -3; } @@ -151,29 +799,29 @@ int rpc_nfs_getattr_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh return 0; } -int rpc_nfs_lookup_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *name, void *private_data) +int rpc_nfs_readlink_async(struct rpc_context *rpc, rpc_cb cb, READLINK3args *args, void *private_data) +{ + return rpc_nfs3_readlink_async(rpc, cb, args, private_data); +} + +int rpc_nfs3_symlink_async(struct rpc_context *rpc, rpc_cb cb, SYMLINK3args *args, void *private_data) { struct rpc_pdu *pdu; - LOOKUP3args args; - pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_LOOKUP, cb, private_data, (zdrproc_t)zdr_LOOKUP3res, sizeof(LOOKUP3res)); + 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 nfs/lookup call"); + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/SYMLINK call"); return -1; } - args.what.dir.data.data_len = fh->data.data_len; - args.what.dir.data.data_val = fh->data.data_val; - args.what.name = name; - - if (zdr_LOOKUP3args(&pdu->zdr, &args) == 0) { - rpc_set_error(rpc, "ZDR error: Failed to encode LOOKUP3args"); + if (zdr_SYMLINK3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode SYMLINK3args"); 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/lookup call"); + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/SYMLINK call"); rpc_free_pdu(rpc, pdu); return -3; } @@ -181,30 +829,29 @@ int rpc_nfs_lookup_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, return 0; } +int rpc_nfs_symlink_async(struct rpc_context *rpc, rpc_cb cb, SYMLINK3args *args, void *private_data) +{ + return rpc_nfs3_symlink_async(rpc, cb, args, private_data); +} -int rpc_nfs_access_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, int access, void *private_data) +int rpc_nfs3_rename_async(struct rpc_context *rpc, rpc_cb cb, struct RENAME3args *args, void *private_data) { struct rpc_pdu *pdu; - ACCESS3args args; - pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_ACCESS, cb, private_data, (zdrproc_t)zdr_ACCESS3res, sizeof(ACCESS3res)); + 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 nfs/access call"); + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/RENAME call"); return -1; } - args.object.data.data_len = fh->data.data_len; - args.object.data.data_val = fh->data.data_val; - args.access = access; - - if (zdr_ACCESS3args(&pdu->zdr, &args) == 0) { - rpc_set_error(rpc, "ZDR error: Failed to encode ACCESS3args"); + if (zdr_RENAME3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode RENAME3args"); 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/access call"); + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/RENAME call"); rpc_free_pdu(rpc, pdu); return -3; } @@ -212,32 +859,39 @@ int rpc_nfs_access_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, return 0; } +int rpc_nfs_rename_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *olddir, char *oldname, struct nfs_fh3 *newdir, char *newname, void *private_data) +{ + RENAME3args args; + + memset(&args, 0, sizeof(RENAME3args)); + args.from.dir.data.data_len = olddir->data.data_len; + args.from.dir.data.data_val = olddir->data.data_val; + args.from.name = oldname; + args.to.dir.data.data_len = newdir->data.data_len; + args.to.dir.data.data_val = newdir->data.data_val; + args.to.name = newname; + return rpc_nfs3_rename_async(rpc, cb, &args, private_data); +} -int rpc_nfs_read_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, uint64_t offset, uint64_t count, void *private_data) +int rpc_nfs3_link_async(struct rpc_context *rpc, rpc_cb cb, struct LINK3args *args, void *private_data) { struct rpc_pdu *pdu; - READ3args args; - pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_READ, cb, private_data, (zdrproc_t)zdr_READ3res, sizeof(READ3res)); + 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 nfs/read call"); + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/LINK call"); return -1; } - args.file.data.data_len = fh->data.data_len; - args.file.data.data_val = fh->data.data_val; - args.offset = offset; - args.count = count; - - if (zdr_READ3args(&pdu->zdr, &args) == 0) { - rpc_set_error(rpc, "ZDR error: Failed to encode READ3args"); + if (zdr_LINK3args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode LINK3args"); 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/read call"); + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/LINK call"); rpc_free_pdu(rpc, pdu); return -3; } @@ -245,67 +899,60 @@ int rpc_nfs_read_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, u return 0; } +int rpc_nfs_link_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *file, struct nfs_fh3 *newdir, char *newname, void *private_data) +{ + LINK3args args; -int rpc_nfs_write_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *buf, uint64_t offset, uint64_t count, int stable_how, void *private_data) + memset(&args, 0, sizeof(LINK3args)); + args.file.data.data_len = file->data.data_len; + args.file.data.data_val = file->data.data_val; + args.link.dir.data.data_len = newdir->data.data_len; + args.link.dir.data.data_val = newdir->data.data_val; + args.link.name = newname; + + return rpc_nfs3_link_async(rpc, cb, &args, private_data); +} + +/* + * NFSv2 + */ +int rpc_nfs2_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; - WRITE3args args; - pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_WRITE, cb, private_data, (zdrproc_t)zdr_WRITE3res, sizeof(WRITE3res)); + 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 nfs/write call"); + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/NULL call"); return -1; } - args.file.data.data_len = fh->data.data_len; - args.file.data.data_val = fh->data.data_val; - args.offset = offset; - args.count = count; - args.stable = stable_how; - args.data.data_len = count; - args.data.data_val = buf; - - if (zdr_WRITE3args(&pdu->zdr, &args) == 0) { - rpc_set_error(rpc, "ZDR error: Failed to encode WRITE3args"); - 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/write call"); + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/NULL call"); rpc_free_pdu(rpc, pdu); - return -3; + return -2; } return 0; } - - -int rpc_nfs_commit_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data) +int rpc_nfs2_getattr_async(struct rpc_context *rpc, rpc_cb cb, struct GETATTR2args *args, void *private_data) { struct rpc_pdu *pdu; - COMMIT3args args; - pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_COMMIT, cb, private_data, (zdrproc_t)zdr_COMMIT3res, sizeof(COMMIT3res)); + 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 nfs/commit call"); + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/GETATTR call"); return -1; } - args.file.data.data_len = fh->data.data_len; - args.file.data.data_val = fh->data.data_val; - args.offset = 0; - args.count = 0; - - if (zdr_COMMIT3args(&pdu->zdr, &args) == 0) { - rpc_set_error(rpc, "ZDR error: Failed to encode WRITE3args"); + if (zdr_GETATTR2args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode GETATTR2args"); 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/commit call"); + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/GETATTR call"); rpc_free_pdu(rpc, pdu); return -3; } @@ -313,25 +960,24 @@ int rpc_nfs_commit_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, return 0; } - -int rpc_nfs_setattr_async(struct rpc_context *rpc, rpc_cb cb, SETATTR3args *args, void *private_data) +int rpc_nfs2_setattr_async(struct rpc_context *rpc, rpc_cb cb, SETATTR2args *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)); + 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 nfs/setattr call"); + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/SETATTR call"); return -1; } - if (zdr_SETATTR3args(&pdu->zdr, args) == 0) { - rpc_set_error(rpc, "ZDR error: Failed to encode SETATTR3args"); + if (zdr_SETATTR2args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode SETATTR2args"); 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/setattr call"); + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/SETATTR call"); rpc_free_pdu(rpc, pdu); return -3; } @@ -339,26 +985,24 @@ int rpc_nfs_setattr_async(struct rpc_context *rpc, rpc_cb cb, SETATTR3args *args return 0; } - - -int rpc_nfs_mkdir_async(struct rpc_context *rpc, rpc_cb cb, MKDIR3args *args, void *private_data) +int rpc_nfs2_lookup_async(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_V3, NFS3_MKDIR, cb, private_data, (zdrproc_t)zdr_MKDIR3res, sizeof(MKDIR3res)); + 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 nfs/setattr call"); + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/LOOKUP call"); return -1; } - if (zdr_MKDIR3args(&pdu->zdr, args) == 0) { - rpc_set_error(rpc, "ZDR error: Failed to encode MKDIR3args"); + if (zdr_LOOKUP2args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode LOOKUP2args"); 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/mkdir call"); + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/LOOKUP call"); rpc_free_pdu(rpc, pdu); return -3; } @@ -366,33 +1010,24 @@ int rpc_nfs_mkdir_async(struct rpc_context *rpc, rpc_cb cb, MKDIR3args *args, vo return 0; } - - - -int rpc_nfs_rmdir_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *dir, void *private_data) +int rpc_nfs2_readlink_async(struct rpc_context *rpc, rpc_cb cb, READLINK2args *args, void *private_data) { struct rpc_pdu *pdu; - RMDIR3args args; - pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_RMDIR, cb, private_data, (zdrproc_t)zdr_RMDIR3res, sizeof(RMDIR3res)); + 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 nfs/rmdir call"); + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/READLINK call"); return -1; } - memset(&args, 0, sizeof(RMDIR3args)); - args.object.dir.data.data_len = fh->data.data_len; - args.object.dir.data.data_val = fh->data.data_val; - args.object.name = dir; - - if (zdr_RMDIR3args(&pdu->zdr, &args) == 0) { - rpc_set_error(rpc, "ZDR error: Failed to encode RMDIR3args"); + if (zdr_READLINK2args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode READLINK2args"); 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/rmdir call"); + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/READLINK call"); rpc_free_pdu(rpc, pdu); return -3; } @@ -400,26 +1035,24 @@ int rpc_nfs_rmdir_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, return 0; } - - -int rpc_nfs_create_async(struct rpc_context *rpc, rpc_cb cb, CREATE3args *args, void *private_data) +int rpc_nfs2_read_async(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_V3, NFS3_CREATE, cb, private_data, (zdrproc_t)zdr_CREATE3res, sizeof(CREATE3res)); + 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 nfs/create call"); + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/READ call"); return -1; } - if (zdr_CREATE3args(&pdu->zdr, args) == 0) { - rpc_set_error(rpc, "ZDR error: Failed to encode CREATE3args"); + if (zdr_READ2args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode READ2args"); 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/create call"); + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/READ call"); rpc_free_pdu(rpc, pdu); return -3; } @@ -427,61 +1060,24 @@ int rpc_nfs_create_async(struct rpc_context *rpc, rpc_cb cb, CREATE3args *args, return 0; } - - -int rpc_nfs_mknod_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *file, int mode, int major, int minor, void *private_data) +int rpc_nfs2_write_async(struct rpc_context *rpc, rpc_cb cb, struct WRITE2args *args, void *private_data) { struct rpc_pdu *pdu; - MKNOD3args args; - pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_MKNOD, cb, private_data, (zdrproc_t)zdr_MKNOD3res, sizeof(MKNOD3res)); + pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_WRITE, cb, private_data, (zdrproc_t)zdr_WRITE2res, sizeof(WRITE2res)); if (pdu == NULL) { - rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nfs/mknod call"); - return -1; - } - - memset(&args, 0, sizeof(MKNOD3args)); - args.where.dir.data.data_len = fh->data.data_len; - args.where.dir.data.data_val = fh->data.data_val; - args.where.name = file; - switch (mode & S_IFMT) { - case S_IFCHR: - args.what.type = NF3CHR; - args.what.mknoddata3_u.chr_device.dev_attributes.mode.set_it = 1; - args.what.mknoddata3_u.chr_device.dev_attributes.mode.set_mode3_u.mode = mode & (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH); - args.what.mknoddata3_u.chr_device.spec.specdata1 = major; - args.what.mknoddata3_u.chr_device.spec.specdata2 = minor; - break; - case S_IFBLK: - args.what.type = NF3BLK; - args.what.mknoddata3_u.blk_device.dev_attributes.mode.set_it = 1; - args.what.mknoddata3_u.blk_device.dev_attributes.mode.set_mode3_u.mode = mode & (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH); - args.what.mknoddata3_u.blk_device.spec.specdata1 = major; - args.what.mknoddata3_u.blk_device.spec.specdata2 = minor; - case S_IFSOCK: - args.what.type = NF3SOCK; - args.what.mknoddata3_u.sock_attributes.mode.set_it = 1; - args.what.mknoddata3_u.sock_attributes.mode.set_mode3_u.mode = mode & (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH); - break; - case S_IFIFO: - args.what.type = NF3FIFO; - args.what.mknoddata3_u.pipe_attributes.mode.set_it = 1; - args.what.mknoddata3_u.pipe_attributes.mode.set_mode3_u.mode = mode & (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH); - break; - default: - rpc_set_error(rpc, "Invalid file type for nfs/mknod call"); - rpc_free_pdu(rpc, pdu); + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/WRITE call"); return -1; } - if (zdr_MKNOD3args(&pdu->zdr, &args) == 0) { - rpc_set_error(rpc, "ZDR error: Failed to encode MKNOD3args"); + if (zdr_WRITE2args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode WRITE2args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { - rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nfs/mknod call"); + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/WRITE call"); rpc_free_pdu(rpc, pdu); return -3; } @@ -489,31 +1085,24 @@ int rpc_nfs_mknod_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, return 0; } - -int rpc_nfs_remove_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *file, void *private_data) +int rpc_nfs2_create_async(struct rpc_context *rpc, rpc_cb cb, CREATE2args *args, void *private_data) { struct rpc_pdu *pdu; - REMOVE3args args; - pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_REMOVE, cb, private_data, (zdrproc_t)zdr_REMOVE3res, sizeof(REMOVE3res)); + 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 nfs/remove call"); + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/CREATE call"); return -1; } - memset(&args, 0, sizeof(REMOVE3args)); - args.object.dir.data.data_len = fh->data.data_len; - args.object.dir.data.data_val = fh->data.data_val; - args.object.name = file; - - if (zdr_REMOVE3args(&pdu->zdr, &args) == 0) { - rpc_set_error(rpc, "ZDR error: Failed to encode REMOVE3args"); + if (zdr_CREATE2args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode CREATE2args"); 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/remove call"); + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/CREATE call"); rpc_free_pdu(rpc, pdu); return -3; } @@ -521,32 +1110,24 @@ 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) +int rpc_nfs2_remove_async(struct rpc_context *rpc, rpc_cb cb, struct REMOVE2args *args, void *private_data) { struct rpc_pdu *pdu; - READDIR3args args; - pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_READDIR, cb, private_data, (zdrproc_t)zdr_READDIR3res, sizeof(READDIR3res)); + 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 nfs/readdir call"); + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/REMOVE call"); return -1; } - memset(&args, 0, sizeof(READDIR3args)); - args.dir.data.data_len = fh->data.data_len; - args.dir.data.data_val = fh->data.data_val; - args.cookie = cookie; - memcpy(&args.cookieverf, cookieverf, sizeof(cookieverf3)); - args.count = count; - - if (zdr_READDIR3args(&pdu->zdr, &args) == 0) { - rpc_set_error(rpc, "ZDR error: Failed to encode READDIR3args"); + if (zdr_REMOVE2args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode REMOVE2args"); 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/readdir call"); + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/REMOVE call"); rpc_free_pdu(rpc, pdu); return -3; } @@ -554,33 +1135,24 @@ 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) +int rpc_nfs2_rename_async(struct rpc_context *rpc, rpc_cb cb, struct RENAME2args *args, void *private_data) { struct rpc_pdu *pdu; - READDIRPLUS3args args; - pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_READDIRPLUS, cb, private_data, (zdrproc_t)zdr_READDIRPLUS3res, sizeof(READDIRPLUS3res)); + 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 nfs/readdirplus call"); + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/RENAME call"); return -1; } - memset(&args, 0, sizeof(READDIRPLUS3args)); - args.dir.data.data_len = fh->data.data_len; - args.dir.data.data_val = fh->data.data_val; - args.cookie = cookie; - memcpy(&args.cookieverf, cookieverf, sizeof(cookieverf3)); - args.dircount = count; - args.maxcount = count; - - if (zdr_READDIRPLUS3args(&pdu->zdr, &args) == 0) { - rpc_set_error(rpc, "ZDR error: Failed to encode READDIRPLUS3args"); + if (zdr_RENAME2args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode RENAME2args"); 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_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/RENAME call"); rpc_free_pdu(rpc, pdu); return -3; } @@ -588,28 +1160,24 @@ int rpc_nfs_readdirplus_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 return 0; } -int rpc_nfs_fsstat_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data) +int rpc_nfs2_link_async(struct rpc_context *rpc, rpc_cb cb, LINK2args *args, void *private_data) { struct rpc_pdu *pdu; - FSSTAT3args args; - pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_FSSTAT, cb, private_data, (zdrproc_t)zdr_FSSTAT3res, sizeof(FSSTAT3res)); + 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 nfs/fsstat call"); + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/LINK call"); return -1; } - args.fsroot.data.data_len = fh->data.data_len; - args.fsroot.data.data_val = fh->data.data_val; - - if (zdr_FSSTAT3args(&pdu->zdr, &args) == 0) { - rpc_set_error(rpc, "ZDR error: Failed to encode FSSTAT3args"); + if (zdr_LINK2args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode LINK2args"); 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/fsstat call"); + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/LINK call"); rpc_free_pdu(rpc, pdu); return -3; } @@ -617,28 +1185,24 @@ int rpc_nfs_fsstat_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, return 0; } -int rpc_nfs_fsinfo_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data) +int rpc_nfs2_symlink_async(struct rpc_context *rpc, rpc_cb cb, SYMLINK2args *args, void *private_data) { struct rpc_pdu *pdu; - FSINFO3args args; - pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_FSINFO, cb, private_data, (zdrproc_t)zdr_FSINFO3res, sizeof(FSINFO3res)); + 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 nfs/fsinfo call"); + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/SYMLINK call"); return -1; } - args.fsroot.data.data_len = fh->data.data_len; - args.fsroot.data.data_val = fh->data.data_val; - - if (zdr_FSINFO3args(&pdu->zdr, &args) == 0) { - rpc_set_error(rpc, "ZDR error: Failed to encode FSINFO3args"); + if (zdr_SYMLINK2args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode SYMLINK2args"); 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/fsinfo call"); + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/SYMLINK call"); rpc_free_pdu(rpc, pdu); return -3; } @@ -646,24 +1210,24 @@ int rpc_nfs_fsinfo_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, return 0; } -int rpc_nfs_readlink_async(struct rpc_context *rpc, rpc_cb cb, READLINK3args *args, void *private_data) +int rpc_nfs2_mkdir_async(struct rpc_context *rpc, rpc_cb cb, MKDIR2args *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)); + 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 nfs/readlink call"); + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/MKDIR call"); return -1; } - if (zdr_READLINK3args(&pdu->zdr, args) == 0) { - rpc_set_error(rpc, "ZDR error: Failed to encode READLINK3args"); + if (zdr_MKDIR2args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode MKDIR2args"); 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/readlink call"); + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/MKDIR call"); rpc_free_pdu(rpc, pdu); return -3; } @@ -671,25 +1235,24 @@ int rpc_nfs_readlink_async(struct rpc_context *rpc, rpc_cb cb, READLINK3args *ar return 0; } - -int rpc_nfs_symlink_async(struct rpc_context *rpc, rpc_cb cb, SYMLINK3args *args, void *private_data) +int rpc_nfs2_rmdir_async(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_V3, NFS3_SYMLINK, cb, private_data, (zdrproc_t)zdr_SYMLINK3res, sizeof(SYMLINK3res)); + 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 nfs/symlink call"); + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/RMDIR call"); return -1; } - if (zdr_SYMLINK3args(&pdu->zdr, args) == 0) { - rpc_set_error(rpc, "ZDR error: Failed to encode SYMLINK3args"); + if (zdr_RMDIR2args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode RMDIR2args"); 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/symlink call"); + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/RMDIR call"); rpc_free_pdu(rpc, pdu); return -3; } @@ -697,36 +1260,24 @@ int rpc_nfs_symlink_async(struct rpc_context *rpc, rpc_cb cb, SYMLINK3args *args return 0; } - - - -int rpc_nfs_rename_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *olddir, char *oldname, struct nfs_fh3 *newdir, char *newname, void *private_data) +int rpc_nfs2_readdir_async(struct rpc_context *rpc, rpc_cb cb, struct READDIR2args *args, void *private_data) { struct rpc_pdu *pdu; - RENAME3args args; - pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_RENAME, cb, private_data, (zdrproc_t)zdr_RENAME3res, sizeof(RENAME3res)); + 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 nfs/rename call"); + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/READDIR call"); return -1; } - memset(&args, 0, sizeof(RENAME3args)); - args.from.dir.data.data_len = olddir->data.data_len; - args.from.dir.data.data_val = olddir->data.data_val; - args.from.name = oldname; - args.to.dir.data.data_len = newdir->data.data_len; - args.to.dir.data.data_val = newdir->data.data_val; - args.to.name = newname; - - if (zdr_RENAME3args(&pdu->zdr, &args) == 0) { - rpc_set_error(rpc, "ZDR error: Failed to encode RENAME3args"); + if (zdr_READDIR2args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode READDIR2args"); 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/rename call"); + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/READDIR call"); rpc_free_pdu(rpc, pdu); return -3; } @@ -734,42 +1285,27 @@ int rpc_nfs_rename_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *old return 0; } - - - -int rpc_nfs_link_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *file, struct nfs_fh3 *newdir, char *newname, void *private_data) +int rpc_nfs2_statfs_async(struct rpc_context *rpc, rpc_cb cb, struct STATFS2args *args, void *private_data) { struct rpc_pdu *pdu; - LINK3args args; - pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_LINK, cb, private_data, (zdrproc_t)zdr_LINK3res, sizeof(LINK3res)); + 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 nfs/link call"); + rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/STATFS call"); return -1; } - memset(&args, 0, sizeof(LINK3args)); - args.file.data.data_len = file->data.data_len; - args.file.data.data_val = file->data.data_val; - args.link.dir.data.data_len = newdir->data.data_len; - args.link.dir.data.data_val = newdir->data.data_val; - args.link.name = newname; - - if (zdr_LINK3args(&pdu->zdr, &args) == 0) { - rpc_set_error(rpc, "ZDR error: Failed to encode LINK3args"); + if (zdr_STATFS2args(&pdu->zdr, args) == 0) { + rpc_set_error(rpc, "ZDR error: Failed to encode STATFS2args"); 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/link call"); + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/STATFS call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } - - - - diff --git a/nfs/nfs.x b/nfs/nfs.x index 6e2d7a4..cc19757 100644 --- a/nfs/nfs.x +++ b/nfs/nfs.x @@ -1,5 +1,8 @@ /* NFS part from rfc 1813, NFSACL part is from wireshark sources */ +/* + * NFS v3 Definitions + */ const NFS3_FHSIZE = 64; /* Maximum bytes in a V3 file handle */ const NFS3_WRITEVERFSIZE = 8; const NFS3_CREATEVERFSIZE = 8; @@ -777,7 +780,338 @@ union SETATTR3res switch (nfsstat3 status) { 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; diff --git a/nsm/Makefile.am b/nsm/Makefile.am new file mode 100644 index 0000000..1ec6ed6 --- /dev/null +++ b/nsm/Makefile.am @@ -0,0 +1,22 @@ +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 +libnsm_la_SOURCES = \ + $(nsm_SOURCES_GENERATED) \ + nsm.c libnfs-raw-nsm.c + +$(nsm_GENERATED) : nsm-stamp +nsm-stamp : nsm.x + rm -f $(nsm_GENERATED) + touch nsm-stamp + +compile_rpc: + rpcgen -h nsm.x | sed -e "s/#include //" | sed -e "s/xdr/zdr/g" -e "s/XDR/ZDR/g" > libnfs-raw-nsm.h + 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;/" > libnfs-raw-nsm.c diff --git a/nsm/libnfs-raw-nsm.c b/nsm/libnfs-raw-nsm.c new file mode 100644 index 0000000..cc3997d --- /dev/null +++ b/nsm/libnfs-raw-nsm.c @@ -0,0 +1,156 @@ +/* + * Please do not edit this file. + * It was generated using rpcgen. + */ + +#include "libnfs-zdr.h" +#include "libnfs-raw-nsm.h" + +bool_t +zdr_nsmstat1 (ZDR *zdrs, nsmstat1 *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_enum (zdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +bool_t +zdr_nsm_my_id (ZDR *zdrs, nsm_my_id *objp) +{ + register int32_t *buf; + buf = NULL; + + 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; +} + +bool_t +zdr_nsm_mon_id (ZDR *zdrs, nsm_mon_id *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_string (zdrs, &objp->mon_name, NSM_MAXSTRLEN)) + return FALSE; + if (!zdr_nsm_my_id (zdrs, &objp->my_id)) + return FALSE; + return TRUE; +} + +bool_t +zdr_NSM1_STATres (ZDR *zdrs, NSM1_STATres *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_nsmstat1 (zdrs, &objp->res)) + return FALSE; + if (!zdr_int (zdrs, &objp->state)) + return FALSE; + return TRUE; +} + +bool_t +zdr_NSM1_STATargs (ZDR *zdrs, NSM1_STATargs *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_string (zdrs, &objp->mon_name, NSM_MAXSTRLEN)) + return FALSE; + return TRUE; +} + +bool_t +zdr_NSM1_MONres (ZDR *zdrs, NSM1_MONres *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_nsmstat1 (zdrs, &objp->res)) + return FALSE; + if (!zdr_int (zdrs, &objp->state)) + return FALSE; + return TRUE; +} + +bool_t +zdr_NSM1_MONargs (ZDR *zdrs, NSM1_MONargs *objp) +{ + register int32_t *buf; + buf = NULL; + + int i; + if (!zdr_nsm_mon_id (zdrs, &objp->mon_id)) + return FALSE; + if (!zdr_opaque (zdrs, objp->priv, 16)) + return FALSE; + return TRUE; +} + +bool_t +zdr_NSM1_UNMONres (ZDR *zdrs, NSM1_UNMONres *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_int (zdrs, &objp->state)) + return FALSE; + return TRUE; +} + +bool_t +zdr_NSM1_UNMONargs (ZDR *zdrs, NSM1_UNMONargs *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_nsm_mon_id (zdrs, &objp->mon_id)) + return FALSE; + return TRUE; +} + +bool_t +zdr_NSM1_UNMONALLres (ZDR *zdrs, NSM1_UNMONALLres *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_int (zdrs, &objp->state)) + return FALSE; + return TRUE; +} + +bool_t +zdr_NSM1_UNMONALLargs (ZDR *zdrs, NSM1_UNMONALLargs *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_nsm_my_id (zdrs, &objp->my_id)) + return FALSE; + return TRUE; +} + +bool_t +zdr_NSM1_NOTIFYargs (ZDR *zdrs, NSM1_NOTIFYargs *objp) +{ + register int32_t *buf; + buf = NULL; + + if (!zdr_string (zdrs, &objp->mon_name, NSM_MAXSTRLEN)) + return FALSE; + if (!zdr_int (zdrs, &objp->state)) + return FALSE; + return TRUE; +} diff --git a/nsm/libnfs-raw-nsm.h b/nsm/libnfs-raw-nsm.h new file mode 100644 index 0000000..b68a1bd --- /dev/null +++ b/nsm/libnfs-raw-nsm.h @@ -0,0 +1,175 @@ +/* + * Please do not edit this file. + * It was generated using rpcgen. + */ + +#ifndef _NSM_H_RPCGEN +#define _NSM_H_RPCGEN + + + + +#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 *, CLIENT *); +extern void * nsm1_null_1_svc(void *, struct svc_req *); +#define NSM1_STAT 1 +extern struct NSM1_STATres * nsm1_stat_1(struct NSM1_STATargs *, CLIENT *); +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 *, CLIENT *); +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 *, CLIENT *); +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 *, CLIENT *); +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 *, CLIENT *); +extern void * nsm1_simu_crash_1_svc(void *, struct svc_req *); +#define NSM1_NOTIFY 6 +extern void * nsm1_notify_1(struct NSM1_NOTIFYargs *, CLIENT *); +extern void * nsm1_notify_1_svc(struct NSM1_NOTIFYargs *, struct svc_req *); +extern int nsm_program_1_freeresult (SVCXPRT *, 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 bool_t zdr_nsmstat1 (ZDR *, nsmstat1*); +extern bool_t zdr_nsm_my_id (ZDR *, nsm_my_id*); +extern bool_t zdr_nsm_mon_id (ZDR *, nsm_mon_id*); +extern bool_t zdr_NSM1_STATres (ZDR *, NSM1_STATres*); +extern bool_t zdr_NSM1_STATargs (ZDR *, NSM1_STATargs*); +extern bool_t zdr_NSM1_MONres (ZDR *, NSM1_MONres*); +extern bool_t zdr_NSM1_MONargs (ZDR *, NSM1_MONargs*); +extern bool_t zdr_NSM1_UNMONres (ZDR *, NSM1_UNMONres*); +extern bool_t zdr_NSM1_UNMONargs (ZDR *, NSM1_UNMONargs*); +extern bool_t zdr_NSM1_UNMONALLres (ZDR *, NSM1_UNMONALLres*); +extern bool_t zdr_NSM1_UNMONALLargs (ZDR *, NSM1_UNMONALLargs*); +extern bool_t zdr_NSM1_NOTIFYargs (ZDR *, NSM1_NOTIFYargs*); + +#else /* K&R C */ +extern bool_t zdr_nsmstat1 (); +extern bool_t zdr_nsm_my_id (); +extern bool_t zdr_nsm_mon_id (); +extern bool_t zdr_NSM1_STATres (); +extern bool_t zdr_NSM1_STATargs (); +extern bool_t zdr_NSM1_MONres (); +extern bool_t zdr_NSM1_MONargs (); +extern bool_t zdr_NSM1_UNMONres (); +extern bool_t zdr_NSM1_UNMONargs (); +extern bool_t zdr_NSM1_UNMONALLres (); +extern bool_t zdr_NSM1_UNMONALLargs (); +extern bool_t zdr_NSM1_NOTIFYargs (); + +#endif /* K&R C */ + +#ifdef __cplusplus +} +#endif + +#endif /* !_NSM_H_RPCGEN */ diff --git a/nsm/nsm.c b/nsm/nsm.c new file mode 100644 index 0000000..2a6f9ec --- /dev/null +++ b/nsm/nsm.c @@ -0,0 +1,203 @@ +/* + 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 WIN32 +#include "win32_compat.h" +#endif/*WIN32*/ + +#include +#include +#include "libnfs-zdr.h" +#include "libnfs.h" +#include "libnfs-raw.h" +#include "libnfs-private.h" +#include "libnfs-raw-nsm.h" + +int rpc_nsm1_null_async(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 -1; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nsm/null call"); + rpc_free_pdu(rpc, pdu); + return -1; + } + + return 0; +} + +int rpc_nsm1_stat_async(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 -1; + } + + 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 -2; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nsm/stat call"); + rpc_free_pdu(rpc, pdu); + return -1; + } + + return 0; +} + +int rpc_nsm1_mon_async(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 -1; + } + + 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 -2; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nsm/mon call"); + rpc_free_pdu(rpc, pdu); + return -1; + } + + return 0; +} + +int rpc_nsm1_unmon_async(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 -1; + } + + 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 -2; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nsm/unmon call"); + rpc_free_pdu(rpc, pdu); + return -1; + } + + return 0; +} + +int rpc_nsm1_unmonall_async(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 -1; + } + + 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 -2; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nsm/unmonall call"); + rpc_free_pdu(rpc, pdu); + return -1; + } + + return 0; +} + +int rpc_nsm1_simucrash_async(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 -1; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nsm/simucrash call"); + rpc_free_pdu(rpc, pdu); + return -1; + } + + return 0; +} + +int rpc_nsm1_notify_async(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 -1; + } + + 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 -2; + } + + if (rpc_queue_pdu(rpc, pdu) != 0) { + rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nsm/notify call"); + rpc_free_pdu(rpc, pdu); + return -1; + } + + return 0; +} + +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/nsm/nsm.x b/nsm/nsm.x new file mode 100644 index 0000000..43fbc14 --- /dev/null +++ b/nsm/nsm.x @@ -0,0 +1,88 @@ +/* + * NSM definitions from: + * Protocols for Interworking: XNFS, Version 3W + * http://pubs.opengroup.org/onlinepubs/9629799/chap11.htm + * + * Symbols then massaged to avoid too much namespace pollution + * and to bring more inline with convention in nlm. + */ + +/* + * 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/packaging/RPM/libnfs.spec.in b/packaging/RPM/libnfs.spec.in index 2497f61..450f10f 100644 --- a/packaging/RPM/libnfs.spec.in +++ b/packaging/RPM/libnfs.spec.in @@ -95,6 +95,15 @@ development libraries for LibNFS %{_libdir}/pkgconfig/libnfs.pc %changelog +* Sun Wed 30 2013 : Version 1.8 + - Fix nasty memory leak in read_from_socket + - minor updates +* Sun Oct 20 2013 : Version 1.7 + - Allow nested eventloops so that a sync function can be called from a callback. + - Fix a bug in unmarshalling a uint64. + - Add PATHCONF support. + - WIN32/64 updates + - AROS updates * Mon May 27 2013 : Version 1.6 - AROS/Amiga support - Chose better initial xid value to reduce the probability for collissions.