From bbed37ca52e89175bd3419984bbd31be34e08629 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Sun, 18 Nov 2012 05:01:01 +1100 Subject: [PATCH] Change the sync example to perform a 'ls -l' on an NFS URL --- examples/nfsclient-sync.c | 344 +++++++++++++++++--------------------- 1 file changed, 153 insertions(+), 191 deletions(-) diff --git a/examples/nfsclient-sync.c b/examples/nfsclient-sync.c index 8563c1e..9cdac9b 100644 --- a/examples/nfsclient-sync.c +++ b/examples/nfsclient-sync.c @@ -15,24 +15,20 @@ along with this program; if not, see . */ +#define _FILE_OFFSET_BITS 64 +#define _GNU_SOURCE + /* Example program using the highlevel sync interface */ #ifdef WIN32 #include "win32_compat.h" #else +#include #include #include #include #endif -#define SERVER "10.1.1.27" -#define EXPORT "/VIRTUAL" -#define NFSFILE "/BOOKS/Classics/Dracula.djvu.truncated" -#define NFSFILER "/BOOKS/Classics/Dracula.djvu.renamed" -#define NFSFILEW "/BOOKS/Classics/foo" -#define NFSDIR "/BOOKS/Classics/" - -#define _GNU_SOURCE #if defined(WIN32) #pragma comment(lib, "ws2_32.lib") @@ -45,11 +41,13 @@ WSADATA wsaData; #include #include #include +#include #include #include #include #include "libnfs.h" #include /* for authunix_create() */ +#include #include "libnfs-raw.h" #include "libnfs-raw-mount.h" @@ -61,27 +59,33 @@ struct client { }; -void PrintServerList() -{ - struct nfs_server_list *srvrs; - struct nfs_server_list *srv; - - srvrs = nfs_find_local_servers(); - - for (srv=srvrs; srv; srv = srv->next) - { - printf("Found nfs server: %s\n", srv->addr); +char buf[3*1024*1024+337]; - } - free_nfs_srvr_list(srvrs); +void print_usage(void) +{ + fprintf(stderr, "Usage: nfsclient-sync [-?|--help] [--usage] \n"); } -char buf[3*1024*1024+337]; +void print_help(void) +{ + fprintf(stderr, "Usage: nfsclient-sync [OPTION...] \n"); + fprintf(stderr, "\n"); + fprintf(stderr, "Help options:\n"); + fprintf(stderr, " -?, --help Show this help message\n"); + fprintf(stderr, " --usage Display brief usage message\n"); + fprintf(stderr, "\n"); + fprintf(stderr, "NFS URL format : nfs:///\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " is either of:\n"); + fprintf(stderr, " \"hostname\" nfs.example\n"); + fprintf(stderr, " \"ipv4-address\" 10.1.1.27\n"); + fprintf(stderr, " \"ipv6-address\" [fce0::1]\n"); +} -int main(int argc _U_, char *argv[] _U_) +int main(int argc, char *argv[]) { - struct nfs_context *nfs; - int i, ret; + struct nfs_context *nfs = NULL; + int i, ret, res; uint64_t offset; struct client client; struct stat st; @@ -90,6 +94,18 @@ int main(int argc _U_, char *argv[] _U_) struct nfsdirent *nfsdirent; struct statvfs svfs; exports export, tmp; + int show_help = 0, show_usage = 0; + poptContext pc; + const char **extra_argv; + int extra_argc = 0; + const char *url = NULL; + char *server = NULL, *path = NULL, *strp; + + struct poptOption popt_options[] = { + { "help", '?', POPT_ARG_NONE, &show_help, 0, "Show this help message", NULL }, + { "usage", 0, POPT_ARG_NONE, &show_usage, 0, "Display brief usage message", NULL }, + POPT_TABLEEND + }; #if defined(WIN32) if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) { @@ -98,212 +114,158 @@ int main(int argc _U_, char *argv[] _U_) } #endif - client.server = SERVER; - client.export = EXPORT; - client.is_finished = 0; - - PrintServerList(); - - export = mount_getexports(SERVER); - if (export != NULL) { - printf("exports on server %s\n", SERVER); - tmp = export; - while (tmp != NULL) { - printf("Export: %s\n", tmp->ex_dir); - tmp = tmp->ex_next; - } - - mount_free_export_list(export); - } else { - printf("no exports on server %s\n", SERVER); - } - - nfs = nfs_init_context(); - if (nfs == NULL) { - printf("failed to init context\n"); + pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_POSIXMEHARDER); + if ((res = poptGetNextOpt(pc)) < -1) { + fprintf(stderr, "Failed to parse option : %s %s\n", + poptBadOption(pc, 0), poptStrerror(res)); exit(10); } - - ret = nfs_mount(nfs, client.server, client.export); - if (ret != 0) { - printf("Failed to mount nfs share : %s\n", nfs_get_error(nfs)); - exit(10); + extra_argv = poptGetArgs(pc); + if (extra_argv) { + url = *extra_argv; + extra_argv++; + while (extra_argv[extra_argc]) { + extra_argc++; + } } - printf("mounted share successfully %s\n", nfs_get_error(nfs)); - + poptFreeContext(pc); - ret = nfs_stat(nfs, NFSFILE, &st); - if (ret != 0) { - printf("Failed to stat(%s) %s\n", NFSFILE, nfs_get_error(nfs)); - exit(10); + if (show_help != 0) { + print_help(); + exit(0); } - printf("Mode %04o\n", st.st_mode); - printf("Size %d\n", (int)st.st_size); - printf("Inode %04o\n", (int)st.st_ino); - ret = nfs_open(nfs, NFSFILE, O_RDONLY, &nfsfh); - if (ret != 0) { - printf("Failed to open(%s) %s\n", NFSFILE, nfs_get_error(nfs)); - exit(10); + if (show_usage != 0) { + print_usage(); + exit(0); } -#if 0 - ret = nfs_read(nfs, nfsfh, 16, buf); - if (ret < 0) { - printf("Failed to pread(%s) %s\n", NFSFILE, nfs_get_error(nfs)); - exit(10); - } - printf("read %d bytes\n", ret); - for (i=0;i<16;i++) { - printf("%02x ", buf[i]&0xff); - } - printf("\n"); -#endif - ret = nfs_read(nfs, nfsfh, sizeof(buf), buf); - if (ret < 0) { - printf("Failed to pread(%s) %s\n", NFSFILE, nfs_get_error(nfs)); - exit(10); + if (url == NULL) { + fprintf(stderr, "No URL specified.\n"); + print_usage(); + exit(0); } - printf("read %d bytes\n", ret); - for (i=0;i<16;i++) { - printf("%02x ", buf[i]&0xff); + + if (strncmp(url, "nfs://", 6)) { + fprintf(stderr, "Invalid URL specified.\n"); + print_usage(); + exit(0); } - printf("\n"); - ret = nfs_read(nfs, nfsfh, sizeof(buf), buf); - if (ret < 0) { - printf("Failed to pread(%s) %s\n", NFSFILE, nfs_get_error(nfs)); + + server = strdup(url + 6); + if (server == NULL) { + fprintf(stderr, "Failed to strdup server string\n"); exit(10); } - printf("read %d bytes\n", ret); - ret = nfs_read(nfs, nfsfh, sizeof(buf), buf); - if (ret < 0) { - printf("Failed to pread(%s) %s\n", NFSFILE, nfs_get_error(nfs)); + if (server[0] == '/' || server[0] == '\0') { + fprintf(stderr, "Invalid server string.\n"); + free(server); exit(10); } - printf("read %d bytes\n", ret); - ret = nfs_read(nfs, nfsfh, sizeof(buf), buf); - if (ret < 0) { - printf("Failed to pread(%s) %s\n", NFSFILE, nfs_get_error(nfs)); - exit(10); + strp = strchr(server, '/'); + if (strp == NULL) { + fprintf(stderr, "Invalid URL specified.\n"); + print_usage(); + free(server); + exit(0); } - printf("read %d bytes\n", ret); - ret = nfs_read(nfs, nfsfh, sizeof(buf), buf); - if (ret < 0) { - printf("Failed to pread(%s) %s\n", NFSFILE, nfs_get_error(nfs)); + path = strdup(strp); + if (path == NULL) { + fprintf(stderr, "Failed to strdup server string\n"); + free(server); exit(10); } - printf("read %d bytes\n", ret); - ret = nfs_read(nfs, nfsfh, sizeof(buf), buf); - if (ret < 0) { - printf("Failed to pread(%s) %s\n", NFSFILE, nfs_get_error(nfs)); + if (path[0] != '/') { + fprintf(stderr, "Invalid path.\n"); + free(server); + free(path); exit(10); } - printf("read %d bytes\n", ret); + *strp = 0; + + client.server = server; + client.export = path; + client.is_finished = 0; - ret = (int)nfs_lseek(nfs, nfsfh, 0, SEEK_CUR, &offset); - if (ret < 0) { - printf("Failed to lseek(%s) %s\n", NFSFILE, nfs_get_error(nfs)); - exit(10); - } - printf("File position is %d\n", (int)offset); - printf("seek to end of file\n"); - ret = (int)nfs_lseek(nfs, nfsfh, 0, SEEK_END, &offset); - if (ret < 0) { - printf("Failed to lseek(%s) %s\n", NFSFILE, nfs_get_error(nfs)); - exit(10); + nfs = nfs_init_context(); + if (nfs == NULL) { + printf("failed to init context\n"); + goto finished; } - printf("File position is %d\n", (int)offset); - ret = nfs_fstat(nfs, nfsfh, &st); + ret = nfs_mount(nfs, client.server, client.export); if (ret != 0) { - printf("Failed to stat(%s) %s\n", NFSFILE, nfs_get_error(nfs)); - exit(10); + printf("Failed to mount nfs share : %s\n", nfs_get_error(nfs)); + goto finished; } - printf("Mode %04o\n", st.st_mode); - printf("Size %d\n", (int)st.st_size); - printf("Inode %04o\n", (int)st.st_ino); - ret = nfs_close(nfs, nfsfh); - if (ret < 0) { - printf("Failed to close(%s): %s\n", NFSFILE, nfs_get_error(nfs)); - exit(10); - } - - ret = nfs_opendir(nfs, NFSDIR, &nfsdir); + ret = nfs_opendir(nfs, "/", &nfsdir); if (ret != 0) { - printf("Failed to open(%s) %s\n", NFSFILE, nfs_get_error(nfs)); + printf("Failed to opendir(\"/\")\n", nfs_get_error(nfs)); exit(10); } while((nfsdirent = nfs_readdir(nfs, nfsdir)) != NULL) { - char filename[1024]; - printf("Inode:%d Name:%s ", (int)nfsdirent->inode, nfsdirent->name); - sprintf(filename, "%s/%s", NFSDIR, nfsdirent->name); - ret = nfs_open(nfs, filename, O_RDONLY, &nfsfh); - if (ret != 0) { - printf("Failed to open(%s) %s\n", filename, nfs_get_error(nfs)); - exit(10); + char path[1024]; + + if (!strcmp(nfsdirent->name, ".") || !strcmp(nfsdirent->name, "..")) { + continue; } - ret = nfs_read(nfs, nfsfh, sizeof(buf), buf); - if (ret < 0) { - printf("Error reading file\n"); + + snprintf(path, 1024, "%s/%s", "/", nfsdirent->name); + ret = nfs_stat(nfs, path, &st); + if (ret != 0) { + fprintf(stderr, "Failed to stat(%s) %s\n", path, nfs_get_error(nfs)); + continue; } - printf("Read %d bytes\n", ret); - ret = nfs_close(nfs, nfsfh); - if (ret < 0) { - printf("Failed to close(%s): %s\n", NFSFILE, nfs_get_error(nfs)); - exit(10); + + switch (st.st_mode & S_IFMT) { + case S_IFLNK: + 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", st.st_nlink); + printf(" %5d", st.st_uid); + printf(" %5d", st.st_gid); + printf(" %12" PRId64, st.st_size); + + printf(" %s\n", nfsdirent->name); } nfs_closedir(nfs, nfsdir); - ret = nfs_open(nfs, NFSFILEW, O_WRONLY, &nfsfh); - if (ret != 0) { - printf("Failed to open(%s) %s\n", NFSFILEW, nfs_get_error(nfs)); - exit(10); - } - ret = nfs_pwrite(nfs, nfsfh, 0, 16, buf); - if (ret < 0) { - printf("Failed to pwrite(%s) %s\n", NFSFILEW, nfs_get_error(nfs)); - exit(10); - } - ret = nfs_fsync(nfs, nfsfh); - if (ret < 0) { - printf("Failed to fsync(%s) %s\n", NFSFILEW, nfs_get_error(nfs)); - exit(10); - } - ret = nfs_close(nfs, nfsfh); - if (ret < 0) { - printf("Failed to close(%s) %s\n", NFSFILEW, nfs_get_error(nfs)); - exit(10); - } - - - ret = nfs_statvfs(nfs, NFSDIR, &svfs); - if (ret < 0) { - printf("Failed to statvfs(%s) %s\n", NFSDIR, nfs_get_error(nfs)); - exit(10); - } - printf("files %d/%d/%d\n", (int)svfs.f_files, (int)svfs.f_ffree, (int)svfs.f_favail); - - - ret = nfs_access(nfs, NFSFILE, R_OK); - if (ret != 0) { - printf("Failed to access(%s) %s\n", NFSFILE, nfs_get_error(nfs)); - } - - /* become root */ - nfs_set_auth(nfs, authunix_create("Ronnies-Laptop", 0, 0, 0, NULL)); - - ret = nfs_link(nfs, NFSFILE, NFSFILER); - if (ret != 0) { - printf("Failed to link(%s) %s\n", NFSFILE, nfs_get_error(nfs)); +finished: + free(server); + free(path); + if (nfs != NULL) { + nfs_destroy_context(nfs); } - - - nfs_destroy_context(nfs); printf("nfsclient finished\n"); return 0; } -- 2.34.1