|
@@ -46,6 +46,8 @@
|
|
|
#define FILE_DESPRAY_URL "FileDesprayAccess"
|
|
|
#define WUDETAILS_REFRESH_MINS 1
|
|
|
|
|
|
+const unsigned dropZoneFileSearchMaxFiles = 1000;
|
|
|
+
|
|
|
void SetResp(StringBuffer &resp, IConstDFUWorkUnit * wu, bool array);
|
|
|
int Schedule::run()
|
|
|
{
|
|
@@ -2833,16 +2835,30 @@ bool CFileSprayEx::checkDropZoneIPAndPath(double clientVersion, const char* drop
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
-void CFileSprayEx::addDropZoneFile(IEspContext& context, IDirectoryIterator* di, const char* name, const char* dropZonePath,
|
|
|
- StringBuffer& relativePath, const char pathSep, IArrayOf<IEspPhysicalFileStruct>& filesInFolder, IArrayOf<IEspPhysicalFileStruct>& files)
|
|
|
+void CFileSprayEx::addDropZoneFile(IEspContext& context, IDirectoryIterator* di, const char* name, const char* path, IArrayOf<IEspPhysicalFileStruct>& files)
|
|
|
{
|
|
|
- StringBuffer path = dropZonePath;
|
|
|
- if (!relativePath.isEmpty())
|
|
|
- path.append(pathSep).append(relativePath.str());
|
|
|
-
|
|
|
Owned<IEspPhysicalFileStruct> aFile = createPhysicalFileStruct();
|
|
|
- aFile->setName(name);
|
|
|
- aFile->setPath(path);
|
|
|
+
|
|
|
+ const char pathSep = getPathSepChar(path);
|
|
|
+ const char* pName = strrchr(name, pathSep);
|
|
|
+ if (!pName)
|
|
|
+ {
|
|
|
+ aFile->setName(name);
|
|
|
+ aFile->setPath(path);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ StringBuffer sPath = path;
|
|
|
+ unsigned len = strlen(path);
|
|
|
+ if (sPath.charAt(len - 1) != pathSep)
|
|
|
+ sPath.append(pathSep);
|
|
|
+ sPath.append(pName - name, name);
|
|
|
+ aFile->setPath(sPath.str());
|
|
|
+
|
|
|
+ pName++; //skip the PathSepChar
|
|
|
+ aFile->setName(pName);
|
|
|
+ }
|
|
|
+
|
|
|
aFile->setIsDir(di->isDir());
|
|
|
CDateTime modtime;
|
|
|
StringBuffer timestr;
|
|
@@ -2853,16 +2869,20 @@ void CFileSprayEx::addDropZoneFile(IEspContext& context, IDirectoryIterator* di,
|
|
|
timestr.appendf("%04d-%02d-%02d %02d:%02d:%02d", y,m,d,h,min,sec);
|
|
|
aFile->setModifiedtime(timestr.str());
|
|
|
aFile->setFilesize(di->getFileSize());
|
|
|
- if (di->isDir() && filesInFolder.ordinality())
|
|
|
- aFile->setFiles(filesInFolder);
|
|
|
files.append(*aFile.getLink());
|
|
|
}
|
|
|
|
|
|
-bool CFileSprayEx::searchDropZoneFileInFolder(IEspContext& context, IFile* f, const char* nameFilter,
|
|
|
- bool returnAll, const char* dropZonePath, StringBuffer& relativePath, const char pathSep, IArrayOf<IEspPhysicalFileStruct>& files)
|
|
|
+void CFileSprayEx::searchDropZoneFiles(IEspContext& context, IpAddress& ip, const char* dir, const char* nameFilter, IArrayOf<IEspPhysicalFileStruct>& files, unsigned& filesFound)
|
|
|
{
|
|
|
- bool foundMatch = false;
|
|
|
- Owned<IDirectoryIterator> di = f->directoryFiles(NULL, false, true);
|
|
|
+ RemoteFilename rfn;
|
|
|
+ SocketEndpoint ep;
|
|
|
+ ep.ipset(ip);
|
|
|
+ rfn.setPath(ep, dir);
|
|
|
+ Owned<IFile> f = createIFile(rfn);
|
|
|
+ if(!f->isDirectory())
|
|
|
+ throw MakeStringException(ECLWATCH_INVALID_DIRECTORY, "%s is not a directory.", dir);
|
|
|
+
|
|
|
+ Owned<IDirectoryIterator> di = f->directoryFiles(nameFilter, true, true);
|
|
|
ForEach(*di)
|
|
|
{
|
|
|
StringBuffer fname;
|
|
@@ -2870,49 +2890,12 @@ bool CFileSprayEx::searchDropZoneFileInFolder(IEspContext& context, IFile* f, co
|
|
|
if (!fname.length())
|
|
|
continue;
|
|
|
|
|
|
- StringBuffer newPath = relativePath;
|
|
|
- if (!newPath.isEmpty())
|
|
|
- newPath.append(pathSep);
|
|
|
- newPath.append(fname.str());
|
|
|
-
|
|
|
- IArrayOf<IEspPhysicalFileStruct> filesInFolder;
|
|
|
- if (returnAll) //Every files and subfolders in this folder have to be returned
|
|
|
- {
|
|
|
- if (di->isDir())
|
|
|
- searchDropZoneFileInFolder(context, &di->get(), NULL, returnAll, dropZonePath, newPath, pathSep, filesInFolder);
|
|
|
- addDropZoneFile(context, di, fname.str(), dropZonePath, relativePath, pathSep, filesInFolder, files);
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- bool foundMatchNew = WildMatch(fname.str(), nameFilter, true);
|
|
|
- if (di->isDir() && searchDropZoneFileInFolder(context, &di->get(), nameFilter, foundMatchNew, dropZonePath,
|
|
|
- newPath, pathSep, filesInFolder))
|
|
|
- {
|
|
|
- foundMatchNew = true;
|
|
|
- }
|
|
|
+ filesFound++;
|
|
|
+ if (filesFound > dropZoneFileSearchMaxFiles)
|
|
|
+ break;
|
|
|
|
|
|
- if (foundMatchNew)
|
|
|
- {
|
|
|
- addDropZoneFile(context, di, fname.str(), dropZonePath, relativePath, pathSep, filesInFolder, files);
|
|
|
- foundMatch = true;
|
|
|
- }
|
|
|
+ addDropZoneFile(context, di, fname.str(), dir, files);
|
|
|
}
|
|
|
- return foundMatch;
|
|
|
-}
|
|
|
-
|
|
|
-void CFileSprayEx::appendDropZoneFiles(IEspContext& context, IpAddress& ip, const char* dir, const char* nameFilter, IArrayOf<IEspPhysicalFileStruct>& files)
|
|
|
-{
|
|
|
- RemoteFilename rfn;
|
|
|
- SocketEndpoint ep;
|
|
|
- ep.ipset(ip);
|
|
|
- rfn.setPath(ep, dir);
|
|
|
- Owned<IFile> f = createIFile(rfn);
|
|
|
- if(!f->isDirectory())
|
|
|
- throw MakeStringException(ECLWATCH_INVALID_DIRECTORY, "%s is not a directory.", dir);
|
|
|
-
|
|
|
- StringBuffer relativePath;
|
|
|
- searchDropZoneFileInFolder(context, f, nameFilter, !nameFilter || !*nameFilter, dir,
|
|
|
- relativePath, getPathSepChar(dir), files);
|
|
|
}
|
|
|
|
|
|
bool CFileSprayEx::onDropZoneFileSearch(IEspContext &context, IEspDropZoneFileSearchRequest &req, IEspDropZoneFileSearchResponse &resp)
|
|
@@ -2924,6 +2907,14 @@ bool CFileSprayEx::onDropZoneFileSearch(IEspContext &context, IEspDropZoneFileSe
|
|
|
const char* dropZoneName = req.getDropZoneName();
|
|
|
if (isEmptyString(dropZoneName))
|
|
|
throw MakeStringException(ECLWATCH_INVALID_INPUT, "DropZone not specified.");
|
|
|
+ const char* dropZoneServerReq = req.getServer(); //IP or hostname
|
|
|
+ if (isEmptyString(dropZoneServerReq))
|
|
|
+ throw MakeStringException(ECLWATCH_INVALID_INPUT, "DropZone server not specified.");
|
|
|
+ const char* nameFilter = req.getNameFilter();
|
|
|
+ if (isEmptyString(nameFilter))
|
|
|
+ throw MakeStringException(ECLWATCH_INVALID_INPUT, "Name Filter not specified.");
|
|
|
+ if (streq(nameFilter, "*"))
|
|
|
+ throw MakeStringException(ECLWATCH_INVALID_INPUT, "Invalid Name Filter '*'");
|
|
|
|
|
|
Owned<IEnvironmentFactory> envFactory = getEnvironmentFactory(true);
|
|
|
Owned<IConstEnvironment> constEnv = envFactory->openEnvironment();
|
|
@@ -2937,14 +2928,13 @@ bool CFileSprayEx::onDropZoneFileSearch(IEspContext &context, IEspDropZoneFileSe
|
|
|
throw MakeStringException(ECLWATCH_INVALID_INPUT, "DropZone Directory not found for %s.", dropZoneName);
|
|
|
|
|
|
IpAddress ipToMatch;
|
|
|
- const char* dropZoneServerReq = req.getServer(); //IP or hostname
|
|
|
- if (!isEmptyString(dropZoneServerReq))
|
|
|
- {
|
|
|
- ipToMatch.ipset(dropZoneServerReq);
|
|
|
- if (ipToMatch.isNull())
|
|
|
- throw MakeStringException(ECLWATCH_INVALID_INPUT, "Invalid server %s specified.", dropZoneServerReq);
|
|
|
- }
|
|
|
+ ipToMatch.ipset(dropZoneServerReq);
|
|
|
+ if (ipToMatch.isNull())
|
|
|
+ throw MakeStringException(ECLWATCH_INVALID_INPUT, "Invalid server %s specified.", dropZoneServerReq);
|
|
|
|
|
|
+ double version = context.getClientVersion();
|
|
|
+ bool serverFound = false;
|
|
|
+ unsigned filesFound = 0;
|
|
|
IArrayOf<IEspPhysicalFileStruct> files;
|
|
|
Owned<IConstDropZoneServerInfoIterator> dropZoneServerItr = dropZoneInfo->getServers();
|
|
|
ForEach(*dropZoneServerItr)
|
|
@@ -2957,8 +2947,21 @@ bool CFileSprayEx::onDropZoneFileSearch(IEspContext &context, IEspDropZoneFileSe
|
|
|
|
|
|
IpAddress ipAddr;
|
|
|
ipAddr.ipset(server.str());
|
|
|
- if (isEmptyString(dropZoneServerReq) || ipAddr.ipequals(ipToMatch))
|
|
|
- appendDropZoneFiles(context, ipAddr, directory.str(), req.getNameFilter(), files);
|
|
|
+ if (ipAddr.ipequals(ipToMatch))
|
|
|
+ {
|
|
|
+ serverFound = true;
|
|
|
+ searchDropZoneFiles(context, ipAddr, directory.str(), nameFilter, files, filesFound);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!serverFound)
|
|
|
+ throw MakeStringException(ECLWATCH_INVALID_INPUT, "Server %s not found in dropzone %s.", dropZoneServerReq, dropZoneName);
|
|
|
+
|
|
|
+ if ((version >= 1.16) && (filesFound > dropZoneFileSearchMaxFiles))
|
|
|
+ {
|
|
|
+ VStringBuffer msg("More than %u files are found. Only %u files are returned.", dropZoneFileSearchMaxFiles, dropZoneFileSearchMaxFiles);
|
|
|
+ resp.setWarning(msg.str());
|
|
|
}
|
|
|
resp.setFiles(files);
|
|
|
}
|