From dcb2390af15d120448f52885171f47a0665d2d5b Mon Sep 17 00:00:00 2001 From: Akayeshmantha Date: Wed, 5 Aug 2020 11:28:04 +0200 Subject: [PATCH 1/2] Add the functionality to download folder content. Signed-off-by: Akayeshmantha --- c/unixFileService.c | 35 +++++++++++++++++++++++++++++++++++ c/zss.c | 1 + h/unixFileService.h | 1 + 3 files changed, 37 insertions(+) diff --git a/c/unixFileService.c b/c/unixFileService.c index e06e777c5..0283592ca 100644 --- a/c/unixFileService.c +++ b/c/unixFileService.c @@ -1032,6 +1032,26 @@ static int serveUnixFileChangeTag(HttpService *service, HttpResponse *response) return 0; } +static int serveUnixFolderDownloadMode(HttpService *service, HttpResponse *response) { + HttpRequest *request = response->request; + char *routeFileFrag = stringListPrint(request->parsedFile, 2, 1000, "/", 0); + + if (routeFileFrag == NULL || strlen(routeFileFrag) == 0) { + respondWithJsonError(response, "Required absolute path of the resource is not provided", HTTP_STATUS_BAD_REQUEST, "Bad Request"); + return 0; + } + char *encodedRouteFolder = stringConcatenate(response->slh, "/", routeFileFrag); + char *routeFolderName = cleanURLParamValue(response->slh, encodedRouteFolder); + + if (!strcmp(request->method, methodGET)) { + createArchiveFromUnixDirectoryAndRespond(response, routeFolderName); + } + else { + respondWithJsonError(response, "Method Not Allowed", HTTP_STATUS_METHOD_NOT_FOUND, "Bad Request"); + return 0; + } + return 0; +} static int serveTableOfContents(HttpService *service, HttpResponse *response) { HttpRequest *request = response->request; @@ -1074,6 +1094,10 @@ static int serveTableOfContents(HttpService *service, HttpResponse *response) { jsonAddString(out, "chmod", "/unixfile/chmod/{absPath}"); jsonEndObject(out); + jsonStartObject(out, NULL); + jsonAddString(out, "folderdownload", "/unixfile/folderdownload/{absPath}"); + jsonEndObject(out); + jsonEndArray(out); jsonEnd(out); @@ -1205,6 +1229,17 @@ void installUnixFileTableOfContentsService(HttpServer *server) { registerHttpService(server, httpService); } +void installUnixFolderToFileConvertAndDownloadService(HttpServer *server) { + HttpService *httpService = makeGeneratedService("UnixFolderDownload", + "/unixfile/folderdownload/**"); + httpService->authType = SERVICE_AUTH_NATIVE_WITH_SESSION_TOKEN; + httpService->serviceFunction = serveUnixFolderDownloadMode; + httpService->runInSubtask = TRUE; + httpService->doImpersonation = TRUE; + registerHttpService(server, httpService); +} + + /* This program and the accompanying materials are diff --git a/c/zss.c b/c/zss.c index 428d0217e..3081edfc6 100644 --- a/c/zss.c +++ b/c/zss.c @@ -1218,6 +1218,7 @@ int main(int argc, char **argv){ installUnixFileChangeTagService(server); #endif installUnixFileChangeModeService(server); + installUnixFolderToFileConvertAndDownloadService(server); installUnixFileTableOfContentsService(server); /* This needs to be registered last */ #ifdef __ZOWE_OS_ZOS installVSAMDatasetContentsService(server); diff --git a/h/unixFileService.h b/h/unixFileService.h index ac491c925..e1cd4685d 100644 --- a/h/unixFileService.h +++ b/h/unixFileService.h @@ -23,6 +23,7 @@ void installUnixFileChangeOwnerService(HttpServer *server); void installUnixFileChangeTagService(HttpServer *server); void installUnixFileTableOfContentsService(HttpServer *server); void installUnixFileChangeModeService(HttpServer *server); +void installUnixFolderToFileConvertAndDownloadService(HttpServer *server); #endif From cbd85aa343e1d547e3f06275074a1266e414650f Mon Sep 17 00:00:00 2001 From: "ayeshmantha.perera" Date: Wed, 23 Sep 2020 18:41:42 +0200 Subject: [PATCH 2/2] fix. Signed-off-by: ayeshmantha.perera --- c/unixFileService.c | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/c/unixFileService.c b/c/unixFileService.c index 0283592ca..90eb9d907 100644 --- a/c/unixFileService.c +++ b/c/unixFileService.c @@ -1037,14 +1037,51 @@ static int serveUnixFolderDownloadMode(HttpService *service, HttpResponse *respo char *routeFileFrag = stringListPrint(request->parsedFile, 2, 1000, "/", 0); if (routeFileFrag == NULL || strlen(routeFileFrag) == 0) { - respondWithJsonError(response, "Required absolute path of the resource is not provided", HTTP_STATUS_BAD_REQUEST, "Bad Request"); + respondWithJsonError(response, "Required absolute path of the resource is not provided", HTTP_STATUS_BAD_REQUEST, + "Bad Request"); return 0; } char *encodedRouteFolder = stringConcatenate(response->slh, "/", routeFileFrag); - char *routeFolderName = cleanURLParamValue(response->slh, encodedRouteFolder); + char *absolutePath = cleanURLParamValue(response->slh, encodedRouteFolder); if (!strcmp(request->method, methodGET)) { - createArchiveFromUnixDirectoryAndRespond(response, routeFolderName); +#ifdef METTLE + respondWithJsonError(response, "Create archive from directory unimplemented in metal", HTTP_STATUS_BAD_REQUEST, + "Bad Request"); +#else + if (isDir(routeFolderName)) { + char fileNameBuffer[USS_MAX_PATH_LENGTH + 1] = {0}; + char commandBuffer[USS_MAX_PATH_LENGTH + 1] = {0}; + + int folderNameLen = strlen(absolutePath); + if (folderNameLen == 0 || absolutePath == NULL) { + respondWithJsonError(response, "Failed to idenity the folder pointed", HTTP_STATUS_BAD_REQUEST, "Bad Request"); + return; + } + + int slashPos = lastIndexOf(absolutePath, folderNameLen, '/'); + char *tarFileName = (slashPos == -1) ? absolutePath : absolutePath + slashPos + 1; + snprintf(fileNameBuffer, sizeof(fileNameBuffer), "%s%s", tarFileName, ".tar"); + + char *tarCommand = "/bin/tar -cf "; + snprintf(commandBuffer, sizeof(commandBuffer), "%s%s%s%s", tarCommand, fileNameBuffer, " ", absolutePath); + + // system command will create the tar. + system(commandBuffer); + if(doesFileExist(fileNameBuffer)) { + respondWithUnixFileContentsWithAutocvtMode(NULL, response, fileNameBuffer, TRUE, 0); + deleteUnixFile(fileNameBuffer); + } + else { + respondWithJsonError(response, "Failed to create tar file", HTTP_STATUS_BAD_REQUEST, "Bad Request"); + return; + } + } + else { + respondWithJsonError(response, "Failed to identify a directory with the given name", HTTP_STATUS_BAD_REQUEST, + "Bad Request"); + return; + } } else { respondWithJsonError(response, "Method Not Allowed", HTTP_STATUS_METHOD_NOT_FOUND, "Bad Request");