afsio: readdir/fidreaddir commands 81/12381/3
authorMichael Meffie <mmeffie@sinenomine.net>
Mon, 23 May 2016 00:35:26 +0000 (20:35 -0400)
committerBenjamin Kaduk <kaduk@mit.edu>
Fri, 18 Dec 2020 15:59:09 +0000 (10:59 -0500)
Add the readdir/fidreaddir sub-commands to afsio dump AFS3 directory
objects.  This command dumps the raw directory object to stdout.  Pipe
the output to a program, such as the afsdump_dirlist program (from the
CMU dumpscan tool kit), to parse the directory object.

Example usage:

   afsio readdir -dir /afs/mycell/mypath/somedir | afsdump_dirlist

Change-Id: Ief181b432cdea6a11bbe61e781686ade2795faad
Reviewed-on: https://gerrit.openafs.org/12381
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Cheyenne Wills <cwills@sinenomine.net>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>

src/venus/afsio.c

index c9b04f2..444ec16 100644 (file)
@@ -87,6 +87,7 @@ static int readlock = 0;      /* Set if -readlock option given */
 static int waittime = 0;       /* Set if -waittime option given */
 static int useFid = 0;         /* Set if fidwrite/fidread/fidappend invoked */
 static int append = 0;         /* Set if append/fidappend invoked */
+static int readDir = 0;                /* Set if readdir/fidreaddir invoked. */
 static struct timeval starttime, opentime, readtime, writetime;
 static afs_uint64 xfered = 0;
 static struct timeval now;
@@ -234,6 +235,9 @@ CmdProlog(struct cmd_syndesc *as, char **cellp, char **realmp,
     if ( (strcmp(as->name, "append") == 0) ||
          (strcmp(as->name, "fidappend") == 0) )
        append = 1;             /* global */
+    if (strcmp(as->name, "readdir") == 0 ||
+        strcmp(as->name, "fidreaddir") == 0)
+        readDir = 1;
 
     /* attempts to ensure loop is bounded: */
     for (pdp = as->parms, i = 0; pdp && (i < as->nParms); i++, pdp++) {
@@ -249,7 +253,8 @@ CmdProlog(struct cmd_syndesc *as, char **cellp, char **realmp,
             else if (strcmp(pdp->name, "-cell") == 0) {
                cellGiven = 1;  /* global */
                *cellp = pdp->items->data;
-            } else if ( strcmp(pdp->name, "-file") == 0) {
+            } else if ( strcmp(pdp->name, "-file") == 0 ||
+                       strcmp(pdp->name, "-dir") == 0) {
                *fnp = pdp->items->data;
 #ifdef AFS_NT40_ENV
                 ConvertAFSPath(fnp);
@@ -366,6 +371,27 @@ main(int argc, char **argv)
     cmd_AddParm(ts, "-md5", CMD_FLAG, CMD_OPTIONAL, "calculate md5 checksum");
     cmd_AddParm(ts, "-realm", CMD_SINGLE, CMD_OPTIONAL, "REALMNAME");
 
+    ts = cmd_CreateSyntax("readdir", readFile, CMD_REQUIRED, 0,
+                         "read a directory from AFS");
+    cmd_AddParm(ts, "-dir", CMD_SINGLE, CMD_REQUIRED, "AFS-dirname");
+    cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cellname");
+    cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, (char *)0);
+    cmd_AddParm(ts, "-clear", CMD_FLAG, CMD_OPTIONAL, (char *)0);
+    cmd_AddParm(ts, "-crypt", CMD_FLAG, CMD_OPTIONAL, (char *)0);
+    cmd_AddParm(ts, "-md5", CMD_FLAG, CMD_OPTIONAL, "calculate md5 checksum");
+    cmd_AddParm(ts, "-realm", CMD_SINGLE, CMD_OPTIONAL, "REALMNAME");
+
+    ts = cmd_CreateSyntax("fidreaddir", readFile, CMD_REQUIRED, 0,
+                         "read on a non AFS-client a directory from AFS");
+    cmd_AddParm(ts, "-fid", CMD_SINGLE, CMD_REQUIRED,
+               "volume.vnode.uniquifier");
+    cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cellname");
+    cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, (char *)0);
+    cmd_AddParm(ts, "-clear", CMD_FLAG, CMD_OPTIONAL, (char *)0);
+    cmd_AddParm(ts, "-crypt", CMD_FLAG, CMD_OPTIONAL, (char *)0);
+    cmd_AddParm(ts, "-md5", CMD_FLAG, CMD_OPTIONAL, "calculate md5 checksum");
+    cmd_AddParm(ts, "-realm", CMD_SINGLE, CMD_OPTIONAL, "REALMNAME");
+
     ts = cmd_CreateSyntax("write", writeFile, NULL, 0,
                          "write a file into AFS");
     cmd_AddParm(ts, "-file", CMD_SINGLE, CMD_REQUIRED, "AFS-filename");
@@ -788,7 +814,14 @@ readFile(struct cmd_syndesc *as, void *unused)
        return code;
     }
 
-    if (avfp->fid.Vnode & 1) {
+    if (readDir) {
+       if ((avfp->fid.Vnode & 1) == 0) {
+           code = ENOENT;
+           afs_com_err(pnp, code, "(%s is a file, not a directory)", fname);
+           afscp_FreeFid(avfp);
+           return code;
+       }
+    } else if (avfp->fid.Vnode & 1) {
        code = ENOENT;
        afs_com_err(pnp, code, "(%s is a directory, not a file)", fname);
        afscp_FreeFid(avfp);