summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVignesh Raman <Vignesh_Raman@mentor.com>2016-10-07 12:38:50 +0530
committerCosmin Cernat <cosmin.cernat@continental-corporation.com>2017-01-26 16:47:12 +0200
commit272398a4ad1aa434b0edb5ba42efd7bceccc3963 (patch)
tree1b90ab47a12574b307735e2b49564856bda79607
parentfca84b3b67600e58d75f738cbe2cf0186b674777 (diff)
downloadpersistence-administrator-272398a4ad1aa434b0edb5ba42efd7bceccc3963.tar.gz
PAS: Set ssw_pers_admin_common.c file formatting to unix
Converted file format from mac to unix format Change-Id: I98f79548fc0e641e002d984b2ae763c5c3b819e9 Signed-off-by: Thangam Ramasamy <Thangam_Ramasamy@mentor.com>
-rw-r--r--Administrator/src/ssw_pers_admin_common.c918
1 files changed, 869 insertions, 49 deletions
diff --git a/Administrator/src/ssw_pers_admin_common.c b/Administrator/src/ssw_pers_admin_common.c
index 839dff0..df4c0e1 100644
--- a/Administrator/src/ssw_pers_admin_common.c
+++ b/Administrator/src/ssw_pers_admin_common.c
@@ -1,51 +1,871 @@
-/********************************************************************************************************************* * * Copyright (C) 2012 Continental Automotive Systems, Inc. * * Author: Ionut.Ieremie@continental-corporation.com * * Implementation of funtions declaredin ssw_pers_admin_common.h * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Date Author Reason * 2013.03.20 uidu0250 CSP_WZ#2250: Provide compress/uncompress functionality * 2013.02.07 uidu0250 CSP_WZ#2220: Removed Helplibs dependency (CRC16 checksum calculation) * 2013.01.22 uidn3591 CSP_WZ#2060: Implemented wrappers over libarchive to compress/uncompress files into/from an archive * 2013.01.04 uidu0250 CSP_WZ#2060: Switched get_hash_for_file implementation from using CRC32 to using CRC16 provided by HelpLibs * 2012.11.15 uidl9757 CSP_WZ#1280: Use protected interface pers_data_organization_if.h * 2012.11.16 uidn3565 CSP_WZ#1280: Added implementation for - persadmin_list_application_folders - persadmin_list_application_folders_get_size * 2012.11.15 uidl9757 CSP_WZ#1280: Created * **********************************************************************************************************************/
-/* ---------------------- include files --------------------------------- */ #include "persComTypes.h" #include <stddef.h> #include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <dirent.h> #include <errno.h> #include <unistd.h> #include <fcntl.h> /* compress/uncompress */ #include <archive.h> #include <archive_entry.h> #include "malloc.h" #include "ssw_pers_admin_common.h" #include "ssw_pers_admin_files_helper.h" #include "persComDataOrg.h" #include "persistence_admin_service.h"
- /* ---------------------- local definitions -------------------------------- */ #define READ_BUFFER_LENGTH (16384) #define COPY_BUFFER_LENGTH (128) #define PATH_ABS_MAX_SIZE ( 512) #define PERSADMIN_POLICY_MARKER_CACHED PERS_ORG_CACHE_FOLDER_NAME #define PERSADMIN_POLICY_MARKER_WT PERS_ORG_WT_FOLDER_NAME
-#define CRC16_FILE_CHUNK_SIZE (10 * 1024) /* TO DO : This should be published in a protected interface */ #define PERSADMIN_LINKS_INFO_FILENAME "linksInfo.lnk"
-#define GetApplicationRootPath( RootPath, FullPath ) \ int pathLength = strlen( RootPath ); \ char FullPath[ strlen( gLocalCachePath ) + pathLength + sizeof( StringTerminator ) ]; \ snprintf( FullPath, sizeof( FullPath ), "%s", RootPath ); \ snprintf( FullPath + pathLength, sizeof( FullPath ) - pathLength, gLocalCachePath, "", "" )
+/*********************************************************************************************************************
+*
+* Copyright (C) 2012 Continental Automotive Systems, Inc.
+*
+* Author: Ionut.Ieremie@continental-corporation.com
+*
+* Implementation of funtions declaredin ssw_pers_admin_common.h
+*
+* This Source Code Form is subject to the terms of the Mozilla Public
+* License, v. 2.0. If a copy of the MPL was not distributed with this
+* file, You can obtain one at http://mozilla.org/MPL/2.0/.
+*
+* Date Author Reason
+* 2013.03.20 uidu0250 CSP_WZ#2250: Provide compress/uncompress functionality
+* 2013.02.07 uidu0250 CSP_WZ#2220: Removed Helplibs dependency (CRC16 checksum calculation)
+* 2013.01.22 uidn3591 CSP_WZ#2060: Implemented wrappers over libarchive to compress/uncompress files into/from an archive
+* 2013.01.04 uidu0250 CSP_WZ#2060: Switched get_hash_for_file implementation from using CRC32 to using CRC16 provided by HelpLibs
+* 2012.11.15 uidl9757 CSP_WZ#1280: Use protected interface pers_data_organization_if.h
+* 2012.11.16 uidn3565 CSP_WZ#1280: Added implementation for
+ - persadmin_list_application_folders
+ - persadmin_list_application_folders_get_size
+* 2012.11.15 uidl9757 CSP_WZ#1280: Created
+*
+**********************************************************************************************************************/
+/* ---------------------- include files --------------------------------- */
+#include "persComTypes.h"
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+/* compress/uncompress */
+#include <archive.h>
+#include <archive_entry.h>
+
+#include "malloc.h"
+
+#include "ssw_pers_admin_common.h"
+#include "ssw_pers_admin_files_helper.h"
+#include "persComDataOrg.h"
+#include "persistence_admin_service.h"
+
+/* ---------------------- local definitions -------------------------------- */
+#define READ_BUFFER_LENGTH (16384)
+#define COPY_BUFFER_LENGTH (128)
+
+#define PATH_ABS_MAX_SIZE ( 512)
+
+#define PERSADMIN_POLICY_MARKER_CACHED PERS_ORG_CACHE_FOLDER_NAME
+#define PERSADMIN_POLICY_MARKER_WT PERS_ORG_WT_FOLDER_NAME
+#define CRC16_FILE_CHUNK_SIZE (10 * 1024)
+/* TO DO : This should be published in a protected interface */
+#define PERSADMIN_LINKS_INFO_FILENAME "linksInfo.lnk"
+#define GetApplicationRootPath( RootPath, FullPath ) \
+ int pathLength = strlen( RootPath ); \
+ char FullPath[ strlen( gLocalCachePath ) + pathLength + sizeof( StringTerminator ) ]; \
+ snprintf( FullPath, sizeof( FullPath ), "%s", RootPath ); \
+ snprintf( FullPath + pathLength, sizeof( FullPath ) - pathLength, gLocalCachePath, "", "" )
/* ---------------------- local types -------------------------------------- */
- /* ---------------------- local functions ---------------------------------- */ static sint_t persadmin_common_extract_group_id(pstr_t linkName) ; static void persadmin_common_remove_endofline(pstr_t line) ; static bool_t persadmin_is_shared_folder( pconststr_t name, int length ); static sint_t persadmin_copy_data(struct archive *ar, struct archive *aw);
- /* ---------------------- local variables ---------------------------------- */ //moved to "ssw_pers_admin_common.h" //extern const char StringTerminator;
- /* * export the application's information about links (to groups and public data) * returns the number of exported links, or a negative value in case of error */ sint_t persadmin_export_links(pstr_t absPathApplicationFolder, pstr_t absPathExportFolder) { pstr_t FuncName = "persadmin_export_links:" ; bool_t bEverythingOK = true ; pstr_t buffer = NIL ; bool_t bNothingToExport = false ; sint_t exportedLinks = 0 ; sint_t neededBufferSize = 0 ; FILE * fileExport = NIL ;
- if( (NIL == absPathApplicationFolder) || (NIL == absPathExportFolder)) { bEverythingOK = false ; printf("\n%s NIL param \n", FuncName) ; } else { if(0 != persadmin_check_if_file_exists(absPathApplicationFolder, true)) { bEverythingOK = false ; printf("\n%s folder does not exist (%s) \n", FuncName, absPathApplicationFolder) ; } else { if(0 != persadmin_check_if_file_exists(absPathExportFolder, true)) { bEverythingOK = false ; printf("\n%s folder does not exist (%s) \n", FuncName, absPathExportFolder) ; } } }
- if(bEverythingOK) { neededBufferSize = persadmin_list_folder_get_size(absPathApplicationFolder, PersadminFilterFilesLink, false) ; if(neededBufferSize > 0) { buffer = (pstr_t)malloc(neededBufferSize*sizeof(str_t)) ; if(NIL == buffer) { bEverythingOK = false ; } else { sint_t listingSize = persadmin_list_folder(absPathApplicationFolder, buffer, neededBufferSize, PersadminFilterFilesLink, false) ; if(neededBufferSize != listingSize) { bEverythingOK = false ; printf("\n%s persadmin_list_folder(%s) returned %d (expected %d) \n", FuncName, absPathApplicationFolder, listingSize, neededBufferSize) ; } } } else { if(0 == neededBufferSize) { /* no links to export */ bNothingToExport = true ; } else { bEverythingOK = false ; printf("\n%s persadmin_list_folder_get_size(<%s>, FilterFilesLink, false) failed\n", FuncName, absPathApplicationFolder) ; } } }
- if(bEverythingOK && (! bNothingToExport)) { /* create the export file */ str_t completePath[PERSADMIN_MAX_PATH_LENGHT] ; sint_t lenPathExport = strlen(absPathExportFolder) ; sint_t lenLinkFilename = strlen(PERSADMIN_LINKS_INFO_FILENAME) ;
- if( (lenPathExport + 1 + lenLinkFilename) < PERSADMIN_MAX_PATH_LENGHT ) { strncpy(completePath, absPathExportFolder, sizeof(completePath)) ; if('/' != completePath[lenPathExport -1]) { strncat(completePath, "/", sizeof(completePath)) ; } strncat(completePath, PERSADMIN_LINKS_INFO_FILENAME, sizeof(completePath)) ;
- fileExport = fopen(completePath, "w") ; if(NIL == fileExport) { bEverythingOK = false ; printf("\n%s fopen(<%s>, w) errno = %s\n", FuncName, completePath, strerror(errno)) ; } } else { bEverythingOK = false ; printf("\n%s path too long (%s/%s)\n", FuncName, absPathExportFolder, PERSADMIN_LINKS_INFO_FILENAME) ; } }
- if(bEverythingOK && (! bNothingToExport)) { /* for each link file in buffer, create an entry (line) in the export file * for links to group - only the number of the group (i.e. a hex value in 0x00 - 0xFF domain) is stored * for links to public data - the word "public" is stored **/ sint_t posInBuffer = 0 ; while((posInBuffer < neededBufferSize) && bEverythingOK) { sint_t lenCurrentLink = strlen(buffer+posInBuffer) ; if(0 == strcmp(buffer+posInBuffer, PERS_ORG_SHARED_PUBLIC_SYMLINK_NAME)) { /* it is the link to the public data */ if(0 > fputs("public\n", fileExport)) { bEverythingOK = false ; printf("\n%s fputs(public) errno=%s\n", FuncName, strerror(errno)) ; } else { exportedLinks++ ; } } else { sint_t groupID = persadmin_common_extract_group_id(buffer+posInBuffer) ; if(groupID >= 0) { str_t line[PERSADMIN_MAX_PATH_LENGHT] ; printf("\n%s groupID(%s)=0x%02X\n", FuncName, buffer+posInBuffer, groupID) ; snprintf(line, sizeof(line), "%02X\n", groupID) ; if(0 > fputs(line, fileExport)) { bEverythingOK = false ; printf("\n%s fputs(%02X) errno=%s\n", FuncName, groupID, strerror(errno)) ; } else { exportedLinks++ ; } } else { printf("\n%s unable to extract group ID from (%s). Ignore it\n", FuncName, buffer+posInBuffer) ; } } posInBuffer += (lenCurrentLink + 1) ; } }
- if(NIL != buffer) { free(buffer) ; }
- if(NIL != fileExport) { fclose(fileExport) ; }
- return bEverythingOK ? exportedLinks : PAS_FAILURE; }
-/* * install links (to groups and public data) into the application folder(indicated by absPathApplicationFolder) * based on information available inside the import folder (indicated by absPathImportFolder) * returns the number of installed links, or a negative value in case of error */ sint_t persadmin_import_links(pstr_t absPathImportFolder, pstr_t absPathApplicationFolder) { pstr_t FuncName = "persadmin_import_links:" ; bool_t bEverythingOK = true ; bool_t bNothingToImport = false ; sint_t importedLinks = 0 ; FILE * fileImport = NIL ; bool_t bImportInCachedPath = true ;
- if( (NIL == absPathImportFolder) || (NIL == absPathApplicationFolder)) { bEverythingOK = false ; printf("\n%s NIL param \n", FuncName) ; } else { if(0 != persadmin_check_if_file_exists(absPathImportFolder, true)) { bEverythingOK = false ; printf("\n%s folder does not exist (%s) \n", FuncName, absPathImportFolder) ; } else { if(0 != persadmin_check_if_file_exists(absPathApplicationFolder, true)) { bEverythingOK = false ; printf("\n%s folder does not exist (%s) \n", FuncName, absPathApplicationFolder) ; } } }
- if(bEverythingOK) { /* check if the absPathApplicationFolder is a cached or write-through path */ if(NIL != strstr(absPathApplicationFolder, PERSADMIN_POLICY_MARKER_CACHED)) { /* cached path */ bImportInCachedPath = true ; } else { /* not a cached path, so it ahould be a write-through path */ if(NIL != strstr(absPathApplicationFolder, PERSADMIN_POLICY_MARKER_WT)) { /* write-through */ bImportInCachedPath = false ; } else { bEverythingOK = false ; printf("\n%s no cached or wt path (%s) \n", FuncName, absPathApplicationFolder) ; } } }
- if(bEverythingOK) { /* open the source file */ str_t completePath[PERSADMIN_MAX_PATH_LENGHT] ; sint_t lenPathImport = strlen(absPathImportFolder) ; sint_t lenLinkFilename = strlen(PERSADMIN_LINKS_INFO_FILENAME) ;
- if( (lenPathImport + 1 + lenLinkFilename) < PERSADMIN_MAX_PATH_LENGHT ) { strncpy(completePath, absPathImportFolder, sizeof(completePath)) ; if('/' != completePath[lenPathImport -1]) { strncat(completePath, "/", sizeof(completePath)) ; } strncat(completePath, PERSADMIN_LINKS_INFO_FILENAME, sizeof(completePath)) ;
- fileImport = fopen(completePath, "r") ; if(NIL == fileImport) { /* nothing to import */ bNothingToImport = true ; printf("\n%s fopen(<%s>, r) errno = %s\n", FuncName, completePath, strerror(errno)) ; } } else { bEverythingOK = false ; printf("\n%s path too long (%s/%s)\n", FuncName, absPathImportFolder, PERSADMIN_LINKS_INFO_FILENAME) ; } }
- if(bEverythingOK && (! bNothingToImport)) { bool_t bEndOfFileReached = false ;
- str_t appFolderPath[PERSADMIN_MAX_PATH_LENGHT] ; sint_t lenAppFolder = strlen(absPathApplicationFolder) ;
- if(lenAppFolder + 1 < PERSADMIN_MAX_PATH_LENGHT) { strncpy(appFolderPath, absPathApplicationFolder, sizeof(appFolderPath)) ; if('/' != appFolderPath[lenAppFolder-1]) { strncat(appFolderPath, "/", sizeof(appFolderPath)) ; lenAppFolder += 1 ; } } else { bEverythingOK = false ; printf("\n%s path too long (%s)\n", FuncName, absPathImportFolder) ; } while((! bEndOfFileReached) && bEverythingOK) { str_t line[256] ; pstr_t pResult = fgets(line, sizeof(line), fileImport) ; if(NIL == pResult) { /* end of file */ bEndOfFileReached = true ; } else { if(strlen(line) > (sizeof(line) - 3)) /* 3 <=> \n \r \0 */ { bEverythingOK = false ; printf("%s - unexpected line too long \n", FuncName) ; } else { str_t linkTarget[256] ; str_t linkPathname[256] ; bool_t bIgnoreLine = false ; persadmin_common_remove_endofline(line) ; if(0 == strcmp(line, "public")) { snprintf(linkTarget, sizeof(linkTarget), "%s", bImportInCachedPath ? PERS_ORG_SHARED_PUBLIC_CACHE_PATH_ : PERS_ORG_SHARED_PUBLIC_WT_PATH_) ; if((sizeof(linkPathname)-1) < snprintf(linkPathname, sizeof(linkPathname), "%s%s", appFolderPath, PERS_ORG_SHARED_PUBLIC_SYMLINK_NAME)) { /* hard to believe, but anyway */ bIgnoreLine = true ; printf("%s - unexpected linkPathname too long (%s%s) \n", FuncName, appFolderPath, PERS_ORG_SHARED_PUBLIC_SYMLINK_NAME) ; } } else { sint_t groupID ; sint_t result = sscanf(line, "%X", &groupID) ; if(1 == result) { snprintf(linkTarget, sizeof(linkTarget), "%s%02X", (bImportInCachedPath ? PERS_ORG_SHARED_GROUP_CACHE_PATH_ : PERS_ORG_SHARED_GROUP_WT_PATH_), groupID) ; if((sizeof(linkPathname)-1) < snprintf(linkPathname, sizeof(linkPathname), "%s%s%02X", appFolderPath, PERS_ORG_SHARED_GROUP_SYMLINK_PREFIX, groupID)) { /* hard to believe, but anyway */ bIgnoreLine = true ; printf("%s - unexpected linkPathname too long (%s%s%02X) \n", FuncName, appFolderPath, PERS_ORG_SHARED_GROUP_SYMLINK_PREFIX, groupID) ; } } else { bIgnoreLine = true ; printf("%s - unable to extract group ID from (%s) - ignore it \n", FuncName, line) ; } }
- if( ! bIgnoreLine) { if(0 <= persadmin_check_if_file_exists(linkPathname, false)) { if(0 > persadmin_delete_file(linkPathname)) { bEverythingOK = false ; printf("%s - unable to delete existing link (%s) \n", FuncName, linkPathname) ; } }
- if(bEverythingOK) { if(0 == persadmin_create_symbolic_link(linkPathname, linkTarget)) { importedLinks++ ; } else { bEverythingOK = false ; printf("%s - persadmin_create_symbolic_link(<%s>, <%s>) failed \n", FuncName, linkPathname, linkTarget) ; } } } } }
- } }
- if(NIL != fileImport) { fclose(fileImport) ; }
- return bEverythingOK ? importedLinks : PAS_FAILURE; }
-
-/* * linkName is not checked against NIL * return group ID, or negative value for error * it is assumed that lenght of linkName < PERSADMIN_MAX_PATH_LENGHT **/ static sint_t persadmin_common_extract_group_id(pstr_t linkName) { sint_t groupID = -1 ; sint_t lenPrefix = strlen(PERS_ORG_SHARED_GROUP_SYMLINK_PREFIX) ;
- if(strlen(linkName) > lenPrefix) { if(0 == strncmp(linkName, PERS_ORG_SHARED_GROUP_SYMLINK_PREFIX, lenPrefix)) { if(1 != sscanf(linkName+lenPrefix, "%X", &groupID)) { groupID = -1 ; } } }
- return groupID ; }
-/* * line is not checked against NIL * the content of line is changed **/ static void persadmin_common_remove_endofline(pstr_t line) { sint_t len = strlen(line) ; if((len > 0) && (('\r' == line[len-1]) || ('\n' == line[len-1]))) { line[len-1] = '\0' ; }
- if((len > 1) && (('\r' == line[len-2]) || ('\n' == line[len-2]))) { line[len-2] = '\0' ; } }
- sint_t persadmin_list_application_folders( pconststr_t rootPath, pstr_t list, sint_t listSize ) { sint_t result = PAS_FAILURE;
- if ( ( rootPath != 0 ) && ( list != 0 ) && ( listSize > 0 ) ) { GetApplicationRootPath( rootPath, completeRootPath );
- // Clear the output buffer before retrieving the actual list memset( list, 0, listSize );
+
+/* ---------------------- local functions ---------------------------------- */
+static sint_t persadmin_common_extract_group_id(pstr_t linkName) ;
+static void persadmin_common_remove_endofline(pstr_t line) ;
+static bool_t persadmin_is_shared_folder( pconststr_t name, int length );
+static sint_t persadmin_copy_data(struct archive *ar, struct archive *aw);
+
+/* ---------------------- local variables ---------------------------------- */
+//moved to "ssw_pers_admin_common.h"
+//extern const char StringTerminator;
+
+/*
+* export the application's information about links (to groups and public data)
+* returns the number of exported links, or a negative value in case of error
+*/
+sint_t persadmin_export_links(pstr_t absPathApplicationFolder, pstr_t absPathExportFolder)
+{
+ pstr_t FuncName = "persadmin_export_links:" ;
+ bool_t bEverythingOK = true ;
+ pstr_t buffer = NIL ;
+ bool_t bNothingToExport = false ;
+ sint_t exportedLinks = 0 ;
+ sint_t neededBufferSize = 0 ;
+ FILE * fileExport = NIL ;
+ if( (NIL == absPathApplicationFolder) || (NIL == absPathExportFolder))
+ {
+ bEverythingOK = false ;
+ printf("\n%s NIL param \n", FuncName) ;
+ }
+ else
+ {
+ if(0 != persadmin_check_if_file_exists(absPathApplicationFolder, true))
+ {
+ bEverythingOK = false ;
+ printf("\n%s folder does not exist (%s) \n", FuncName, absPathApplicationFolder) ;
+ }
+ else
+ {
+ if(0 != persadmin_check_if_file_exists(absPathExportFolder, true))
+ {
+ bEverythingOK = false ;
+ printf("\n%s folder does not exist (%s) \n", FuncName, absPathExportFolder) ;
+ }
+ }
+ }
+ if(bEverythingOK)
+ {
+ neededBufferSize = persadmin_list_folder_get_size(absPathApplicationFolder, PersadminFilterFilesLink, false) ;
+ if(neededBufferSize > 0)
+ {
+ buffer = (pstr_t)malloc(neededBufferSize*sizeof(str_t)) ;
+ if(NIL == buffer)
+ {
+ bEverythingOK = false ;
+ }
+ else
+ {
+ sint_t listingSize = persadmin_list_folder(absPathApplicationFolder, buffer, neededBufferSize, PersadminFilterFilesLink, false) ;
+ if(neededBufferSize != listingSize)
+ {
+ bEverythingOK = false ;
+ printf("\n%s persadmin_list_folder(%s) returned %d (expected %d) \n", FuncName, absPathApplicationFolder, listingSize, neededBufferSize) ;
+ }
+ }
+ }
+ else
+ {
+ if(0 == neededBufferSize)
+ {
+ /* no links to export */
+ bNothingToExport = true ;
+ }
+ else
+ {
+ bEverythingOK = false ;
+ printf("\n%s persadmin_list_folder_get_size(<%s>, FilterFilesLink, false) failed\n", FuncName, absPathApplicationFolder) ;
+ }
+ }
+ }
+ if(bEverythingOK && (! bNothingToExport))
+ {
+ /* create the export file */
+ str_t completePath[PERSADMIN_MAX_PATH_LENGHT] ;
+ sint_t lenPathExport = strlen(absPathExportFolder) ;
+ sint_t lenLinkFilename = strlen(PERSADMIN_LINKS_INFO_FILENAME) ;
+ if( (lenPathExport + 1 + lenLinkFilename) < PERSADMIN_MAX_PATH_LENGHT )
+ {
+ strncpy(completePath, absPathExportFolder, sizeof(completePath)) ;
+ if('/' != completePath[lenPathExport -1])
+ {
+ strncat(completePath, "/", sizeof(completePath)) ;
+ }
+ strncat(completePath, PERSADMIN_LINKS_INFO_FILENAME, sizeof(completePath)) ;
+ fileExport = fopen(completePath, "w") ;
+ if(NIL == fileExport)
+ {
+ bEverythingOK = false ;
+ printf("\n%s fopen(<%s>, w) errno = %s\n", FuncName, completePath, strerror(errno)) ;
+ }
+ }
+ else
+ {
+ bEverythingOK = false ;
+ printf("\n%s path too long (%s/%s)\n", FuncName, absPathExportFolder, PERSADMIN_LINKS_INFO_FILENAME) ;
+ }
+ }
+ if(bEverythingOK && (! bNothingToExport))
+ {
+ /* for each link file in buffer, create an entry (line) in the export file
+ * for links to group - only the number of the group (i.e. a hex value in 0x00 - 0xFF domain) is stored
+ * for links to public data - the word "public" is stored
+ **/
+ sint_t posInBuffer = 0 ;
+ while((posInBuffer < neededBufferSize) && bEverythingOK)
+ {
+ sint_t lenCurrentLink = strlen(buffer+posInBuffer) ;
+ if(0 == strcmp(buffer+posInBuffer, PERS_ORG_SHARED_PUBLIC_SYMLINK_NAME))
+ {
+ /* it is the link to the public data */
+ if(0 > fputs("public\n", fileExport))
+ {
+ bEverythingOK = false ;
+ printf("\n%s fputs(public) errno=%s\n", FuncName, strerror(errno)) ;
+ }
+ else
+ {
+ exportedLinks++ ;
+ }
+ }
+ else
+ {
+ sint_t groupID = persadmin_common_extract_group_id(buffer+posInBuffer) ;
+ if(groupID >= 0)
+ {
+ str_t line[PERSADMIN_MAX_PATH_LENGHT] ;
+ printf("\n%s groupID(%s)=0x%02X\n", FuncName, buffer+posInBuffer, groupID) ;
+ snprintf(line, sizeof(line), "%02X\n", groupID) ;
+ if(0 > fputs(line, fileExport))
+ {
+ bEverythingOK = false ;
+ printf("\n%s fputs(%02X) errno=%s\n", FuncName, groupID, strerror(errno)) ;
+ }
+ else
+ {
+ exportedLinks++ ;
+ }
+ }
+ else
+ {
+ printf("\n%s unable to extract group ID from (%s). Ignore it\n", FuncName, buffer+posInBuffer) ;
+ }
+ }
+ posInBuffer += (lenCurrentLink + 1) ;
+ }
+ }
+ if(NIL != buffer)
+ {
+ free(buffer) ;
+ }
+ if(NIL != fileExport)
+ {
+ fclose(fileExport) ;
+ }
+ return bEverythingOK ? exportedLinks : PAS_FAILURE;
+}
+/*
+* install links (to groups and public data) into the application folder(indicated by absPathApplicationFolder)
+* based on information available inside the import folder (indicated by absPathImportFolder)
+* returns the number of installed links, or a negative value in case of error
+*/
+sint_t persadmin_import_links(pstr_t absPathImportFolder, pstr_t absPathApplicationFolder)
+{
+ pstr_t FuncName = "persadmin_import_links:" ;
+ bool_t bEverythingOK = true ;
+ bool_t bNothingToImport = false ;
+ sint_t importedLinks = 0 ;
+ FILE * fileImport = NIL ;
+ bool_t bImportInCachedPath = true ;
+ if( (NIL == absPathImportFolder) || (NIL == absPathApplicationFolder))
+ {
+ bEverythingOK = false ;
+ printf("\n%s NIL param \n", FuncName) ;
+ }
+ else
+ {
+ if(0 != persadmin_check_if_file_exists(absPathImportFolder, true))
+ {
+ bEverythingOK = false ;
+ printf("\n%s folder does not exist (%s) \n", FuncName, absPathImportFolder) ;
+ }
+ else
+ {
+ if(0 != persadmin_check_if_file_exists(absPathApplicationFolder, true))
+ {
+ bEverythingOK = false ;
+ printf("\n%s folder does not exist (%s) \n", FuncName, absPathApplicationFolder) ;
+ }
+ }
+ }
+ if(bEverythingOK)
+ {
+ /* check if the absPathApplicationFolder is a cached or write-through path */
+ if(NIL != strstr(absPathApplicationFolder, PERSADMIN_POLICY_MARKER_CACHED))
+ {
+ /* cached path */
+ bImportInCachedPath = true ;
+ }
+ else
+ {
+ /* not a cached path, so it ahould be a write-through path */
+ if(NIL != strstr(absPathApplicationFolder, PERSADMIN_POLICY_MARKER_WT))
+ {
+ /* write-through */
+ bImportInCachedPath = false ;
+ }
+ else
+ {
+ bEverythingOK = false ;
+ printf("\n%s no cached or wt path (%s) \n", FuncName, absPathApplicationFolder) ;
+ }
+ }
+ }
+ if(bEverythingOK)
+ {
+ /* open the source file */
+ str_t completePath[PERSADMIN_MAX_PATH_LENGHT] ;
+ sint_t lenPathImport = strlen(absPathImportFolder) ;
+ sint_t lenLinkFilename = strlen(PERSADMIN_LINKS_INFO_FILENAME) ;
+ if( (lenPathImport + 1 + lenLinkFilename) < PERSADMIN_MAX_PATH_LENGHT )
+ {
+ strncpy(completePath, absPathImportFolder, sizeof(completePath)) ;
+ if('/' != completePath[lenPathImport -1])
+ {
+ strncat(completePath, "/", sizeof(completePath)) ;
+ }
+ strncat(completePath, PERSADMIN_LINKS_INFO_FILENAME, sizeof(completePath)) ;
+ fileImport = fopen(completePath, "r") ;
+ if(NIL == fileImport)
+ {
+ /* nothing to import */
+ bNothingToImport = true ;
+ printf("\n%s fopen(<%s>, r) errno = %s\n", FuncName, completePath, strerror(errno)) ;
+ }
+ }
+ else
+ {
+ bEverythingOK = false ;
+ printf("\n%s path too long (%s/%s)\n", FuncName, absPathImportFolder, PERSADMIN_LINKS_INFO_FILENAME) ;
+ }
+ }
+ if(bEverythingOK && (! bNothingToImport))
+ {
+ bool_t bEndOfFileReached = false ;
+ str_t appFolderPath[PERSADMIN_MAX_PATH_LENGHT] ;
+ sint_t lenAppFolder = strlen(absPathApplicationFolder) ;
+ if(lenAppFolder + 1 < PERSADMIN_MAX_PATH_LENGHT)
+ {
+ strncpy(appFolderPath, absPathApplicationFolder, sizeof(appFolderPath)) ;
+ if('/' != appFolderPath[lenAppFolder-1])
+ {
+ strncat(appFolderPath, "/", sizeof(appFolderPath)) ;
+ lenAppFolder += 1 ;
+ }
+ }
+ else
+ {
+ bEverythingOK = false ;
+ printf("\n%s path too long (%s)\n", FuncName, absPathImportFolder) ;
+ }
+
+ while((! bEndOfFileReached) && bEverythingOK)
+ {
+ str_t line[256] ;
+ pstr_t pResult = fgets(line, sizeof(line), fileImport) ;
+ if(NIL == pResult)
+ {
+ /* end of file */
+ bEndOfFileReached = true ;
+ }
+ else
+ {
+ if(strlen(line) > (sizeof(line) - 3)) /* 3 <=> \n \r \0 */
+ {
+ bEverythingOK = false ;
+ printf("%s - unexpected line too long \n", FuncName) ;
+ }
+ else
+ {
+ str_t linkTarget[256] ;
+ str_t linkPathname[256] ;
+ bool_t bIgnoreLine = false ;
+
+ persadmin_common_remove_endofline(line) ;
+ if(0 == strcmp(line, "public"))
+ {
+ snprintf(linkTarget, sizeof(linkTarget), "%s",
+ bImportInCachedPath ? PERS_ORG_SHARED_PUBLIC_CACHE_PATH_ : PERS_ORG_SHARED_PUBLIC_WT_PATH_) ;
+ if((sizeof(linkPathname)-1) < snprintf(linkPathname, sizeof(linkPathname), "%s%s",
+ appFolderPath, PERS_ORG_SHARED_PUBLIC_SYMLINK_NAME))
+ {
+ /* hard to believe, but anyway */
+ bIgnoreLine = true ;
+ printf("%s - unexpected linkPathname too long (%s%s) \n", FuncName, appFolderPath, PERS_ORG_SHARED_PUBLIC_SYMLINK_NAME) ;
+ }
+ }
+ else
+ {
+ sint_t groupID ;
+ sint_t result = sscanf(line, "%X", &groupID) ;
+ if(1 == result)
+ {
+ snprintf(linkTarget, sizeof(linkTarget), "%s%02X",
+ (bImportInCachedPath ? PERS_ORG_SHARED_GROUP_CACHE_PATH_ : PERS_ORG_SHARED_GROUP_WT_PATH_), groupID) ;
+ if((sizeof(linkPathname)-1) < snprintf(linkPathname, sizeof(linkPathname), "%s%s%02X", appFolderPath, PERS_ORG_SHARED_GROUP_SYMLINK_PREFIX, groupID))
+ {
+ /* hard to believe, but anyway */
+ bIgnoreLine = true ;
+ printf("%s - unexpected linkPathname too long (%s%s%02X) \n", FuncName, appFolderPath, PERS_ORG_SHARED_GROUP_SYMLINK_PREFIX, groupID) ;
+ }
+ }
+ else
+ {
+ bIgnoreLine = true ;
+ printf("%s - unable to extract group ID from (%s) - ignore it \n", FuncName, line) ;
+ }
+ }
+ if( ! bIgnoreLine)
+ {
+ if(0 <= persadmin_check_if_file_exists(linkPathname, false))
+ {
+ if(0 > persadmin_delete_file(linkPathname))
+ {
+ bEverythingOK = false ;
+ printf("%s - unable to delete existing link (%s) \n", FuncName, linkPathname) ;
+ }
+ }
+ if(bEverythingOK)
+ {
+ if(0 == persadmin_create_symbolic_link(linkPathname, linkTarget))
+ {
+ importedLinks++ ;
+ }
+ else
+ {
+ bEverythingOK = false ;
+ printf("%s - persadmin_create_symbolic_link(<%s>, <%s>) failed \n", FuncName, linkPathname, linkTarget) ;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if(NIL != fileImport)
+ {
+ fclose(fileImport) ;
+ }
+ return bEverythingOK ? importedLinks : PAS_FAILURE;
+}
+
+/*
+* linkName is not checked against NIL
+* return group ID, or negative value for error
+* it is assumed that lenght of linkName < PERSADMIN_MAX_PATH_LENGHT
+**/
+static sint_t persadmin_common_extract_group_id(pstr_t linkName)
+{
+ sint_t groupID = -1 ;
+ sint_t lenPrefix = strlen(PERS_ORG_SHARED_GROUP_SYMLINK_PREFIX) ;
+ if(strlen(linkName) > lenPrefix)
+ {
+ if(0 == strncmp(linkName, PERS_ORG_SHARED_GROUP_SYMLINK_PREFIX, lenPrefix))
+ {
+ if(1 != sscanf(linkName+lenPrefix, "%X", &groupID))
+ {
+ groupID = -1 ;
+ }
+ }
+ }
+ return groupID ;
+}
+
+/*
+* line is not checked against NIL
+* the content of line is changed
+**/
+static void persadmin_common_remove_endofline(pstr_t line)
+{
+ sint_t len = strlen(line) ;
+ if((len > 0) && (('\r' == line[len-1]) || ('\n' == line[len-1])))
+ {
+ line[len-1] = '\0' ;
+ }
+ if((len > 1) && (('\r' == line[len-2]) || ('\n' == line[len-2])))
+ {
+ line[len-2] = '\0' ;
+ }
+}
+
+sint_t persadmin_list_application_folders( pconststr_t rootPath, pstr_t list, sint_t listSize ) {
+ sint_t result = PAS_FAILURE;
+ if ( ( rootPath != 0 ) && ( list != 0 ) && ( listSize > 0 ) ) {
+ GetApplicationRootPath( rootPath, completeRootPath );
+ // Clear the output buffer before retrieving the actual list
+ memset( list, 0, listSize );
result = persadmin_list_folder( completeRootPath, list, listSize, PersadminFilterFolders, false );
- if ( result >= 0 ) { char * crtName = list; bool_t done = false; result += sizeof( StringTerminator ); while ( ( ( * crtName ) != 0 ) && ( done == false ) ) { int length = strlen( crtName ); if ( persadmin_is_shared_folder( crtName, length ) == true ) { result -= length + sizeof( StringTerminator ); memmove( crtName, crtName + length + sizeof( StringTerminator ), listSize - ( crtName - list ) - length - sizeof( StringTerminator ) ); done = true; } else { crtName += length + sizeof( StringTerminator ); } } } }
- return result; }
-sint_t persadmin_list_application_folders_get_size( pconststr_t rootPath ) { sint_t result = PAS_FAILURE;
- GetApplicationRootPath( rootPath, completeRootPath ); result = persadmin_list_folder_get_size( completeRootPath, PersadminFilterFolders, false );
- if ( result > 0 ) { // Add space for doubling the final '\0' - this is not done inside persadmin_list_folder_get_size() result += sizeof( StringTerminator ); }
- return result; }
-bool_t persadmin_is_shared_folder( pconststr_t name, int length ) { bool_t result = false; int compLen = strlen( gSharedPathName );
- if ( ( name != 0 ) && ( length == compLen ) ) { int i = 0; result = true; for ( ; ( ( i < compLen ) && ( result == true ) ); ++i ) { if ( gSharedPathName[ i ] != name[ i ] ) { result = false; } } }
- return result; } /** * @brief Saves files together into a single archive. * @usage persadmin_compress("/path/to/compress/to/archive_name.tgz", "/path/from/where/to/compress") * @return 0 for success, negative value otherwise. */ sint_t persadmin_compress(pstr_t compressTo, pstr_t compressFrom) { uint8_t buffer [READ_BUFFER_LENGTH]; str_t pchParentPath [PATH_ABS_MAX_SIZE]; pstr_t pchStrPos = NIL; struct archive *psArchive = NIL; struct archive *psDisk = NIL; struct archive_entry *psEntry = NIL; sint_t s32Result = ARCHIVE_OK; sint_t s32Length = 0; sint_t fd; sint_t s32ParentPathLength = 0; if( (NIL == compressTo) || (NIL == compressFrom) ) { s32Result = ARCHIVE_FAILED; printf("persadmin_compress - invalid parameters \n"); } if( ARCHIVE_OK == s32Result ) { printf("persadmin_compress - create <%s> from <%s>\n", compressTo, compressFrom); psArchive = archive_write_new(); if( NIL == psArchive ) { s32Result = ARCHIVE_FAILED; printf("persadmin_compress - archive_write_new ERR\n"); } } if( ARCHIVE_OK == s32Result ) { /* this in turn calls archive_write_add_filter_gzip; */ s32Result = archive_write_set_compression_gzip(psArchive); if( ARCHIVE_OK != s32Result ) { printf("persadmin_compress - archive_write_set_compression_gzip ERR %d\n", s32Result); } } if( ARCHIVE_OK == s32Result ) { /* portable archive exchange; */ archive_write_set_format_pax(psArchive); compressTo = (strcmp(compressTo, "-") == 0) ? NIL : compressTo; s32Result = archive_write_open_filename(psArchive, compressTo); if( ARCHIVE_OK != s32Result ) { printf("persadmin_compress - archive_write_open_filename ERR %d\n", s32Result); } } if( ARCHIVE_OK == s32Result ) { psDisk = archive_read_disk_new(); if( NIL == psDisk ) { s32Result = ARCHIVE_FAILED; printf("persadmin_compress - archive_read_disk_new ERR\n"); } } if( ARCHIVE_OK == s32Result ) { archive_read_disk_set_standard_lookup(psDisk); s32Result = archive_read_disk_open(psDisk, compressFrom); if( ARCHIVE_OK != s32Result ) { printf("persadmin_compress - archive_read_disk_new ERR %s\n", archive_error_string(psDisk)); } } memset(pchParentPath, 0, sizeof(pchParentPath)); snprintf(pchParentPath, sizeof(pchParentPath), compressFrom); pchStrPos = strrchr(pchParentPath, '/'); if(NIL != pchStrPos) { *pchStrPos = '\0'; } s32ParentPathLength = strlen(pchParentPath); while( ARCHIVE_OK == s32Result ) { psEntry = archive_entry_new(); s32Result = archive_read_next_header2(psDisk, psEntry); switch( s32Result ) { case ARCHIVE_EOF: { /* nothing else to do; */ break; } case ARCHIVE_OK: { str_t pstrTemp[PATH_ABS_MAX_SIZE]; pstr_t p = (pstr_t)archive_entry_pathname(psEntry); if(NIL != p) { /* remove parent section and save relative pathnames */ memset(pstrTemp, 0, sizeof(pstrTemp)); snprintf(pstrTemp, sizeof(pstrTemp), "%s", p + (s32ParentPathLength + 1)); archive_entry_copy_pathname(psEntry, pstrTemp); } archive_read_disk_descend(psDisk); s32Result = archive_write_header(psArchive, psEntry); if( ARCHIVE_OK > s32Result) { printf("persadmin_compress - archive_write_header ERR %s\n", archive_error_string(psArchive)); } if( ARCHIVE_FATAL == s32Result ) { /* exit; */ printf("persadmin_compress - archive_write_header ERR FATAL\n"); } if( ARCHIVE_FAILED < s32Result ) { #if 0 /* Ideally, we would be able to use * the same code to copy a body from * an archive_read_disk to an * archive_write that we use for * copying data from an archive_read * to an archive_write_disk. * Unfortunately, this doesn't quite * work yet. */ persadmin_copy_data(psDisk, psArchive); #else /* For now, we use a simpler loop to copy data * into the target archive. */ fd = open(archive_entry_sourcepath(psEntry), O_RDONLY); s32Length = read(fd, buffer, READ_BUFFER_LENGTH); while( s32Length > 0 ) { archive_write_data(psArchive, buffer, s32Length); s32Length = read(fd, buffer, READ_BUFFER_LENGTH); } close(fd); #endif } break; } default: { printf("persadmin_compress - archive_read_next_header2 ERR %s\n", archive_error_string(psDisk)); /* exit; */ break; } } if( NIL != psEntry ) { archive_entry_free(psEntry); } } /* perform cleaning operations; */ if( NIL != psDisk ) { archive_read_close(psDisk); archive_read_free(psDisk); } if( NIL != psArchive ) { archive_write_close(psArchive); archive_write_free(psArchive); } /* overwrite result; */ s32Result = (s32Result == ARCHIVE_EOF) ? ARCHIVE_OK : s32Result; /* return result; */ return s32Result; } /* persadmin_compress() */ /** * @brief Restore files from an archive. * @usage persadmin_uncompress("/path/from/where/to/extract/archive_name.tgz", "/path/where/to/extract/") - extract to specified folder * @usage persadmin_uncompress("/path/from/where/to/extract/archive_name.tgz", "") - extract to local folder * @return 0 for success, negative value otherwise. */ sint_t persadmin_uncompress(pstr_t extractFrom, pstr_t extractTo) { struct archive *psArchive = NIL; struct archive *psExtract = NIL; struct archive_entry *psEntry = NIL; sint_t s32Result = ARCHIVE_OK; sint_t s32Flags = ARCHIVE_EXTRACT_TIME; /* select which attributes to restore; */ s32Flags |= ARCHIVE_EXTRACT_PERM; s32Flags |= ARCHIVE_EXTRACT_ACL; s32Flags |= ARCHIVE_EXTRACT_FFLAGS; if( (NIL == extractFrom) || (NIL == extractTo) ) { s32Result = ARCHIVE_FAILED; printf("persadmin_uncompress - invalid parameters\n"); } if( ARCHIVE_OK == s32Result ) { psArchive = archive_read_new(); if( NIL == psArchive ) { s32Result = ARCHIVE_FAILED; printf("persadmin_uncompress - archive_read_new ERR\n"); } } if( ARCHIVE_OK == s32Result ) { archive_read_support_format_all(psArchive); archive_read_support_compression_all(psArchive); psExtract = archive_write_disk_new(); s32Result = ((NIL == psExtract) ? ARCHIVE_FAILED : s32Result); archive_write_disk_set_options(psExtract, s32Flags); archive_write_disk_set_standard_lookup(psExtract); } if( ARCHIVE_OK == s32Result ) { s32Result = archive_read_open_filename(psArchive, extractFrom, 10240); /* exit if s32Result != ARCHIVE_OK; */ } while( ARCHIVE_OK == s32Result ) { s32Result = archive_read_next_header(psArchive, &psEntry); switch( s32Result ) { case ARCHIVE_EOF: { /* nothing else to do; */ break; } case ARCHIVE_OK: { /* modify entry here to extract to the needed location; */ str_t pstrTemp[PATH_ABS_MAX_SIZE]; memset(pstrTemp, 0, sizeof(pstrTemp)); snprintf(pstrTemp, sizeof(pstrTemp), "%s%s", extractTo, archive_entry_pathname(psEntry)); printf("persadmin_uncompress - archive_entry_pathname %s\n", pstrTemp); archive_entry_copy_pathname(psEntry, pstrTemp); s32Result = archive_write_header(psExtract, psEntry); if( ARCHIVE_OK == s32Result ) { if( archive_entry_size(psEntry) > 0 ) { s32Result = persadmin_copy_data(psArchive, psExtract); if( ARCHIVE_OK != s32Result ) { printf("persadmin_uncompress - copy_data ERR %s\n", archive_error_string(psExtract)); } /* if( ARCHIVE_WARN > s32Result ) exit; */ } if( ARCHIVE_OK == s32Result ) { s32Result = archive_write_finish_entry(psExtract); if( ARCHIVE_OK != s32Result ) { printf("persadmin_uncompress - archive_write_finish_entry ERR %s\n", archive_error_string(psExtract)); } /* if( ARCHIVE_WARN > s32Result ) exit; */ } } else { printf("persadmin_uncompress - archive_write_header ERR %s\n", archive_error_string(psExtract)); } break; } default: { printf("persadmin_uncompress - archive_read_next_header ERR %d\n", s32Result); break; } } } /* perform cleaning operations; */ if( NIL != psArchive ) { archive_read_close(psArchive); archive_read_free(psArchive); } if( NIL != psExtract ) { archive_write_close(psExtract); archive_write_free(psExtract); } /* overwrite result; */ s32Result = (s32Result == ARCHIVE_EOF) ? ARCHIVE_OK : s32Result; /* return result; */ return s32Result; } /* persadmin_uncompress() */ static sint_t persadmin_copy_data(struct archive *ar, struct archive *aw) { sint_t s32Result = ARCHIVE_OK; sint_t s32Size = 0; uint8_t buffer[COPY_BUFFER_LENGTH]; while( ARCHIVE_OK == s32Result ) { s32Size = archive_read_data(ar, buffer, COPY_BUFFER_LENGTH); if( 0 > s32Size ) { printf("persadmin_copy_data - archive_read_data ERR\n"); s32Result = ARCHIVE_FAILED; } else { if( 0 < s32Size ) { s32Size = archive_write_data(aw, buffer, COPY_BUFFER_LENGTH); if( 0 > s32Size ) { printf("persadmin_copy_data - archive_write_data ERR\n"); s32Result = ARCHIVE_FAILED; } } else { /* nothing to copy; */ break; } } } /* return result; */ return s32Result; } /* persadmin_copy_data() */
+ if ( result >= 0 ) {
+ char * crtName = list;
+ bool_t done = false;
+ result += sizeof( StringTerminator );
+ while ( ( ( * crtName ) != 0 ) && ( done == false ) ) {
+ int length = strlen( crtName );
+ if ( persadmin_is_shared_folder( crtName, length ) == true ) {
+ result -= length + sizeof( StringTerminator );
+ memmove( crtName, crtName + length + sizeof( StringTerminator ), listSize - ( crtName - list ) - length - sizeof( StringTerminator ) );
+ done = true;
+ }
+ else {
+ crtName += length + sizeof( StringTerminator );
+ }
+ }
+ }
+ }
+ return result;
+}
+
+sint_t persadmin_list_application_folders_get_size( pconststr_t rootPath ) {
+ sint_t result = PAS_FAILURE;
+ GetApplicationRootPath( rootPath, completeRootPath );
+ result = persadmin_list_folder_get_size( completeRootPath, PersadminFilterFolders, false );
+ if ( result > 0 ) {
+ // Add space for doubling the final '\0' - this is not done inside persadmin_list_folder_get_size()
+ result += sizeof( StringTerminator );
+ }
+ return result;
+}
+
+bool_t persadmin_is_shared_folder( pconststr_t name, int length ) {
+ bool_t result = false;
+ int compLen = strlen( gSharedPathName );
+ if ( ( name != 0 ) && ( length == compLen ) ) {
+ int i = 0;
+ result = true;
+ for ( ; ( ( i < compLen ) && ( result == true ) ); ++i ) {
+ if ( gSharedPathName[ i ] != name[ i ] ) {
+ result = false;
+ }
+ }
+ }
+ return result;
+}
+
+
+/**
+ * @brief Saves files together into a single archive.
+ * @usage persadmin_compress("/path/to/compress/to/archive_name.tgz", "/path/from/where/to/compress")
+ * @return 0 for success, negative value otherwise.
+ */
+sint_t persadmin_compress(pstr_t compressTo, pstr_t compressFrom)
+{
+ uint8_t buffer [READ_BUFFER_LENGTH];
+ str_t pchParentPath [PATH_ABS_MAX_SIZE];
+ pstr_t pchStrPos = NIL;
+ struct archive *psArchive = NIL;
+ struct archive *psDisk = NIL;
+ struct archive_entry *psEntry = NIL;
+ sint_t s32Result = ARCHIVE_OK;
+ sint_t s32Length = 0;
+ sint_t fd;
+ sint_t s32ParentPathLength = 0;
+
+
+ if( (NIL == compressTo) ||
+ (NIL == compressFrom) )
+ {
+ s32Result = ARCHIVE_FAILED;
+ printf("persadmin_compress - invalid parameters \n");
+ }
+
+ if( ARCHIVE_OK == s32Result )
+ {
+ printf("persadmin_compress - create <%s> from <%s>\n", compressTo, compressFrom);
+ psArchive = archive_write_new();
+ if( NIL == psArchive )
+ {
+ s32Result = ARCHIVE_FAILED;
+ printf("persadmin_compress - archive_write_new ERR\n");
+ }
+ }
+
+ if( ARCHIVE_OK == s32Result )
+ {
+ /* this in turn calls archive_write_add_filter_gzip; */
+ s32Result = archive_write_set_compression_gzip(psArchive);
+ if( ARCHIVE_OK != s32Result )
+ {
+ printf("persadmin_compress - archive_write_set_compression_gzip ERR %d\n", s32Result);
+ }
+ }
+
+ if( ARCHIVE_OK == s32Result )
+ {
+ /* portable archive exchange; */
+ archive_write_set_format_pax(psArchive);
+ compressTo = (strcmp(compressTo, "-") == 0) ? NIL : compressTo;
+ s32Result = archive_write_open_filename(psArchive, compressTo);
+ if( ARCHIVE_OK != s32Result )
+ {
+ printf("persadmin_compress - archive_write_open_filename ERR %d\n", s32Result);
+ }
+ }
+
+ if( ARCHIVE_OK == s32Result )
+ {
+ psDisk = archive_read_disk_new();
+ if( NIL == psDisk )
+ {
+ s32Result = ARCHIVE_FAILED;
+ printf("persadmin_compress - archive_read_disk_new ERR\n");
+ }
+ }
+
+ if( ARCHIVE_OK == s32Result )
+ {
+ archive_read_disk_set_standard_lookup(psDisk);
+ s32Result = archive_read_disk_open(psDisk, compressFrom);
+ if( ARCHIVE_OK != s32Result )
+ {
+ printf("persadmin_compress - archive_read_disk_new ERR %s\n", archive_error_string(psDisk));
+ }
+ }
+
+ memset(pchParentPath, 0, sizeof(pchParentPath));
+ snprintf(pchParentPath, sizeof(pchParentPath), compressFrom);
+ pchStrPos = strrchr(pchParentPath, '/');
+ if(NIL != pchStrPos)
+ {
+ *pchStrPos = '\0';
+ }
+ s32ParentPathLength = strlen(pchParentPath);
+
+
+ while( ARCHIVE_OK == s32Result )
+ {
+ psEntry = archive_entry_new();
+ s32Result = archive_read_next_header2(psDisk, psEntry);
+
+ switch( s32Result )
+ {
+ case ARCHIVE_EOF:
+ {
+ /* nothing else to do; */
+ break;
+ }
+ case ARCHIVE_OK:
+ {
+ str_t pstrTemp[PATH_ABS_MAX_SIZE];
+ pstr_t p = (pstr_t)archive_entry_pathname(psEntry);
+ if(NIL != p)
+ {
+ /* remove parent section and save relative pathnames */
+ memset(pstrTemp, 0, sizeof(pstrTemp));
+ snprintf(pstrTemp, sizeof(pstrTemp), "%s", p + (s32ParentPathLength + 1));
+ archive_entry_copy_pathname(psEntry, pstrTemp);
+ }
+
+ archive_read_disk_descend(psDisk);
+ s32Result = archive_write_header(psArchive, psEntry);
+ if( ARCHIVE_OK > s32Result)
+ {
+ printf("persadmin_compress - archive_write_header ERR %s\n", archive_error_string(psArchive));
+ }
+ if( ARCHIVE_FATAL == s32Result )
+ {
+ /* exit; */
+ printf("persadmin_compress - archive_write_header ERR FATAL\n");
+ }
+ if( ARCHIVE_FAILED < s32Result )
+ {
+#if 0
+ /* Ideally, we would be able to use
+ * the same code to copy a body from
+ * an archive_read_disk to an
+ * archive_write that we use for
+ * copying data from an archive_read
+ * to an archive_write_disk.
+ * Unfortunately, this doesn't quite
+ * work yet. */
+ persadmin_copy_data(psDisk, psArchive);
+#else
+
+ /* For now, we use a simpler loop to copy data
+ * into the target archive. */
+ fd = open(archive_entry_sourcepath(psEntry), O_RDONLY);
+ s32Length = read(fd, buffer, READ_BUFFER_LENGTH);
+ while( s32Length > 0 )
+ {
+ archive_write_data(psArchive, buffer, s32Length);
+ s32Length = read(fd, buffer, READ_BUFFER_LENGTH);
+ }
+ close(fd);
+#endif
+ }
+
+ break;
+ }
+ default:
+ {
+ printf("persadmin_compress - archive_read_next_header2 ERR %s\n", archive_error_string(psDisk));
+ /* exit; */
+ break;
+ }
+ }
+
+ if( NIL != psEntry )
+ {
+ archive_entry_free(psEntry);
+ }
+ }
+
+ /* perform cleaning operations; */
+ if( NIL != psDisk )
+ {
+ archive_read_close(psDisk);
+ archive_read_free(psDisk);
+ }
+
+ if( NIL != psArchive )
+ {
+ archive_write_close(psArchive);
+ archive_write_free(psArchive);
+ }
+
+ /* overwrite result; */
+ s32Result = (s32Result == ARCHIVE_EOF) ? ARCHIVE_OK : s32Result;
+ /* return result; */
+ return s32Result;
+
+} /* persadmin_compress() */
+
+/**
+ * @brief Restore files from an archive.
+ * @usage persadmin_uncompress("/path/from/where/to/extract/archive_name.tgz", "/path/where/to/extract/") - extract to specified folder
+ * @usage persadmin_uncompress("/path/from/where/to/extract/archive_name.tgz", "") - extract to local folder
+ * @return 0 for success, negative value otherwise.
+ */
+sint_t persadmin_uncompress(pstr_t extractFrom, pstr_t extractTo)
+{
+ struct archive *psArchive = NIL;
+ struct archive *psExtract = NIL;
+ struct archive_entry *psEntry = NIL;
+ sint_t s32Result = ARCHIVE_OK;
+ sint_t s32Flags = ARCHIVE_EXTRACT_TIME;
+
+ /* select which attributes to restore; */
+ s32Flags |= ARCHIVE_EXTRACT_PERM;
+ s32Flags |= ARCHIVE_EXTRACT_ACL;
+ s32Flags |= ARCHIVE_EXTRACT_FFLAGS;
+
+ if( (NIL == extractFrom) ||
+ (NIL == extractTo) )
+ {
+ s32Result = ARCHIVE_FAILED;
+ printf("persadmin_uncompress - invalid parameters\n");
+ }
+
+ if( ARCHIVE_OK == s32Result )
+ {
+ psArchive = archive_read_new();
+ if( NIL == psArchive )
+ {
+ s32Result = ARCHIVE_FAILED;
+ printf("persadmin_uncompress - archive_read_new ERR\n");
+ }
+ }
+
+ if( ARCHIVE_OK == s32Result )
+ {
+ archive_read_support_format_all(psArchive);
+ archive_read_support_compression_all(psArchive);
+ psExtract = archive_write_disk_new();
+ s32Result = ((NIL == psExtract) ? ARCHIVE_FAILED : s32Result);
+ archive_write_disk_set_options(psExtract, s32Flags);
+ archive_write_disk_set_standard_lookup(psExtract);
+ }
+
+ if( ARCHIVE_OK == s32Result )
+ {
+ s32Result = archive_read_open_filename(psArchive, extractFrom, 10240);
+ /* exit if s32Result != ARCHIVE_OK; */
+ }
+
+ while( ARCHIVE_OK == s32Result )
+ {
+ s32Result = archive_read_next_header(psArchive, &psEntry);
+ switch( s32Result )
+ {
+ case ARCHIVE_EOF:
+ {
+ /* nothing else to do; */
+ break;
+ }
+ case ARCHIVE_OK:
+ {
+ /* modify entry here to extract to the needed location; */
+ str_t pstrTemp[PATH_ABS_MAX_SIZE];
+ memset(pstrTemp, 0, sizeof(pstrTemp));
+ snprintf(pstrTemp, sizeof(pstrTemp), "%s%s", extractTo, archive_entry_pathname(psEntry));
+ printf("persadmin_uncompress - archive_entry_pathname %s\n", pstrTemp);
+ archive_entry_copy_pathname(psEntry, pstrTemp);
+
+ s32Result = archive_write_header(psExtract, psEntry);
+ if( ARCHIVE_OK == s32Result )
+ {
+ if( archive_entry_size(psEntry) > 0 )
+ {
+ s32Result = persadmin_copy_data(psArchive, psExtract);
+ if( ARCHIVE_OK != s32Result )
+ {
+ printf("persadmin_uncompress - copy_data ERR %s\n", archive_error_string(psExtract));
+ }
+ /* if( ARCHIVE_WARN > s32Result ) exit; */
+ }
+
+ if( ARCHIVE_OK == s32Result )
+ {
+ s32Result = archive_write_finish_entry(psExtract);
+ if( ARCHIVE_OK != s32Result )
+ {
+ printf("persadmin_uncompress - archive_write_finish_entry ERR %s\n", archive_error_string(psExtract));
+ }
+ /* if( ARCHIVE_WARN > s32Result ) exit; */
+ }
+ }
+ else
+ {
+ printf("persadmin_uncompress - archive_write_header ERR %s\n", archive_error_string(psExtract));
+ }
+
+ break;
+ }
+ default:
+ {
+ printf("persadmin_uncompress - archive_read_next_header ERR %d\n", s32Result);
+ break;
+ }
+ }
+ }
+
+ /* perform cleaning operations; */
+ if( NIL != psArchive )
+ {
+ archive_read_close(psArchive);
+ archive_read_free(psArchive);
+ }
+ if( NIL != psExtract )
+ {
+ archive_write_close(psExtract);
+ archive_write_free(psExtract);
+ }
+
+ /* overwrite result; */
+ s32Result = (s32Result == ARCHIVE_EOF) ? ARCHIVE_OK : s32Result;
+
+ /* return result; */
+ return s32Result;
+
+} /* persadmin_uncompress() */
+
+
+static sint_t persadmin_copy_data(struct archive *ar, struct archive *aw)
+{
+ sint_t s32Result = ARCHIVE_OK;
+ sint_t s32Size = 0;
+ uint8_t buffer[COPY_BUFFER_LENGTH];
+
+ while( ARCHIVE_OK == s32Result )
+ {
+ s32Size = archive_read_data(ar, buffer, COPY_BUFFER_LENGTH);
+ if( 0 > s32Size )
+ {
+ printf("persadmin_copy_data - archive_read_data ERR\n");
+ s32Result = ARCHIVE_FAILED;
+ }
+ else
+ {
+ if( 0 < s32Size )
+ {
+ s32Size = archive_write_data(aw, buffer, COPY_BUFFER_LENGTH);
+ if( 0 > s32Size )
+ {
+ printf("persadmin_copy_data - archive_write_data ERR\n");
+ s32Result = ARCHIVE_FAILED;
+ }
+ }
+ else
+ {
+ /* nothing to copy; */
+ break;
+ }
+ }
+ }
+
+ /* return result; */
+ return s32Result;
+
+} /* persadmin_copy_data() */