|
@@ -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);
|