From 1dc9ea0d52ba69fa5b1265bc3c24214d429a5baf Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Fri, 20 Dec 2013 15:08:04 +0100 Subject: [PATCH] examples/nfs-ls: recursion and summary support this adds recusrion and summary support, fixes some compiler warnings, fixes exit codes and avoids a possible sprintf buffer overflow. Signed-off-by: Peter Lieven --- examples/nfs-ls.c | 175 ++++++++++++++++++++++++++++------------------ 1 file changed, 106 insertions(+), 69 deletions(-) diff --git a/examples/nfs-ls.c b/examples/nfs-ls.c index e0131c8..7aed4df 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,9 +63,90 @@ struct client { int is_finished; }; + int recursive = 0, summary = 0; + void print_usage(void) { - fprintf(stderr, "Usage: nfs-ls [-?|--help] [--usage] \n"); + fprintf(stderr, "Usage: nfs-ls [-?|--help|--usage] [-R|--recursive] [-s|--summary] \n"); +} + +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); + } + + ret = nfs_opendir(nfs, dir, &nfsdir); + if (ret != 0) { + printf("Failed to opendir(\"%s\")\n", dir, nfs_get_error(nfs)); + exit(10); + } + while((nfsdirent = nfs_readdir(nfs, nfsdir)) != NULL) { + char path[1024]; + + if (!strcmp(nfsdirent->name, ".") || !strcmp(nfsdirent->name, "..")) { + continue; + } + + 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)); + continue; + } + + 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(" %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[]) @@ -73,11 +155,8 @@ int main(int argc, char *argv[]) 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; + struct statvfs stvfs; exports export, tmp; const char *url = NULL; char *server = NULL, *path = NULL, *strp; @@ -93,18 +172,29 @@ int main(int argc, char *argv[]) aros_init_socket(); #endif - url = argv[1]; + url = argv[argc - 1]; if (url == NULL) { fprintf(stderr, "No URL specified.\n"); print_usage(); - exit(0); + exit(10); + } + + 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 { + print_usage(); + exit(10); + } } if (strncmp(url, "nfs://", 6)) { fprintf(stderr, "Invalid URL specified.\n"); print_usage(); - exit(0); + exit(10); } server = strdup(url + 6); @@ -122,7 +212,7 @@ int main(int argc, char *argv[]) fprintf(stderr, "Invalid URL specified.\n"); print_usage(); free(server); - exit(0); + exit(10); } path = strdup(strp); if (path == NULL) { @@ -137,12 +227,11 @@ int main(int argc, char *argv[]) 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"); @@ -155,68 +244,16 @@ int main(int argc, char *argv[]) goto finished; } + process_dir(nfs, "", 16); - ret = nfs_opendir(nfs, "/", &nfsdir); - if (ret != 0) { - printf("Failed to opendir(\"/\")\n", nfs_get_error(nfs)); - exit(10); - } - while((nfsdirent = nfs_readdir(nfs, nfsdir)) != NULL) { - char path[1024]; - - if (!strcmp(nfsdirent->name, ".") || !strcmp(nfsdirent->name, "..")) { - continue; - } - - sprintf(path, "%s/%s", "/", nfsdirent->name); - ret = nfs_stat(nfs, path, &st); + if (summary) { + ret = nfs_statvfs(nfs, "/", &stvfs); if (ret != 0) { - fprintf(stderr, "Failed to stat(%s) %s\n", path, nfs_get_error(nfs)); - continue; + goto finished; } - - switch (st.st_mode & S_IFMT) { -#ifndef WIN32 - case S_IFLNK: -#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", 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("\n%12" PRId64 " of %12" PRId64 " bytes free.\n", + stvfs.f_frsize * stvfs.f_bfree, stvfs.f_frsize * stvfs.f_blocks); } - nfs_closedir(nfs, nfsdir); - - finished: free(server); free(path); -- 2.34.1