Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions dali/dfuplus/dfuplus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,8 @@ int CDfuPlusHelper::doit()
return remove();
else if(stricmp(action, "rename") == 0)
return rename();
else if(stricmp(action, "dfsrename") == 0)
return dfsrename();
else if(stricmp(action, "list") == 0)
return list();
else if(stricmp(action, "recover") == 0)
Expand Down Expand Up @@ -1250,6 +1252,89 @@ int CDfuPlusHelper::rename()
return 0;
}

int CDfuPlusHelper::dfsrename()
{
// Collect all oldname/newname pairs from the globals
IArrayOf<IEspDFSFileRenameItem> renameItems;

// First, check for simple oldname/newname pair
const char* oldname = globals->queryProp("oldname");
const char* newname = globals->queryProp("newname");
if (oldname && newname)
{
Owned<IEspDFSFileRenameItem> item = createDFSFileRenameItem();
item->setOldName(oldname);
item->setNewName(newname);
renameItems.append(*item.getClear());
}

// Then check for numbered oldname1/newname1, oldname2/newname2, etc.
for (int i = 1; i < 1000; i++) // reasonable limit
{
StringBuffer oldnameProp, newnameProp;
oldnameProp.appendf("oldname%d", i);
newnameProp.appendf("newname%d", i);

const char* oldnameN = globals->queryProp(oldnameProp.str());
const char* newnameN = globals->queryProp(newnameProp.str());

if (oldnameN && newnameN)
{
Owned<IEspDFSFileRenameItem> item = createDFSFileRenameItem();
item->setOldName(oldnameN);
item->setNewName(newnameN);
renameItems.append(*item.getClear());
}
else if (oldnameN || newnameN)
{
throw MakeStringException(-1, "Both oldname%d and newname%d must be specified", i, i);
}
else
{
break; // No more numbered pairs
}
}

if (renameItems.ordinality() == 0)
throw MakeStringException(-1, "No files specified for rename. Use oldname=/newname= or oldname1=/newname1=, etc.");

info("\nRenaming %d file(s)\n", renameItems.ordinality());

Owned<IClientDFSFileRenameRequest> req = dfuclient->createDFSFileRenameRequest();
setMtlsSecret(req->rpc());
req->setFileRenames(renameItems);

Owned<IClientDFSFileRenameResponse> result = dfuclient->DFSFileRename(req);

// Check for general exceptions
if (outputServiceCallExceptions(result))
return -1;

// Display results for each rename
IArrayOf<IConstDFSFileRenameResult>& results = result->getResults();
int successCount = 0;
int failCount = 0;

ForEachItemIn(i, results)
{
IConstDFSFileRenameResult& res = results.item(i);
if (res.getSuccess())
{
info("Successfully renamed: %s -> %s\n", res.getOldName(), res.getNewName());
successCount++;
}
else
{
error("Failed to rename: %s -> %s: %s\n", res.getOldName(), res.getNewName(), res.getMessage());
failCount++;
}
}

info("\nRename Summary: %d succeeded, %d failed\n", successCount, failCount);

return (failCount > 0) ? -1 : 0;
}


int CDfuPlusHelper::list()
{
Expand Down
1 change: 1 addition & 0 deletions dali/dfuplus/dfuplus.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class CDfuPlusHelper : public CInterface, implements IInterface
int copy();
int remove();
int rename();
int dfsrename();
int list();
int recover();
int superfile(const char* action);
Expand Down
11 changes: 10 additions & 1 deletion dali/dfuplus/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ void handleSyntax()

out.append("Usage:\n");
out.append(" dfuplus [-v|--version] | action=[spray|replicate|despray|copy|remove|rename|\n");
out.append(" list|addsuper|removesuper|listsuper|\n");
out.append(" dfsrename|list|addsuper|removesuper|listsuper|\n");
out.append(" copysuper|dafilesrv|savexml|add|status|\n");
out.append(" abort|resubmit|monitor] {<options>}\n\n");
out.append(" -v | --version -- display version info\n\n");
Expand Down Expand Up @@ -131,6 +131,15 @@ void handleSyntax()
out.append(" rename options:\n");
out.append(" srcname=<source-logical-name>\n");
out.append(" dstname=<destination-logical-name>\n");
out.append(" dfsrename options:\n");
out.append(" oldname=<old-logical-name>\n");
out.append(" newname=<new-logical-name>\n");
out.append(" oldname1=<old-logical-name-1>\n");
out.append(" newname1=<new-logical-name-1>\n");
out.append(" ...\n");
out.append(" oldnameN=<old-logical-name-N>\n");
out.append(" newnameN=<new-logical-name-N>\n");
out.append(" -- Efficiently rename one or more files using direct filesystem operations\n");
out.append(" list options:\n");
out.append(" name=<logical-name-mask>\n");
out.append(" saveto=<path and file name to save the result>\n");
Expand Down
30 changes: 28 additions & 2 deletions esp/scm/ws_dfu.ecm
Original file line number Diff line number Diff line change
Expand Up @@ -1009,12 +1009,36 @@ ESPresponse [exceptions_inline, nil_remove] DFUMetaInquiryResponse
ESParray<ESPstruct DFUMetaFieldInfo> Fields;
};

ESPStruct [min_ver("1.68")] DFSFileRenameItem
{
string OldName;
string NewName;
};

