examples/nfs-ls: recursion and summary support
authorPeter Lieven <pl@kamp.de>
Fri, 20 Dec 2013 14:08:04 +0000 (15:08 +0100)
committerPeter Lieven <pl@kamp.de>
Mon, 23 Dec 2013 11:46:26 +0000 (12:46 +0100)
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 <pl@kamp.de>
examples/nfs-ls.c

index e0131c8b745d719daaa34f7ca8e62103eca9463c..7aed4dfe6cc6260ce1fd1b88635d6b7d601cf615 100644 (file)
@@ -35,6 +35,7 @@ WSADATA wsaData;
 #include <inttypes.h>
 #include <string.h>
 #include <sys/stat.h>
+#include <sys/statvfs.h>
 #ifndef AROS
 #include <sys/statvfs.h>
 #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] <url>\n");
+       fprintf(stderr, "Usage: nfs-ls [-?|--help|--usage] [-R|--recursive] [-s|--summary] <url>\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);