Browse Source

HPCC-8742 Add a dfsls command to daliadmin/daliadmin

daliadmin <ip> dfsls [<name>] [<options>]

name is the name of the initial root directory (:: for root).  Options can
include
  l - long format
  r - recurse
  s - expand subfile contents

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
Gavin Halliday 9 years ago
parent
commit
77794ef72a
1 changed files with 103 additions and 0 deletions
  1. 103 0
      dali/daliadmin/daliadmin.cpp

+ 103 - 0
dali/daliadmin/daliadmin.cpp

@@ -83,6 +83,7 @@ void usage(const char *exe)
   printf("  dfscsv <logicalnamemask>       -- get csv info. for files matching mask\n");
   printf("  dfsgroup <logicalgroupname> [filename] -- get IPs for logical group (aka cluster). Written to optional filename if provided\n");
   printf("  clusternodes <clustername> [filename] -- get IPs for cluster group. Written to optional filename if provided\n");
+  printf("  dfsls [<logicalname>] [options]-- get list of files within a scope (options=lrs)\n");
   printf("  dfsmap <logicalname>           -- get part files (primary and replicates)\n");
   printf("  dfsexists <logicalname>        -- sets return value to 0 if file exists\n");
   printf("  dfsparents <logicalname>       -- list superfiles containing file\n");
@@ -691,6 +692,104 @@ static int clusterGroup(const char *name, const char *outputFilename)
     return 1;
 }
 
+static IPropertyTree * selectLevel(IPropertyTree * root, const char * name)
+{
+    StringBuffer xpath;
+    xpath.append("*[@name='").append(name).append("']");
+    Owned<IPropertyTree> match = root->getPropTree(xpath);
+    if (match)
+        return match.getClear();
+    ERRLOG("Path %s not found", name);
+    return nullptr;
+}
+
+static IPropertyTree * selectPath(IPropertyTree * root, const char * path)
+{
+    if (!path || !*path)    // use / to refer to the root directory
+        return LINK(root);
+
+    const char * split = strstr(path, "::");
+    if (split)
+    {
+        //Can use :: to refer to the root directory
+        if (split == path)
+            return selectPath(root, split + 2);
+
+        StringAttr name(path, split - path);
+        Owned<IPropertyTree> match = selectLevel(root, name);
+        if (match)
+            return selectPath(match, split + 2);
+        return nullptr;
+    }
+    return selectLevel(root, path);
+}
+
+static void displayDirectory(IPropertyTree * directory, const char * options, unsigned depth)
+{
+    Owned<IPropertyTreeIterator> elems = directory->getElements("*");
+    ForEach(*elems)
+    {
+        IPropertyTree & cur = elems->query();
+        const char * tag = cur.queryName();
+        const char * name = cur.queryProp("@name");
+        const char * modified = cur.queryProp("@modified");
+        if (name && tag)
+        {
+            if (strieq(tag, "Scope"))
+            {
+                OUTLOG("%*sD %s", depth, "", name);
+                if (options && strchr(options, 'r'))
+                    displayDirectory(&cur, options, depth+1);
+            }
+            else if (strieq(tag, "File"))
+            {
+                const char * group = cur.queryProp("@group");
+                const char * size = cur.queryProp("Attr[1]/@size");
+                if (options && strchr(options, 'l'))
+                    OUTLOG("%*s  %-30s %12s %s %s", depth, "", name, size ? size : "", group ? group : "?", modified ? modified : "");
+                else
+                    OUTLOG("%*s  %s", depth, "", name);
+            }
+            else if (strieq(tag, "SuperFile"))
+            {
+                if (options && strchr(options, 'l'))
+                    OUTLOG("%*sS %s %s (%d)", depth, "", name, modified ? modified : "", cur.getPropInt("@numsubfiles"));
+                else
+                    OUTLOG("%*sS %s", depth, "", name);
+
+                if (options && strchr(options, 's'))
+                {
+                    Owned<IPropertyTreeIterator> subs = cur.getElements("SubFile");
+                    ForEach(*subs)
+                    {
+                        OUTLOG("%*s->%s", depth, "", subs->query().queryProp("@name"));
+                    }
+                }
+            }
+            else
+                OUTLOG("? %s %s", name, tag);
+        }
+    }
+}
+
+static void dfsLs(const char *name, const char *options, bool safe = false)
+{
+    StringBuffer xpath;
+    Owned<IRemoteConnection> conn = connectXPathOrFile("/Files",safe,xpath);
+    if (!conn) {
+        ERRLOG("Could not connect to %s","/Files");
+        return;
+    }
+
+    {
+        Owned<IPropertyTree> directory = selectPath(conn->queryRoot(), name);
+        if (directory)
+            displayDirectory(directory, options, 0);
+    }
+    conn->commit();
+    conn->close();
+}
+
 //=============================================================================
 
 static void dfsmap(const char *lname, IUserDescriptor *user)
@@ -2893,6 +2992,10 @@ int main(int argc, char* argv[])
                         CHECKPARAMS(1,2);
                         ret = clusterGroup(params.item(1),(np>1)?params.item(2):NULL);
                     }
+                    else if (stricmp(cmd,"dfsls")==0) {
+                        CHECKPARAMS(0,2);
+                        dfsLs((np>0)?params.item(1):NULL,(np>1)?params.item(2):NULL);
+                    }
                     else if (stricmp(cmd,"dfsmap")==0) {
                         CHECKPARAMS(1,1);
                         dfsmap(params.item(1), userDesc);