ESPrequest DFSFileRenameRequest
{
[min_ver("1.68")] ESParray<ESPstruct DFSFileRenameItem> FileRenames;
};

ESPStruct [min_ver("1.68")] DFSFileRenameResult
{
string OldName;
string NewName;
bool Success;
string Message;
};

ESPresponse [exceptions_inline, nil_remove] DFSFileRenameResponse
{
[min_ver("1.68")] ESParray<ESPstruct DFSFileRenameResult> Results;
};


// ===========================================================================
ESPservice [
auth_feature("DEFERRED"),
version("1.67"),
default_client_version("1.67"),
version("1.68"),
default_client_version("1.68"),
noforms,
exceptions_inline("./smc_xslt/exceptions.xslt")] WsDfu
{
Expand All @@ -1040,6 +1064,8 @@ ESPservice [
ESPmethod [auth_feature("DfuAccess:WRITE")] Add(AddRequest, AddResponse);
ESPmethod [auth_feature("DfuAccess:WRITE")] AddRemote(AddRemoteRequest, AddRemoteResponse);

ESPmethod [auth_feature("DfuAccess:WRITE"), min_ver("1.68")] DFSFileRename(DFSFileRenameRequest, DFSFileRenameResponse);

ESPmethod ListHistory(ListHistoryRequest, ListHistoryResponse);
ESPmethod EraseHistory(EraseHistoryRequest, EraseHistoryResponse);
ESPmethod DFURecordTypeInfo(DFURecordTypeInfoRequest, DFURecordTypeInfoResponse);
Expand Down
69 changes: 69 additions & 0 deletions esp/services/ws_dfu/ws_dfuService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4165,6 +4165,75 @@ bool CWsDfuEx::onAddRemote(IEspContext &context, IEspAddRemoteRequest &req, IEsp
return true;
}

bool CWsDfuEx::onDFSFileRename(IEspContext &context, IEspDFSFileRenameRequest &req, IEspDFSFileRenameResponse &resp)
{
try
{
context.ensureFeatureAccess(FEATURE_URL, SecAccess_Write, ECLWATCH_DFU_ACCESS_DENIED, "WsDfu::DFSFileRename: Permission denied.");

StringBuffer username;
context.getUserID(username);
Owned<IUserDescriptor> userdesc;
if(username.length() > 0)
{
userdesc.setown(createUserDescriptor());
userdesc->set(username.str(), context.queryPassword(), context.querySignature());
}

IArrayOf<IConstDFSFileRenameItem>& items = req.getFileRenames();
if (items.ordinality() == 0)
throw MakeStringException(ECLWATCH_MISSING_PARAMS, "No files specified for rename.");

IArrayOf<IEspDFSFileRenameResult> results;
IDistributedFileDirectory &fdir = queryDistributedFileDirectory();

ForEachItemIn(i, items)
{
IConstDFSFileRenameItem& item = items.item(i);
const char* oldname = item.getOldName();
const char* newname = item.getNewName();

Owned<IEspDFSFileRenameResult> result = createDFSFileRenameResult();
result->setOldName(oldname);
result->setNewName(newname);

try
{
if (isEmptyString(oldname))
throw MakeStringException(ECLWATCH_INVALID_INPUT, "Old file name cannot be empty.");
if (isEmptyString(newname))
throw MakeStringException(ECLWATCH_INVALID_INPUT, "New file name cannot be empty.");

PROGLOG("DFSFileRename: Renaming %s to %s", oldname, newname);

// Use renamePhysical to rename both logical entry and physical files
fdir.renamePhysical(oldname, newname, userdesc.get(), nullptr);

result->setSuccess(true);
result->setMessage("Successfully renamed.");
}
catch(IException* e)
{
StringBuffer msg;
e->errorMessage(msg);
ERRLOG("DFSFileRename failed for %s to %s: %s", oldname, newname, msg.str());
result->setSuccess(false);
result->setMessage(msg.str());
e->Release();
}

results.append(*result.getClear());
}

resp.setResults(results);
}
catch(IException* e)
{
FORWARDEXCEPTION(context, e, ECLWATCH_INTERNAL_ERROR);
}
return true;
}

const int INTEGELSIZE = 20;
const int REALSIZE = 32;
const int STRINGSIZE = 128;
Expand Down
1 change: 1 addition & 0 deletions esp/services/ws_dfu/ws_dfuService.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ class CWsDfuEx : public CWsDfu
virtual bool onSavexml(IEspContext &context, IEspSavexmlRequest &req, IEspSavexmlResponse &resp);
virtual bool onAdd(IEspContext &context, IEspAddRequest &req, IEspAddResponse &resp);
virtual bool onAddRemote(IEspContext &context, IEspAddRemoteRequest &req, IEspAddRemoteResponse &resp);
virtual bool onDFSFileRename(IEspContext &context, IEspDFSFileRenameRequest &req, IEspDFSFileRenameResponse &resp);
virtual bool onSuperfileList(IEspContext &context, IEspSuperfileListRequest &req, IEspSuperfileListResponse &resp);
virtual bool onSuperfileAction(IEspContext &context, IEspSuperfileActionRequest &req, IEspSuperfileActionResponse &resp);
virtual bool onListHistory(IEspContext &context, IEspListHistoryRequest &req, IEspListHistoryResponse &resp);
Expand Down