From: Antoni Adaszkiewicz Date: Thu, 1 Sep 2022 11:28:55 +0000 (+0200) Subject: Rename delta-ua directory to upgrade-apply-deltafs and delta.ua binary to upgrade... X-Git-Tag: accepted/tizen/unified/20221220.041635~16 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=60d44b759c9f84e63de7a8e80aa63389c5a877d0;p=platform%2Fcore%2Fsystem%2Fupgrade.git Rename delta-ua directory to upgrade-apply-deltafs and delta.ua binary to upgrade-apply-deltafs Change-Id: I0f7ad405d7a2cbc055fbd1649597c2f46fc52e9c --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 439f010..310f4c5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,7 +43,7 @@ SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed -pie") ADD_SUBDIRECTORY(src/dmverity) ADD_SUBDIRECTORY(src/img-verifier) ADD_SUBDIRECTORY(src/upgrade-apply) -ADD_SUBDIRECTORY(src/delta-ua) +ADD_SUBDIRECTORY(src/upgrade-apply-deltafs) ADD_SUBDIRECTORY(src/blkid-print) ADD_SUBDIRECTORY(data) ADD_SUBDIRECTORY(scripts/rw-upgrade) diff --git a/data/40-upgrade.list.in b/data/40-upgrade.list.in index ad15233..f927f86 100644 --- a/data/40-upgrade.list.in +++ b/data/40-upgrade.list.in @@ -1,7 +1,6 @@ # ---- Target contents ----------------------------------------------------- # WITHLIBS=" ${CMAKE_INSTALL_LIBDIR}/libcrypto.so.1.1 -${CMAKE_INSTALL_LIBDIR}/libtota.so.1.0.0 /usr/bin/verity_handler /usr/sbin/img-verifier /bin/sed diff --git a/packaging/upgrade.spec b/packaging/upgrade.spec index cf88573..b048365 100644 --- a/packaging/upgrade.spec +++ b/packaging/upgrade.spec @@ -136,7 +136,7 @@ fi %{upgrade_support_dir}/upgrade-common.inc %{_bindir}/upgrade-apply %{_bindir}/verity_handler -%{_bindir}/delta.ua +%{_bindir}/upgrade-apply-deltafs %{_bindir}/blkid-print # Image verifier %{_sbindir}/img-verifier diff --git a/src/delta-ua/CMakeLists.txt b/src/delta-ua/CMakeLists.txt deleted file mode 100644 index 9b5c61f..0000000 --- a/src/delta-ua/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -ADD_DEFINITIONS("-DFEATURE_SUPPORT_CAPABILITY") -ADD_DEFINITIONS("-D_FILE_OFFSET_BITS=64") - -SET(SRCS - fota_cfg.c - fota_util.c - ua.c - engine/SS_Common.c - ../upgrade-apply/sha1/sha1.c - engine/SS_UPI.c - engine/SS_FSUpdate.c - engine/fota_tar.c - engine/SS_ApplyPatch.c - engine/SS_PatchDelta.c - engine/fota_log.c - engine/fota_tar.c - engine/ss_bspatch_common.c -) - -INCLUDE_DIRECTORIES(../upgrade-apply/sha1) - -INCLUDE(FindPkgConfig) -pkg_check_modules(${PROJECT_NAME}_pkgs REQUIRED liblzma-tool libbrotlienc hal-api-device zlib) - -FOREACH(flag ${${PROJECT_NAME}_pkgs_CFLAGS}) - SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") -ENDFOREACH(flag) - -SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -I./include") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") - -SET(EXECNAME "delta.ua") -SET(BINDIR "/usr/bin") -ADD_EXECUTABLE(${EXECNAME} ${SRCS}) -TARGET_LINK_LIBRARIES(${EXECNAME} ${${PROJECT_NAME}_pkgs_LDFLAGS} "-g" "-pthread") -INSTALL(TARGETS ${EXECNAME} DESTINATION ${BINDIR}) diff --git a/src/delta-ua/engine/SS_ApplyPatch.c b/src/delta-ua/engine/SS_ApplyPatch.c deleted file mode 100755 index bc9e86b..0000000 --- a/src/delta-ua/engine/SS_ApplyPatch.c +++ /dev/null @@ -1,115 +0,0 @@ -/*- - * Copyright 2003-2005 Colin Percival - * Copyright 2012 Matthew Endsley - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * Modifications are made in reimplementing suffix sort array generation - * and how the data is read and written to.Iterative part replaced the - * recursive implementation to avoid buffer overflow problems - */ -#include -#include -#include "SS_PatchDelta.h" -#include "fota_common.h" -#include "sha1.h" -#include "SS_Engine_Errors.h" -#include "SS_FSUpdate.h" - -#include "ss_bspatch_common.h" -#include -#include <7zFile.h> -#include <7zVersion.h> -#include -#include - - -int SS_ApplyBsdiff(char *oldfile, char *newfile, char *patch, SinkFn sink, void *token, SHA1_CTX * ctx1) -{ - UInt64 unpackSize = 0; - CFileSeqInStream inStream; - ISeqOutStream outStream; - unsigned char *buf_res = NULL; - unsigned char *new_data = NULL; - char buf[256]; - ssize_t new_size = 0; - int result = E_SS_FAILURE; - - FileSeqInStream_CreateVTable(&inStream); - File_Construct(&inStream.file); - FileOutStream_CreateVTable((CFileOutStream *) & outStream); - - if (InFile_Open(&inStream.file, patch) != 0) - return E_SS_FAILURE; - - UInt64 i; - CLzmaDec state; - unsigned char header[LZMA_PROPS_SIZE + 8]; - - RINOK(SeqInStream_Read(&inStream.s, header, sizeof(header))); - - unpackSize = 0; - for (i = 0; i < 8; i++) - unpackSize += (UInt64) header[LZMA_PROPS_SIZE + i] << (i * 8); - - LzmaDec_Construct(&state); - RINOK(LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc)); - - //decompress the patch file into buf_res - buf_res = (unsigned char *)SS_Malloc(unpackSize); - if (!buf_res) { - LOGE("Bad memory allocation\n"); - goto Cleanup; - } - result = Decode2(&state, &outStream, &inStream.s, &unpackSize, buf_res); - - LzmaDec_Free(&state, &g_Alloc); - File_Close(&inStream.file); - - if (result != S_SS_SUCCESS) { - LOGE("Error decompression failed with code : [%d]\n", result); - goto Cleanup; - } - //apply patch using buffer decoded by Decode2 - result = apply_patch(oldfile, buf_res, &new_data, &new_size); - if (result != S_SS_SUCCESS) - goto Cleanup; - - result = (sink(new_data, new_size, token) < new_size) ? E_SS_FAILURE : S_SS_SUCCESS; - if (result != S_SS_SUCCESS) { - strerror_r(errno, buf, sizeof(buf)); - LOGE("short write of output: %d (%s)\n", errno, buf); - goto Cleanup; - } - - if (ctx1) - SHA1Update(ctx1, new_data, new_size); -Cleanup: - if (new_data) - SS_Free(new_data); - if (buf_res) - SS_Free(buf_res); - File_Close(&inStream.file);//wgid: 27007 - return result; - -} diff --git a/src/delta-ua/engine/SS_Common.c b/src/delta-ua/engine/SS_Common.c deleted file mode 100755 index fe4c74d..0000000 --- a/src/delta-ua/engine/SS_Common.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * delta-ua - * - * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "SS_Engine_Errors.h" -#include "SS_Common.h" - -#include "ua_types.h" -#include "fota_tar.h" -#include "fota_common.h" -#include "sha1.h" - -void hex_digest(char * sha1, char *buffer, int size) -{ - for (int i = 0; i < size; i++) { - snprintf(&buffer[i * 2], (size * 2) - (i * 2) + 1, "%02x", sha1[i]); - } -} diff --git a/src/delta-ua/engine/SS_Common.h b/src/delta-ua/engine/SS_Common.h deleted file mode 100755 index 8a2caf1..0000000 --- a/src/delta-ua/engine/SS_Common.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * delta-ua - * - * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include "SS_FSUpdate.h" -#include "SS_Engine_Errors.h" -typedef enum { - FT_REGULAR_FILE, - FT_SYMBOLIC_LINK, - FT_FOLDER, - FT_MISSING -} enumFileType; - -#include "ua_types.h" - -#define MAX_PATH 256 - -#define SIZE_4GB (0Xffffffff) - -void SS_unicode_to_char(const char *src, char *dest, int size); - -void hex_digest(char * sha1, char *buffer, int size); diff --git a/src/delta-ua/engine/SS_Engine_Errors.h b/src/delta-ua/engine/SS_Engine_Errors.h deleted file mode 100755 index 2fa68e9..0000000 --- a/src/delta-ua/engine/SS_Engine_Errors.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * delta-ua - * - * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - SS_Engine Errors - - 0xAxx Series define INPUT/UA Errors - - 0xBxx Series define Delta Errors - - 0xCxx Series define System Errors - - 0xDxx Series define Engine Errors - - 0xExx Series define any Other Errors - -*/ - -#ifndef __SS_Engine_ERRORS__ -#define __SS_Engine_ERRORS__ - -#define S_SS_SUCCESS (0) /*! Success Code */ -#define E_SS_FAILURE (1) /*! Failure Code */ - -/* INPUT Processing errors */ - -/* invocation errors */ -#define E_SS_BAD_PARAMS (0xA00) /**< error in a run parameter */ -#define E_SS_FSINVALIDNODEPARAMS (0xA01) /* Failed to Parse the Params to verify NODE */ -#define E_SS_FSBADNODES (0xA02) /* Failed to verify NODE for FS */ -#define E_SS_FSBADDELTA (0xA03) /* Delta File does NOT contain required information on FS */ -#define E_SS_FSBADATTRIBUTES (0xA04) /* Failed to parse attribute data */ -#define E_SS_FSFAILEDTOOPENPATCHINFO (0xA05) /*Failed to open patch list file having details of PATCH info */ -#define E_SS_FSFAILEDTOPARSEDELTACNT (0xA06) /* Failed to parse the PATCH count information */ -#define E_SS_FSFAILEDTOPARSEDELTAINFO (0xA07) /* Failed to parse the Delta patch information */ - -/*Delta Errors*/ -#define E_SS_FSSHA_MISMATCH (0xB00) /*Could NOT produce expected Target SHA for file */ - -/* Resources errors */ -#define E_SS_MALLOC_ERROR (0xC00) /**< memory allocation failure */ - -/* Image update Error codes */ -#define E_SS_WRITE_ERROR (0xC01) /**< flash writing failure */ -#define E_SS_READ_ERROR (0xC02) /**< flash reading failure */ - -/*File System Error codes */ -#define E_SS_OPENFILE_ONLYR (0xC03) /**< file does not exist */ -#define E_SS_OPENFILE_WRITE (0xC04) /**< RO or no access rights */ -#define E_SS_DELETEFILE (0xC05) /**< no access rights */ -#define E_SS_READFILE_SIZE (0xC06) /**< cannot read specified size*/ -#define E_SS_CLOSEFILE_ERROR (0xC07) /**< cannot close file handle */ -#define E_SS_CANNOT_CREATE_DIRECTORY (0xC08) /**< Failed creating directory */ -#define E_SS_FSMEMORYERROR (0xC09) /* Failed to allocate Memory */ -#define E_SS_FILENAMELENERROR (0xC10) /* Failed to serve filename length */ - -/*Engine errors */ -#define E_SS_FSFAILEDTOBACKUPPATCHINFO (0xD00) /* Failed to create backup file to write Delta patch info data */ -#define E_SS_FSUPDATEFAILED (0xD01) /*FS Failed during UPGRADE */ -#define E_SS_FSSRCBACKUPFAILED (0xD02) /*Failed to backup FS */ -#define E_SS_FSSRCCURRUPTED (0xD03) /*Could NOT update FS as SRC seems to be corrupted */ -#define E_SS_PATCHFILE_DEL_ERROR (0xD04) /*Failed to Clear/Del Patched SRC file */ - -#endif diff --git a/src/delta-ua/engine/SS_FSUpdate.c b/src/delta-ua/engine/SS_FSUpdate.c deleted file mode 100755 index d8d031f..0000000 --- a/src/delta-ua/engine/SS_FSUpdate.c +++ /dev/null @@ -1,1101 +0,0 @@ -/* - * delta-ua - * - * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define _XOPEN_SOURCE 600 -#define _POSIX_C_SOURCE 200809L -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "SS_Common.h" - -#include "fota_common.h" -#include "ua_types.h" - -static int feature_support_capability; - -enum smack_label_type { - SMACK_LABEL_ACCESS, - SMACK_LABEL_EXEC, - SMACK_LABEL_MMAP, - SMACK_LABEL_TRANSMUTE, - SMACK_LABEL_IPIN, - SMACK_LABEL_IPOUT, -}; - -#define SMACK_LABEL_LEN 255 - -/************************************************************ - * common functions - ************************************************************/ -void SS_create_dir(char *pathname, int mode) -{ - char *p; - int r; - - /* Strip trailing '/' */ - if (pathname[strlen(pathname) - 1] == '/') - pathname[strlen(pathname) - 1] = '\0'; - - /* Try creating the directory. */ - r = mkdir(pathname, mode); - - if (r != 0) { - /* On failure, try creating parent directory. */ - p = strrchr(pathname, '/'); - if (p != NULL) { - *p = '\0'; - SS_create_dir(pathname, 0755); - *p = '/'; - r = mkdir(pathname, mode); - } - } - if (r != 0) { - if (r != EEXIST && r != -1) - LOG("Could not create directory [%s] Error[%d]\n", pathname, r); - } -} - - -void SS_unicode_to_char(const char *src, char *dest, int size) -{ - if (src == NULL) - return; - - strncpy(dest, src, size); -} - -void SS_char_to_unicode(const char *src, char *dest, int size) -{ - if (src == NULL) - return; - - strncpy(dest, src, size); -} - -long SS_recursive_folder_creater(const char *path, const mode_t mode) { - - if (path == 0) { - LOGL(LOG_SSENGINE, "Bad path param value \n"); - return -E_SS_BAD_PARAMS; - } - - if (path[0] == '\0') { - LOGL(LOG_SSENGINE, "Path empty \n"); - return -E_SS_FILENAMELENERROR; - } - - char input_path[MAX_PATH] = {'\0'}; - char temppath[MAX_PATH] = {'\0'}; - - strncpy(input_path, path, MAX_PATH - 1); - - if (input_path[0] == '/') { - temppath[0] = '/'; - } - - char *path_token; - char *path_pos = input_path; - - int temppath_current_len = (temppath[0] == '/'); - - while((path_token = strtok_r(path_pos, "/", &path_pos))) { - - int path_token_len = strnlen(path_token, MAX_PATH-temppath_current_len); - strncat(temppath, path_token, path_token_len); - temppath_current_len += path_token_len; - - int mkd_res = mkdir(temppath, mode); - - if(mkd_res != 0 && errno != EEXIST) { - LOGL(LOG_SSENGINE,"cannot create dir %s\n system error: %d error: %m\n", temppath, errno); - return -E_SS_CANNOT_CREATE_DIRECTORY; - } - - if(temppath_current_len < (MAX_PATH - 1)) { - strncat(temppath, "/", 1); - } - } - return 0; -} - -long -SS_CopyFile(const char *strFromPath, const char *strToPath) -{ - int fd1, fd2; - int readCount = 0, writeCount = 0; - char buf[1 << 15]; // copy 32KB wise - int ret = 0; - - char path1[MAX_PATH] = { '\0' }; - char path2[MAX_PATH] = { '\0' }; - - if (!strFromPath || !strToPath) { - LOGE("NULL file name find. Abort.\n"); - return -1; - } - - SS_unicode_to_char((const char *)strFromPath, (char *)path1, MAX_PATH - 1); - SS_unicode_to_char((const char *)strToPath, (char *)path2, MAX_PATH - 1); - - //LOGL(LOG_SSENGINE, "%s -> %s \n", path1, path2); - - fd1 = open(path1, O_RDONLY); - if (fd1 < 0) - return E_SS_OPENFILE_ONLYR; - ret = SS_OpenFile(strToPath, ONLY_W, (long *)&fd2); - if (ret != S_SS_SUCCESS || fd2 < 0) { - close(fd1); - LOGE(" SS_OpenFile fail leaved path1:%s | path2:%s\n", path1, path1); - return E_SS_WRITE_ERROR; - } - - while ((readCount = read(fd1, buf, sizeof(buf))) > 0) { - writeCount = write(fd2, buf, readCount); - if (writeCount != readCount) { - LOGE(" read %d, but write %d, abort.\n", readCount, - writeCount); - ret = E_SS_WRITE_ERROR; - break; - } - } - - close(fd1); - fsync(fd2); - close(fd2); - //LOGL(LOG_INFO, " leaved path1:%s | path2:%s\n", path1, path2); - - return ret; -} - -long SS_DeleteFile(const char *strPath) -{ - char path[MAX_PATH] = { '\0' }; - int ret = 0; - - SS_unicode_to_char((const char *)strPath, (char *)path, MAX_PATH - 1); - //LOGL(LOG_SSENGINE, "%s\n", path); - ret = unlink(path); - if (ret == 0) - return S_SS_SUCCESS; - - LOGE("failed to delete path [%s] unlink value: %d, errno: %d\n", path, ret, errno); - if (ret < 0 && errno == ENOENT) - return S_SS_SUCCESS; - return E_SS_DELETEFILE; -} - -int SS_unlink_cbf(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf) -{ - int rv = remove(fpath);//returns zero on success and -1 on failure - - if (rv) { - perror(fpath); - LOGE("path : %s, remove value: %d, errno: %d\n", fpath, rv, errno); - } - return rv; -} -long SS_DeleteFolder(const char *strPath) -{ - //runs till either tree is exhausted or when unlink_cbf returns non zero value. - return ((long)nftw(strPath, SS_unlink_cbf, 64, FTW_DEPTH | FTW_PHYS) == 0) ? S_SS_SUCCESS : E_SS_FAILURE; -} - -long SS_CreateFolder(const char *strPath) -{ - mode_t mode = 0; - int ret = 0; - char path[MAX_PATH] = { '\0' }; - - SS_unicode_to_char((const char *)strPath, (char *)path, MAX_PATH - 1); - mode = S_IRUSR /*Read by owner */ | - S_IWUSR /*Write by owner */ | - S_IXUSR /*Execute by owner */ | - S_IRGRP /*Read by group */ | - S_IWGRP /*Write by group */ | - S_IXGRP /*Execute by group */ | - S_IROTH /*Read by others */ | - S_IWOTH /*Write by others */ | - S_IXOTH /*Execute by others */ ; - - LOGL(LOG_SSENGINE, "%s, mode:0x%x\n", path, mode); - - ret = mkdir(path, mode); - - if (ret == 0 || ((ret == -1) && (errno == EEXIST))) { - return S_SS_SUCCESS; - } else if ((ret == -1) && (errno == ENOENT)) { //maybe multi directory problem - //do//Recursive Function - //{ - ret = SS_recursive_folder_creater(path, mode); - if (ret == S_SS_SUCCESS) { - ret = mkdir(path, mode); //After creating all the depth Directories we try to create the Original one again. - if (ret == 0) - return S_SS_SUCCESS; - else - return E_SS_FAILURE; - } else { - return E_SS_FAILURE; - } - //} - //while(ret != 0); - - } else { - return E_SS_FAILURE; - } -} - -mode_t SS_get_mode(E_RW_TYPE wFlag) -{ - switch (wFlag) { - case ONLY_R: - //LOGL(LOG_SSENGINE, " RDONLY \n"); - return O_RDONLY; - case ONLY_W: - //LOGL(LOG_SSENGINE, " WRONLY \n"); - return O_WRONLY | O_CREAT; - case BOTH_RW: - //LOGL(LOG_SSENGINE, " RDWR \n"); - return O_RDWR | O_CREAT; - default: - //LOGL(LOG_SSENGINE, " Unknown \n"); - return 0; - } -} - -long -SS_OpenFile(const char *strPath, E_RW_TYPE wFlag, long *pwHandle) -{ - mode_t mode; - char path[MAX_PATH] = { '\0' }; - - SS_unicode_to_char((const char *)strPath, (char *)path, MAX_PATH - 1); - - mode = SS_get_mode(wFlag); - //LOGL(LOG_SSENGINE, "Path:%s wFlag:%d Mode:%d\n", path, wFlag, mode); - - if (mode & O_CREAT) { - //LOGL(LOG_SSENGINE, " open() S_IRWXU\n"); - *pwHandle = open(path, mode, S_IRWXU); - } else { - //LOGL(LOG_SSENGINE, " open() %d\n", mode); - *pwHandle = open(path, mode); - } - if (*pwHandle == -1) { - *pwHandle = 0; - LOGE(" First open() with error %d\n", errno); - if (wFlag == ONLY_R) { - LOGE(" error in ONLY_R return E_SS_OPENFILE_ONLYR\n"); - return E_SS_OPENFILE_ONLYR; - } - - //if we need to open the file for write or read/write then we need to create the folder (in case it does not exist) - if ((wFlag != ONLY_R) && (errno == ENOENT)) { - char dir[MAX_PATH] = { '\0' }; - char dirShort[MAX_PATH] = { '\0' }; - int i = 0; - //copy the full file path to directory path variable - while (path[i] != '\0') { - dir[i] = path[i]; - i++; - } - LOGL(LOG_SSENGINE, " copy dir[]=%s\n", dir); - //search for the last '/' char - while (dir[i--] != '/') ; - dir[i + 1] = '\0'; - - SS_char_to_unicode((const char *)dir, - (char *)dirShort, MAX_PATH - 1); - - if (SS_CreateFolder(dirShort)) { - LOGE(" Fail create folder, Leave SS_OpenFile\n"); - return E_SS_OPENFILE_WRITE; - } - - *pwHandle = open(path, mode); - if (*pwHandle == -1) { - *pwHandle = 0; - LOGE(" After successful creating folder, fail open() with error %d\n", errno); - return E_SS_OPENFILE_WRITE; - } - } else { - LOG(" fail open() *pwHandle:%ld\n", *pwHandle); - return E_SS_OPENFILE_WRITE; - } - } - - //LOGL(LOG_SSENGINE, " Successful open() *pwHandle:%ld\n", *pwHandle); - - return S_SS_SUCCESS; -} - -long SS_CloseFile(long wHandle) -{ - int ret = 0; - LOGL(LOG_SSENGINE, "wHandle = %ld\n", wHandle); - - if (wHandle) { - ret = fsync(wHandle); - if (ret < 0) { - LOG(" fsync Failed with return value: %d\n", ret); - return E_SS_WRITE_ERROR; - } - LOG(" fsync after write: %d\n", ret); - ret = close(wHandle); - } - - if (ret == 0) - return S_SS_SUCCESS; - - return E_SS_CLOSEFILE_ERROR; -} - -long -SS_WriteFile(long wHandle, - SS_UINT32 dwPosition, - unsigned char *pbBuffer, SS_UINT32 dwSize) -{ - int ret = 0; - - LOGL(LOG_SSENGINE, "Handle:%ld , Pos:%u , Size: %u\n", wHandle, - dwPosition, dwSize); - - ret = lseek(wHandle, dwPosition, SEEK_SET); - if (ret < 0) { - LOGE(" lseek failed with return value: %d\n", ret); - LOGL(LOG_SSENGINE, "lseek errno=%d\n", errno); - return E_SS_WRITE_ERROR; - } - - ret = write(wHandle, pbBuffer, dwSize); - if (ret < 0 || ret != dwSize) { - LOGE(" Failed with return value: %d\n", ret); - LOGL(LOG_SSENGINE, "ret=%d, dwSize=%u write errno=%d\n", - ret, (unsigned int)dwSize, errno); - return E_SS_WRITE_ERROR; - } - LOGL(LOG_SSENGINE, "leave Bytes Write: %d\n", ret); - - return S_SS_SUCCESS; -} - -long SS_MoveFile(const char *strFromPath, const char *strToPath) -{ - int ret = 0; - struct stat sbuf; - char path1[MAX_PATH] = { '\0' }; - char path2[MAX_PATH] = { '\0' }; - - if (!strFromPath || !strToPath) - return -1; //should never happen - - SS_unicode_to_char(strFromPath, (char *)path1, MAX_PATH - 1); - SS_unicode_to_char(strToPath, (char *)path2, MAX_PATH - 1); - - LOGL(LOG_INFO, "entered path1:%s | path2:%s\n", path1, path2); - ret = stat(path1, &sbuf); - if (ret < 0) { - LOGE("stat failed with return value: %d errno: %d\n", ret, errno); - return E_SS_FAILURE; - } - ret = rename(path1, path2); - if (ret < 0) { - LOGL(LOG_INFO, "rename fail with code [%d], try to create dir if errno is 2\n", errno); - if (errno == 2) { - char * file_name = strrchr(path2, '/'); - *file_name = '\0'; - SS_create_dir(path2, 0755); - *file_name = '/'; - ret = rename(path1, path2); - if (ret < 0) { - LOGE("Move failed, error code [%d]\n", errno); - return E_SS_WRITE_ERROR; - } - } else if (errno == 18) { //EXDEV 18 /* Cross-device link */ - //Moving file across partitions if mount point is different (Extremely rare) - ret = (int)SS_CopyFile(path1, path2); - if (ret != S_SS_SUCCESS) { - LOGE("failed to copy file [%s] result [%d]\n", path1, ret); - return E_SS_WRITE_ERROR; - } - ret = unlink(path1); - if (ret != 0) { - LOGE("failed to unlink [%s] code [%d]\n", path1, errno); - return E_SS_WRITE_ERROR; - } - } else { - LOGE("Move failed, error code [%d]\n", errno); - return E_SS_WRITE_ERROR; - } - } - LOGL(LOG_INFO, "leaved path1:%s | path2:%s\n", path1, path2); - return S_SS_SUCCESS; -} - -long -SS_ReadFile(long wHandle, - SS_UINT32 dwPosition, - unsigned char *pbBuffer, SS_UINT32 dwSize) -{ - int ret = 0; - -#if 0 - LOG(" %s: Handle:%ld , Pos:%u , Size: %u", __func__, wHandle, - dwPosition, dwSize); -#endif - ret = lseek(wHandle, dwPosition, SEEK_SET); - if (ret < 0) { - LOGE("Handle:%ld , Pos:%u , Size: %u\n", wHandle, dwPosition, - dwSize); - LOGE("lseek failed with return value: %d\n", ret); - return E_SS_READ_ERROR; - } - ret = read(wHandle, pbBuffer, dwSize); - if (ret < 0) { - LOGE("Handle:%ld , Pos:%u , Size: %u\n", wHandle, dwPosition, - dwSize); - LOGE("read failed with return value: %d\n", ret); - return E_SS_READ_ERROR; - } - - if (ret != dwSize && ((ret + dwPosition) != (unsigned long)SS_GetFileSize(wHandle))) - return E_SS_READ_ERROR; - - pbBuffer[ret] = '\0'; -#if 0 - LOGL(LOG_DEBUG, "Bytes Read: %d\n", ret); -#endif - return S_SS_SUCCESS; -} - -long SS_GetFileSize(long wHandle) -{ - int ret = 0; - - - ret = lseek(wHandle, 0, SEEK_END); - - if (ret == -1) { - LOGE(" lseek errno: %d\n", errno); - return E_SS_READFILE_SIZE; - } - LOGL(LOG_SSENGINE, "handle=%d Returning Size = %ld(0x%x)\n", - (int)wHandle, (long int)ret, ret); - - return ret; -} - -long SS_Unlink(char *pLinkName) -{ - int ret = 0; - char path[MAX_PATH] = { '\0' }; - //enumFileType fileType = FT_REGULAR_FILE; - - - SS_unicode_to_char((const char *)pLinkName, (char *)path, MAX_PATH - 1); - - ret = unlink(path); - if (ret < 0 && errno != ENOENT) { - LOGE("unlink failed with return value: %d\n", ret); - return E_SS_FAILURE; - } - LOGL(LOG_SSENGINE, "unlink with return value: %d\n", ret); - - return S_SS_SUCCESS; -} - -long -SS_VerifyLinkReference(char *pLinkName, char *pReferenceFileName) -{ - int ret = 0; - char path[MAX_PATH] = { '\0' }; - char linkedpath[MAX_PATH] = { '\0' }; - char refpath[MAX_PATH] = { '\0' }; - - - SS_unicode_to_char((const char *)pLinkName, (char *)path, MAX_PATH - 1); - SS_unicode_to_char((const char *)pReferenceFileName, (char *)refpath, MAX_PATH - 1); - - ret = readlink(path, linkedpath, MAX_PATH); - if (ret < 0) { - LOGE("readlink failed with return value: %d\n", ret); - return E_SS_FAILURE; - } - - if ((memcmp(&linkedpath, &refpath, ret)) != 0) { - LOGE("not same linked path\n"); - return E_SS_FAILURE; - } - LOGL(LOG_SSENGINE, "same linked path\n"); - - return S_SS_SUCCESS; -} - -long -SS_Link(void *pbUserData, char *pLinkName, char *pReferenceFileName) -{ - int ret = 0; - char sympath[MAX_PATH] = { '\0' }; - char refpath[MAX_PATH] = { '\0' }; - //enumFileType fileType = FT_SYMBOLIC_LINK; - struct stat sbuf; - - SS_unicode_to_char((const char *)pLinkName, (char *)sympath, MAX_PATH - 1); - SS_unicode_to_char((const char *)pReferenceFileName, (char *)refpath, MAX_PATH - 1); - - ret = symlink(refpath, sympath); - if (ret != 0) { - LOGE(" symlink failed with return value: %d, errno: %d\n", ret, errno); - - if (errno == EEXIST) { - ret = lstat(sympath, &sbuf); - LOGL(LOG_SSENGINE, "symlink LSTAT with return value: %d\n", ret); - if (ret >= 0) { - if (S_ISREG(sbuf.st_mode)) { - LOGL(LOG_SSENGINE, " stat->st_mode = regular file, To be deleted and create a LINK \n"); - SS_DeleteFile(sympath); - SS_Link(pbUserData, pLinkName, pReferenceFileName); - } - } - if (SS_VerifyLinkReference(pLinkName - , pReferenceFileName) == S_SS_SUCCESS) { - return S_SS_SUCCESS; - } else { - return E_SS_FAILURE; - } - } else if (errno == ENOENT) {//to handle cases where new symlink points to a new symlink yet to be created - return errno; - } else { - return E_SS_FAILURE; - } - } - //LOGL(LOG_SSENGINE, "symlink with return value: %d\n", ret); - - return S_SS_SUCCESS; -} - -long -SS_HardLink(char *hardLinkName, char *referenceName) -{ - int ret = 0; - char hardpath[MAX_PATH] = { '\0' }; - char refpath[MAX_PATH] = { '\0' }; - - SS_unicode_to_char((const char *)hardLinkName, (char *)hardpath, MAX_PATH - 1); - SS_unicode_to_char((const char *)referenceName, (char *)refpath, MAX_PATH - 1); - - ret = link(refpath, hardpath); - if (ret != 0) { - LOGE("Linking failed for hardlink %s with errno: %d\n", hardpath, errno); - return E_SS_FAILURE; - } - return S_SS_SUCCESS; -} - -long SS_GetFileType(char *pLinkName, enumFileType * fileType) -{ - int ret = 0; - char path[MAX_PATH] = { '\0' }; - struct stat sbuf; - - //LOGL(LOG_SSENGINE, "\n"); - SS_unicode_to_char((const char *)pLinkName, (char *)path, MAX_PATH - 1); - - ret = lstat(path, &sbuf); - if (ret < 0) { - ret = stat(path, &sbuf); - if (ret < 0) { - LOGE("stat failed with return value: %d errno: %d\n", - ret, errno); - *fileType = FT_MISSING; - return S_SS_SUCCESS; - } - } - //LOGL(LOG_SSENGINE, " sbuf.st_mode: %d\n", sbuf.st_mode); - //LOGL(LOG_SSENGINE, " S_ISREG(sbuf.st_mode): %d\n", S_ISREG(sbuf.st_mode)); - //LOGL(LOG_SSENGINE, " S_ISLNK(sbuf.st_mode): %d\n", S_ISLNK(sbuf.st_mode)); - - if (S_ISLNK(sbuf.st_mode)) { - //LOGL(LOG_SSENGINE, " stat->st_mode = symbolic link file\n"); - *fileType = FT_SYMBOLIC_LINK; - return S_SS_SUCCESS; - } - - if (S_ISREG(sbuf.st_mode)) { - //LOGL(LOG_SSENGINE, " stat->st_mode = regular file\n"); - *fileType = FT_REGULAR_FILE; - return S_SS_SUCCESS; - } - - if (S_ISDIR(sbuf.st_mode)) { - //LOGL(LOG_SSENGINE, " stat->st_mode = regular file\n"); - *fileType = FT_FOLDER; - return S_SS_SUCCESS; - } - LOGE("failed to lstat, err : %d\n", ret); - return E_SS_FAILURE; -} - -static inline char *SS_get_xattr_name(enum smack_label_type type) -{ - switch (type) { - case SMACK_LABEL_ACCESS: - return "security.SMACK64"; - case SMACK_LABEL_EXEC: - return "security.SMACK64EXEC"; - case SMACK_LABEL_MMAP: - return "security.SMACK64MMAP"; - case SMACK_LABEL_TRANSMUTE: - return "security.SMACK64TRANSMUTE"; - case SMACK_LABEL_IPIN: - return "security.SMACK64IPIN"; - case SMACK_LABEL_IPOUT: - return "security.SMACK64IPOUT"; - default: - /* Should not reach this point */ - return NULL; - } -} - -int SS_smack_lsetlabel(const char *path, const char *label, enum smack_label_type type) -{ - if (path == NULL) { - LOGE("Path is NULL\n"); - return -1; - } - - char *xattr_name = SS_get_xattr_name(type); - if (xattr_name == NULL) { - LOGE("Failed get xattr name\n"); - return -1; - } - - /* Check validity of labels for LABEL_TRANSMUTE */ - if (type == SMACK_LABEL_TRANSMUTE && label != NULL) { - if (!strncmp(label, "0", strlen("0"))) { - label = NULL; - } else if (!strncmp(label, "1", strlen("0"))) { - label = "TRUE"; - } else { - return -1; - } - } - - if (label == NULL || label[0] == '\0') { - return lremovexattr(path, xattr_name); - } else { - int len = strnlen(label, SMACK_LABEL_LEN + 1); - if (len > SMACK_LABEL_LEN) { - return -1; - } - return lsetxattr(path, xattr_name, label, len, 0); - } -} - -/*! - ******************************************************************************* - * Set file attributes.

- * - * The file attributes token (\a ui8pAttribs) is defined at generation time. - * If attributes are not defined explicitly, they are given the following, - * OS-dependent values: - * \li Windows: _foo_ro_ for R/O files, _foo_rw_ for R/W files - * \li Linux: _foo_oooooo:xxxx:yyyy indicating the file mode, uid, and gid - * (uid and gid use capitalized hex digits as required) - * - * \param pbUserData Optional opaque data-structure to pass to IPL - * functions - * \param ui16pFilePath File path - * \param ui32AttribSize Size of \a ui8pAttribs - * \param ui8pAttribs Attributes to set - * - * \return S_SS_SUCCESS on success or < 0 on error - ******************************************************************************* - */ - -long SS_SetFileAttributes(const char *ui16pFilePath, - const SS_UINT32 ui32AttribSize, - const unsigned char *ui8pAttribs) -{ - static char tmpAttribs[512]; - static char tmpSmackAttribs[512]; - char *tp; - char *endstr; - char *saveptr; - char *smack_value, *psmack; - uid_t setUserID = 0; - gid_t setGroupID = 0; - mode_t setFileMode = 0; - const char attrDelim[2] = ":"; - - char setFilePath[MAX_PATH] = { '\0' }; - struct stat sbuf; - int ret = 0; - char *smack_attr_pos = NULL; - int has_cap = 0; - char cap_raw[100]; - int cap_len; - /*ACL */ - int has_acl = 0; - char acl_raw[256]; - int acl_len; - - if (NULL == ui16pFilePath) { - LOGL(LOG_SSENGINE, "ui16pFilePath NULL [error]\n"); - return E_SS_BAD_PARAMS; - } else if (NULL == ui8pAttribs) { - LOGL(LOG_SSENGINE, "ui8pAttribs NULL [error]\n"); - return E_SS_BAD_PARAMS; - } else if (0 == ui32AttribSize) { - LOGL(LOG_SSENGINE, "ui32AttribSize 0\n"); - return S_SS_SUCCESS; - } - - SS_unicode_to_char((const char *)ui16pFilePath, (char *)setFilePath, MAX_PATH - 1); - - ret = lstat(setFilePath, &sbuf); - if (ret < 0) { - ret = stat(setFilePath, &sbuf); - if (ret < 0) { - LOGL(LOG_SSENGINE, " stat failed with return value: %d\n", ret); - return E_SS_FAILURE; - } else { - if (S_ISLNK(sbuf.st_mode)) { - LOGL(LOG_SSENGINE, " stat->st_mode = symbolic link file\n"); -// return S_RB_SUCCESS; // sybolic link should be set mode. - } - if (S_ISREG(sbuf.st_mode)) - LOGL(LOG_SSENGINE, " stat->st_mode = regular file\n"); - if (S_ISDIR(sbuf.st_mode)) - LOGL(LOG_SSENGINE, " stat->st_mode = directory\n"); - } - - LOGL(LOG_SSENGINE, "ui16pFilePath = %s\n", setFilePath); - LOGL(LOG_SSENGINE, "ui32AttribSize = %u\n", ui32AttribSize); - LOGL(LOG_SSENGINE, "ui8pAttribs = %s\n", ui8pAttribs); - - } - memset(tmpAttribs, 0x0, sizeof(tmpAttribs)); - memcpy(tmpAttribs, ui8pAttribs, (size_t) ui32AttribSize-1); - smack_attr_pos = tmpAttribs; - tp = strtok_r(tmpAttribs, attrDelim, &saveptr); - - // Get FileMode - if (tp != NULL) { - smack_attr_pos += strlen(tp); - smack_attr_pos++; - setFileMode = strtol(tp, &endstr, 8); - tp = strtok_r(NULL, attrDelim, &saveptr); - } - // Get UserID - if (tp != NULL) { - smack_attr_pos += strlen(tp); - smack_attr_pos++; - setUserID = (uid_t) strtol(tp, &endstr, 10); - tp = strtok_r(NULL, attrDelim, &saveptr); - } - // Get GroupID - if (tp != NULL) { - smack_attr_pos += strlen(tp); - smack_attr_pos++; - setGroupID = (gid_t) strtol(tp, &endstr, 10); - } - - if (feature_support_capability) { - // Get Capability - has_cap = 0; - if (*smack_attr_pos != '\0') { - char *cap_mark = "capability=0x"; - int cap_mark_len = strlen(cap_mark); - psmack = strstr(smack_attr_pos, cap_mark); - if (psmack) { - int cap_hex_len; - int i; - char ch1, ch2; - int raw1, raw2; - - tp = strstr(psmack, ":"); - smack_attr_pos = tp + 1; - memset(tmpSmackAttribs, 0x0, sizeof(tmpSmackAttribs)); - memcpy(tmpSmackAttribs, psmack+cap_mark_len, - (int)tp - (int)psmack - cap_mark_len); - - // convert hexadecimal into raw data - cap_hex_len = strlen(tmpSmackAttribs); - cap_len = cap_hex_len/2; - memset(cap_raw, 0x00, sizeof(cap_raw)); - for (i = 0; i < cap_len; i++) { - ch1 = tmpSmackAttribs[i*2]; - ch2 = tmpSmackAttribs[i*2+1]; - if ((ch1 >= '0') && (ch1 <= '9')) raw1 = ch1 - '0'; - else if ((ch1 >= 'a') && (ch1 <= 'f')) raw1 = ch1 - 'a' + 10; - else if ((ch1 >= 'A') && (ch1 <= 'F')) raw1 = ch1 - 'A' + 10; - else raw1 = 0; - if ((ch2 >= '0') && (ch2 <= '9')) raw2 = ch2 - '0'; - else if ((ch2 >= 'a') && (ch2 <= 'f')) raw2 = ch2 - 'a' + 10; - else if ((ch2 >= 'A') && (ch2 <= 'F')) raw2 = ch2 - 'A' + 10; - else raw2 = 0; - - cap_raw[i] = raw1*16 + raw2; - } - LOGL(LOG_SSENGINE, "[Cap] %s (cap_len=%d)\n", tmpSmackAttribs, cap_len); - has_cap = 1; - } - - } - // Get ACL - has_acl = 0; - if (*smack_attr_pos != '\0') { - char *acl_mark = "acl_access=0x"; - int acl_mark_len = strlen(acl_mark); - psmack = strstr(smack_attr_pos, acl_mark); - if (psmack) { - int acl_hex_len; - int i; - char ch1, ch2; - int raw1, raw2; - - tp = strstr(psmack, ":"); - smack_attr_pos = tp + 1; - memset(tmpSmackAttribs, 0x0, sizeof(tmpSmackAttribs)); - memcpy(tmpSmackAttribs, psmack+acl_mark_len, - (int)tp - (int)psmack - acl_mark_len); - - // convert hexadecimal into raw data - acl_hex_len = strlen(tmpSmackAttribs); - acl_len = acl_hex_len/2; - memset(acl_raw, 0x00, sizeof(acl_raw)); - for (i = 0; i < acl_len; i++) { - ch1 = tmpSmackAttribs[i*2]; - ch2 = tmpSmackAttribs[i*2+1]; - if ((ch1 >= '0') && (ch1 <= '9')) raw1 = ch1 - '0'; - else if ((ch1 >= 'a') && (ch1 <= 'f')) raw1 = ch1 - 'a' + 10; - else if ((ch1 >= 'A') && (ch1 <= 'F')) raw1 = ch1 - 'A' + 10; - else raw1 = 0; - if ((ch2 >= '0') && (ch2 <= '9')) raw2 = ch2 - '0'; - else if ((ch2 >= 'a') && (ch2 <= 'f')) raw2 = ch2 - 'a' + 10; - else if ((ch2 >= 'A') && (ch2 <= 'F')) raw2 = ch2 - 'A' + 10; - else raw2 = 0; - - acl_raw[i] = raw1*16 + raw2; - } - LOG("[ACL] %s (acl_len=%d)\n", tmpSmackAttribs, acl_len); - has_acl = 1; - } - - } - } - - // Get Smack value -> Set Smack value - if (*smack_attr_pos != '\0') { - SS_smack_lsetlabel(setFilePath, NULL, SMACK_LABEL_ACCESS); - SS_smack_lsetlabel(setFilePath, NULL, SMACK_LABEL_EXEC); - SS_smack_lsetlabel(setFilePath, NULL, SMACK_LABEL_MMAP); - SS_smack_lsetlabel(setFilePath, NULL, SMACK_LABEL_TRANSMUTE); - - psmack = strstr(smack_attr_pos, "access=\""); - if (psmack) { - memset(tmpSmackAttribs, 0x0, sizeof(tmpSmackAttribs)); - memcpy(tmpSmackAttribs, psmack, sizeof(tmpSmackAttribs) - 1); - smack_value = strtok_r(tmpSmackAttribs, "\"", &saveptr); - if (smack_value) { - smack_value = strtok_r(NULL, "\"", &saveptr); - //LOGL(LOG_SSENGINE, "[SMACK_LABEL_ACCESS] smack_value=%s\n", smack_value); - if (smack_value) { - ret = SS_smack_lsetlabel(setFilePath, smack_value, SMACK_LABEL_ACCESS); - if (ret < 0) - LOGL(LOG_SSENGINE, "SS_smack_lsetlabel() failed\n"); - } - } - } - psmack = strstr(smack_attr_pos, "execute=\""); - if (psmack) { - memset(tmpSmackAttribs, 0x0, sizeof(tmpSmackAttribs)); - memcpy(tmpSmackAttribs, psmack, sizeof(tmpSmackAttribs) - 1); - smack_value = strtok_r(tmpSmackAttribs, "\"", &saveptr); - if (smack_value) { - smack_value = strtok_r(NULL, "\"", &saveptr); - //LOGL(LOG_SSENGINE, "[SMACK_LABEL_EXEC] smack_value=%s\n", smack_value); - if (smack_value) { - ret = SS_smack_lsetlabel(setFilePath, smack_value, SMACK_LABEL_EXEC); - if (ret < 0) - LOGL(LOG_SSENGINE, "SS_smack_lsetlabel() failed\n"); - } - } - } - psmack = strstr(smack_attr_pos, "mmap=\""); - if (psmack) { - memset(tmpSmackAttribs, 0x0, sizeof(tmpSmackAttribs)); - memcpy(tmpSmackAttribs, psmack, sizeof(tmpSmackAttribs) - 1); - smack_value = strtok_r(tmpSmackAttribs, "\"", &saveptr); - if (smack_value) { - smack_value = strtok_r(NULL, "\"", &saveptr); - //LOGL(LOG_SSENGINE, "[SMACK_LABEL_MMAP] smack_value=%s\n", smack_value); - if (smack_value) { - ret = SS_smack_lsetlabel(setFilePath, smack_value, SMACK_LABEL_MMAP); - if (ret < 0) - LOGL(LOG_SSENGINE, "SS_smack_lsetlabel() failed\n"); - } - } - } - psmack = strstr(smack_attr_pos, "transmute=\""); - if (psmack) { - memset(tmpSmackAttribs, 0x0, sizeof(tmpSmackAttribs)); - memcpy(tmpSmackAttribs, psmack, sizeof(tmpSmackAttribs) - 1); - smack_value = strtok_r(tmpSmackAttribs, "\"", &saveptr); - if (smack_value) { - smack_value = strtok_r(NULL, "\"", &saveptr); - //LOGL(LOG_SSENGINE, "[SMACK_LABEL_TRANSMUTE] smack_value=%s\n", smack_value); - if (smack_value) { - if (strcasecmp(smack_value, "TRUE") == 0) - ret = SS_smack_lsetlabel(setFilePath, "1", SMACK_LABEL_TRANSMUTE); - else - ret = SS_smack_lsetlabel(setFilePath, "0", SMACK_LABEL_TRANSMUTE); - if (ret < 0) - LOGL(LOG_SSENGINE, "SS_smack_lsetlabel() failed\n"); - } - } - } - } - - // Set UserID,GroupID - if (lchown(setFilePath, setUserID, setGroupID)) { - // debug start - LOGL(LOG_SSENGINE, "%s chown error\n", __func__); - LOGL(LOG_SSENGINE, "%s setUserID = %d\n", __func__, setUserID); - LOGL(LOG_SSENGINE, "%s setGroupID = %d\n", __func__, setGroupID); - LOGL(LOG_SSENGINE, "%s chown errno = %d\n", __func__, errno); - // debug end - - return E_SS_FAILURE; - } - - // mode is always 0777 at symlink file. It doesn't need to call chmod(). - if (S_ISLNK(sbuf.st_mode)) { - LOGL(LOG_SSENGINE, " stat->st_mode = symbolic link file\n"); - return S_SS_SUCCESS; - } - - if (chmod(setFilePath, setFileMode)) { - LOGL(LOG_SSENGINE, "%s chmod error\n", __func__); - return E_SS_FAILURE; - } - - if (feature_support_capability) { - char buf[256]; - if (has_cap) { - if (setxattr(setFilePath, "security.capability", (void*)cap_raw, cap_len, 0) < 0) { - strerror_r(errno, buf, sizeof(buf)); - LOGL(LOG_SSENGINE, "cap setxattr() failed: %s\n", buf); - } - } - - if (has_acl) { - if (setxattr(setFilePath, "system.posix_acl_access", (void*)acl_raw, acl_len, 0) < 0) { - strerror_r(errno, buf, sizeof(buf)); - LOGL(LOG_SSENGINE, "Acl setxattr() failed: %s\n", buf); - } - //LOG("Acl setxattr() :")asfd - } - } - - //LOGL(LOG_SSENGINE, "%s SUCCESS\n", __func__); - - return S_SS_SUCCESS; -} - -/* vrm functions */ -long -SS_GetAvailableFreeSpace(const char *partition_name, - SS_UINT32 *available_flash_size) -{ - int result = 0; - char path[MAX_PATH] = { '\0' }; - - SS_unicode_to_char(partition_name, (char *)path, MAX_PATH - 1); - //LOGL(LOG_SSENGINE, "Enter %s path=%s\n", __func__, path); - struct statfs vfs; - - //LOGL(LOG_SSENGINE, "path=%s\n", path); - result = statfs(path, &vfs); - if (result < 0) { - LOGE("failed to fstatfs, err : %d errno: %d\n", result, errno); - return -1; - } - - *available_flash_size = ((long long)vfs.f_bsize * (long long)vfs.f_bavail >= (long long)SIZE_4GB) ? SIZE_4GB : vfs.f_bsize * vfs.f_bavail; - if (*available_flash_size == 0) { - *available_flash_size = 0x80000; //Same as Legecy RB - LOGE("available_flash_size=%u(vfs.f_bsize=%d vfs.f_bavail=%d\n", - (unsigned int)*available_flash_size, (int)vfs.f_bsize, (int)vfs.f_bavail); - return 0; // Same as Legecy RB - } - return 0; -} - -#ifdef HEAP_PROFILING - int max_mem; - int cur_mem; -#endif -/*******[ Multiprocess API sample implementation ]******/ -void *SS_Malloc(SS_UINT32 size) -{ - void *p = malloc(size); - - if (p) - memset(p, 0, size); -#ifdef HEAP_PROFILING - cur_mem += size; - if (cur_mem > max_mem) { - max_mem = cur_mem; - LOGL(LOG_SSENGINE, "New chunk [%d] assigned making heap [%d]\n", size, cur_mem); - } -#endif - - return p; -} - -void SS_Free(void *pMemBlock) -{ -#ifdef HEAP_PROFILING - cur_mem -= malloc_usable_size(pMemBlock); - LOGL(LOG_SSENGINE, "Old chunk [%d] removed making heap [%d]\n", malloc_usable_size(pMemBlock), cur_mem); -#endif - if (pMemBlock) - free(pMemBlock); -} -int SS_get_feature_support_capability(void) -{ - return feature_support_capability; -} - -void SS_set_feature_support_capability(int val) -{ - feature_support_capability = val; -} \ No newline at end of file diff --git a/src/delta-ua/engine/SS_FSUpdate.h b/src/delta-ua/engine/SS_FSUpdate.h deleted file mode 100755 index 668bf61..0000000 --- a/src/delta-ua/engine/SS_FSUpdate.h +++ /dev/null @@ -1,324 +0,0 @@ -/* - * delta-ua - * - * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*! - ******************************************************************************* - * \file SS_FileSystemUpdate.h - * - * \brief UPI FS Update API - ******************************************************************************* - */ -#ifndef _SS_FILESYSTEM_UPDATE_H_ -#define _SS_FILESYSTEM_UPDATE_H_ - -#include "SS_Engine_Errors.h" -#include "ua_types.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/*! - * File access modes - */ - typedef enum tag_RW_TYPE { - ONLY_R, //!< Read-only - ONLY_W, //!< Write-only - BOTH_RW //!< Read-write - } E_RW_TYPE; -/*! - ******************************************************************************* - * Copy file.

- * - * Must create the path to the new file as required. Must overwrite any contents - * in the old file, if any. Must check if the source file is a symbolic link. - * If it is, instead create a new symbolic link using \ref SS_Link. - * - * \param strFromPath Path to old file - * \param strToPath Path to new file - * - * \return S_SS_SUCCESS on success or an \ref SS_vRM_Errors.h error code - ******************************************************************************* - */ - - long SS_CopyFile(const char *strFromPath, const char *strToPath); - -/*! - ******************************************************************************* - * Move (rename) file.

- * - * \param strFromPath Path to old file location - * \param strToPath Path to new file location - * - * \return S_SS_SUCCESS on success or an \ref SS_vRM_Errors.h error code - ******************************************************************************* - */ - - long SS_MoveFile(const char *strFromPath, const char *strToPath); - -/*! - ******************************************************************************* - * Delete file.

- * - * Must return success if the file is deleted or didn't exist. - * - * \param strPath Path to file - * - * \return S_SS_SUCCESS on success, E_SS_DELETEFILE if the file cannot be - * deleted, or an \ref SS_vRM_Errors.h error code - ******************************************************************************* - */ - - long SS_DeleteFile(const char *strPath); - -/*! - ******************************************************************************* - * Delete folder.

- * - * Must return success if the folder is now deleted or didn't exist. - * - * \param strPath Path to folder - * - * \return S_SS_SUCCESS on success or an \ref SS_vRM_Errors.h error code - ******************************************************************************* - */ - - long SS_DeleteFolder(const char *strPath); - -/*! - ******************************************************************************* - * Create folder.

- * - * Must return success if the folder is created or already existsed. It is - * recommended that the new folder's attributes are a copy of its parent's - * attributes. - * - * \param strPath Path to folder - * - * \return S_SS_SUCCESS on success or an \ref SS_vRM_Errors.h error code - ******************************************************************************* - */ - - long SS_CreateFolder(const char *strPath); - -/*! - ******************************************************************************* - * Open file.

- * - * Must create the the file (and the path to the file) if it doesn't exist. Must - * open in binary mode. - * - * \param strPath Path to file - * \param wFlag Read/write mode, an \ref E_RW_TYPE value - * \param pwHandle (out) File handle - * - * \return S_SS_SUCCESS on success, E_SS_OPENFILE_ONLYR if attempting to open a - * non-existant file in R/O mode, E_SS_OPENFILE_WRITE if there is an - * error opening a file for writing, or an \ref SS_vRM_Errors.h error code - ******************************************************************************* - */ - - long SS_OpenFile(const char *strPath, E_RW_TYPE wFlag, long *pwHandle); - -/*! - ******************************************************************************* - * Close file. - * - * \param wHandle File handle - * - * \return S_SS_SUCCESS on success or an \ref SS_vRM_Errors.h error code - ******************************************************************************* - */ - - long SS_CloseFile(long wHandle); - -/*! - ******************************************************************************* - * Write data to a specified position within a file.

- * - * Must return success if the block is written or at least resides in - * non-volatile memory. Use \ref SS_SyncFile to commit the file to storage. - * - * \param wHandle File handle - * \param dwPosition Position within the file to which to write - * \param pbBuffer Data to write - * \param dwSize Size of \a pbBuffer - * - * \return S_SS_SUCCESS on success, or an \ref SS_vRM_Errors.h error code - ******************************************************************************* - */ - - long SS_WriteFile(long wHandle, SS_UINT32 dwPosition, unsigned char *pbBuffer, SS_UINT32 dwSize); - -/*! - ******************************************************************************* - * Read data from a specified position within a file. - * If fewer bytes than requested are available in the specified position, this - * function should read up to the end of file and return S_SS_SUCCESS. - * - * \param wHandle File handle - * \param dwPosition Position within the file from which to read - * \param pbBuffer Buffer to contain data - * \param dwSize Size of data to read - * - * \return S_SS_SUCCESS on success or an \ref SS_vRM_Errors.h error code - ******************************************************************************* - */ - - long SS_ReadFile(long wHandle, SS_UINT32 dwPosition, unsigned char *pbBuffer, SS_UINT32 dwSize); - -/*! - ******************************************************************************* - * Get file size. - * - * \param wHandle File handle - * - * \return File size, -1 if file not found, or < -1 on error - ******************************************************************************* - */ - long SS_GetFileSize(long wHandle); - -/*! - ******************************************************************************* - * Get free space of a mounted file system. - * - * \param path Name of any directory within the mounted - * file system - * \param available_flash_size (out) Available space - * - * \return S_SS_SUCCESS on success or an \ref SS_vRM_Errors.h error code - ******************************************************************************* - */ - long SS_GetAvailableFreeSpace(const char *path, SS_UINT32 * available_flash_size); - -/*! - ******************************************************************************* - * Remove symbolic link.

- * - * Must return an error if the file does not exist or is not a symbolic link.

- * - * If your platform does not support symbolic links, you do not need to - * implement this. - * - * \param pLinkName Link - * - * \return S_SS_SUCCESS on success or an \ref SS_vRM_Errors.h error code - ******************************************************************************* - */ - long SS_Unlink(char *pLinkName); - -/*! - ******************************************************************************* - * Create symbolic link.

- * - * Must create the path to the link as required. If a file already exists at the - * named location, must return success if the file is a symbolic link or an - * error if the file is a regular file. The non-existance of the target of the - * link must NOT cause an error.

- * - * If your platform does not support symbolic links, you do not need to - * implement this. - * - * \param pbUserData Optional opaque data-structure to pass to IPL - * functions - * \param pLinkName Path to the link file to create - * \param pReferenceFileName Path to which to point the link - * - * \return S_SS_SUCCESS on success or an \ref SS_vRM_Errors.h error code - ******************************************************************************* - */ - long SS_Link(void *pbUserData, char *pLinkName, char *pReferenceFileName); - -/*! - ******************************************************************************* - * Set file attributes.

- * - * The file attributes token (\a ui8pAttribs) is defined at generation time. - * If attributes are not defined explicitly, they are given the following, - * OS-dependent values: - * \li Windows: _foo_ro_ for R/O files, _foo_rw_ for R/W files - * \li Linux: _foo_oooooo:xxxx:yyyy indicating the file mode, uid, and gid - * (uid and gid use capitalized hex digits as required) - * - * \param pbUserData Optional opaque data-structure to pass to IPL - * functions - * \param ui16pFilePath File path - * \param ui32AttribSize Size of \a ui8pAttribs - * \param ui8pAttribs Attributes to set - * - * \return S_SS_SUCCESS on success or < 0 on error - ******************************************************************************* - */ - - long SS_SetFileAttributes(const char *ui16pFilePath, - const SS_UINT32 ui32AttribSize, const unsigned char *ui8pAttribs); - -/** - ******************************************************************************* - * Allocate a memory block. - * - * \param size Memory block size, in blocks - * - * \return A pointer to the memory block on success, NULL on failure - ******************************************************************************* - */ - void *SS_Malloc(SS_UINT32 size); - -/** - ******************************************************************************* - * Free a memory block. - * - * \param pMemBlock Pointer to the memory block - ******************************************************************************* - */ - void SS_Free(void *pMemBlock); -/** - ******************************************************************************* - * Get capability feature flag value - * - * \return The value of feature_support_capability - ******************************************************************************* - */ - int SS_get_feature_support_capability(void); - -/** - ******************************************************************************* - * Set capability feature flag - * - * \param val The value to set feature_support_capability - ******************************************************************************* - */ - void SS_set_feature_support_capability(int val); - -/** - ******************************************************************************* - * Create a hardlink to a file - * - * \param hardLinkName Name of the hardlink to be created - * \param referenceName Name of the file that we link to - * - * \return S_SS_SUCCESS on success, E_SS_FAILURE otherwise - ******************************************************************************* - */ - - long SS_HardLink(char *hardLinkName, char *referenceName); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif diff --git a/src/delta-ua/engine/SS_PatchDelta.c b/src/delta-ua/engine/SS_PatchDelta.c deleted file mode 100755 index 9c87579..0000000 --- a/src/delta-ua/engine/SS_PatchDelta.c +++ /dev/null @@ -1,402 +0,0 @@ -/* - * libtota - * - * Copyright (c) 2017 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../../upgrade-apply/sha1/sha1.h" -#include "SS_PatchDelta.h" -#include "fota_common.h" -#include "SS_Engine_Errors.h" -#include "SS_Common.h" - -extern void *SS_Malloc(unsigned int size); - -typedef struct { - unsigned char *buffer; - ssize_t size; - ssize_t pos; -} MemorySinkInfo; - -ssize_t ss_fileSink(unsigned char *data, ssize_t len, void *token) -{ - int ss_fd = *(int *)token; - char buf[256]; - ssize_t done = 0; - ssize_t wrote; - while (done < (ssize_t) len) { - wrote = write(ss_fd, data + done, len - done); - if (wrote <= 0) { - if (errno == EINTR || errno == EAGAIN) - continue; // try again - strerror_r(errno, buf, sizeof(buf)); - LOGE("error writing %d bytes: %s\n", (int)(len - done), buf); - return done; - } - done += wrote; - } - return done; -} - -// Take a string 'str' of 40 hex digits and parse it into the 20 -// byte array 'digest'. 'str' may contain only the digest or be of -// the form ":". Return 0 on success, -1 on any -// error. -int ParseSha1(const char *str, uint8_t * digest) -{ - int i; - const char *ps = str; - uint8_t *pd = digest; - for (i = 0; i < SHA_DIGEST_SIZE * 2; ++i, ++ps) { - int digit; - if (*ps >= '0' && *ps <= '9') - digit = *ps - '0'; - else if (*ps >= 'a' && *ps <= 'f') - digit = *ps - 'a' + 10; - else if (*ps >= 'A' && *ps <= 'F') - digit = *ps - 'A' + 10; - else - return -1; - if (i % 2 == 0) { - *pd = digit << 4; - } else { - *pd |= digit; - ++pd; - } - } - if (*ps != '\0') - return -1; - return 0; -} - -int SS_LoadFile(const char *filename, FileInfo * file) -{ - char buf[256]; - - file->data = NULL; - //LOGL(LOG_SSENGINE,"SS_LoadFile --- [File name %s]\n",filename); - - if (stat(filename, &file->st) != 0) { - strerror_r(errno, buf, sizeof(buf)); - LOGE("failed to stat \"%s\": %s\n", filename, buf); - return -1; - } - - file->size = file->st.st_size; - file->data = SS_Malloc(file->size); - if (!file->data) { - strerror_r(errno, buf, sizeof(buf)); - LOGE("failed to allocate memory for \"%s\": %s\n", filename, buf); - return -1; - } - - FILE *f = fopen(filename, "rb"); - if (f == NULL) { - strerror_r(errno, buf, sizeof(buf)); - LOGE("failed to open \"%s\": %s\n", filename, buf); - SS_Free(file->data); - file->data = NULL; - return -1; - } - - ssize_t bytes_read = fread(file->data, 1, file->size, f); - if (bytes_read != file->size) { - LOGE("short read of \"%s\" (%ld bytes of %ld)\n", filename, (long)bytes_read, (long)file->size); - SS_Free(file->data); - file->data = NULL; - fclose(f); - return -1; - } - fclose(f); - //LOGL(LOG_SSENGINE,"SS_LoadFile --- [bytes_read %d]\n",bytes_read); - SHA1(file->sha1, file->data, file->size); - return 0; -} - -extern int gvalid_session; -extern void create_dir(char *pathname, int mode); - -/*! - ********************************************************************************* - * SS_UpdateDeltaFS - ********************************************************************************* - * - * @brief - * This is used to apply patch for a file during delta FS upgrade - * - * - * @param - * - * @return 0 - in case of success - * 1 - in case of error during patch application - * - ********************************************************************************* - */ - -int SS_UpdateDeltaFS(const char *source_filename, const char *target_filename, - const char *source_sha1_str, const char *target_sha1_str, int patch_data_size, char *delta_folder) -{ - char backup_path[MAX_FILE_PATH], patchfile_source_path[MAX_FILE_PATH]; - snprintf(backup_path, MAX_FILE_PATH, "%s/%s", delta_folder, SS_BACKUP_SOURCE); - snprintf(patchfile_source_path, MAX_FILE_PATH, "%s/%s", delta_folder, SS_PATCHFILE_SOURCE); - uint8_t target_sha1[SHA_DIGEST_SIZE] = { 0, }; - uint8_t source_sha1[SHA_DIGEST_SIZE] = { 0, }; - SHA1_CTX ctx1; - int output; - int retry = 1; - int use_backup = 0; - char *outname = NULL; - int backupsrc = -1; - int result = 0; - char buf[256]; - FileInfo source_file; - FileInfo target_file; - - if (ParseSha1(target_sha1_str, target_sha1) != 0) { - LOGE("failed to parse tgt-sha1 \"%s\"\n", target_sha1_str); - return E_SS_FAILURE; - } - - /* - if battery removed in between update gvalid_session becomes 0 - need to check file integrity in that case - */ - if (0 == gvalid_session) { - if (ParseSha1(source_sha1_str, source_sha1) != 0) { - LOGE("failed to parse tgt-sha1 \"%s\"\n", source_sha1_str); - return E_SS_FAILURE; - } - if (SS_LoadFile(source_filename, &source_file) == 0) { - SS_Free(source_file.data); - - if (memcmp(source_file.sha1, source_sha1, SHA_DIGEST_SIZE) == 0) { - LOGL(LOG_SSENGINE, "Patch Can be applied\n"); - } else if (memcmp(source_file.sha1, target_sha1, SHA_DIGEST_SIZE) == 0) { - LOGL(LOG_SSENGINE, "Patch Already applied\n"); - return S_SS_SUCCESS; - } else { - //Check for backup file SHA - LOGL(LOG_SSENGINE, "Source was currupted, Try loading from backup source\n"); - - if (SS_LoadFile(target_filename, &target_file) == 0) { - SS_Free(target_file.data); - - if (memcmp(target_file.sha1, target_sha1, SHA_DIGEST_SIZE) == 0) { - LOGL(LOG_SSENGINE, "Patch Already applied\n"); - return S_SS_SUCCESS; - } - } - - if (SS_LoadFile(backup_path, &source_file) == 0) { - SS_Free(source_file.data); - - if (memcmp(source_file.sha1, source_sha1, SHA_DIGEST_SIZE) == 0) { - if (SS_CopyFile(backup_path, source_filename) != S_SS_SUCCESS) { - strerror_r(errno, buf, sizeof(buf)); - LOGE("copy of backup to \"%s\" failed: %s\n", source_filename, buf); - SS_SetUpgradeState(E_SS_FSUPDATEFAILED); - return E_SS_FAILURE; - } - LOGL(LOG_SSENGINE, - "Patch Can be applied from using backup file as source\n"); - } else { - SS_SetUpgradeState(E_SS_FSSRCCURRUPTED); - return E_SS_FAILURE; - } - } else { - SS_SetUpgradeState(E_SS_FSSRCCURRUPTED); - return E_SS_FAILURE; - } - } - } else { - LOGL(LOG_SSENGINE, "Source was deleted!!\n"); - if (SS_LoadFile(target_filename, &target_file) == 0) { - SS_Free(target_file.data); - - if (memcmp(target_file.sha1, target_sha1, SHA_DIGEST_SIZE) == 0) { - LOGL(LOG_SSENGINE, "Patch Already applied\n"); - return S_SS_SUCCESS; - } - } - - LOGL(LOG_SSENGINE, "Try loading from backup source\n"); - if (SS_LoadFile(backup_path, &source_file) == 0) { - SS_Free(source_file.data); - - if (memcmp(source_file.sha1, source_sha1, SHA_DIGEST_SIZE) == 0) { - use_backup = 1; - LOGL(LOG_SSENGINE, "Patch Can be applied from using backup file as source\n"); - } else { - SS_SetUpgradeState(E_SS_FSSRCCURRUPTED); - return E_SS_FAILURE; - } - } else { - LOGE(" SS_LoadFile from backup source failed!!\n"); - SS_SetUpgradeState(E_SS_FSSRCCURRUPTED); - return E_SS_FAILURE; - } - } - } - //Now proceed wit patch application since patch can be applied - do { - int enough_space = 0; - size_t free_space = 0; - char *tok; - - if (retry > 0) { - if (use_backup) { - tok = strrchr(source_filename, '/'); - *tok = '\0'; - } - SS_GetAvailableFreeSpace(source_filename, &free_space); - enough_space = (free_space > (256 << 10)) && // 256k (two-block) minimum - (free_space > (patch_data_size * 3 / 2)); // 50% margin of error - if (use_backup) - *tok = '/'; - } - - if (!use_backup) { -#ifndef ENHANCED_BSDIFF - backupsrc = SS_BackupSource(source_filename, backup_path); - if (backupsrc != 0) { - LOGE("failed to Backup source File:[%s] \n", source_filename); - SS_SetUpgradeState(E_SS_FSSRCBACKUPFAILED); - return E_SS_FAILURE; - } -#endif - } - if (!enough_space) { - LOGL(LOG_SSENGINE, "For %s: free space %ld bytes; enough %d\n", source_filename, (long)free_space, - enough_space); - retry = 0; - use_backup = 1; - unlink(source_filename); - } - //LOGL(LOG_SSENGINE, "For %s: target %ld bytes; free space %ld bytes; enough %d\n", - // source_filename, (long)patch_data_size, (long)free_space, enough_space); - //LOGL(LOG_SSENGINE,"Generate Target Space availabitiy [%d]\n", enough_space); - - SinkFn sink = NULL; - void *token = NULL; - output = -1; - outname = NULL; - - { - // We write the decoded output to ".patch". - //allocate some extra space to allow for concatinating ".patch" with the name - outname = (char *)SS_Malloc(strlen(target_filename) + 10); - if (outname == NULL) { - LOGE("SS_Malloc failed!!\n"); - return E_SS_FAILURE; - } - snprintf(outname, strlen(target_filename) + 10, - "%s.patch", target_filename); - - output = open(outname, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU); - if (output < 0) { - if (errno == 2) { - char *dir_path = strrchr(outname, '/'); - *dir_path = '\0'; - // need to create directory as the target may be different from source - LOGL(LOG_SSENGINE, "need to create directory [%s]\n", outname); - create_dir(outname, 0755); - *dir_path = '/'; - output = open(outname, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU); - if (output < 0) { - strerror_r(errno, buf, sizeof(buf)); - LOGE("failed to open output file %s: %s\n", outname, buf); - SS_Free(outname); - return E_SS_FAILURE; - } - } - } - sink = ss_fileSink; - token = &output; - } - SHA1Init(&ctx1); - if (use_backup) - result = SS_ApplyBsdiff(backup_path, outname, patchfile_source_path, sink, token, &ctx1); - else - result = SS_ApplyBsdiff((char *)source_filename, outname, patchfile_source_path, sink, token, &ctx1); - if (output >= 0) { - fsync(output); - close(output); - } - - if (result != S_SS_SUCCESS) { - if (retry == 0) { - LOGE("applying patch failed result : [%d]\n", result); - SS_Free(outname);//wgid: 20739 - SS_SetUpgradeState(E_SS_FSUPDATEFAILED); - return E_SS_FAILURE; - } else { - LOGE("applying patch failed; retrying\n"); - SS_Free(outname);//wgid: 20739 - } - } else { - // succeeded; no need to retry - break; - } - } while (retry-- > 0); - - unsigned char current_target_sha1[SHA_DIGEST_SIZE] = { 0, }; - SHA1Final(current_target_sha1, &ctx1); - if (memcmp(current_target_sha1, target_sha1, SHA_DIGEST_SIZE) != 0) { - LOGE("patch did not produce expected sha1\n"); - SS_SetUpgradeState(E_SS_FSSHA_MISMATCH); - if (outname != NULL) - SS_Free(outname); - return E_SS_FAILURE; - } - - // Finally, rename the .patch file to replace the target file. -#ifdef ENHANCED_BSDIFF - if (SS_rename1(outname, target_filename) != 0) { - strerror_r(errno, buf, sizeof(buf)); - LOGE("rename of .patch to \"%s\" failed: %s\n", target_filename, buf); - SS_SetUpgradeState(E_SS_FSUPDATEFAILED); - if (outname != NULL) - SS_Free(outname); - return E_SS_FAILURE; - } -#else - if (rename(outname, target_filename) != 0) { - strerror_r(errno, buf, sizeof(buf)); - LOGE("rename of .patch to \"%s\" failed: %s\n", target_filename, buf); - SS_SetUpgradeState(E_SS_FSUPDATEFAILED); - if (outname != NULL) - SS_Free(outname); - return E_SS_FAILURE; - } - //remove source file if target is not same - if (strcmp(source_filename, target_filename) != 0) - unlink(source_filename); - SS_BackupSourceClear(backup_path); -#endif - SS_PatchSourceClear(patchfile_source_path); - SS_Free(outname); - - return result; -} \ No newline at end of file diff --git a/src/delta-ua/engine/SS_PatchDelta.h b/src/delta-ua/engine/SS_PatchDelta.h deleted file mode 100755 index d8cb16a..0000000 --- a/src/delta-ua/engine/SS_PatchDelta.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * delta-ua - * - * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _SS_PATCHDELTA_H -#define _SS_PATCHDELTA_H - -#include -#include "sha1.h" -#include "unistd.h" -#include "fcntl.h" -#include "errno.h" -#include "ua_types.h" - -#define SHA_DIGEST_SIZE 20 - -typedef struct _FileInfo { - unsigned char sha1[20]; //SHA_DIGEST_SIZE 20 - unsigned char *data; - int size; - struct stat st; -} FileInfo; -typedef ssize_t(*SinkFn) (unsigned char *, ssize_t, void *); - -int ParseSha1(const char *str, uint8_t * digest); - -int SS_LoadFile(const char *filename, FileInfo * file); -extern void SS_SetUpgradeState(int Val); -extern long SS_GetAvailableFreeSpace(const char *partition_name, SS_UINT32 * available_flash_size); -extern int SS_BackupSource(const char *source_filename, char *backup_path); -extern int SS_ApplyBsdiff(char *oldfile, char *newfile, char *patch, SinkFn sink, void *token, SHA1_CTX * ctx1); -extern int SS_BackupSourceClear(char * backup_path); -extern int SS_PatchSourceClear(char *patch_path); -extern long SS_WriteFile(long wHandle, SS_UINT32 dwPosition, unsigned char *pbBuffer, SS_UINT32 dwSize); -extern void SS_Free(void * pMemBlock); -extern long SS_CopyFile(const char * strFromPath, const char * strToPath); -extern long SS_DeleteFolder(const char * strPath); -extern long SS_DeleteFile(const char * strPath); -extern int tar_get_item_size(char * tar, char * item); -extern int tar_extract_file(char * tar, char * item, char * pathname); -extern int _system_cmd_wait(const char * command); -#endif diff --git a/src/delta-ua/engine/SS_UPI.c b/src/delta-ua/engine/SS_UPI.c deleted file mode 100755 index 7a168ed..0000000 --- a/src/delta-ua/engine/SS_UPI.c +++ /dev/null @@ -1,2207 +0,0 @@ -/* - * delta-ua - * - * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*HEADER */ - -/* - -Function Prototypes Mandatory - -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ua_types.h" -#include "SS_Common.h" -#include "fota_common.h" -#include "SS_UPI.h" -#include "SS_PatchDelta.h" -#include "SS_Engine_Errors.h" -#include "SS_FSUpdate.h" - -int gtotalFSCnt = 0; -int FS_UpgradeState = E_SS_FAILURE; -int gvalid_session = 0; //used as fail-safe in case device is turmed off or battery removed during update -fs_list *headptr_list; -tar_Data_t *tar_cfg_data = NULL; - -#ifdef MEM_PROFILING -/* - Description: - Create script file , set it executable, execute script in child process - Only works if valid delta.tar is present for upgrade - Summary: - If MEM_PROFILING is activated, - we can see the result of memory profiling after delta upgrade - in file defined by macro - SS_MEMORY_PROFILING_SCRIPT -*/ -int mem_profiling_start = 0; -int SS_Do_Memory_Profiling() -{ - int ret = -1; - pid_t pid; - char memory_usage_script[1024] = "#!/bin/bash\nlog_file=$1\npid=$2\nmaxmem=0\nwhile [[ -d \"/proc/${pid}\" ]]; do\n\ - mem=`cat /proc/${pid}/smaps | grep Pss | grep -v Swap|awk '{print $2}'|awk '{s+=$1} END {print s}'`\n\ - if [[ ${mem} -gt ${maxmem} ]]; then\nmaxmem=${mem}\n\ - echo -e \"Memory usage till now is: ${maxmem} KB.\" >> $log_file\n fi\n sleep 0.01\ndone\n\ - echo -e \"Max was : ${maxmem} KB.\" >> $log_file\n"; - char cmd[1024] = { 0, }; - - //Open a file and write the script contents in it - FILE *fp = fopen(SS_MEMORY_PROFILING_SCRIPT, "w+"); - fwrite(memory_usage_script, strlen(memory_usage_script), 1, fp); - fclose(fp); - //make the file executable - Octal 495 is 757 decimal - if (chmod(SS_MEMORY_PROFILING_SCRIPT, 495) < 0) { - LOGE("Error in chmod(%s, 495) - %d (%s)\n", SS_MEMORY_PROFILING_SCRIPT, errno, strerror(errno)); - return E_SS_FAILURE; - } - //calling mem_use.sh - //Usage : - pid = getpid(); - snprintf(cmd, sizeof(cmd) - 1, "%s %s %d", SS_MEMORY_PROFILING_SCRIPT, SS_MEMORY_USAGE_LOG, pid); - ret = _system_cmd_nowait(cmd); - sleep(1); - LOG("ret for memory profiling cmd is %d\n", ret); - if (ret == 0) { - mem_profiling_start = 1; - return S_SS_SUCCESS; - } else { - LOGE("Could not start Memory Profiling\n"); - return E_SS_FAILURE; - } -} -#endif -#ifdef TIME_PROFILING -static char ts1[256]; -static double ts2; -double t1; -double t2; -double fast_tar_get_item_size_time = 0.0; -double SS_LoadFile_time = 0.0; -double SS_FSBuildNodes_time = 0.0; - -static void get_time_stamp1(void) -{ - struct timeval tv; - int sec, msec; - - gettimeofday(&tv, NULL); - sec = (int)tv.tv_sec; - msec = (int)(tv.tv_usec / 1000); - snprintf(ts1, 256, "%06d.%03d", sec % 100000, msec); -} -#endif - -//Check SS function if available -int file_exist(char *filename) -{ - struct stat buf; - int ret = 0; - - ret = lstat(filename, &buf); - if (ret < 0) - ret = stat(filename, &buf); - - return (ret >= 0) ? (1) : (0); -} - -#ifdef POWER_FAIL_TEST - -static int SS_Get_power_fail_flag(void) -{ - int fd; - char buf[256]; - char *ptr = NULL; - int result = 0; - int ret_val = 0; - - if (file_exist(SS_POWER_FAIL_TEST_FLAG) == 0) { - LOGE("No exist file!!\n"); - return -1; - } - - fd = open(SS_POWER_FAIL_TEST_FLAG, O_RDWR, S_IRWXU); - if (fd == -1) { - LOGE("Could not open status file!!\n"); - return -1; - } - - result = SS_ReadFile(fd, 0, buf, sizeof(buf)); - if (result != 0) { - LOGE("SS_ReadFile failed!!\n"); - return -1; - } - - ret_val = atoi(buf); - - result = SS_CloseFile(fd); - if (result != 0) - LOGE("SS_CloseFile failed!!\n"); - - return ret_val; -} - -static void SS_Set_power_fail_flag(int del_type) -{ - int fd; - int result = 0; - char num_str[16]; - LOG("del_type:[%d]\n", del_type); - - fd = open(SS_POWER_FAIL_TEST_FLAG, O_RDWR | O_CREAT, S_IRWXU); - if (fd == -1) { - LOGE("Could not open status file!!\n"); - return; - } - - sprintf(num_str, "%d", del_type); - result = SS_WriteFile(fd, 0, num_str, strlen(num_str)); - if (result != 0) - LOGE("SS_WriteFile failed!!\n"); - - result = SS_CloseFile(fd); - if (result != 0) - LOGE("SS_CloseFile failed!!\n"); - - sync(); - -} - -int SS_Do_Power_fail_test(int del_type) -{ - int ret = -1; - char cmd[1024] = { 0, }; - - SS_Set_power_fail_flag(del_type); - - snprintf(cmd, sizeof(cmd) - 1, "%s", "/usr/sbin/reboot fota"); - ret = _system_cmd_nowait(cmd); - sleep(1); - LOG("ret for SS_Do_Power_fail_test cmd is %d\n", ret); - if (ret == 0) { - return S_SS_SUCCESS; - } else { - LOGE("Could not start Memory Profiling\n"); - return E_SS_FAILURE; - } -} -#endif - -int SS_GetProgressResolution(int ultotalFSCnt) -{ - if (ultotalFSCnt < DISPLAYRESOLUTION_SIZE) - return 1; - else - return (ultotalFSCnt / DISPLAYRESOLUTION_SIZE); -} - -void SS_SetUpgradeState(int Val) -{ - LOGE("FAILED to upgrade Cause:[0x%x]\n", Val); - FS_UpgradeState = Val; - return; -} - -int SS_GetUpgradeState() -{ - return FS_UpgradeState; -} - -int SS_Get_last_update_status(int* last_update_status, int* del_type, char* status_path) -{ - int fd; - unsigned char buf[257]; - char *ptr = NULL; - char *saveptr = NULL; - int result = 0; - - if (file_exist(status_path) == 0) { - LOG("No exist file!! - File_path:[%s]\n", status_path); - return -1; - } - - fd = open(status_path, O_RDWR, S_IRWXU); - if (fd == -1) { - LOGE("Could not open status file!!, File_path:[%s]\n", status_path); - return -1; - } - - result = SS_ReadFile(fd, 0, buf, sizeof(buf)-1); - if (result != 0) { - LOGE("SS_ReadFile failed!!\n"); - result = SS_CloseFile(fd); - if (result != 0) - LOGE("SS_CloseFile failed!!\n"); - return -1; - } - - ptr = strtok_r((char *)buf, " ", &saveptr); - - if (ptr != NULL) { - *last_update_status = atoi(ptr); - ptr = strtok_r(NULL, " ", &saveptr); - } - - if (ptr != NULL) { - *del_type = atoi(ptr); - } - - result = SS_CloseFile(fd); - if (result != 0) - LOGE("SS_CloseFile failed!!\n"); - - return 0; -} - -void SS_Set_last_update_status(int last_update_status, int del_type, char *status_path) -{ - int fd; - int result = 0; - char num_str[16]; - LOG("last_update_status:[%d], del_type:[%d]\n", last_update_status, del_type); - - fd = open(status_path, O_RDWR | O_CREAT, S_IRWXU); - if (fd == -1) { - LOGE("Could not open status file!!, File_path:[%s]\n", status_path); - return; - } - - snprintf(num_str, sizeof(num_str), "%d %d", last_update_status, del_type); - result = SS_WriteFile(fd, 0, (unsigned char *)num_str, strlen(num_str)); - if (result != 0) - LOGE("SS_WriteFile failed!!\n"); - - result = SS_CloseFile(fd); - if (result != 0) - LOGE("SS_CloseFile failed!!\n"); - - sync(); - -} - -int SS_rename1(const char *old_file_name, const char *new_file_name) -{ - int result = E_SS_FAILURE; - char *temp_name = NULL; - temp_name = (char *)SS_Malloc(strlen(new_file_name) + 10); - if (temp_name == NULL) - return E_SS_FAILURE; - snprintf(temp_name, strlen(new_file_name) + 10, "%s.temp", new_file_name); - result = rename(new_file_name, temp_name); - if (result != 0) - goto Cleanup; - result = rename(old_file_name, new_file_name); - if (result != 0) - goto Cleanup; - result = unlink(temp_name); - Cleanup: - if (temp_name) - SS_Free(temp_name); - return result; -} - -/*! - ********************************************************************************* - * SS_FSVerifyNode - ********************************************************************************* - * - * @brief - * This is to verify nodes being added to global control structure for diff and delete cases. - * gvalid_session global is used to check if nodes are already verified. - * - * - * @param - * - * @return returns S_SS_SUCCESS and - * returns E_SS_FAILURE in case any error occurs - * - ********************************************************************************* - */ -int SS_FSVerifyNode(const char *path, const char *patchname, const char *sha1src, int type, - char *patchpath_name, int *data_size, int *data_offset) -{ - char patch[MAX_FILE_PATH] = { 0 }; - FileInfo source_file; - uint8_t source_sha1[SHA_DIGEST_SIZE]; - - if (gvalid_session) { - if ((type == DIFFS || type == DELETES || type == MOVES) && !file_exist((char *)path)) { - LOGE("failed to verifyNodes [does not exist], Path : [%s] Type[%d]\n", path, type); - SS_SetUpgradeState(E_SS_FSBADNODES); - return E_SS_FAILURE; - } - snprintf(patch, MAX_FILE_PATH, "%s%s%s", patchpath_name, "/", patchname); - if ((type == DIFFS/*||type == NEWFILES */)) { // allowing size 0 also for folders - if (tar_get_item_size_from_struct(&tar_cfg_data, patchname, data_size, data_offset) - != S_SS_SUCCESS) { - LOGE("failed to get item size from struct, Patch : [%s]\n", patchname); - SS_SetUpgradeState(E_SS_FSBADNODES); - return E_SS_FAILURE; - } - if (*data_size < 0) { - LOGE("failed to verifyNodes [delta absent], Patch : [%s] Type[%d]\n", patch, type); - SS_SetUpgradeState(E_SS_FSBADNODES); - return E_SS_FAILURE; - } - } - //For other types (NEWs, SYMs, Folders), SHA check not required - if ((type == DIFFS || type == MOVES/* ||type == DELETES */) && - (strcmp(sha1src, SS_NULLENTRY) != 0)) { - if (ParseSha1(sha1src, source_sha1) != 0) { - LOGE("Failed to parse Src-sha1 \"%s\"\n", sha1src); - return E_SS_FAILURE; - } - if (SS_LoadFile(path, &source_file) == 0) { - if (memcmp(source_file.sha1, source_sha1, SHA_DIGEST_SIZE) != 0) { - SS_Free(source_file.data); - unsigned char actualShaBuffer[41] = { 0, }; - hex_digest(source_file.sha1, actualShaBuffer, SHA_DIGEST_SIZE); - LOGE("SS_FSVerifyNode - SHA mismatch with SRC - PATH [%s] Expected [%s] Actual [%s]\n", - path, sha1src, actualShaBuffer); - SS_SetUpgradeState(E_SS_FSSRCCURRUPTED); // Define other error - return E_SS_FAILURE; - } - } - SS_Free(source_file.data); - } - } else { - LOGL(LOG_SSENGINE, "FS partition Already verified - Filling only size and offset \n"); - snprintf(patch, MAX_FILE_PATH, "%s%s%s", patchpath_name, "/", patchname); - if ((type == DIFFS/* ||type == NEWFILES */)) { // allowing size 0 also for folders - if (tar_get_item_size_from_struct(&tar_cfg_data, patchname, data_size, data_offset) - != S_SS_SUCCESS) { - LOGE("failed to get item size from struct, Patch : [%s] \n", patchname); - SS_SetUpgradeState(E_SS_FSBADNODES); - return E_SS_FAILURE; - } - if (*data_size < 0) { - LOGE("failed to verifyNodes [delta absent], Patch : [%s] Type[%d]\n", patch, type); - SS_SetUpgradeState(E_SS_FSBADNODES); - return E_SS_FAILURE; - } - } - } - return S_SS_SUCCESS; -} - -/*! - ********************************************************************************* - * SS_AppendNode - ********************************************************************************* - * - * @brief - * This is to append node to the global control structure for delta files. - * - * - * @param - * - * @return returns S_SS_SUCCESS and - * returns E_SS_FAILURE in case any error occurs - * - ********************************************************************************* - */ -int SS_AppendNode(const char *ubDeltaPath, fs_params ** headparam, fs_params ** tailparam, const char *old_path, - const char *new_path, const char *patchname, const char *sha1src, const char *sha1trg, int type, - char *patchpath_name) -{ - fs_params *newnode = NULL; - int data_size = 0; - int data_offset = 0; - - if (!ubDeltaPath || !old_path || !new_path || !patchname || !sha1src || !sha1trg || !patchpath_name) { - LOGE("Bad Nodes, NULL params passed for Appending Nodes \n"); - SS_SetUpgradeState(E_SS_FSINVALIDNODEPARAMS); - return E_SS_FAILURE; - } - if ((E_SS_FAILURE == - SS_FSVerifyNode(old_path, patchname, sha1src, type, patchpath_name, &data_size, &data_offset))) { - LOGE("Bad Nodes, Failed to pass verification - [Delta Path - %s][OldPath - %s] [NewPath - %s] \n", ubDeltaPath, - old_path, new_path); - return E_SS_FAILURE; - } - newnode = (fs_params *) SS_Malloc(sizeof(fs_params)); - if (!newnode) - return E_SS_FAILURE; - strncpy(newnode->file_old_path, old_path, SS_MAX_NAMELENSUPPORTED);//wgid: 29483 - strncpy(newnode->file_new_path, new_path, SS_MAX_NAMELENSUPPORTED);//wgid: 29482 - strncpy(newnode->patch_name, patchname, SS_MAX_NAMELENSUPPORTED);//wgid: 28033 - strncpy(newnode->sha1src, sha1src, sizeof(newnode->sha1src) -1);//wgid: 25282 - strncpy(newnode->sha1trg, sha1trg, sizeof(newnode->sha1trg) - 1);//wgid: 25283 - newnode->type = type; - newnode->data_size = data_size; - newnode->data_offset = data_offset; - newnode->nextnode = NULL; - - //LOG("%s %s %d %s %s \n",newnode->file_path,newnode->patch_name,newnode->type, newnode->sha1src, newnode->sha1trg); - - if (*headparam == NULL) { - *headparam = newnode; - *tailparam = newnode; - } else { - (*tailparam)->nextnode = newnode; - (*tailparam) = (*tailparam)->nextnode; - } - return S_SS_SUCCESS; - -} - -void SS_UpdateUIProgress(ua_dataSS_t * ua_dataSS, int ulTotalFsCnt, int ulDone) -{ - static int ss_count = 1; - int res_val = SS_GetProgressResolution(ulTotalFsCnt); - if (!ua_dataSS) { - LOGE("Error ua_dataSS\n"); - return; - } -//LOG("\nvalues are ss_count[%d] total_file_cnt[%d]",ss_count,ulTotalFsCnt); - if (ulDone == 1) { - if (ua_dataSS->ui_progress) - ua_dataSS->ui_progress(ua_dataSS, 100); - ss_count = 1; - } else if (ss_count < ulTotalFsCnt) { - if (ss_count % res_val == 0) { //Max 50 times display - double data = (double)ss_count / (double)ulTotalFsCnt; - if (ua_dataSS->ui_progress) - ua_dataSS->ui_progress(ua_dataSS, data * 100); - } - ss_count++; - } else { - if (ua_dataSS->ui_progress) - ua_dataSS->ui_progress(ua_dataSS, 100); - ss_count = 1; - } - -} - -/*! - ********************************************************************************* - * SS_FSClearNodes - ********************************************************************************* - * - * @brief - * This is to clear the global control structure for delta files. - * - * - * @param - * - * @return - * - ********************************************************************************* - */ -void SS_FSClearNodes() -{ - fs_params *local_temp = NULL; - fs_params *local_next = NULL; - LOGL(LOG_SSENGINE, "Free Nodes\n"); - if (headptr_list) { - if (headptr_list->del_ref) { - local_temp = headptr_list->del_ref; - while (local_temp) { - local_next = local_temp->nextnode; - SS_Free(local_temp); - local_temp = local_next; - } - } - if (headptr_list->dif_ref) { - local_temp = headptr_list->dif_ref; - while (local_temp) { - local_next = local_temp->nextnode; - SS_Free(local_temp); - local_temp = local_next; - } - } - if (headptr_list->move_ref) { - local_temp = headptr_list->move_ref; - while (local_temp) { - local_next = local_temp->nextnode; - SS_Free(local_temp); - local_temp = local_next; - } - } - if (headptr_list->new_ref) { - local_temp = headptr_list->new_ref; - while (local_temp) { - local_next = local_temp->nextnode; - SS_Free(local_temp); - local_temp = local_next; - } - } - if (headptr_list->sym_difref) { - local_temp = headptr_list->sym_difref; - while (local_temp) { - local_next = local_temp->nextnode; - SS_Free(local_temp); - local_temp = local_next; - } - } - if (headptr_list->sym_newref) { - local_temp = headptr_list->sym_newref; - while (local_temp) { - local_next = local_temp->nextnode; - SS_Free(local_temp); - local_temp = local_next; - } - } - if (headptr_list->hard_newref) { - local_temp = headptr_list->hard_newref; - while (local_temp) { - local_next = local_temp->nextnode; - SS_Free(local_temp); - local_temp = local_next; - } - } - if (headptr_list->hard_difref) { - local_temp = headptr_list->hard_difref; - while (local_temp) { - local_next = local_temp->nextnode; - SS_Free(local_temp); - local_temp = local_next; - } - } - SS_Free(headptr_list); - headptr_list = NULL; - } -} - -/*! - ********************************************************************************* - * SS_FSGetDeltaCount - ********************************************************************************* - * - * @brief - * This is to get the delta count for diffs , deletes etc. - * - * - * @param - * - * @return returns structure with delta count info - * NULL in case of error - * - ********************************************************************************* - */ - -struct details *SS_FSGetDeltaCount(char *ubDeltaPath, char *ubDeltaInfoFile, char *patchlist_backup_patch) -{ - int size = 0, bckupsize = 0, ret = 1; - char *token = NULL; - char *FileData = NULL; - int data_size = -1; - char *line = NULL; - char *saveptr = NULL; - char buf[256]; - struct details *refer_copy = NULL; - FILE *filename_bkup = NULL; - - if (!(ubDeltaPath && ubDeltaInfoFile)) { - LOGE("failed to Parse DELTA count information: \n"); - SS_SetUpgradeState(E_SS_BAD_PARAMS); - return NULL; - } - refer_copy = (struct details *)SS_Malloc(sizeof(struct details)); - - if (refer_copy == NULL) { - LOGE("failed to allocate memory\n"); - return NULL; - } - - LOGL(LOG_SSENGINE, "Delta File Info =%s\n", ubDeltaInfoFile); - - size = tar_get_item_size(ubDeltaPath, ubDeltaInfoFile); - if (size < 0) { - LOGE("failed to Access DELTA info file DPath:[%s] File: [%s]\n", ubDeltaPath, ubDeltaInfoFile); - SS_SetUpgradeState(E_SS_FSBADDELTA); - ret = 0; - goto cleanup; - } - - FileData = SS_Malloc(size + 1); - if (FileData == NULL) { - LOGE("Failed to Allocate Memory\n"); - SS_SetUpgradeState(E_SS_MALLOC_ERROR); - ret = 0; - goto cleanup; - } - - memset(FileData, 0, size + 1); - data_size = tar_get_cfg_data(ubDeltaPath, ubDeltaInfoFile, FileData, size); - if (data_size <= 0) { // == 0 is NOT okay?? - LOGE("Failed to read cfg data from Delta\n"); - SS_SetUpgradeState(E_SS_FSBADDELTA); - ret = 0; - goto cleanup; - } - filename_bkup = fopen(patchlist_backup_patch, "wb+"); - if (filename_bkup == NULL) { - strerror_r(errno, buf, sizeof(buf)); - LOGE("Failed to create BACKUP file Error:[%s]\n", buf); - SS_SetUpgradeState(E_SS_FSFAILEDTOBACKUPPATCHINFO); - ret = 0; - goto cleanup; - } - - bckupsize = fwrite(FileData, 1, data_size, filename_bkup); //RECHECK SIZE 1 - if (bckupsize <= 0) { - SS_SetUpgradeState(E_SS_FSFAILEDTOBACKUPPATCHINFO); - ret = 0; - goto cleanup; - } - LOGL(LOG_SSENGINE, " Size [%d] DataSize [%d] BakUpSize [%d]\n", size, data_size, bckupsize); - - line = strstr(FileData, SS_FSCOUNT_MAGIC_KEY); - if (line) { - LOGL(LOG_SSENGINE, "SS_FSGetDeltaCount() last line %s \n", line); - - token = strtok_r(&line[SS_FSCOUNT_MAGIG_KEYLEN], SS_TOKEN_SPACE, &saveptr); - if (token) - refer_copy->diffs = atoi(token); - else { - SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT); - ret = 0; - goto cleanup; - } - token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr); - if (token) - refer_copy->moves = atoi(token); - else { - SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT); - ret = 0; - goto cleanup; - } - - token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr); - if (token) - refer_copy->news = atoi(token); - else { - SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT); - ret = 0; - goto cleanup; - } - - token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr); - if (token) - refer_copy->deletes = atoi(token); - else { - SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT); - ret = 0; - goto cleanup; - } - - token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr); - if (token) - refer_copy->symdiffs = atoi(token); - else { - SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT); - ret = 0; - goto cleanup; - } - - token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr); - if (token) - refer_copy->symnews = atoi(token); - else { - SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT); - ret = 0; - goto cleanup; - } - - token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr); - if (token) - refer_copy->harddiffs = atoi(token); - else { - SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT); - ret = 0; - goto cleanup; - } - - token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr); - if (token) - refer_copy->hardnews = atoi(token); - else { - SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT); - ret = 0; - goto cleanup; - } - - gtotalFSCnt = - refer_copy->diffs + refer_copy->moves + refer_copy->news + refer_copy->deletes + refer_copy->symdiffs + - refer_copy->symnews + refer_copy->harddiffs + refer_copy->hardnews; - LOG("SS_FSGetDeltaCount() total no of file %d\n", gtotalFSCnt); - - } else { - SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT); - LOG("SS_FSGetDeltaCount() Failed to read last line\n"); - } - if (gtotalFSCnt < 0) { - ret = 0; - goto cleanup; - } - - cleanup: - if (ret) { - SS_Free(FileData); - if (filename_bkup) - fclose(filename_bkup); - return refer_copy; - } else { - SS_Free(FileData); - SS_Free(refer_copy); - if (filename_bkup) - fclose(filename_bkup); - return NULL; - } - -} - -/*! - ********************************************************************************* - * SS_FSBuildNodes - ********************************************************************************* - * - * @brief - * This is used to build the gobal control structure for diffs, deletes etc. - * For all the entries in config file (which has info) the information is parsed to the global control struct - * - * - * @param - * - * @return returns fs_list structure filled with details of all the files to be diff-ed ,deleted etc. - * NULL in case of error - * - ********************************************************************************* - */ -fs_list *SS_FSBuildNodes(ua_dataSS_t * ua_dataSS) -{ - FILE *fp = NULL; - char line[SS_TOKEN_MAXLINE_LEN] = { '\0' }; - char patchlist_backup_patch[MAX_FILE_PATH]; - snprintf(patchlist_backup_patch, MAX_FILE_PATH, "%s/%s",ua_dataSS->update_data->ua_delta_folder, SS_PATCHLIST_BKUPLOC); - char string_na[] = "NA"; - char *patch_name = NULL; - char *source_name = NULL; - char *target_name = NULL; - char *sha1src = NULL; - char *sha1trg = NULL; - char *change_type = NULL; - char *file_type = NULL; - char *saveptr = NULL; - uint32_t ulPatchCount = 0, del_type = DELETES; - fs_params *fs_diffhead = NULL; - fs_params *fs_difftail = NULL; - fs_params *fs_movehead = NULL; - fs_params *fs_movetail = NULL; - fs_params *fs_newhead = NULL; - fs_params *fs_delhead = NULL; - fs_params *fs_deltail = NULL; - fs_params *fs_symlinkdiffhead = NULL; - fs_params *fs_symlinkdifftail = NULL; - fs_params *fs_symlinknewhead = NULL; - fs_params *fs_symlinknewtail = NULL; - fs_params *fs_hardlinkdiffhead = NULL; - fs_params *fs_hardlinkdifftail = NULL; - fs_params *fs_hardlinknewhead = NULL; - fs_params *fs_hardlinkdnewtail = NULL; - - struct details *local = NULL; - fs_list *fs_head_node = NULL; - int i = 0, retval = 0; - if (!ua_dataSS) { - LOGE("Bad structure ua_dataSS\n"); - SS_SetUpgradeState(E_SS_BAD_PARAMS); - return NULL; - } - LOGL(LOG_SSENGINE, " Build Nodes Entry \n"); - if (tar_cfg_data == NULL) - tar_cfg_data = tar_build_cfg_table(ua_dataSS->update_data->ua_delta_path); - if (!tar_cfg_data) { - LOGE(" tar_build_cfg_table Failed \n"); - SS_SetUpgradeState(E_SS_BAD_PARAMS); - return NULL; - } - local = SS_FSGetDeltaCount(ua_dataSS->update_data->ua_delta_path, ua_dataSS->update_delta->ua_patch_info, patchlist_backup_patch); - if (local == NULL) { - LOGE(" Build Nodes Failed \n"); - if (tar_cfg_data) - tar_free_cfg_table(&tar_cfg_data); - SS_SetUpgradeState(E_SS_BAD_PARAMS); - return NULL; - } - - fp = fopen(patchlist_backup_patch, "r"); - if (!fp) { - SS_SetUpgradeState(E_SS_FSFAILEDTOOPENPATCHINFO); - if (tar_cfg_data) - tar_free_cfg_table(&tar_cfg_data); - SS_Free(local); - return NULL; - } - - ulPatchCount = local->diffs + local->deletes + local->news + local->moves + local->symdiffs + - local->symnews + local->harddiffs + local->hardnews; - LOG("Total FS count [%d].\n", ulPatchCount); -/* -************************************************************************ -Parsing logic implemented for patchlist -************************************************************************ -Sample entries in patchlist as below : -:: -************************************************************************ -DIFF:REG:system/bin/vi:system/bin/vi:2f2f3dc6d3ee06af0080ac7975f22941660f2480:78b2d44af32d854c70f1cb7431a60c2682a320cc:diff1_vi.delta -DIFF:TPK:system/usr/packages/removable/com.samsung.calculator.tpk:system/usr/packages/removable/com.samsung.calculator.tpk: - 96fc1bcde30d501ba65ef0038e05da46d255a7b3:fa1d5d9daa4097ac302b69244297f508577c3a01:diff1598_com.samsung.calculator.tpk.delta/ -MOVE:REG:system/etc/smack/accesses.d/heremaps-engine-devel:system/usr/apps/com.samsung.contacts/res/temp:da39a3ee5e6b4b0d3255bfef95601890afd80709 -DEL:REG:system/usr/ug/res/images/ug-phone/contacts/favorites_icon_remove.PNG:38ad8be378506d19b1c769d46be262cf100f6c59 -DEL:SYM:system/usr/apps/com.samsung.message-lite/lib/libmsg-common.so -DEL:HARD:system/usr/apps/com.samsung.message-lite/lib/libmsg-common.so -SYM:DIFF:system/usr/lib/sync-agent/kies-private/libplugin-na-mobex.so.0:system/usr/lib/sync-agent/kies-private/libplugin-na-mobex.so.0: - libplugin-na-mobex.so.0.3.57 -SYM:NEW:system/lib/firmware/vbc_eq:/opt/system/vbc_eq -HARD:DIFF:system/usr/lib/sync-agent/kies-private/libplugin-na-mobex.so.0:system/usr/lib/sync-agent/kies-private/libplugin-na-mobex.so.0: - libplugin-na-mobex.so.0.3.57 -HARD:NEW:system/lib/firmware/vbc_eq:/opt/system/vbc_eq -*********************************************************************** -*/ - if (local && ((local->diffs) > 0 || (local->moves > 0))) { - LOGL(LOG_SSENGINE, "%ss [%d] %ss [%d]\n", SS_STRING_DIFF, local->diffs, SS_STRING_MOVE, local->moves); - for (i = 0; i < (local->diffs + local->moves); i++) { - if (fgets(line, SS_TOKEN_MAXLINE_LEN, fp) == NULL) { - SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO); - break; - } - //LOGL(LOG_SSENGINE, "DIFF LINE:[%d] [%s] \n",i+1,line); - - change_type = strtok_r(line, SS_TOEKN_COLON, &saveptr); - file_type = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); - if (!file_type) { - LOGE("Unexpected null in strtok_r"); - goto CleanUp; - } - - if (change_type && strcmp(change_type, SS_STRING_MOVE) == 0) { // && strcmp(file_type,"TPK") == 0){ - source_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); - target_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); - sha1src = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr); - //LOGL(LOG_SSENGINE, "%s Index [%d]\n", SS_STRING_MOVE, i); - - if (!source_name || !target_name || !sha1src) { - SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO); - //LOGE("Failed to extract Patch Info Type:DELETES \n"); - LOGE("Failed to parse DIFFS - LINE:[%d] [%s] \n", i + 1, line); - goto CleanUp; - } - retval = - SS_AppendNode(ua_dataSS->update_data->ua_delta_path, &fs_movehead, &fs_movetail, source_name, - target_name, string_na, sha1src, string_na, MOVES, - ua_dataSS->update_delta->ua_patch_path); - if (retval == E_SS_FAILURE) // ONLY test purpose, should enable this - goto CleanUp; - - if (ua_dataSS->ua_operation == UI_OP_SCOUT) { - SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0); - } - } else if (change_type && strcmp(change_type, SS_STRING_DIFF) == 0) { // && strcmp(file_type,"TPK") == 0){ - source_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); - target_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); - sha1src = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); - sha1trg = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); - patch_name = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr); - //LOGL(LOG_SSENGINE, "%s Index [%d]\n", SS_STRING_DIFF, i); - - if (patch_name && (strlen(patch_name) <= SS_MAX_NAMELENSUPPORTED)) { - retval = - SS_AppendNode(ua_dataSS->update_data->ua_delta_path, &fs_diffhead, &fs_difftail, - source_name, target_name, patch_name, sha1src, sha1trg, DIFFS, - ua_dataSS->update_delta->ua_patch_path); - if (retval == E_SS_FAILURE) // ONLY test purpose, should enable this - goto CleanUp; - } else { - SS_SetUpgradeState(E_SS_FILENAMELENERROR); - LOGE("File Name length Limitation Error File:[%s]\n", patch_name); - goto CleanUp; - } - - if (ua_dataSS->ua_operation == UI_OP_SCOUT) { - SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0); - } - } else { - SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO); - LOGE("Patch Name format Error File\n"); - goto CleanUp; - } - } - } - if (local && (local->news) > 0) { //check if new files archive is present in the delta - char new_patch_path[MAX_FILE_PATH] = { 0, }; - snprintf(new_patch_path, MAX_FILE_PATH, "%s%s", ua_dataSS->parti_info->ua_subject_name, SS_COMPRESSED_FILE); - if (tar_get_item_size(ua_dataSS->update_data->ua_delta_path, new_patch_path) <= 0) { - SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO); - LOGE("New files not present in Patch\n"); - goto CleanUp; - } - } - if (local && (local->deletes) > 0) { //this is to group to delete list - LOGL(LOG_SSENGINE, "%ss [%d]\n", SS_STRING_DEL, local->deletes); - for (i = 0; i < (local->deletes); i++) { - if (fgets(line, SS_TOKEN_MAXLINE_LEN, fp) == NULL) { - SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO); - break; - } - - change_type = strtok_r(line, SS_TOEKN_COLON, &saveptr); - if (!change_type) { - LOGE("Unexpected null in strtok_r"); - goto CleanUp; - } - file_type = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); - - if (file_type && strcmp(file_type, SS_STRING_REG) == 0) { - source_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); - sha1src = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr); - del_type = DELETES; - } else if (file_type && ((strcmp(file_type, SS_STRING_SYM) == 0) || (strcmp(file_type, SS_STRING_HARD) == 0))) { - source_name = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr); - sha1src = string_na; - del_type = DELETES; - } else if (file_type && strcmp(file_type, SS_STRING_END) == 0) { - source_name = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr); - sha1src = string_na; - del_type = DELETE_END; - } else { - LOGE("Failed to parse DELETES - LINE:[%d] [%s] \n", i + 1, line); - goto CleanUp; - } - - if (!source_name || !sha1src) { - SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO); - //LOGE("Failed to extract Patch Info Type:DELETES \n"); - LOGE("Failed to parse DELETES - LINE:[%d] [%s] \n", i + 1, line); - goto CleanUp; - } - //LOGL(LOG_SSENGINE, "%s Index [%d]\n", SS_STRING_DEL, i); - retval = - SS_AppendNode(ua_dataSS->update_data->ua_delta_path, &fs_delhead, &fs_deltail, source_name, - string_na, string_na, sha1src, string_na, del_type, - ua_dataSS->update_delta->ua_patch_path); - if (retval == E_SS_FAILURE) // ONLY test purpose, should enable this - goto CleanUp; - if (ua_dataSS->ua_operation == UI_OP_SCOUT) { - SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0); - } - - } - } //For symlink files - - if (local && (local->symdiffs) > 0) { - LOGL(LOG_SSENGINE, "%s %ss [%d]\n", SS_STRING_SYM, SS_STRING_DIFF, local->symdiffs); - for (i = 0; i < (local->symdiffs); i++) { //get the count from below function - if (fgets(line, SS_TOKEN_MAXLINE_LEN, fp) == NULL) { - SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO); - break; - } - //LOGL(LOG_SSENGINE, "SYMDIFF LINE:[%d] [%s] \n",i+1,line); - - change_type = strtok_r(line, SS_TOEKN_COLON, &saveptr); - file_type = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); - - if ((change_type && file_type) && - strcmp(change_type, SS_STRING_SYM) == 0 && strcmp(file_type, SS_STRING_DIFF) == 0) { // && strcmp(file_type,"TPK") == 0){ - source_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); - target_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); - patch_name = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr); - //LOGL(LOG_SSENGINE, "%s %s Index [%d]\n", SS_STRING_SYM, SS_STRING_DIFF, i); - - if (!source_name || !target_name || !patch_name) { - SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO); - //LOGE("Failed to extract Patch Info Type:DELETES \n"); - LOGE("Failed to parse SymDiffs - LINE:[%d] [%s] \n", i + 1, line); - goto CleanUp; - } - retval = - SS_AppendNode(ua_dataSS->update_data->ua_delta_path, &fs_symlinkdiffhead, &fs_symlinkdifftail, - source_name, target_name, patch_name, string_na, string_na, SYMDIFFS, - ua_dataSS->update_delta->ua_patch_path); - if (retval == E_SS_FAILURE) // ONLY test purpose, should enable this - goto CleanUp; - if (ua_dataSS->ua_operation == UI_OP_SCOUT) { - SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0); - } - } - } - } - if (local && (local->symnews) > 0) { - LOGL(LOG_SSENGINE, "%s %ss [%d]n", SS_STRING_SYM, SS_STRING_NEW, local->symnews); - for (i = 0; i < (local->symnews); i++) { - if (fgets(line, SS_TOKEN_MAXLINE_LEN, fp) == NULL) { - SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO); - break; - } - //LOGL(LOG_SSENGINE, "SYMNEWS LINE:[%d] [%s] \n",i+1,line); - - change_type = strtok_r(line, SS_TOEKN_COLON, &saveptr); - file_type = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); - - if ((change_type && file_type) && - (strcmp(change_type, SS_STRING_SYM) == 0 && strcmp(file_type, SS_STRING_NEW) == 0)) { - source_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); - patch_name = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr); - //LOGL(LOG_SSENGINE, "%s %s Index [%d]\n", SS_STRING_SYM, SS_STRING_NEW, i); - - if (!source_name || !patch_name) { - SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO); - //LOGE("Failed to extract Patch Info Type:DELETES \n"); - LOGE("Failed to parse SymNews - LINE:[%d] [%s] \n", i + 1, line); - goto CleanUp; - } - retval = - SS_AppendNode(ua_dataSS->update_data->ua_delta_path, &fs_symlinknewhead, &fs_symlinknewtail, - source_name, string_na, patch_name, string_na, string_na, SYMNEWFILES, - ua_dataSS->update_delta->ua_patch_path); - if (retval == E_SS_FAILURE) // ONLY test purpose, should enable this - goto CleanUp; - if (ua_dataSS->ua_operation == UI_OP_SCOUT) { - SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0); - } - } - } - } // For hardlinks - if (local && (local->hardnews) > 0) { - LOGL(LOG_SSENGINE, "%s %ss [%d]\n", SS_STRING_HARD, SS_STRING_NEW, local->hardnews); - for (i = 0; i < (local->hardnews); i++) { - if (fgets(line, SS_TOKEN_MAXLINE_LEN, fp) == NULL) { - SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO); - break; - } - //LOGL(LOG_SSENGINE, "HARDNEWS LINE:[%d] [%s] \n",i+1,line); - - change_type = strtok_r(line, SS_TOEKN_COLON, &saveptr); - file_type = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); - - if ((change_type && file_type) && - (strcmp(change_type, SS_STRING_HARD) == 0 && strcmp(file_type, SS_STRING_NEW) == 0)) { - source_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); - patch_name = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr); - //LOGL(LOG_SSENGINE, "%s %s Index [%d]\n", SS_STRING_SYM, SS_STRING_NEW, i); - - if (!source_name || !patch_name) { - SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO); - //LOGE("Failed to extract Patch Info Type:DELETES \n"); - LOGE("Failed to parse HardNews - LINE:[%d] [%s] \n", i + 1, line); - goto CleanUp; - } - retval = - SS_AppendNode(ua_dataSS->update_data->ua_delta_path, &fs_hardlinknewhead, &fs_hardlinkdnewtail, - source_name, string_na, patch_name, string_na, string_na, HARDNEWFILES, - ua_dataSS->update_delta->ua_patch_path); - if (retval == E_SS_FAILURE) // ONLY test purpose, should enable this - goto CleanUp; - if (ua_dataSS->ua_operation == UI_OP_SCOUT) { - SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0); - } - } - } - } - - if (local && (local->harddiffs) > 0) { - LOGL(LOG_SSENGINE, "%s %ss [%d]\n", SS_STRING_HARD, SS_STRING_DIFF, local->harddiffs); - for (i = 0; i < (local->harddiffs); i++) { //get the count from below function - if (fgets(line, SS_TOKEN_MAXLINE_LEN, fp) == NULL) { - SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO); - break; - } - //LOGL(LOG_SSENGINE, "HARDIFFS LINE:[%d] [%s] \n",i+1,line); - - change_type = strtok_r(line, SS_TOEKN_COLON, &saveptr); - file_type = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); - - if ((change_type && file_type) && - strcmp(change_type, SS_STRING_HARD) == 0 && strcmp(file_type, SS_STRING_DIFF) == 0) { // && strcmp(file_type,"TPK") == 0){ - source_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); - target_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); - patch_name = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr); - //LOGL(LOG_SSENGINE, "%s %s Index [%d]\n", SS_STRING_SYM, SS_STRING_DIFF, i); - - if (!source_name || !target_name || !patch_name) { - SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO); - //LOGE("Failed to extract Patch Info Type:DELETES \n"); - LOGE("Failed to parse HardDiffs - LINE:[%d] [%s] \n", i + 1, line); - goto CleanUp; - } - retval = - SS_AppendNode(ua_dataSS->update_data->ua_delta_path, &fs_hardlinkdiffhead, &fs_hardlinkdifftail, - source_name, target_name, patch_name, string_na, string_na, HARDDIFFS, - ua_dataSS->update_delta->ua_patch_path); - if (retval == E_SS_FAILURE) // ONLY test purpose, should enable this - goto CleanUp; - if (ua_dataSS->ua_operation == UI_OP_SCOUT) { - SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0); - } - } - } - } - - fs_head_node = (fs_list *) SS_Malloc(sizeof(fs_list)); - if (!fs_head_node) { - SS_SetUpgradeState(E_SS_MALLOC_ERROR); - goto CleanUp; - } - fs_head_node->dif_ref = fs_diffhead; - fs_head_node->move_ref = fs_movehead; - fs_head_node->new_ref = fs_newhead; - fs_head_node->del_ref = fs_delhead; - fs_head_node->sym_difref = fs_symlinkdiffhead; - fs_head_node->sym_newref = fs_symlinknewhead; - fs_head_node->hard_difref = fs_hardlinkdiffhead; - fs_head_node->hard_newref = fs_hardlinknewhead; - fs_head_node->ulPatchCount = ulPatchCount; - - if (ua_dataSS->ua_operation == UI_OP_SCOUT) { - SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 1); - } - - CleanUp: - fclose(fp); - SS_Free(local); - unlink(patchlist_backup_patch); - if (retval == E_SS_FAILURE) - if (tar_cfg_data) - tar_free_cfg_table(&tar_cfg_data); - return fs_head_node; -} - -void SS_GetPartition_LocDetails(ua_dataSS_t * ua_dataSS) -{ - LOGL(LOG_SSENGINE, "PART NAME: [%s] \n", ua_dataSS->parti_info->ua_parti_name); - snprintf(ua_dataSS->update_delta->ua_patch_path, MAX_FILE_PATH, "%s", ua_dataSS->parti_info->ua_subject_name); - snprintf(ua_dataSS->update_delta->ua_patch_info, MAX_FILE_PATH, "%s%s%s", ua_dataSS->parti_info->ua_subject_name, - ua_dataSS->parti_info->ua_parti_name, SS_PATCHLISTFORMAT); - snprintf(ua_dataSS->update_delta->ua_attrib_path, MAX_FILE_PATH, "%s%s%s", ua_dataSS->parti_info->ua_subject_name, - ua_dataSS->parti_info->ua_parti_name, SS_PATCH_ATTR_FORMAT); - LOGL(LOG_SSENGINE, "PatchPath[%s] PatchInfo [%s] Attributes [%s]\n", ua_dataSS->update_delta->ua_patch_path, - ua_dataSS->update_delta->ua_patch_info, ua_dataSS->update_delta->ua_attrib_path); - - return; -} - -//Support functions//Change Struct format details (Can include total file count also???)/*! -/* -******************************************************************************** * -SS_FSSetAttributes - ********************************************************************************* - * *@brief - * This is used to set the file attributes at the end of application of patches in FS - * - * *@param - * - *@return returns S_SS_SUCCESS - * E_SS_FAILURE in case of error - * - ********************************************************************************* - */ -int SS_FSSetAttributes(ua_dataSS_t * ua_dataSS) -{ - char *pline = NULL; - char *psaveptr = NULL; - char *pfilePath = NULL; - char *pfiletype = NULL; - char *attributSize = NULL; - char *pattribs = NULL; - int ulAttribSize = 0; - int result = S_SS_SUCCESS; - int fail_cnt = 0; - - if (!(ua_dataSS && ua_dataSS->update_delta && ua_dataSS->update_data->ua_delta_path)) { - LOGE("Bad params for SS_FSSetAttributes\n"); - SS_SetUpgradeState(E_SS_BAD_PARAMS); - return E_SS_FAILURE; - } - LOGL(LOG_SSENGINE, "ATTRIB PATH: [%s] \n", ua_dataSS->update_delta->ua_attrib_path); - - int item_size = tar_get_item_size(ua_dataSS->update_data->ua_delta_path, ua_dataSS->update_delta->ua_attrib_path); - - if (item_size <= 0) { - LOGL(LOG_SSENGINE, "No Attributes to SET\n"); - return S_SS_SUCCESS; // Delta with ONLY deletes - } - char *item_data = SS_Malloc(item_size + 1); - if (item_data == NULL) { - LOGE("SS_Malloc failed!! - item_data\n"); - SS_SetUpgradeState(E_SS_MALLOC_ERROR); - return E_SS_FAILURE; - } - int read_data = - tar_get_cfg_data(ua_dataSS->update_data->ua_delta_path, ua_dataSS->update_delta->ua_attrib_path, item_data, - item_size); - if (read_data <= 0) { - LOGE("read_data failed!!\n"); - SS_SetUpgradeState(E_SS_FSBADDELTA); - if (item_data != NULL) { - SS_Free(item_data); - item_data = NULL; - } - return E_SS_FAILURE; - } - item_data[read_data] = '\0'; - - pline = strtok_r(item_data, "\n", &psaveptr); - if (pline == NULL) { - LOGL(LOG_SSENGINE, "No Attributes to SET as no lines in file\n"); - if (item_data != NULL) { - SS_Free(item_data); - item_data = NULL; - } - return E_SS_FAILURE; - } - - while (pline) { - char *saveptr_pline = NULL; - pfilePath = strtok_r(pline, "\"", &saveptr_pline); - - if (pfilePath && strcmp(pfilePath, SS_FWSLASH) == 0) { - LOGE("skip root: it is RO\n"); - pline = strtok_r(NULL, SS_TOKEN_NEWLINE, &psaveptr); - continue; - } - - pfiletype = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr_pline); - attributSize = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr_pline); - pattribs = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr_pline); - //LOG("\nSS_FSSetAttributes [%s][%s][%s]", pfiletype, attributSize, pattribs); - if (pattribs && pfilePath && pfiletype && attributSize) { - ulAttribSize = strlen(pattribs); - //LOG("\nSS_SetFileAttributes [%s][%s][%d][%s]",pfilePath,pfiletype,ulAttribSize, pattribs ); - //LOG("SS_SetFileAttributes [%s]\n", pfilePath); - - result = SS_SetFileAttributes(pfilePath, ulAttribSize, (const unsigned char *)pattribs); - if (result != S_SS_SUCCESS) { - LOGE("Failed to set Attributes %s\n", pfilePath); - SS_SetUpgradeState(E_SS_FSBADATTRIBUTES); - if (item_data) { - SS_Free(item_data); - item_data = NULL; - } - fail_cnt++; - } - } else { - LOGE("Failed to Parse Attributes - LINE %s\n", pline); - SS_SetUpgradeState(E_SS_FSBADATTRIBUTES); - if (item_data) { - SS_Free(item_data); - item_data = NULL; - } - fail_cnt++; - } - pline = strtok_r(NULL, SS_TOKEN_NEWLINE, &psaveptr); - } - - if (item_data != NULL) { - SS_Free(item_data); - item_data = NULL; - } - - if (fail_cnt > 0) - result = E_SS_FAILURE; - else - result = S_SS_SUCCESS; - - return result; -} - -/*! - ********************************************************************************* - * SS_FSUpdateFile - ********************************************************************************* - * - * @brief - * This is used to update individual files on case basis - * - * - * @param - * - * @return returns S_SS_SUCCESS - * E_SS_FAILURE in case of error - * - ********************************************************************************* - */ -int SS_FSUpdateFile(int ubFileType, ua_dataSS_t * ua_dataSS, int ulPatchCount, fs_params * pFsNode, - const char *patch_path) -{ - int ulFileIndex = 1; - char ubPatch[SS_MAX_FILE_PATH] = { 0, }; - int ulReadCnt = 0; - int ulResult = S_SS_SUCCESS; - FileInfo source_file; - FileInfo target_file; - uint8_t target_sha1[SHA_DIGEST_SIZE] = { 0, }; - char new_compressed_path[MAX_FILE_PATH], patchfile_source_path[MAX_FILE_PATH]; - snprintf(new_compressed_path, MAX_FILE_PATH, "%s/%s", ua_dataSS->update_data->ua_delta_folder, SS_NEW_COMPRESSED_FILE); - snprintf(patchfile_source_path, MAX_FILE_PATH, "%s/%s", ua_dataSS->update_data->ua_delta_folder, SS_PATCHFILE_SOURCE); - - if (!patch_path) { - LOGE("Bad patch_path name\n"); - return E_SS_FAILURE; - } - switch (ubFileType) { - case DIFFS: - { - LOGL(LOG_SSENGINE, "DIFFS mode start\n"); -#ifdef TIME_PROFILING - get_time_stamp1(); //total time capturing - t1 = atof(ts1); - LOGL(LOG_SSENGINE, "DIFFS mode start time = [%lf]\n", - t1); -#endif - tar_open(ua_dataSS->update_data->ua_delta_path); - while (pFsNode) { - //LOGL(LOG_SSENGINE, "DIFFS update Index: [%d] \n", ulFileIndex++); - snprintf(ubPatch, SS_MAX_FILE_PATH, "%s%s", patch_path, pFsNode->patch_name); - //LOGL(LOG_SSENGINE, "DIFF list --- [File Name %s]\n [Patch Name %s]",pFsNode->file_path, ubPatch); - if (pFsNode->data_size > 0) { - ulReadCnt = - fast_tar_extract_file(ua_dataSS->update_data->ua_delta_path, ubPatch, patchfile_source_path, - pFsNode->data_size, pFsNode->data_offset); - if (ulReadCnt < 0) { - ulResult = E_SS_FAILURE; - tar_close(); - SS_SetUpgradeState(E_SS_FSUPDATEFAILED); - LOGE("Delta Read Failed\n"); - break; - } - //LOGL(LOG_SSENGINE,"Updating [Item - %s]and size is[%d] Read Count[%d]\n",ubPatch, pFsNode->data_size, ulReadCnt); - - if (ulReadCnt > 0) - ulResult = - SS_UpdateDeltaFS(pFsNode->file_old_path, pFsNode->file_new_path, pFsNode->sha1src, - pFsNode->sha1trg, pFsNode->data_size, ua_dataSS->update_data->ua_delta_folder); - if (ulResult != S_SS_SUCCESS) { - LOGE("FS update Failed Result : [%d], [Item - %s]and size is[%d] Read Count[%d], index = [%d]\n", ulResult, - ubPatch, pFsNode->data_size, ulReadCnt, ulFileIndex); - tar_close(); - SS_SetUpgradeState(E_SS_FSUPDATEFAILED); - break; - } - SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0); - pFsNode = pFsNode->nextnode; - } - else { - ulResult = E_SS_FAILURE; - tar_close(); - LOGE("size is invalid, index = [%d]\n", - ulFileIndex); - SS_SetUpgradeState(E_SS_FSUPDATEFAILED); - break; - } - ulFileIndex++; - } - LOGL(LOG_SSENGINE, "DIFFS : Total index = [%d]\n", - ulFileIndex - 1); -#ifdef TIME_PROFILING - get_time_stamp1(); //total time capturing - t2 = atof(ts1); - LOGL(LOG_SSENGINE, - "DIFFS mode end time = [%lf], diff = [%lf]\n", t2, - (t2 - t1)); -#endif - tar_close(); - LOGL(LOG_SSENGINE, "DIFFS mode end\n"); - } - break; - case MOVES: - { - LOGL(LOG_SSENGINE, "MOVES mode start\n"); - -#ifdef TIME_PROFILING - get_time_stamp1(); //total time capturing - t1 = atof(ts1); - LOGL(LOG_SSENGINE, "MOVES mode start time = [%lf]\n", - t1); -#endif - while (pFsNode) { - //LOGL(LOG_SSENGINE, "MOVES update Index: [%d] \n", ulFileIndex++); - int skip_flag = 0; - if (SS_LoadFile(pFsNode->file_old_path, &source_file) == 0) { - LOGL(LOG_SSENGINE, "Patch Can be applied\n"); - if (source_file.data) - SS_Free(source_file.data); - } else if (SS_LoadFile(pFsNode->file_new_path, &target_file) == 0) { - LOGL(LOG_SSENGINE, "source deleted!!, file_old_path: [%s]\n", pFsNode->file_old_path); - if (ParseSha1(pFsNode->sha1src, target_sha1) != 0) { - LOGE("failed to parse sha1 \"%s\"\n", pFsNode->sha1src); - ulResult = E_SS_FAILURE; - SS_SetUpgradeState(E_SS_FSUPDATEFAILED); - if (target_file.data) - SS_Free(target_file.data); - break; - } - if (memcmp(target_file.sha1, target_sha1, SHA_DIGEST_SIZE) == 0) { - LOGL(LOG_SSENGINE, "Patch already applied\n"); - skip_flag = 1; - if (target_file.data) - SS_Free(target_file.data); - } else { - LOGL(LOG_SSENGINE, "target_sha1 diff!!: [%s]\n", target_sha1); - ulResult = E_SS_FAILURE; - SS_SetUpgradeState(E_SS_FSUPDATEFAILED); - if (target_file.data) - SS_Free(target_file.data); - break; - } - } else { - LOGE("No exist files. - file_old_path: [%s] file_new_path: [%s]\n", pFsNode->file_old_path, pFsNode->file_new_path); - ulResult = E_SS_FAILURE; - SS_SetUpgradeState(E_SS_FSUPDATEFAILED); - break; - } - - if (skip_flag == 0) { - ulResult = SS_MoveFile(pFsNode->file_old_path, pFsNode->file_new_path); - if (ulResult != S_SS_SUCCESS) { - LOGE("Move Failed for [%s] to [%s], result = [%d], index = [%d]\n", pFsNode->file_old_path, pFsNode->file_new_path, ulResult, ulFileIndex); - SS_SetUpgradeState(ulResult); - break; - } else { - // Verification - if (SS_LoadFile(pFsNode->file_new_path, &target_file) == 0) { - if (ParseSha1(pFsNode->sha1src, target_sha1) != 0) { - LOGE("failed to parse sha1 \"%s\"\n", pFsNode->sha1src); - ulResult = E_SS_FAILURE; - SS_SetUpgradeState(E_SS_FSUPDATEFAILED); - if (target_file.data) - SS_Free(target_file.data); - break; - } - if (memcmp(target_file.sha1, target_sha1, SHA_DIGEST_SIZE) == 0) { - LOGL(LOG_SSENGINE, "Patch success!!\n"); - if (target_file.data) - SS_Free(target_file.data); - } else { - LOGL(LOG_SSENGINE, "target_sha1 diff!!: [%s]\n", target_sha1); - ulResult = E_SS_FAILURE; - SS_SetUpgradeState(E_SS_FSUPDATEFAILED); - if (target_file.data) - SS_Free(target_file.data); - break; - } - } - } - } - SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0); - pFsNode = pFsNode->nextnode; - ulFileIndex++; - } - LOGL(LOG_SSENGINE, "MOVES : Total index = [%d]\n", - ulFileIndex - 1); -#ifdef TIME_PROFILING - get_time_stamp1(); //total time capturing - t2 = atof(ts1); - LOGL(LOG_SSENGINE, - "MOVES mode end time = [%lf], diff = [%lf]\n", t2, - (t2 - t1)); -#endif - LOGL(LOG_SSENGINE, "MOVES mode end\n"); - } - break; - case DELETES: - { - LOGL(LOG_SSENGINE, "DELETES mode start\n"); - - int ulFiletype = 0; -#ifdef TIME_PROFILING - get_time_stamp1(); //total time capturing - t1 = atof(ts1); - LOGL(LOG_SSENGINE, "DELETES mode start time = [%lf]\n", - t1); -#endif - while (pFsNode) { - if (pFsNode->type == DELETES) { - //LOGL(LOG_SSENGINE, "DELETES update Index: [%d] \n", ulFileIndex++); - SS_GetFileType(pFsNode->file_old_path, (enumFileType *) & ulFiletype); - if (ulFiletype == 2) //FT_FOLDER - ulResult = SS_DeleteFolder(pFsNode->file_old_path); - else - ulResult = SS_DeleteFile(pFsNode->file_old_path); - if (ulResult != S_SS_SUCCESS) { - LOGE("Delete Failed, result = [%d], index = [%d]\n", ulResult, ulFileIndex); - SS_SetUpgradeState(ulResult); - break; - } - ulFileIndex++; - } - SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0); - pFsNode = pFsNode->nextnode; - } - LOGL(LOG_SSENGINE, "DELETES : Total index = [%d]\n", - ulFileIndex - 1); -#ifdef TIME_PROFILING - get_time_stamp1(); //total time capturing - t2 = atof(ts1); - LOGL(LOG_SSENGINE, - "DELETES mode end time = [%lf], diff = [%lf]\n", - t2, (t2 - t1)); -#endif - LOGL(LOG_SSENGINE, "DELETES mode end\n"); - } - break; - case DELETE_END: - { - LOGL(LOG_SSENGINE, "DELETE_END mode start\n"); - - int ulFiletype = 0; -#ifdef TIME_PROFILING - get_time_stamp1(); //total time capturing - t1 = atof(ts1); - LOGL(LOG_SSENGINE, - "DELETE_END mode start time = [%lf]\n", t1); -#endif - while (pFsNode) { - if (pFsNode->type == DELETE_END) { - LOGL(LOG_SSENGINE, "DELETE_END update Index: [%d] \n", ulFileIndex++); - SS_GetFileType(pFsNode->file_old_path, (enumFileType *) & ulFiletype); - if (ulFiletype == 2) //FT_FOLDER - ulResult = SS_DeleteFolder(pFsNode->file_old_path); - else - ulResult = SS_DeleteFile(pFsNode->file_old_path); - if (ulResult != S_SS_SUCCESS) { - LOGE("Delete Failed, result = [%d], index = [%d]\n", ulResult, ulFileIndex); - SS_SetUpgradeState(ulResult); - break; - } - ulFileIndex++; - } - pFsNode = pFsNode->nextnode; - } - LOGL(LOG_SSENGINE, "DELETE_END : Total index = [%d]\n", - ulFileIndex - 1); -#ifdef TIME_PROFILING - get_time_stamp1(); //total time capturing - t2 = atof(ts1); - LOGL(LOG_SSENGINE, - "DELETE_END mode start time = [%lf], diff = [%lf]\n", - t2, (t2 - t1)); -#endif - LOGL(LOG_SSENGINE, "DELETE_END mode end\n"); - } - break; - - case NEWFILES: - { - LOGL(LOG_SSENGINE, "NEWFILES mode start\n"); - -#ifdef TIME_PROFILING - get_time_stamp1(); //total time capturing - t1 = atof(ts1); - LOGL(LOG_SSENGINE, "NEWFILES mode start time = [%lf]\n", - t1); -#endif - LOGL(LOG_SSENGINE, "Starting New file upgrade for [%s]\n", patch_path); - if (tar_extract_file(ua_dataSS->update_data->ua_delta_path, (char *)patch_path, new_compressed_path) >= - 0) - if (_7zdecompress(new_compressed_path) == 0) - LOGL(LOG_SSENGINE, "7zip extracted successfully %s\n", ua_dataSS->parti_info->ua_parti_name); - else - LOGL(LOG_SSENGINE, "7zip extraction error for %s\n", ua_dataSS->parti_info->ua_parti_name); - else - LOGL(LOG_SSENGINE, "tar extraction error for %s\n", ua_dataSS->parti_info->ua_parti_name); - SS_DeleteFile(new_compressed_path); -#ifdef TIME_PROFILING - get_time_stamp1(); //total time capturing - t2 = atof(ts1); - LOGL(LOG_SSENGINE, - "NEWFILES mode end time = [%lf], diff = [%lf]\n", - t2, (t2 - t1)); -#endif - LOGL(LOG_SSENGINE, "NEWFILES mode end\n"); - } - break; - case SYMDIFFS: - { - LOGL(LOG_SSENGINE, "SYMDIFFS mode start\n"); - -#ifdef TIME_PROFILING - get_time_stamp1(); //total time capturing - t1 = atof(ts1); - LOGL(LOG_SSENGINE, "SYMDIFFS mode start time = [%lf]\n", - t1); -#endif - while (pFsNode) { - //LOGL(LOG_SSENGINE, "SYMDIFFS update Index: [%d] \n", ulFileIndex++); - //LOG("Sym Diff file paths: [Linkname - %s] [reference file name- %s][]\n", pFsNode->file_path,pFsNode->patch_name); - ulResult = SS_Unlink(pFsNode->file_old_path); - if (ulResult == S_SS_SUCCESS) { - ulResult = SS_Link(NULL, pFsNode->file_new_path, pFsNode->patch_name); - if (ulResult != S_SS_SUCCESS) { - LOGE("SS_Link Failed, Linkname:[%s], reference file name, index = [%d]:[%s]\n", - pFsNode->file_new_path, ulFileIndex, pFsNode->patch_name); - } - } else { - LOGE("Unlink Failed, result = [%d], index = [%d]\n", ulResult, ulFileIndex); - SS_SetUpgradeState(E_SS_FSUPDATEFAILED); - break; - } - SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0); - pFsNode = pFsNode->nextnode; - ulFileIndex++; - } - LOGL(LOG_SSENGINE, "SYMDIFFS : Total index = [%d]\n", - ulFileIndex - 1); -#ifdef TIME_PROFILING - get_time_stamp1(); //total time capturing - t2 = atof(ts1); - LOGL(LOG_SSENGINE, - "SYMDIFFS mode end time = [%lf], diff = [%lf]\n", - t2, (t2 - t1)); -#endif - LOGL(LOG_SSENGINE, "SYMDIFFS mode end\n"); - } - break; - case SYMNEWFILES: - { - LOGL(LOG_SSENGINE, "SYMNEWFILES mode start\n"); - - fs_params *head_node; - int retry_count = 0, do_retry = 0; -#ifdef TIME_PROFILING - get_time_stamp1(); //total time capturing - t1 = atof(ts1); - LOGL(LOG_SSENGINE, - "SYMNEWFILES mode start time = [%lf]\n", t1); -#endif - SYMLINK_CREATE: - head_node = pFsNode; - while (head_node) { - //LOGL(LOG_SSENGINE, "SYMNEWS update Index: [%d] \n", ulFileIndex++); - snprintf(ubPatch, SS_MAX_FILE_PATH, "%s%s%s", patch_path, "/", head_node->patch_name); - LOGL(LOG_SSENGINE, "Sym New file paths: [Linkname - %s] [reference file name- %s][]\n", - head_node->file_old_path, head_node->patch_name); - ulResult = SS_Link(NULL, head_node->file_old_path, head_node->patch_name); - if (ulResult == E_SS_FAILURE) { - LOGE("Link Failed, result = [%d], index = [%d]\n", ulResult, ulFileIndex); - SS_SetUpgradeState(E_SS_FSUPDATEFAILED); - break; - } else if (ulResult == ENOENT) { //to handle cases where new symlink points to a new symlink yet to be created - do_retry = 1; //we will retry the failed symlinks with error 2 (no file or dir) again after this cycle - //SS_UpdateUIProgress(ua_dataSS,ulPatchCount); - head_node = head_node->nextnode; - continue; - } - SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0); - head_node = head_node->nextnode; - ulFileIndex++; - } - LOGL(LOG_SSENGINE, "SYMNEWFILES : Total index = [%d]\n", - ulFileIndex - 1); - if (do_retry && (retry_count < 4)) { - retry_count++; - ulFileIndex = 0; - do_retry = 0; - goto SYMLINK_CREATE; - } else if (do_retry && (retry_count >= 4)) { //retry to be done maximum 4 times - LOGE("Link Failed after %d retrys\n", retry_count); - //SS_SetUpgradeState(E_SS_FSUPDATEFAILED); - break; - } -#ifdef TIME_PROFILING - get_time_stamp1(); //total time capturing - t2 = atof(ts1); - LOGL(LOG_SSENGINE, - "SYMNEWFILES mode end time = [%lf], diff = [%lf]\n", - t2, (t2 - t1)); -#endif - LOGL(LOG_SSENGINE, "SYMNEWFILES mode end\n"); - } - break; - case HARDDIFFS: - { - LOGL(LOG_SSENGINE, "HARDDIFFS mode start\n"); - -#ifdef TIME_PROFILING - get_time_stamp1(); //total time capturing - t1 = atof(ts1); - LOGL(LOG_SSENGINE, "HARDDIFFS mode start time = [%lf]\n", - t1); -#endif - while (pFsNode) { - //LOGL(LOG_SSENGINE, "SYMDIFFS update Index: [%d] \n", ulFileIndex++); - //LOG("Sym Diff file paths: [Linkname - %s] [reference file name- %s][]\n", pFsNode->file_path,pFsNode->patch_name); - ulResult = SS_DeleteFile(pFsNode->file_old_path); - if (ulResult == S_SS_SUCCESS) { - ulResult = SS_HardLink(pFsNode->file_new_path, pFsNode->patch_name); - if (ulResult != S_SS_SUCCESS) { - LOGE("SS_HardLink Failed, Linkname:[%s], reference file name, index = [%d]:[%s]\n", - pFsNode->file_new_path, ulFileIndex, pFsNode->patch_name); - } - } else { - LOGE("Removing old hardlink Failed, result = [%d], index = [%d]\n", ulResult, ulFileIndex); - SS_SetUpgradeState(E_SS_FSUPDATEFAILED); - break; - } - SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0); - pFsNode = pFsNode->nextnode; - ulFileIndex++; - } - LOGL(LOG_SSENGINE, "HARDDIFFS : Total index = [%d]\n", - ulFileIndex - 1); -#ifdef TIME_PROFILING - get_time_stamp1(); //total time capturing - t2 = atof(ts1); - LOGL(LOG_SSENGINE, - "HARDDIFFS mode end time = [%lf], diff = [%lf]\n", - t2, (t2 - t1)); -#endif - LOGL(LOG_SSENGINE, "HARDDIFFS mode end\n"); - } - break; - case HARDNEWFILES: - { - LOGL(LOG_SSENGINE, "HARDNEWFILES mode start\n"); - -#ifdef TIME_PROFILING - get_time_stamp1(); //total time capturing - t1 = atof(ts1); - LOGL(LOG_SSENGINE, - "HARDNEWFILES mode start time = [%lf]\n", t1); -#endif - fs_params *head_node = pFsNode; - while (head_node) { - //LOGL(LOG_SSENGINE, "SYMNEWS update Index: [%d] \n", ulFileIndex++); - LOGL(LOG_SSENGINE, "Hardlink New file paths: [Linkname - %s] [reference file name- %s][]\n", - head_node->file_old_path, head_node->patch_name); - ulResult = SS_HardLink(head_node->file_old_path, head_node->patch_name); - if (ulResult == E_SS_FAILURE) { - LOGE("Link Failed, result = [%d], index = [%d]\n", ulResult, ulFileIndex); - SS_SetUpgradeState(E_SS_FSUPDATEFAILED); - break; - } - SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0); - head_node = head_node->nextnode; - ulFileIndex++; - } - LOGL(LOG_SSENGINE, "HARDNEWFILES : Total index = [%d]\n", - ulFileIndex - 1); - -#ifdef TIME_PROFILING - get_time_stamp1(); //total time capturing - t2 = atof(ts1); - LOGL(LOG_SSENGINE, - "HARDNEWFILES mode end time = [%lf], diff = [%lf]\n", - t2, (t2 - t1)); -#endif - LOGL(LOG_SSENGINE, "HARDNEWFILES mode end\n"); - - } - break; - default: - break; - } - return ulResult; -} - -#ifdef MEM_PROFILING -extern int max_mem; -extern int cur_mem; -#endif -/*! - ********************************************************************************* - * SS_FSUpdatemain - ********************************************************************************* - * - * @brief - * This is the API exposed from the engine to update FS. - * - * - * @param - * - * @return returns S_SS_SUCCESS - * E_SS_FAILURE in case of error - * - ********************************************************************************* - */ - -int SS_FSUpdatemain(ua_dataSS_t * ua_dataSS) -{ - int ulResult = S_SS_SUCCESS; - int last_update_status = 0; - int del_type = 0; - fs_list *head_ptr_node = NULL; - char new_patch_path[SS_MAX_FILE_PATH] = { - 0 - }; - char status_path[MAX_FILE_PATH]; - snprintf(status_path, MAX_FILE_PATH, "%s/%s",ua_dataSS->update_data->ua_delta_folder, SS_UPDATE_STATUS_PATH); - - if (!ua_dataSS) - return E_SS_BAD_PARAMS; // Set error ?? - head_ptr_node = headptr_list; - - if (!head_ptr_node) { //in case of power failure, try rebilding nodes again - SS_FSVerifyPartition(ua_dataSS); - head_ptr_node = headptr_list; - } - - if (!head_ptr_node) - return E_SS_FSBADNODES; - - SS_GetPartition_LocDetails(ua_dataSS); - - LOGL(LOG_SSENGINE, "FS Update Entry\n"); - -#ifdef POWER_FAIL_TEST - int fail_test_flag = 0; - fail_test_flag = SS_Get_power_fail_flag(); - LOGL(LOG_SSENGINE, "fail_test_flag: [%d]\n", fail_test_flag); -#endif - - if(SS_Get_last_update_status(&last_update_status, &del_type, status_path) == -1) - LOGE("SS_Get_last_update_status failed!!\n"); - - LOGL(LOG_SSENGINE, "last_update_status: [%d], del_type: [%d]\n", last_update_status, del_type); - - // for now, we don't want to read last del_type as the logic doesn't work - del_type = 0; - - if (head_ptr_node->del_ref == NULL) { - LOGL(LOG_SSENGINE, "No DEL header\n"); - } else if (ulResult == S_SS_SUCCESS) { - if (del_type < DELETES) { - ulResult = SS_FSUpdateFile(DELETES, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->del_ref, - ua_dataSS->update_delta->ua_patch_path); - if (ulResult == S_SS_SUCCESS) { - LOGL(LOG_SSENGINE, "SS_FSUpdateFile - DELETES success!!\n"); - -#ifdef POWER_FAIL_TEST - if (fail_test_flag < DELETES) { - if (SS_Do_Power_fail_test(DELETES) == E_SS_FAILURE) { - LOGE("SS_Do_Power_fail_test failed!!\n"); - } - } -#endif - SS_Set_last_update_status(0, DELETES, status_path); - } - } else { - LOGL(LOG_SSENGINE, "SS_FSUpdateFile - DELETES already applied!!\n"); - } - } - - if (head_ptr_node->dif_ref == NULL) { - LOGL(LOG_SSENGINE, "No DIFF header\n"); - } else if (ulResult == S_SS_SUCCESS) { - ulResult = - SS_FSUpdateFile(DIFFS, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->dif_ref, - ua_dataSS->update_delta->ua_patch_path); - if (ulResult == S_SS_SUCCESS) { - LOGL(LOG_SSENGINE, "SS_FSUpdateFile - DIFFS success!!\n"); -#ifdef POWER_FAIL_TEST - if (fail_test_flag < DIFFS) { - if (SS_Do_Power_fail_test(DIFFS) == E_SS_FAILURE) { - LOGE("SS_Do_Power_fail_test failed!!\n"); - } - } -#endif - } - } - - if (head_ptr_node->move_ref == NULL) { - LOGL(LOG_SSENGINE, "No MOVE header\n"); - } else if (ulResult == S_SS_SUCCESS) { - if (del_type < MOVES) { - ulResult = - SS_FSUpdateFile(MOVES, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->move_ref, - ua_dataSS->update_delta->ua_patch_path); - if (ulResult == S_SS_SUCCESS) { - LOGL(LOG_SSENGINE, "SS_FSUpdateFile - MOVES success!!\n"); -#ifdef POWER_FAIL_TEST - if (fail_test_flag < MOVES) { - if (SS_Do_Power_fail_test(MOVES) == E_SS_FAILURE) { - LOGE("SS_Do_Power_fail_test failed!!\n"); - } - } -#endif - SS_Set_last_update_status(0, MOVES, status_path); - } - } else { - LOGL(LOG_SSENGINE, "SS_FSUpdateFile - MOVES already applied!!\n"); - } - } - - if (head_ptr_node->del_ref == NULL) { - LOGL(LOG_SSENGINE, "No DEL header\n"); - } else if (ulResult == S_SS_SUCCESS) { - if (del_type < DELETE_END) { - ulResult = SS_FSUpdateFile(DELETE_END, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->del_ref, - ua_dataSS->update_delta->ua_patch_path); - if (ulResult == S_SS_SUCCESS) { - LOGL(LOG_SSENGINE, "SS_FSUpdateFile - DELETE_END success!!\n"); -#ifdef POWER_FAIL_TEST - if (fail_test_flag < DELETE_END) { - if (SS_Do_Power_fail_test(DELETE_END) == E_SS_FAILURE) { - LOGE("SS_Do_Power_fail_test failed!!\n"); - } - } -#endif - SS_Set_last_update_status(0, DELETE_END, status_path); - } - } else { - LOGL(LOG_SSENGINE, "SS_FSUpdateFile - DELETE_END already applied!!\n"); - } - } - - if (ulResult == S_SS_SUCCESS) { - //new file extraction start - snprintf(new_patch_path, SS_MAX_FILE_PATH, "%s%s", ua_dataSS->parti_info->ua_subject_name, SS_COMPRESSED_FILE); // subject name wil have fw slash as part of cfg file - LOGL(LOG_SSENGINE, "File path created to extract new files : [%s]\n", new_patch_path); - ulResult = - SS_FSUpdateFile(NEWFILES, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->new_ref, new_patch_path); - //new file extraction end - if (ulResult == S_SS_SUCCESS) { - LOGL(LOG_SSENGINE, "SS_FSUpdateFile - NEWFILES success!!\n"); - } - } - - if (head_ptr_node->sym_difref == NULL) { - LOGL(LOG_SSENGINE, "No SYMDIFF header\n"); - } else if (ulResult == S_SS_SUCCESS) { - ulResult = - SS_FSUpdateFile(SYMDIFFS, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->sym_difref, - ua_dataSS->update_delta->ua_patch_path); - if (ulResult == S_SS_SUCCESS) { - LOGL(LOG_SSENGINE, "SS_FSUpdateFile - SYMDIFFS success!!\n"); -#ifdef POWER_FAIL_TEST - if (fail_test_flag < SYMDIFFS) { - if (SS_Do_Power_fail_test(SYMDIFFS) == E_SS_FAILURE) { - LOGE("SS_Do_Power_fail_test failed!!\n"); - } - } -#endif - } - } - - if (head_ptr_node->sym_newref == NULL) { - LOGL(LOG_SSENGINE, "No SYMNEW header\n"); - } else if (ulResult == S_SS_SUCCESS) { - ulResult = - SS_FSUpdateFile(SYMNEWFILES, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->sym_newref, - ua_dataSS->update_delta->ua_patch_path); - if (ulResult == S_SS_SUCCESS) { - LOGL(LOG_SSENGINE, "SS_FSUpdateFile - SYMNEWFILES success!!\n"); -#ifdef POWER_FAIL_TEST - if (fail_test_flag < SYMNEWFILES) { - if (SS_Do_Power_fail_test(SYMNEWFILES) == E_SS_FAILURE) { - LOGE("SS_Do_Power_fail_test failed!!\n"); - } - } -#endif - } - } - - if (head_ptr_node->hard_newref == NULL) { - LOGL(LOG_SSENGINE, "No HARDNEW header\n"); - } else if (ulResult == S_SS_SUCCESS) { - ulResult = - SS_FSUpdateFile(HARDNEWFILES, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->hard_newref, - ua_dataSS->update_delta->ua_patch_path); - if (ulResult == S_SS_SUCCESS) { - LOGL(LOG_SSENGINE, "SS_FSUpdateFile - HARDNEWFILES success!!\n"); -#ifdef POWER_FAIL_TEST - if (fail_test_flag < HARDNEWFILES) { - if (SS_Do_Power_fail_test(HARDNEWFILES) == E_SS_FAILURE) { - LOGE("SS_Do_Power_fail_test failed!!\n"); - } - } -#endif - } - } - - if (head_ptr_node->hard_difref == NULL) { - LOGL(LOG_SSENGINE, "No HARDDIFF header\n"); - } else if (ulResult == S_SS_SUCCESS) { - ulResult = - SS_FSUpdateFile(HARDDIFFS, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->hard_difref, - ua_dataSS->update_delta->ua_patch_path); - if (ulResult == S_SS_SUCCESS) { - LOGL(LOG_SSENGINE, "SS_FSUpdateFile - HARDDIFFs success!!\n"); -#ifdef POWER_FAIL_TEST - if (fail_test_flag < HARDDIFFS) { - if (SS_Do_Power_fail_test(HARDDIFFS) == E_SS_FAILURE) { - LOGE("SS_Do_Power_fail_test failed!!\n"); - } - } -#endif - } - } - - if (ulResult == S_SS_SUCCESS) { - ulResult = SS_FSSetAttributes(ua_dataSS); - } else { - SS_FSSetAttributes(ua_dataSS); // To prevent boot failures by smack. - } - - sync(); - sleep(1); - SS_FSClearNodes(); - - if (ulResult == S_SS_SUCCESS) { - SS_UpdateUIProgress(ua_dataSS, 0, 1); //fix WGID : 51963, When all updates are done to FS , patchcount is not needed, passing 1 to 3rd arg is enough - SS_Set_last_update_status(0, DEL_TYPE_MAX, status_path); - } - - LOGL(LOG_SSENGINE, "FS update Complete\n"); -#ifdef MEM_PROFILING - LOGL(LOG_SSENGINE, "Stats are : Cur Max : [%d] Global Max : [%d]\n", cur_mem, max_mem); -#endif -#ifdef POWER_FAIL_TEST - unlink(SS_POWER_FAIL_TEST_FLAG); -#endif - if (ulResult == S_SS_SUCCESS) - return ulResult; - else - return SS_GetUpgradeState(); -} - -/*! - ********************************************************************************* - * SS_FSUpdatemain - ********************************************************************************* - * - * @brief - * This is the API exposed from the engine to update FS. - * FS entry function for updating FS partition. Should be invoked only after verification of the partition - * - * - * @param Requires common data structure having all details & Partition Index. - * (Used for getting right NODES information that built during verification) - * (Configuration, Delta info, Partition Info, UI link , Kind of operation.(Verify or Updates)) - * - * @return returns S_SS_SUCCESS - * E_SS_FAILURE in case of error - * - ********************************************************************************* - */ -size_t SS_FSAvailiableFreeSpace(char *block_name) -{ - - struct mntent *ent; - FILE *aFile; - struct statfs sb; - aFile = setmntent("/proc/mounts", "r"); - if (aFile == NULL) { - LOGE("setmntent error\n"); - return E_SS_FAILURE; - } - while (NULL != (ent = getmntent(aFile))) { - if (strcmp(ent->mnt_fsname, block_name) == 0) { - if (statfs(ent->mnt_dir, &sb) == 0) - LOGL(LOG_SSENGINE, "Total free space = %" PRIu64 ", blocks free = %" PRIu64 "\n", sb.f_bsize * sb.f_bavail, sb.f_bfree); - } - } - endmntent(aFile); - return ((long long)sb.f_bsize * (long long)sb.f_bavail >= (long long)SIZE_4GB) ? SIZE_4GB : sb.f_bsize * sb.f_bavail ; -} - -int SS_FSVerifyPartition(ua_dataSS_t * ua_dataSS) -{ - int ulResult = S_SS_SUCCESS; - if (!ua_dataSS) { - LOGE("Wrong Param for fs verification\n"); - SS_SetUpgradeState(E_SS_BAD_PARAMS); - return E_SS_FAILURE; - } - -#ifdef MEM_PROFILING - if (!mem_profiling_start) - if (!(S_SS_SUCCESS == SS_Do_Memory_Profiling())) - return E_SS_FAILURE; -#endif - SS_GetPartition_LocDetails(ua_dataSS); - LOGL(LOG_SSENGINE, "FS Verification Start\n"); - if (ua_dataSS->ua_operation == UI_OP_SCOUT) - gvalid_session = 1; // (shd b true if called during verification) - headptr_list = SS_FSBuildNodes(ua_dataSS); -#ifdef TIME_PROFILING - LOGL(LOG_SSENGINE, "fast_tar_get_item_size_time :[%lf]\n", fast_tar_get_item_size_time); - LOGL(LOG_SSENGINE, "SS_LoadFile_time :[%lf]\n", SS_LoadFile_time); - LOGL(LOG_SSENGINE, "SS_FSBuildNodes_time :[%lf]\n", SS_FSBuildNodes_time); -#endif - if (!headptr_list) { - LOGE("FS Verification Failed\n"); - SS_FSClearNodes(); - ulResult = E_SS_FAILURE; - } - - if (ulResult == S_SS_SUCCESS) - return ulResult; - else - return SS_GetUpgradeState(); -} - -//Should check if space is available???? -int SS_BackupSource(const char *source_filename, char *backup_path) -{ - int ret = E_SS_FAILURE; - - if (source_filename) { - ret = (int)SS_CopyFile(source_filename, backup_path); - if (ret != S_SS_SUCCESS) { - LOGE("failed to back up source file Error [%d]\n", ret); - SS_SetUpgradeState(E_SS_FSSRCBACKUPFAILED); - } - } - return ret; -} - -int SS_BackupSourceClear(char *backup_path) -{ - int ret = E_SS_FAILURE; - ret = (int)SS_DeleteFile(backup_path); - if (ret != S_SS_SUCCESS) { - LOGE("failed to delete BACKUP file\n"); - SS_SetUpgradeState(E_SS_FSSRCBACKUPFAILED); - } - return ret; -} - -int SS_PatchSourceClear(char *patch_path) -{ - int ret = E_SS_FAILURE; - ret = (int)SS_DeleteFile(patch_path); - if (ret != S_SS_SUCCESS) { - LOGE("failed to delete PATCHFILE file\n"); - SS_SetUpgradeState(E_SS_PATCHFILE_DEL_ERROR); - } - return ret; -} - -long SS_GetUPIVersion(unsigned char *ver_str) -{ - if (ver_str) { - strncpy((char *)ver_str, SS_TOTA_VERSION, MAX_PATH); -#ifdef MEM_PROFILING - if (!mem_profiling_start) - if (!(S_SS_SUCCESS == SS_Do_Memory_Profiling())) - LOGE("Unable to start Memory_Profiling\n"); -#endif - return S_SS_SUCCESS;//wgid: 2456 - } else - return E_SS_FAILURE; -} \ No newline at end of file diff --git a/src/delta-ua/engine/SS_UPI.h b/src/delta-ua/engine/SS_UPI.h deleted file mode 100755 index 107a810..0000000 --- a/src/delta-ua/engine/SS_UPI.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * delta-ua - * - * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _SS_UPI_H_ -#define _SS_UPI_H_ -#include -#include "fota_common.h" - -#define DISPLAYRESOLUTION_SIZE 50 - -struct details { - int diffs; - int moves; - int news; - int deletes; - int symdiffs; - int symnews; - int harddiffs; - int hardnews; -}; - -enum DEL_TYPE { DELETES = 1, DIFFS, MOVES, DELETE_END, NEWFILES, SYMDIFFS, SYMNEWFILES, HARDDIFFS, HARDNEWFILES, DEL_TYPE_MAX }; -struct fs_params { // Use Macros - char file_old_path[512]; - char file_new_path[512]; - char patch_name[256]; - char sha1src[64]; - char sha1trg[64]; - int data_size; - int data_offset; - int type; //0 is for diff and 1 is for verbatim - struct fs_params *nextnode; -}; -typedef struct fs_params fs_params; - -struct fs_list { - fs_params *dif_ref; - fs_params *move_ref; - fs_params *new_ref; - fs_params *del_ref; - fs_params *sym_difref; - fs_params *sym_newref; - fs_params *hard_difref; - fs_params *hard_newref; - int ulPatchCount; -}; -typedef struct fs_list fs_list; - -int SS_AppendNode(const char *ubDeltaPath, fs_params ** headparam, fs_params ** tailparam, const char *old_path, - const char *new_path, const char *patchname, const char *sha1src, const char *sha1trg, int type, - char *patchpath_name); -long SS_GetUPIVersion(unsigned char *ver_str); -extern int SS_FSUpdatemain(ua_dataSS_t * ua_dataSS); -extern int SS_FSVerifyPartition(ua_dataSS_t * ua_dataSS); - -//extra functions -extern void *SS_Malloc(unsigned int size); -extern int tar_get_item_size_from_struct(tar_Data_t **, const char *, int *, int *); -extern void SS_Free(void *pMemBlock); -extern int tar_get_item_size(char *tar, char *item); -extern int tar_get_cfg_data(char *tar, char *item, char *buf, int buflen); -extern tar_Data_t *tar_build_cfg_table(char *tar); -extern int tar_open(char *tar); -extern int fast_tar_extract_file(char *tar, char *item, char *pathname, int size, int offset); -extern int tar_close(); -extern int SS_UpdateDeltaFS(const char *source_filename, const char *target_filename, - const char *source_sha1_str, const char *target_sha1_str, int patch_data_size, char *delta_folder); -extern int tar_extract_file(char *tar, char *item, char *pathname); -extern int _7zdecompress(char *path); -extern void tar_free_cfg_table(tar_Data_t ** delta_tar); -extern long SS_GetFileType(char *pLinkName, enumFileType * fileType); - -extern int SS_Get_last_update_status(int* last_update_status, int* del_type, char *status_path); -extern void SS_Set_last_update_status(int last_update_status, int del_type, char *status_path); - -#endif //_SS_UPI_H_ diff --git a/src/delta-ua/engine/fota_common.h b/src/delta-ua/engine/fota_common.h deleted file mode 100755 index 607ae5f..0000000 --- a/src/delta-ua/engine/fota_common.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * delta-ua - * - * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __FOTA_COMMON_H__ -#define __FOTA_COMMON_H__ - -#include -#include "fota_log.h" - -typedef unsigned int u32; -#ifndef __size_t /* typedef check for x86 env: stddef.h */ -#define __size_t -typedef u32 size_t; -#endif /* __size_t */ - -#define MAX_FILE_PATH 512 - -#ifndef TIME_PROFILING - //#define TIME_PROFILING -#endif -#ifndef HEAP_PROFILING - //#define HEAP_PROFILING; -#endif -#ifndef MEM_PROFILING - //#define MEM_PROFILING -#endif -#ifndef POWER_FAIL_TEST - //#define POWER_FAIL_TEST -#endif - -#define UNUSED(x) (void)(x) - -#define SS_TOTA_VERSION "1.0.19" -#define BSDIFF "BSDIFF40" -#define IMGDIFF "IMGDIFF2" -#define SECTOR_SIZE 512F -#define SS_KERNEL_DELTA_HEADER 128 - -#define SS_BACKUP_SOURCE "/saved.file" //How to make sure there is SPACE -#define SS_PATCHFILE_SOURCE "/patchfile.file" //define in common place -#define SS_PATCHLIST_BKUPLOC "/patchlist.txt" -#define SS_NEW_COMPRESSED_FILE "/system.7z" -#define SS_UPDATE_STATUS_PATH "/UP.STATUS" - -#define SS_PATCHLISTFORMAT ".txt" -#define SS_PATCH_ATTR_FORMAT "_attr.txt" -#define SS_FSCOUNT_MAGIC_KEY "PaTcHCoUnT:" -#define SS_FSCOUNT_MAGIG_KEYLEN (11) //length of SS_FSCOUNT_MAGIC_KEY - -#define SS_TOKEN_SPACE " " -#define SS_TOKEN_NEWLINE "\n" -#define SS_TOEKN_COLON ":" -#define SS_FWSLASH "/" -#define SS_NULLENTRY "0" -#define SS_MAX_NAMELENSUPPORTED (200) //(Tar supports 256, But extra space is used for PartitionName, .delta, /p, so restricting filename max to 200) -#define SS_MAX_FILE_PATH (512) -#define SS_TOKEN_MAXLINE_LEN (1024) -#define SS_COMPRESSED_FILE "system.7z" - -#define SS_STRING_DIFF "DIFF" -#define SS_STRING_MOVE "MOVE" -#define SS_STRING_DEL "DEL" -#define SS_STRING_SYM "SYM" -#define SS_STRING_HARD "HARD" -#define SS_STRING_NEW "NEW" -#define SS_STRING_REG "REG" -#define SS_STRING_TPK "TPK" -#define SS_STRING_ZIP "ZIP" -#define SS_STRING_END "END" - -#define SS_COMMON_WORKSPACE "/run/upgrade-sysroot/opt/usr/data/fota" - -#ifdef MEM_PROFILING -#define SS_MEMORY_USAGE_LOG SS_COMMON_WORKSPACE "/log_memory" -#define SS_MEMORY_PROFILING_SCRIPT SS_COMMON_WORKSPACE "/mem_use.sh" -#endif - -#ifdef POWER_FAIL_TEST -#define SS_POWER_FAIL_TEST_FLAG SS_COMMON_WORKSPACE "/power_fail_test_flag" -#endif - -struct tar_Data { - int itemSize; - int itemOffset; - int itemName[256]; - struct tar_Data *nextnode; -}; -typedef struct tar_Data tar_Data_t; - -#endif /* __FOTA_COMMON_H__ */ diff --git a/src/delta-ua/engine/fota_log.c b/src/delta-ua/engine/fota_log.c deleted file mode 100755 index 0fb8285..0000000 --- a/src/delta-ua/engine/fota_log.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * libtota - * - * Copyright (c) 2017 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define LOG_SIZE_OPT_PATH "/opt/data/recovery/.ua_log_size" -#define DEF_MAX_LOG_SIZE (2*1024*1024) -#define MAX_FILE_PATH 512 - -long curr_offset = 0; -long next_offset = 0; -long backup_offset = 0; -long max_logfile_size = DEF_MAX_LOG_SIZE; - -/*----------------------------------------------------------------------------- - __check_existence - ----------------------------------------------------------------------------*/ -static long __check_existence(const char *file_path) -{ - struct stat statbuf; - char filename[MAX_FILE_PATH]; - - if (strncpy(filename, file_path, strlen(file_path) + 1) == NULL) - return 0; - if (stat(filename, &statbuf)) { - if (ENOENT == errno) - return 0; - } - return statbuf.st_size; -} - -/*----------------------------------------------------------------------------- - __read_from_file - ----------------------------------------------------------------------------*/ -static int __read_from_file(const char *path, char *buf, size_t size) -{ - int fd; - ssize_t count; - - if (!path) - return -1; - - if (size == 0) - return 0; - - fd = open(path, O_RDONLY, 0); - if (fd == -1) - return -1; - - count = read(fd, buf, size); - if (count > 0) { - count = (count < (ssize_t)size) ? count : ((ssize_t)size - 1); - while (count > 0 && buf[count - 1] == '\n') - count--; - buf[count] = '\0'; - } else { - buf[0] = '\0'; - } - - close(fd); - - return (int)count; -} - -/*----------------------------------------------------------------------------- - get_opt_logfile_size - ----------------------------------------------------------------------------*/ -static int get_opt_logfile_size(void) -{ - /* - if status file does not exist, status = UP_START_NONE. - if status file exist, read status from file. - */ - char buf[256]; - - if (__check_existence(LOG_SIZE_OPT_PATH) == 0) - return -1; - - if (__read_from_file(LOG_SIZE_OPT_PATH, buf, sizeof(buf)) < 0) - return -1; - - return atoi(buf); -} - -/*----------------------------------------------------------------------------- - set_max_logfile_size - ----------------------------------------------------------------------------*/ -void set_max_logfile_size(void) -{ - int size = get_opt_logfile_size(); - - if (size <= 0) - size = DEF_MAX_LOG_SIZE; - - max_logfile_size = size; -} - -/*----------------------------------------------------------------------------- - log_printf - ----------------------------------------------------------------------------*/ -int log_printf(FILE* log_fp, char* format_str, ...) -{ - int ret = 0; - char log_str[4096]; - char backup_ch; - int len; - va_list list; - - va_start(list, format_str); - vsnprintf(log_str, sizeof(log_str), format_str, list); - va_end(list); - - len = strlen(log_str); - next_offset = curr_offset + len; - - if (next_offset <= max_logfile_size) { - if (fprintf(log_fp, "%s", log_str) < 0) { - ret = -1; - goto exit; - } - curr_offset = next_offset; - if (curr_offset == max_logfile_size) { - rewind(log_fp); - curr_offset = 0; - } - } else { - backup_offset = max_logfile_size - curr_offset; - backup_ch = log_str[backup_offset]; - log_str[backup_offset] = 0x00; - if (fprintf(log_fp, "%s", log_str) < 0) { - ret = -1; - goto exit; - } - rewind(log_fp); - log_str[backup_offset] = backup_ch; - if (fprintf(log_fp, "%s", log_str+backup_offset) < 0) { - ret = -1; - goto exit; - } - curr_offset = next_offset - max_logfile_size; - } - -exit: - return ret; -} \ No newline at end of file diff --git a/src/delta-ua/engine/fota_log.h b/src/delta-ua/engine/fota_log.h deleted file mode 100755 index f3e8b35..0000000 --- a/src/delta-ua/engine/fota_log.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * libtota - * - * Copyright (c) 2017 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __FOTA_LOG_H__ -#define __FOTA_LOG_H__ - -#include - -/* - * DEBUGGING FEATURE - */ - -extern unsigned int __log_level__; -extern FILE *__log_out_file__; -extern int log_printf(FILE* log_fp, char* format_str, ...); -extern void set_max_logfile_size(void); - -#define LOG_INFO (1<<8) -#define LOG_ENGINE (1<<7) -#define LOG_FUNCS (1<<6) -#define LOG_GUI (1<<5) -#define LOG_DEBUG (1<<4) -#define LOG_FILE (1<<3) -#define LOG_FLASH (1<<2) -#define LOG_SSENGINE LOG_ENGINE - -//#define DEBUG_STDOUT -#define DEBUG_FILE - -#ifdef DEBUG_STDOUT -#define LOGE(s, args...) printf("UA/ERROR(%s) " s, __func__, ##args) // Error log -#define LOGL(mask, s, args...) do { if ((mask) & __log_level__) printf("UA/(%s): " s, __func__, ##args); } while (0) -#define LOG(s, args...) LOGL(LOG_DEBUG, s, ##args) - -#elif defined(DEBUG_FILE) -#define LOGE(s, args...) (void)log_printf(__log_out_file__, "UA/ERROR(%s) " s, __func__, ##args) -#define LOGL(mask, s, args...) do { if ((mask) & __log_level__) (void)log_printf(__log_out_file__, "UA/(%s): " s , __func__, ##args); } while (0) -#define LOG(s, args...) LOGL(LOG_DEBUG, s, ##args) - -#elif defined(DEBUG_STDOUT_FILE) // debug printf -#define LOGE(s, args...) do {\ - printf("UA/ERROR(%s) " s, __func__, ##args);\ - (void)log_printf(__log_out_file__, "UA/ERROR(%s) " s, __func__, ##args);\ - } while (0) -#define LOGL(mask, s, args...) do { \ - if ((mask) & __log_level__) {\ - printf("UA/(%s): " s , __func__, ##args);\ - (void)log_printf(__log_out_file__, "UA/(%s): " s, __func__, ##args);\ - } \ - } while (0) -#define LOG(s, args...) LOGL(LOG_DEBUG, s, ##args) - -#else -#define LOGE(s, args...) -#define LOGL(mask, s, args...) -#define LOG(s, args...) - -#endif - -#endif /* __FOTA_LOG_H__ */ diff --git a/src/delta-ua/engine/fota_tar.c b/src/delta-ua/engine/fota_tar.c deleted file mode 100755 index d0304f9..0000000 --- a/src/delta-ua/engine/fota_tar.c +++ /dev/null @@ -1,843 +0,0 @@ -/* - * libtota - * - * Copyright (c) 2017 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "SS_Engine_Errors.h" -#include "SS_FSUpdate.h" -#include "fota_common.h" -#include "fota_tar.h" -#include "ua_types.h" - -/* tar Header Block, from POSIX 1003.1-1990. for reference */ -#if 0 - /* POSIX header. */ - -struct posix_header { /* byte offset */ - char name[100]; /* 0 */ - char mode[8]; /* 100 */ - char uid[8]; /* 108 */ - char gid[8]; /* 116 */ - char size[12]; /* 124 */ - char mtime[12]; /* 136 */ - char chksum[8]; /* 148 */ - char typeflag; /* 156 */ - char linkname[100]; /* 157 */ - char magic[6]; /* 257 */ - char version[2]; /* 263 */ - char uname[32]; /* 265 */ - char gname[32]; /* 297 */ - char devmajor[8]; /* 329 */ - char devminor[8]; /* 337 */ - char prefix[155]; /* 345 */ - /* 500 */ -}; -#endif - -#define MAX_ITEM_SIZE 0x7FFFFFFF -#define TAR_ITEM_SIZE_POSITION 124 -#define TAR_SIZE_OF_ITEM_SIZE 8 -#define TAR_SIZE_OF_HEADER 12 -#define TAR_BLOCK_SIZE 512 -#define TAR_ITEM_NAME_SIZE 100 -#define TAR_LONG_NAME_SIZE 256 -#define TAR_ITEM_TYPE_FLAG_POS 156 -/*** The byte that indicates whether the prefix is present or not */ -#define PREFIX_INDICATOR_BYTE 345 -#define PREFIX_LEN 155 - -/** the rest heavily based on (ie mostly) untgz.c from zlib **/ - -/* Values used in typeflag field. */ - -#define REGTYPE '0' /* regular file */ -#define AREGTYPE '\0' /* regular file */ -#define LNKTYPE '1' /* link */ -#define SYMTYPE '2' /* reserved */ -#define CHRTYPE '3' /* character special */ -#define BLKTYPE '4' /* block special */ -#define DIRTYPE '5' /* directory */ -#define FIFOTYPE '6' /* FIFO special */ -#define CONTTYPE '7' /* reserved, for compatibility with gnu tar, - treat as regular file, where it represents - a regular file, but saved contiguously on disk */ - -/* GNU tar extensions */ - -#define GNUTYPE_DUMPDIR 'D' /* file names from dumped directory */ -#define GNUTYPE_LONGLINK 'K' /* long link name */ -#define GNUTYPE_LONGNAME 'L' /* long file name */ -#define GNUTYPE_MULTIVOL 'M' /* continuation of file from another volume */ -#define GNUTYPE_NAMES 'N' /* file name that does not fit into main hdr */ -#define GNUTYPE_SPARSE 'S' /* sparse file */ -#define GNUTYPE_VOLHDR 'V' /* tape/volume header */ - -extern void *SS_Malloc(SS_UINT32 size); - -int gTarFd = -1; // Currenlty this logic supports only one tar file - -void create_dir(char *pathname, int mode) -{ - char *p; - int r; - - /* Strip trailing '/' */ - if (pathname[strlen(pathname) - 1] == '/') - pathname[strlen(pathname) - 1] = '\0'; - - /* Try creating the directory. */ - r = mkdir(pathname, mode); - - if (r != 0) { - /* On failure, try creating parent directory. */ - p = strrchr(pathname, '/'); - if (p != NULL) { - *p = '\0'; - create_dir(pathname, 0755); - *p = '/'; - r = mkdir(pathname, mode); - } - } - if (r != 0) { - if (r != EEXIST && r != -1) - LOG("Could not create directory [%s] Error[%d]\n", pathname, r); - } -} - -/*----------------------------------------------------------------------------- - tar_get_item_offset - ----------------------------------------------------------------------------*/ -int tar_get_item_offset(char *tar, char *item) -{ - int ret = -1; - int fd = -1; - char header[TAR_BLOCK_SIZE] = { 0, }; - char uExtendedName[MAX_FILE_PATH + 1] = { 0, }; - char size_oct[TAR_SIZE_OF_HEADER] = { 0, }; - unsigned long size_dec = 0; - int blknum = 0; - off_t pos = 0; - off_t tar_len = 0; - ssize_t rdcnt = 0; - - if (!item || !tar){ - LOG("Invalid params\n"); - return -1; - }; - //check if gTarFd was opened by tar_open during SS_FSUpdateFile then use it - if (gTarFd >= 0) - fd = gTarFd; - else { - fd = open(tar, O_RDONLY); - if (fd < 0) { - LOGE("can't open file(%s).\n", tar); - return -1; - } - } - - tar_len = lseek(fd, 0, SEEK_END); - if (tar_len < 0) { - LOGL(LOG_SSENGINE, "can't read tar_len (%s).\n", tar); - goto Cleanup; - } - pos = lseek(fd, 0, SEEK_SET); - if (pos < 0) { - LOGL(LOG_SSENGINE, "can't read pos (%s).\n", tar); - goto Cleanup; - } - while (pos < tar_len) { - /* read file header */ - rdcnt = read(fd, header, sizeof(header)); - if (rdcnt <= 0) { - LOG("read failed. (rdcnt=%d)\n", rdcnt); - break; - } - - /* get file name and file size */ - if (header[TAR_ITEM_TYPE_FLAG_POS] == GNUTYPE_LONGNAME || header[TAR_ITEM_TYPE_FLAG_POS] == GNUTYPE_LONGLINK) { - //rdcnt = read(fd, header, sizeof(header)); - memset(uExtendedName, 0, sizeof(uExtendedName)); - rdcnt = read(fd, uExtendedName, sizeof(uExtendedName) - 1); - if (rdcnt <= 0) { - LOG("read failed. (rdcnt=%d)\n", rdcnt); - break; - } - rdcnt = read(fd, header, sizeof(header)); - if (rdcnt <= 0) { - LOG("read failed. (rdcnt=%d)\n", rdcnt); - break; - } - } else { - memset(uExtendedName, 0, sizeof(uExtendedName)); - memcpy(uExtendedName, header, TAR_ITEM_NAME_SIZE); - } - memcpy(size_oct, header + TAR_ITEM_SIZE_POSITION, sizeof(size_oct)); - size_dec = strtoul(size_oct, NULL, TAR_SIZE_OF_ITEM_SIZE); - if (size_dec > MAX_ITEM_SIZE) { - LOG("ITEM : [%s]\n", item); - LOG("size too big. (size_dec=0x%08X)\n", size_dec); - break; - } - - /* check if the file is what we are looking for */ - if (strncmp(uExtendedName, item, sizeof(uExtendedName) - 1) == 0) { - ret = (int)lseek(fd, 0, SEEK_CUR); - break; - } - - /* move file pointer to next file header */ - blknum = size_dec / TAR_BLOCK_SIZE; - if (size_dec % TAR_BLOCK_SIZE) - blknum++; - - pos = lseek(fd, (off_t) (blknum * TAR_BLOCK_SIZE), SEEK_CUR); - if (pos < 0) { - LOGE("can't read next block (%s).\n", tar); - close(fd); - return -1; - } - } - - Cleanup: - if (gTarFd < 0) - close(fd); - - return ret; -} - -/*----------------------------------------------------------------------------- - tar_get_item_size - ----------------------------------------------------------------------------*/ -int tar_get_item_size(char *tar, char *item) -{ - int ret = -1; - int fd = -1; - char header[TAR_BLOCK_SIZE] = { 0, }; - char uExtendedName[MAX_FILE_PATH + 1] = { 0, }; - char size_oct[TAR_SIZE_OF_HEADER] = { 0, }; - unsigned long size_dec = 0; - int blknum = 0; - off_t pos = 0; - off_t tar_len = 0; - ssize_t rdcnt = 0; - - if (!item || !tar){ - LOG("Invalid params\n"); - return -1; - } - LOGL(LOG_SSENGINE, "Tar file Looking for (%s)\n", item); - fd = open(tar, O_RDONLY); - if (fd < 0) { - LOG("can't open file(%s).\n", tar); - return -1; - } - - tar_len = lseek(fd, 0, SEEK_END); - if (tar_len < 0) { - LOGL(LOG_SSENGINE, "can't read tar_len (%s).\n", tar); - goto Cleanup; - } - pos = lseek(fd, 0, SEEK_SET); - if (pos < 0) { - LOGL(LOG_SSENGINE, "can't read pos (%s).\n", tar); - goto Cleanup; - } - - while (pos < tar_len) { - /* read file header */ - rdcnt = read(fd, header, sizeof(header)); - if (rdcnt <= 0) { - LOG("read failed. (rdcnt=%d)\n", rdcnt); - break; - } - - /* get file name and file size */ - if (header[TAR_ITEM_TYPE_FLAG_POS] == GNUTYPE_LONGNAME || header[TAR_ITEM_TYPE_FLAG_POS] == GNUTYPE_LONGLINK) { - //rdcnt = read(fd, header, sizeof(header)); - memset(uExtendedName, 0, sizeof(uExtendedName)); - rdcnt = read(fd, uExtendedName, sizeof(uExtendedName) - 1); - if (rdcnt <= 0) { - LOG("read failed. (rdcnt=%d)\n", rdcnt); - break; - } - rdcnt = read(fd, header, sizeof(header)); - if (rdcnt <= 0) { - LOG("read failed. (rdcnt=%d)\n", rdcnt); - break; - } - } else { - memset(uExtendedName, 0, sizeof(uExtendedName)); - memcpy(uExtendedName, header, TAR_ITEM_NAME_SIZE); - } - memcpy(size_oct, header + TAR_ITEM_SIZE_POSITION, sizeof(size_oct)); - size_dec = strtoul(size_oct, NULL, TAR_SIZE_OF_ITEM_SIZE); - if (size_dec > MAX_ITEM_SIZE) { - LOG("ITEM : [%s]\n", item); - LOG("size too big. (size_dec=0x%08X)\n", (unsigned int)size_dec); - break; - } - - /* check if the file is what we are looking for */ - if (strncmp(uExtendedName, item, sizeof(uExtendedName) - 1) == 0) { - ret = (int)size_dec; - if ((ret == 0) && (header[TAR_ITEM_TYPE_FLAG_POS] == DIRTYPE)) - ret = tar_get_folder_size(tar, item); - break; - } - /* move file pointer to next file header */ - //LOGL(LOG_SSENGINE,"Item in Tar (%s)\n", uExtendedName); - blknum = size_dec / TAR_BLOCK_SIZE; - if (size_dec % TAR_BLOCK_SIZE) - blknum++; - - pos = lseek(fd, (off_t) (blknum * TAR_BLOCK_SIZE), SEEK_CUR); - if (pos < 0) { - LOGL(LOG_SSENGINE, "can't read next block (%s).\n", tar); - close(fd); - return -1; - } - } - - Cleanup: - close(fd); - - return ret; -} - -/*----------------------------------------------------------------------------- - tar_get_cfg_data - ----------------------------------------------------------------------------*/ -int tar_get_cfg_data(char *tar, char *item, char *buf, int buflen) -{ - int fd = -1; - int data_size = -1; - int data_offset = -1; - off_t pos = 0; - ssize_t rdcnt = 0; - - if (!buf){ - LOG("Invalid params\n"); - return -1; - } - data_size = tar_get_item_size(tar, item); - if (data_size <= 0) - return -1; - - if (data_size > buflen) - data_size = buflen; - - data_offset = tar_get_item_offset(tar, item); - if (data_offset < 0) - return -1; - - fd = open(tar, O_RDONLY); - if (fd < 0) { - LOG("can't open file(%s).\n", tar); - return -1; - } - - pos = lseek(fd, data_offset, SEEK_SET); - if (pos < 0) { - LOG("lseek fail (%s offset %d).\n", tar, data_offset); - close(fd); - return -1; - } - - rdcnt = read(fd, buf, data_size); - if (rdcnt != (ssize_t) data_size) { - LOG("read fail(%s from %s).\n", item, tar); - close(fd); - return -1; - } - - close(fd); - - return rdcnt; -} - -tar_Data_t *tar_build_cfg_table(char *tar) -{ - - int fd = -1; - int ret = 0; - char header[TAR_BLOCK_SIZE] = { 0, }; - char uExtendedName[MAX_FILE_PATH + 1] = { 0, }; - char size_oct[TAR_SIZE_OF_HEADER] = { 0, }; - unsigned long size_dec = 0; - int blknum = 0; - off_t pos = 0; - off_t tar_len = 0; - ssize_t rdcnt = 0; - - int itemSize; - int itemOffset; - tar_Data_t *headparam = NULL, *tailparam = NULL, *newnode = NULL; - tar_Data_t *local_temp = NULL; - tar_Data_t *local_next = NULL; - if (!tar) { - LOGE("Bad param tar\n"); - return NULL; - } - //check if gTarFd was opened by tar_open during SS_FSUpdateFile then use it - if (gTarFd >= 0) - fd = gTarFd; - else { - fd = open(tar, O_RDONLY); - if (fd < 0) { - LOG("can't open file(%s).\n", tar); - return NULL; - } - } - - tar_len = lseek(fd, 0, SEEK_END); - if (tar_len < 0) { - LOGL(LOG_SSENGINE, "can't read tar_len (%s).\n", tar); - goto Cleanup; - } - pos = lseek(fd, 0, SEEK_SET); - if (pos < 0) { - LOGL(LOG_SSENGINE, "can't read pos (%s).\n", tar); - goto Cleanup; - } - while (pos < tar_len) { - /* read file header */ - rdcnt = read(fd, header, sizeof(header)); - if (rdcnt <= 0) { - LOG("read failed. (rdcnt=%d)\n", rdcnt); - ret = -1; - break; - } - /* get file name and file size */ - if (header[TAR_ITEM_TYPE_FLAG_POS] == GNUTYPE_LONGNAME || header[TAR_ITEM_TYPE_FLAG_POS] == GNUTYPE_LONGLINK) { - //rdcnt = read(fd, header, sizeof(header)); - memset(uExtendedName, 0, sizeof(uExtendedName)); - rdcnt = read(fd, uExtendedName, sizeof(uExtendedName) - 1); - if (rdcnt <= 0) { - LOG("read failed. (rdcnt=%d)\n", rdcnt); - ret = -1; - break; - } - rdcnt = read(fd, header, sizeof(header)); - if (rdcnt <= 0) { - LOG("read failed. (rdcnt=%d)\n", rdcnt); - ret = -1; - break; - } - } else { - memset(uExtendedName, 0, sizeof(uExtendedName)); - memcpy(uExtendedName, header, TAR_ITEM_NAME_SIZE); - } - memcpy(size_oct, header + TAR_ITEM_SIZE_POSITION, sizeof(size_oct)); - size_dec = strtoul(size_oct, NULL, TAR_SIZE_OF_ITEM_SIZE); - if (size_dec > MAX_ITEM_SIZE) { - LOG("uExtendedName is : [%s]\n", uExtendedName); - LOG("size too big. (size_dec=0x%08X)\n", (unsigned int)size_dec); - ret = -1; - break; - } - //fix WGID : 51254 , size_dec comparison is not required - if ((strstr(uExtendedName, "/diff") != NULL)) { //add only delta files from rootfs and csc, hardcoding shd b removed.. - - /* check if the file is what we are looking for */ - //strncpy(itemName, name,100); - itemSize = (int)size_dec; - itemOffset = (int)lseek(fd, 0, SEEK_CUR); - newnode = (tar_Data_t *) SS_Malloc(sizeof(tar_Data_t)); - if (!newnode) { - ret = -1; - break; - } - memset(newnode->itemName, 0, sizeof(newnode->itemName)); - strncpy((char *)newnode->itemName, uExtendedName, sizeof(newnode->itemName) - 1); - newnode->itemOffset = itemOffset; - newnode->itemSize = itemSize; - newnode->nextnode = NULL; - if (headparam == NULL) { - headparam = newnode; - tailparam = newnode; - } else { - (tailparam)->nextnode = newnode; - (tailparam) = (tailparam)->nextnode; - } - } - - /* move file pointer to next file header */ - blknum = size_dec / TAR_BLOCK_SIZE; - if (size_dec % TAR_BLOCK_SIZE) - blknum++; - - pos = lseek(fd, (off_t) (blknum * TAR_BLOCK_SIZE), SEEK_CUR); - if (pos < 0) { - LOGL(LOG_SSENGINE, "can't read next block (%s).\n", tar); - ret = -1; - break; - } - } - Cleanup: - //if gTarFd was opened by tar_open during SS_FSUpdateFile we do not close it - if (gTarFd < 0) - close(fd); - if (ret != -1) - return headparam; - else { - if (headparam != newnode && newnode) - SS_Free(newnode); - if (headparam) { - local_temp = headparam; - while (local_temp) { - local_next = local_temp->nextnode; - SS_Free(local_temp); - local_temp = local_next; - } - } - return NULL; - } -} - -void tar_free_cfg_table(tar_Data_t ** delta_tar) -{ - tar_Data_t *local_temp = NULL; - tar_Data_t *local_next = NULL; - LOGL(LOG_SSENGINE, "Free TAR CFG TABLE\n"); - if (*delta_tar) { - local_temp = *delta_tar; - while (local_temp) { - local_next = local_temp->nextnode; - //LOGL(LOG_SSENGINE,"freeing [%s]\n",local_temp->itemName); - SS_Free(local_temp); - local_temp = local_next; - } - } -} - -void deleteNode(tar_Data_t * head, tar_Data_t * n) -{ - tar_Data_t *prev = head; - if (head == n) { - if (head->nextnode == NULL) { - LOG("There is only one node. The list can't be made empty\n"); - return; - } - strncpy((char *)head->itemName, (const char *)head->nextnode->itemName, TAR_ITEM_NAME_SIZE); //head->itemName = head->nextnode->itemName; - head->itemSize = head->nextnode->itemSize; - head->itemOffset = head->nextnode->itemOffset; - n = head->nextnode; - head->nextnode = head->nextnode->nextnode; - SS_Free(n); - return; - } - while (prev->nextnode != NULL && prev->nextnode != n) - prev = prev->nextnode; - if (prev->nextnode == NULL) { - LOG("Given node is not present in Linked List\n"); - return; - } - prev->nextnode = prev->nextnode->nextnode; - SS_Free(n); - return; -} - -int tar_get_item_size_from_struct(tar_Data_t ** delta_tar, const char *patchname, int *data_size, int *data_offset) -{ - tar_Data_t *head = *delta_tar; - tar_Data_t *base = *delta_tar; - if (head == NULL) - return 1; - else { - //LOG("fast_tar_get_item_size- looking for [%s] [%s]\n",patchname,head->itemName); - while (1) { - if (strstr((const char *)head->itemName, patchname) != 0) { - //LOG("fast_tar_get_item_size found [%s] in [%s]\n",patchname, head->itemName); - *data_size = head->itemSize; - *data_offset = head->itemOffset; - deleteNode(base, head); - return 0; - - } else if (head->nextnode != NULL) { - head = head->nextnode; - //LOG("fast_tar_get_item_size current node [%s] \n",head->itemName); - } else { - LOGE("fast_tar_get_item_size FAILED TO GET [%s] in [%s]\n", patchname, (char *)head->itemName); - break; - } - } - return 1; - } -} - -int tar_open(char *tar) -{ - if (gTarFd >= 0) - close(gTarFd); - gTarFd = open(tar, O_RDONLY); - if (gTarFd < 0) { - LOG("can't open TAR file(%s).\n", tar); - return -1; - } - return 0; -} - -int tar_close() -{ - if (gTarFd >= 0) - close(gTarFd); - gTarFd = -1; - return 0; -} - -int tar_get_folder_size(char *tar, char *item) -{ - int ret = -1; - int fd = -1; - char header[TAR_BLOCK_SIZE] = { 0, }; - char name[TAR_LONG_NAME_SIZE + 1] = { 0, }; - char *lastfolder = NULL; - int folderpathlen = 0; - char size_oct[TAR_SIZE_OF_HEADER] = { 0, }; - unsigned long size_dec = 0; - int blknum = 0; - off_t pos = 0; - off_t tar_len = 0; - ssize_t rdcnt = 0; - - if (!item || !tar){ - LOG("Invalid params\n"); - return -1; - } - LOG("Tar folder Looking for (%s)\n", item); - fd = open(tar, O_RDONLY); - if (fd < 0) { - LOG("can't open file(%s).\n", tar); - return -1; - } - - tar_len = lseek(fd, 0, SEEK_END); - if (tar_len < 0) { - LOGL(LOG_SSENGINE, "can't read tar_len (%s).\n", tar); - goto Cleanup; - } - pos = lseek(fd, 0, SEEK_SET); - if (pos < 0) { - LOGL(LOG_SSENGINE, "can't read pos (%s).\n", tar); - goto Cleanup; - } - - while (pos < tar_len) { - /* read file header */ - rdcnt = read(fd, header, sizeof(header)); - if (rdcnt <= 0) { - LOG("read failed. (rdcnt=%d)\n", rdcnt); - ret = -1; - break; - } - - /* get file name and file size */ - memcpy(name, header, sizeof(name) - 1); - memcpy(size_oct, header + TAR_ITEM_SIZE_POSITION, sizeof(size_oct)); - errno = 0; - size_dec = strtoul(size_oct, NULL, TAR_SIZE_OF_ITEM_SIZE); - if (errno != 0) { - LOG("strtoul failed. (errno=%d)\n", errno); - ret = -1; - break; - } else if (size_dec > MAX_ITEM_SIZE) { - LOG("size too big. (size_dec=0x%08X)\n", (unsigned int)size_dec); - ret = -1; - break; - } - - /* check if the file is what we are looking for */ - //Get until folder name - - lastfolder = strrchr(name, '/'); - if (lastfolder) - folderpathlen = strlen(name) - strlen(lastfolder); - - if (strncmp(name, item, folderpathlen) == 0) { - ret += (int)size_dec; - //LOG("Tar Files under folder [%s]\n", name); - //break; - } - - /* move file pointer to next file header */ - blknum = size_dec / TAR_BLOCK_SIZE; - if (size_dec % TAR_BLOCK_SIZE) - blknum++; - - pos = lseek(fd, (off_t) (blknum * TAR_BLOCK_SIZE), SEEK_CUR); - if (pos < 0) { - LOGL(LOG_SSENGINE, "can't read next block (%s).\n", tar); - close(fd); - return -1; - } - } - - Cleanup: - close(fd); - LOG("ret=%d\n", ret); - - return ret; //Should return +1?? or Ignore?? -} - -int fast_tar_extract_file(char *tar, char *item, char *pathname, int size, int offset) -{ - int fd = -1; - int data_size = size; - int data_offset = offset; - off_t pos = 0; - ssize_t rdcnt = 0; - ssize_t writeCount = 0; - char *buf = NULL; - char err_buf[256]; - int fd2; - - if (!item || !tar || !pathname){ - LOG("Invalid params\n"); - return -1; - } - if (gTarFd >= 0) - fd = gTarFd; - else { - fd = open(tar, O_RDONLY); - if (fd < 0) { - LOG("can't open file(%s).\n", tar); - return -1; - } - } - - pos = lseek(fd, data_offset, SEEK_SET); - if (pos < 0) { - LOG("lseek fail (%s offset %d).\n", tar, data_offset); - close(fd); - return -1; - } - buf = SS_Malloc(data_size + 1); - if (buf == NULL) { - close(fd); - LOGE("Failed to Allocate Memory\n"); - return -1; - } - rdcnt = read(fd, buf, data_size); - if (rdcnt != (ssize_t) data_size) { - LOG(" rdcnt read fail(%s from %s).\n", item, tar); - SS_Free(buf); - close(fd); - return -1; - } - fd2 = open(pathname, O_CREAT | O_WRONLY, S_IRWXU); // Directory where file is required should be created already. - if (fd2 < 0) { - LOG("can't open file(%s).\n", pathname); - SS_Free(buf); - close(fd); - return -1; - } - writeCount = write(fd2, buf, rdcnt); - if (writeCount != rdcnt) { - LOG("writeCount write fail(%s from %s).\n", item, tar); - strerror_r(errno, err_buf, sizeof(err_buf)); - LOG("Oh dear, something went wrong with read()! %s\n", err_buf); - close(fd); - close(fd2); - SS_Free(buf); - return -1; - } - SS_Free(buf); - if (gTarFd < 0) - close(fd); - fsync(fd2); - close(fd2); - return rdcnt; // or jus return success? -} - -int tar_extract_file(char *tar, char *item, char *pathname) -{ - int fd = -1; - int data_size = -1; - int data_offset = -1; - off_t pos = 0; - ssize_t rdcnt = 0; - ssize_t writeCount = 0; - char *buf = NULL; - char err_buf[256]; - int fd2; - - if (!item || !tar || !pathname){ - LOG("Invalid params\n"); - return -1; - } - data_size = tar_get_item_size(tar, item); - data_offset = tar_get_item_offset(tar, item); - - if (data_size <= 0 || data_offset < 0) { - LOGE("Error Not a file , size is [%d], offset [%d] for item [%s]\n", data_size, data_offset, item); - return -1; - } else - LOGL(LOG_SSENGINE, "extracting file [%s] size [%d]\n", item, data_size); - fd = open(tar, O_RDONLY); - if (fd < 0) { - LOG("can't open file(%s).\n", tar); - return -1; - } - pos = lseek(fd, data_offset, SEEK_SET); - if (pos < 0) { - LOG("lseek fail (%s offset %d).\n", tar, data_offset); - close(fd); - return -1; - } - buf = SS_Malloc(data_size + 1); - if (buf == NULL) { - close(fd); - LOGE("Failed to Allocate Memory\n"); - return -1; - } - rdcnt = read(fd, buf, data_size); - if (rdcnt != (ssize_t) data_size) { - LOG(" rdcnt read fail(%s from %s).\n", item, tar); - SS_Free(buf); - close(fd); - return -1; - } - fd2 = open(pathname, O_CREAT | O_WRONLY, S_IRWXU); // Directory where file is required should be created already. - if (fd2 < 0) { - LOG("can't open file(%s).\n", pathname); - SS_Free(buf); - close(fd); - return -1; - } - writeCount = write(fd2, buf, rdcnt); - if (writeCount != rdcnt) { - LOG("writeCount write fail(%s from %s).\n", item, tar); - strerror_r(errno, err_buf, sizeof(err_buf)); - LOG("Oh dear, something went wrong with read()! %s\n", err_buf); - close(fd); - close(fd2); - SS_Free(buf); - return -1; - } - SS_Free(buf); - close(fd); - fsync(fd2); - close(fd2); - return rdcnt; // or jus return success? -} diff --git a/src/delta-ua/engine/fota_tar.h b/src/delta-ua/engine/fota_tar.h deleted file mode 100755 index 6d141ef..0000000 --- a/src/delta-ua/engine/fota_tar.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * libtota - * - * Copyright (c) 2017 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _FOTA_TAR_H_ -#define _FOTA_TAR_H_ - -int tar_get_item_offset(char *tar, char *item); - -int tar_get_item_size(char *tar, char *item); - -int tar_get_cfg_data(char *tar, char *item, char *buf, int buflen); - -int tar_get_folder_size(char *tar, char *item); - -#endif /* _FOTA_TAR_H_ */ diff --git a/src/delta-ua/engine/ss_bspatch_common.c b/src/delta-ua/engine/ss_bspatch_common.c deleted file mode 100755 index e7bd45e..0000000 --- a/src/delta-ua/engine/ss_bspatch_common.c +++ /dev/null @@ -1,291 +0,0 @@ -/*- - * Copyright 2003-2005 Colin Percival - * Copyright 2012 Matthew Endsley - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * Modifications are made in reimplementing suffix sort array generation - * and how the data is read and written to.Iterative part replaced the - * recursive implementation to avoid buffer overflow problems - */ -//#define ZLIB_MOD //not stable yet. -//#define MAX_MATCH_SIZE // define ( MAX_MATCH_SIZE or CONST_MEMORY_USAGE ) or ( none of them ) -#define CONST_MEMORY_USAGE (64*1024) //tests show smallest time when using 64 kb -#define PATCH_FILE_FORMAT_MOD -#define BSDIFF_HEADER "BSDIFF40" -#define SSDIFF_HEADER "SSDIFF40" -//#define MULTI_THREADING -#include -#include -#include - -#include -#include -#include - -#include -#include <7zFile.h> -#include <7zVersion.h> -#include -#include - -static void *SzAlloc(void *p, size_t size) -{ - p = p; - return MyAlloc(size); -} - -static void SzFree(void *p, void *address) -{ - p = p; - MyFree(address); -} -ISzAlloc g_Alloc = { SzAlloc, SzFree }; - -static off_t offtin(u_char *buf) -{ - off_t y; - - y = buf[7] & 0x7F; - y = y * 256; - y += buf[6]; - y = y * 256; - y += buf[5]; - y = y * 256; - y += buf[4]; - y = y * 256; - y += buf[3]; - y = y * 256; - y += buf[2]; - y = y * 256; - y += buf[1]; - y = y * 256; - y += buf[0]; - - if (buf[7] & 0x80) - y = -y; - - return y; -} - -#define IN_BUF_SIZE (1 << 16) -#define OUT_BUF_SIZE (1 << 16) - -SRes Decode2(CLzmaDec *state, ISeqOutStream *outStream, ISeqInStream *inStream, - UInt64 *unpackSize, unsigned char *dec_data) -{ - int thereIsSize = (*unpackSize != (UInt64)(Int64) - 1); - UInt64 offset = 0; - Byte inBuf[IN_BUF_SIZE]; - Byte outBuf[OUT_BUF_SIZE]; - size_t inPos = 0, inSize = 0, outPos = 0; - - LzmaDec_Init(state); - - offset = 0; - - for (;;) { - if (inPos == inSize) { - inSize = IN_BUF_SIZE; - RINOK(inStream->Read(inStream, inBuf, &inSize)); - inPos = 0; - } - - SRes res; - SizeT inProcessed = inSize - inPos; - SizeT outProcessed = OUT_BUF_SIZE - outPos; - ELzmaFinishMode finishMode = LZMA_FINISH_ANY; - ELzmaStatus status; - - if (thereIsSize && outProcessed > *unpackSize) { - outProcessed = (SizeT) * unpackSize; - finishMode = LZMA_FINISH_END; - } - - res = LzmaDec_DecodeToBuf(state, outBuf + outPos, &outProcessed, - inBuf + inPos, &inProcessed, finishMode, &status); - inPos += inProcessed; - outPos += outProcessed; - *unpackSize -= outProcessed; - memcpy(dec_data + offset, outBuf, outProcessed); - offset += outProcessed; - - outPos = 0; - - if ((res != SZ_OK) || (thereIsSize && *unpackSize == 0)) - return res; - - if (inProcessed == 0 && outProcessed == 0) { - if (thereIsSize || status != LZMA_STATUS_FINISHED_WITH_MARK) - return SZ_ERROR_DATA; - return res; - } - } -} - -int apply_patch(const char *oldfile, unsigned char *patch_buffer, unsigned char **dest_buf, ssize_t *dest_size) -{ - int fd = -1, result = 0; - off_t oldsize, newsize; - u_char header[16], buf[8]; - u_char *old = NULL; - off_t oldpos, newpos; - off_t ctrl[4]; /////////////////////////////////////THREAD - off_t total_write; /////////////////////////////////////////THREAD - off_t j; - off_t memory_usage = CONST_MEMORY_USAGE; - off_t match_size; - off_t patch_buffer_offset = 0; - bool flag; - - /* - File format: - 0 8 "BSDIFF40" - 8 8 X - 16 8 Y - 24 8 sizeof(newfile) - 32 X bzip2(control block) - 32+X Y bzip2(diff block) - 32+X+Y ??? bzip2(extra block) - with control block a set of triples (x,y,z) meaning "add x bytes - from oldfile to x bytes from the diff block; copy y bytes from the - extra block; seek forwards in oldfile by z bytes". - */ - // Read header - if (patch_buffer) - memcpy(header, patch_buffer, 16); - else { - printf("%s().%d Corrupt decoded patch buffer\n", __FUNCTION__, __LINE__); - return 1; - } - - /* Check for appropriate magic */ - if (memcmp(header, BSDIFF_HEADER, 8) != 0 && memcmp(header, SSDIFF_HEADER, 8) != 0) { - printf("%s().%d Patch buffer header corrupt\n", __FUNCTION__, __LINE__); - return 1; - } - - /* Read lengths from header */ - newsize = offtin(header + 8); - - if ((newsize < 0)) { - printf("%s().%d Patch buffer corrupt\n", __FUNCTION__, __LINE__); - return 1; - } - - /* Cset patch_buffer_offset at the right place */ - patch_buffer_offset += 16; - - if (((fd = open(oldfile, O_RDONLY, 0)) < 0) || - ((oldsize = lseek(fd, 0, SEEK_END)) == -1) || - ((old = malloc(memory_usage + 1)) == NULL) || - (lseek(fd, 0, SEEK_SET) != 0)) { - printf("Corruption in old file %s\n", oldfile); - result = 1; - goto Cleanup; - } - - if ((*dest_buf = malloc(newsize + 1)) == NULL) { - printf("Corruption in old file %s\n", oldfile); - result = 1; - goto Cleanup; - } - oldpos = 0; - newpos = 0; - - total_write = 0; - - while (total_write != newsize) { - /* Read control data */ - for (j = 0; j <= 3; j++) { - memcpy(buf, patch_buffer + patch_buffer_offset, 8); - patch_buffer_offset += 8; - ctrl[j] = offtin(buf); - }; - - total_write += (ctrl[0] + ctrl[1]); - newpos = ctrl[3]; - oldpos = ctrl[2]; - - ////////////////////////////////////////////////////////////////////////////////// - flag = true; - match_size = ctrl[0]; - while (flag == true) { - if (match_size <= memory_usage) { - if (pread(fd, old, match_size, oldpos) != match_size) { - printf("Corruption in old file %s\n", oldfile); - result = 1; - goto Cleanup; - } - if (newpos + match_size > newsize) { - printf("%s().%d Corrupt patch\n", __FUNCTION__, __LINE__); - result = 1; - goto Cleanup; - } - memcpy((*dest_buf) + newpos, patch_buffer + patch_buffer_offset, match_size); - patch_buffer_offset += match_size; - for (j = 0; j < match_size; j++) - (*dest_buf)[newpos + j] += old[j]; - newpos += match_size; - flag = false; - } else { - if (pread(fd, old, memory_usage, oldpos) != memory_usage) { - printf("%s().%d Corruption in old file %s\n", __FUNCTION__, __LINE__ , oldfile); - result = 1; - goto Cleanup; - } - if (newpos + memory_usage > newsize) { - printf("%s().%d Corrupt patch\n", __FUNCTION__, __LINE__); - result = 1; - goto Cleanup; - } - memcpy((*dest_buf) + newpos, patch_buffer + patch_buffer_offset, memory_usage); - patch_buffer_offset += memory_usage; - for (j = 0; j < memory_usage; j++) - (*dest_buf)[newpos + j] += old[j]; - match_size -= memory_usage; - oldpos += memory_usage; - newpos += memory_usage; - } - } - - //////////////////////////////////////////////////////////////////////////////////////// - /* Sanity-check */ - if (newpos + ctrl[1] > newsize) { - printf("%s().%d Corrupt patch\n", __FUNCTION__, __LINE__); - result = 1; - goto Cleanup; - } - /* Read extra string */ - memcpy((*dest_buf) + newpos, patch_buffer + patch_buffer_offset, ctrl[1]); - patch_buffer_offset += ctrl[1]; - }; - *dest_size = newsize; -Cleanup: - //close old file - if (fd >= 0) - close(fd); - if (old) - free(old); - return result; -} diff --git a/src/delta-ua/engine/ss_bspatch_common.h b/src/delta-ua/engine/ss_bspatch_common.h deleted file mode 100644 index 3075ea2..0000000 --- a/src/delta-ua/engine/ss_bspatch_common.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef _SS_BSPATCH_COMMON_H -#define _SS_BSPATCH_COMMON_H 1 - -#include -#include <7zFile.h> -#include <7zVersion.h> -#include -#include - -extern ISzAlloc g_Alloc; - -SRes Decode2(CLzmaDec *state, ISeqOutStream *outStream, ISeqInStream *inStream, - UInt64 *unpackSize, unsigned char *dec_data); - -int apply_patch(const char *oldfile, unsigned char *patch_buffer, unsigned char **dest_buf, ssize_t *dest_size); - -#endif /* _SS_BSPATCH_COMMON_H */ diff --git a/src/delta-ua/engine/ua_types.h b/src/delta-ua/engine/ua_types.h deleted file mode 100755 index 5adb0ad..0000000 --- a/src/delta-ua/engine/ua_types.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * delta-ua - * - * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __UA_TYPES_H__ -#define __UA_TYPES_H__ - -#include - -#define MAX_FILE_PATH 512 - -/* - * FOTA Adaptaion header - */ - -#define UI_OP_SCOUT_UPDATE 0 -#define UI_OP_SCOUT 1 -#define UI_OP_UPDATE 3 - -typedef struct _ua_update_data_t { - unsigned int weight; // the sum of weight should be 100 - unsigned int weight_offset; // start offset - unsigned int data_size; // byte - char *ua_delta_path; // it will be allocated to copy delta file path, need to free memory - char *ua_temp_path; // it will be allocated to copy delta file path, need to free memory - char *ua_delta_folder; -} ua_update_data_t; - -typedef struct _ua_update_cfg_t { - int skip_verify; - int skip_update; - int source_img_size; //TOTA -} ua_update_cfg_t; - -typedef struct _ua_part_info_t { - char *ua_parti_name; - char *ua_subject_name; -} ua_part_info_t; - -// User data structure -typedef struct _ua_data_t { // partition operations - ua_part_info_t *parti_info; - ua_update_cfg_t *update_cfg; - ua_update_data_t *update_data; - unsigned long ua_operation; - - int (*ua_op_read_block)(void *, unsigned char *, unsigned long, unsigned long); - int (*ua_op_write_block)(void *, unsigned char *, unsigned long); - void (*ui_progress)(void *, unsigned long); -} ua_data_t; - -typedef struct _ua_delta_info_t { - char ua_patch_path[MAX_FILE_PATH]; - char ua_patch_info[MAX_FILE_PATH]; - char ua_delta_path[MAX_FILE_PATH]; - char ua_attrib_path[MAX_FILE_PATH]; -} ua_delta_info_t; - -typedef struct _ua_dataSS_t { // partition operations - ua_part_info_t *parti_info; - ua_update_cfg_t *update_cfg; - ua_update_data_t *update_data; - ua_delta_info_t *update_delta; - unsigned long ua_operation; - void (*ui_progress)(void *, unsigned long); - int (*write_data_to_blkdev)(char *, int, int, char *); -} ua_dataSS_t; - -typedef unsigned int SS_UINT32; - -#endif diff --git a/src/delta-ua/fota_cfg.c b/src/delta-ua/fota_cfg.c deleted file mode 100755 index 033e558..0000000 --- a/src/delta-ua/fota_cfg.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * delta-ua - * - * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include "fota_cfg.h" - -char fota_cfg_str[EN_CFG_MAX][CFG_MAX_LEN]; - -void fota_cfg_str_load(void) -{ - strncpy(fota_cfg_str[EN_CFG_SUPPORT_FB], "1", CFG_MAX_LEN-1); - strncpy(fota_cfg_str[EN_CFG_SUPPORT_DRM], "0", CFG_MAX_LEN-1); - strncpy(fota_cfg_str[EN_CFG_DEV_FB], "/dev/fb0", CFG_MAX_LEN-1); - strncpy(fota_cfg_str[EN_CFG_DEV_DRM_NAME], "exynos", CFG_MAX_LEN-1); -} - diff --git a/src/delta-ua/fota_cfg.h b/src/delta-ua/fota_cfg.h deleted file mode 100755 index e55d223..0000000 --- a/src/delta-ua/fota_cfg.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * delta-ua - * - * Copyright (c) 2017 -2022 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __FOTA_CFG_H__ -#define __FOTA_CFG_H__ - -#define CFG_MAX_LEN 1024 - -enum { - EN_CFG_SUPPORT_FB, - EN_CFG_SUPPORT_DRM, - EN_CFG_DEV_FB, - EN_CFG_DEV_DRM_NAME, - EN_CFG_MAX -}; - -extern char fota_cfg_str[EN_CFG_MAX][CFG_MAX_LEN]; - - -extern void fota_cfg_str_load(void); - - - -#endif /* __FOTA_FB_H__ */ - - diff --git a/src/delta-ua/fota_util.c b/src/delta-ua/fota_util.c deleted file mode 100755 index a8552df..0000000 --- a/src/delta-ua/fota_util.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * delta-ua - * - * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "engine/fota_common.h" - -int s_fd_stdin = -1; -int s_fd_stdout = -1; -int s_fd_stderr = -1; - -/*----------------------------------------------------------------------------- - _exit_stdio - ----------------------------------------------------------------------------*/ -void _exit_stdio(void) -{ - if (s_fd_stdin >= 0) - close(s_fd_stdin); - - if (s_fd_stdout >= 0) - close(s_fd_stdout); - - if (s_fd_stderr >= 0) - close(s_fd_stderr); -} - -/*----------------------------------------------------------------------------- - _system_cmd_wait - ----------------------------------------------------------------------------*/ -int _system_cmd_wait(const char *command) -{ - - int pid = 0; - int status = 0; - char* const environ[2] = {"DISPLAY=:0", NULL }; - - if (command == NULL) - return -1; - - pid = fork(); - - if (pid == -1) - return -1; - - if (pid == 0) { - char *argv[4]; - argv[0] = "sh"; - argv[1] = "-c"; - argv[2] = (char*)command; - argv[3] = 0; - execve("/bin/sh", argv, environ); - exit(127); - } - - do { - if (waitpid(pid, &status, 0) == -1) { - if (errno != EINTR) - return -1; - } else { - return status; - } - } while (1); -} - -/*----------------------------------------------------------------------------- - _system_cmd_nowait - ----------------------------------------------------------------------------*/ -int _system_cmd_nowait(const char *command) -{ - - int pid = 0; - char* const environ[2] = {"DISPLAY=:0", NULL }; - - if (command == NULL) - return -1; - - pid = fork(); - - if (pid == -1) - return -1; - - if (pid == 0) { - char *argv[4]; - argv[0] = "sh"; - argv[1] = "-c"; - argv[2] = (char*)command; - argv[3] = 0; - execve("/bin/sh", argv, environ); - exit(127); - } - - return 0; -} diff --git a/src/delta-ua/fota_util.h b/src/delta-ua/fota_util.h deleted file mode 100755 index ae0e568..0000000 --- a/src/delta-ua/fota_util.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * delta-ua - * - * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _FOTA_UTIL_H_ -#define _FOTA_UTIL_H_ - -extern void _exit_stdio(void); -extern int _system_cmd_wait(const char *command); -extern int _system_cmd_nowait(const char *command); - -#endif /* _FOTA_UTIL_H_ */ - diff --git a/src/delta-ua/ua.c b/src/delta-ua/ua.c deleted file mode 100755 index 479ccdf..0000000 --- a/src/delta-ua/ua.c +++ /dev/null @@ -1,857 +0,0 @@ -/* - * delta-ua - * - * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "fota_cfg.h" -#include "ua.h" -#include "fota_util.h" -#include "engine/SS_Common.h" -#include "engine/SS_UPI.h" -#include "engine/fota_common.h" -#include "engine/fota_tar.h" -#include "engine/ua_types.h" - - -#define SYSTEM_LOG_DIR "/opt/var/log" -#define TEMP_FOLDER "/tmp" // TODO - -//char ua_slot_mode = 0; -int dm_verity_status = DM_VERITY_DISABLED; - -// TODO: Consider changing all to PATH_MAX -static char fota_result[MAX_FILE_PATH]; -static char fota_cause[MAX_FILE_PATH]; -static char fota_status_path[MAX_FILE_PATH]; -static char delta_folder[MAX_FOLDER_PATH]; -static char delta_path[MAX_FILE_PATH]; -static char log_folder[MAX_FOLDER_PATH]; -static char result_folder[MAX_FOLDER_PATH]; -static char temp_folder[MAX_FOLDER_PATH]; -static char log_path[MAX_FILE_PATH]; - -static ua_part_info_t s_part_info; - -static ua_update_cfg_t s_update_cfg; - -static ua_update_data_t s_update_data; - -typedef struct temp_opt{ - char * archive; - char * archive_file; - char * dest; -}temp_opt; - -static ua_delta_info_t s_delta_info; - -unsigned int __log_level__ = - (LOG_DEBUG | LOG_FLASH | LOG_FILE | LOG_FUNCS | LOG_GUI | LOG_ENGINE | LOG_INFO); -FILE *__log_out_file__; - -static void save_result(int result); -static void save_cause(int cause); - -#define TMP_DIR "/tmp/upgrade" -#define PROGRESS_FILE TMP_DIR "/ro_progress" - -#define HAL_PROGRESS_MIN 40 -#define HAL_PROGRESS_MAX 80 - -void print_usage(const char *msg) -{ - if (msg) { - printf("%s\n", msg); - } - printf("print_usage: delta.ua --archive delta_dir --dest label --archive-file label.img\n" - "delta_dir: directory path where delta.tar file is located\n" - "label: label of the partition to be updated\n" - "label.img: name of the file inside of delta that is to be used during upgrade\n" - ); -} - -void print_error_code(int err) -{ - char msg[]="delta.ua error:"; - switch (err) { - case UPI_CONFIG_ERROR: - printf("%s config error.\n", msg); - break; - case UPI_DELTA_PATH_ERROR: - printf("%s delta path error.\n", msg); - break; - case UPI_DELTA_PATH_LENGTH_ERROR: - printf("%s delta path length error.\n", msg); - break; - case UPI_VERSION_ERROR: - printf("%s version error.\n", msg); - break; - case UPI_VERIFY_ERROR: - printf("%s verify error.\n", msg); - break; - case UPI_UPDATE_ERROR: - printf("%s update error.\n", msg); - break; - case UPI_INVALID_PARAM_ERROR: - printf("%s invalid parameter error.\n", msg); - break; - case UPI_DELTACOUNT_ERROR: - printf("%s delta count error.\n", msg); - break; - case UPI_PARTINFO_ERROR: - printf("%s partition information error.\n", msg); - break; - default: - printf("delta.ua unable to determine error code: %d\n", err); - } -} - -void fota_gui_update_progress(int percent) -{ - int ret; - int fd; - struct stat s; - - // Check directory - ret = stat(TMP_DIR, &s); - if (ret == 0) { - // TMP_DIR exists but it is not directory - if (!S_ISDIR(s.st_mode)) - goto remove_file; - else - goto update_progress; - } else if (errno == ENOENT) // TMP_DIR not exists - goto make_directory; - else { - LOG("stat failed : %m\n"); - return; - } - -remove_file: - ret = remove(TMP_DIR); - if (ret != 0) { - LOG("remove failed : %m\n"); - return; - } - -make_directory: - ret = mkdir(TMP_DIR, 0755); - if (ret != 0) { - LOG("mkdir failed : %m\n"); - return; - } - -update_progress: - fd = creat(PROGRESS_FILE, 0644); - if (fd < 0) { - LOG("creat failed : %m\n"); - return; - } - - ret = dprintf(fd, "%d\n", percent); - if (close(fd) != 0) { - LOG("close failed : %m\n"); - return; - } - if (ret < 2) { - LOG("write failed (%d) : %m\n", ret); - return; - } - - LOG("Succeed to write\n"); -} - -static void set_upgrade_progress(int percent) -{ - int relative_precent = HAL_PROGRESS_MIN + ((HAL_PROGRESS_MAX - HAL_PROGRESS_MIN) * percent)/100; - if (hal_device_board_set_upgrade_status(relative_precent) < 0) { - LOG("set_upgrade_status failed: %d\n", relative_precent); - return; - } - - LOG("set_upgrade_status success: %d\n", relative_precent); -} - -/*----------------------------------------------------------------------------- - fota_gui_progress - ----------------------------------------------------------------------------*/ - // TODO - remove this mechanism, only makes log less readable -void fota_gui_progress(void * pbUserData, unsigned long uPercent) -{ - int percent; - int from, to; - ua_dataSS_t *ua_data = (ua_dataSS_t *)pbUserData; - ua_update_data_t *ua_update_data = ua_data->update_data; - - LOGL(LOG_FUNCS|LOG_GUI, "%s: ++ uPercent(%lu%%), config->weight=%lu\n", __func__, - uPercent, (long unsigned int)ua_update_data->weight); - - if (uPercent == 100) - percent = ua_update_data->weight_offset + ua_update_data->weight; - else - percent = ua_update_data->weight_offset + (ua_update_data->weight * uPercent / 100); - - set_upgrade_progress(percent); - /** - * re-arrange progress percentage between scout & update - * - * 0 ~ 100 -> from ~ to - */ - switch (ua_data->ua_operation) { - case UI_OP_SCOUT: - from = 0; - to = 20; - break; - case UI_OP_SCOUT_UPDATE: - case UI_OP_UPDATE: - from = 20; - to = (dm_verity_status == DM_VERITY_ENABLED) ? 80 : 100; - break; - default: - from = 0; - to = 100; - break; - } - - percent = from + ((to - from) * percent / 100); - - fota_gui_update_progress(percent); /* update progress bar and text */ - - LOGL(LOG_FUNCS|LOG_GUI, "-- uPercent=%lu, Print Percent(%d%%)\n", uPercent, percent); -} - -/*----------------------------------------------------------------------------- - verify_Delta_FS - ----------------------------------------------------------------------------*/ -int verify_Delta_FS() -{ - int ret = SUCCESS; - ua_dataSS_t ua_dataSS; - ua_part_info_t *ua_part_info = &s_part_info; - ua_update_cfg_t *ua_update_cfg = &s_update_cfg; - ua_update_data_t *ua_update_data = &s_update_data; - ua_delta_info_t *ua_delta_info = &s_delta_info; - ua_dataSS.parti_info = ua_part_info; - ua_dataSS.update_cfg = ua_update_cfg; - ua_dataSS.update_data = ua_update_data; - ua_dataSS.update_delta = ua_delta_info; - ua_dataSS.ua_operation = UI_OP_SCOUT; - ua_dataSS.ui_progress = fota_gui_progress; - - if (ua_update_data->ua_delta_path != NULL) { - LOG("Verifying %s \n", ua_dataSS.parti_info->ua_parti_name); - ret = SS_FSVerifyPartition(&ua_dataSS); - } - - return ret; -} - -/*----------------------------------------------------------------------------- - update_Delta_FS - ----------------------------------------------------------------------------*/ -int update_Delta_FS(unsigned long ui32Operation) -{ - int ret = SUCCESS; - ua_dataSS_t ua_dataSS; - ua_part_info_t *ua_part_info = &s_part_info; - ua_update_cfg_t *ua_update_cfg = &s_update_cfg; - ua_update_data_t *ua_update_data = &s_update_data; - ua_delta_info_t *ua_delta_info = &s_delta_info; - ua_dataSS.parti_info = ua_part_info; - ua_dataSS.update_cfg = ua_update_cfg; - ua_dataSS.update_data = ua_update_data; - ua_dataSS.update_delta = ua_delta_info; - ua_dataSS.ua_operation = ui32Operation; - ua_dataSS.ui_progress = fota_gui_progress; - - if (ua_update_data->ua_delta_path != NULL) - ret = SS_FSUpdatemain(&ua_dataSS); - - return ret; -} - -/*----------------------------------------------------------------------------- - set_data_weight - ----------------------------------------------------------------------------*/ -/* set data weight using data size minimum:1 total: 100 */ -// TODO - remove -static void set_data_weight(unsigned int total_data_size) -{ - LOG("%s entered, total_data_size=%u\n", __func__, total_data_size); - s_update_data.weight = 100; - LOG("%s leaved\n", __func__); -} - -/*----------------------------------------------------------------------------- - set_data_weight_offset - ----------------------------------------------------------------------------*/ - // TODO - remove -static void set_data_weight_offset(void) -{ - LOG("%s entered\n", __func__); - s_update_data.weight_offset = 0; // not sure what it does, keep it like this for now - LOG("s_update_data.weight_offset=%u\n", s_update_data.weight_offset); - LOG("%s leaved\n", __func__); -} - -/*----------------------------------------------------------------------------- - get_time_stamp - ----------------------------------------------------------------------------*/ -static char ts[256]; -static void get_time_stamp(void) -{ - struct timeval tv; - int sec, msec; - - gettimeofday(&tv, NULL); - sec = (int) tv.tv_sec; - msec = (int) (tv.tv_usec / 1000); - snprintf(ts, sizeof(ts), "%06d.%03d", sec % 100000, msec); -} - -/*----------------------------------------------------------------------------- - update_all - ----------------------------------------------------------------------------*/ -int update_all() -{ - int ret = OK; - int cause = 0, item_size = 0; - int last_update_status = UP_START_NONE; - int update_status = UP_START_NONE; - unsigned long ui32Operation = UI_OP_SCOUT; - int del_type = 0; // TODO, for clarity - char status_path[MAX_FILE_PATH]; - snprintf(status_path, MAX_FILE_PATH, "%s/%s",s_update_data.ua_delta_folder, SS_UPDATE_STATUS_PATH); - - item_size = tar_get_item_size(s_update_data.ua_delta_path, s_part_info.ua_subject_name); - if (item_size > 0) - s_update_data.data_size = (unsigned int)item_size; - else - s_update_data.data_size = 0; - - LOGL(LOG_DEBUG, "s_update_data.data_size=%lu, ua_delta_path=%s, " - "ua_subject_name=%s\n", - (long unsigned int)s_update_data.data_size, - s_update_data.ua_delta_path, - s_part_info.ua_subject_name); - - if (s_update_data.data_size <= 0) { - ret = UPI_DELTACOUNT_ERROR; - sleep(3); - - goto CleanUp; - } - LOG(" set weight to draw progressive bar.....\n"); - set_data_weight(s_update_data.data_size); - set_data_weight_offset(); - - LOG("s_part_info.ua_parti_name = %s ua_delta_path = %s ua_subject_name=%s\n", - s_part_info.ua_parti_name, - s_update_data.ua_delta_path, - s_part_info.ua_subject_name); - - if (SS_Get_last_update_status(&last_update_status, &del_type, status_path) == -1) - LOG("No last_update_status. Go normal update scenario.\n"); - else - LOG("Get last_update_status. Go Power safe update scenario.\n"); - - LOG("last_update_status: [%d], del_type: [%d] \n", last_update_status, del_type); - /* Verify */ - if (last_update_status == UP_START_NONE) { - - if (s_update_data.data_size > 0) { - get_time_stamp(); - LOG("[%s] Verify %s ..............................................................\n", ts, - s_part_info.ua_parti_name); - - ret = verify_Delta_FS(); - LOG("return form verify : %d\n", ret); - if (ret != OK) { - cause = ret; - ret = UPI_VERIFY_ERROR; - LOG("%s verify fail\n", s_part_info.ua_parti_name); - goto CleanUp; - } - } - - } - - get_time_stamp(); - LOG("[%s] Verify End ..............................................................\n", ts); - - /* Update */ - ui32Operation = UI_OP_SCOUT_UPDATE; - - - if (s_update_data.data_size > 0) { - get_time_stamp(); - LOG("[%s] Update %s ..............................................................\n", ts, - s_part_info.ua_parti_name); - - SS_Set_last_update_status(update_status, del_type, status_path); // i have to look into what it does - - ret = update_Delta_FS(ui32Operation); - LOG("return form update : %d\n", ret); - if (ret != OK) { - cause = ret; - ret = UPI_UPDATE_ERROR; - LOG("%s update fail\n", s_part_info.ua_parti_name); - goto CleanUp; - } - } - - get_time_stamp(); - LOG("[%s] Update End ..............................................................\n", ts); - - CleanUp: - if (ret != OK) - save_cause(cause); - - return ret; -} - -/*----------------------------------------------------------------------------- - log_init - ----------------------------------------------------------------------------*/ -void log_init(void) -{ - memset(log_path, 0x00, sizeof(log_path)); - snprintf(log_path, sizeof(log_path), "%s", LOG_FILE_PATH); - - __log_out_file__ = fopen(log_path, "w"); - if (__log_out_file__ == NULL) { - perror("file open error\n"); - return; - } - get_time_stamp(); - LOG("===== log start [%s] =====\n", ts); -} - -/*----------------------------------------------------------------------------- - log_deinit - ----------------------------------------------------------------------------*/ -void log_deinit(void) -{ - get_time_stamp(); - LOG("===== log end [%s] =====\n", ts); - - if (__log_out_file__) { - fclose(__log_out_file__); - __log_out_file__ = NULL; - } - - sync(); -} - -/*----------------------------------------------------------------------------- - print_error_cause - ----------------------------------------------------------------------------*/ -static void print_error_cause(int error) -{ - switch (error) { - case E_SS_FSBADDELTA: - LOG("Corrupted firmware update package, did not store correctly. Detected, for example, by mismatched CRCs between actual and expected.\n"); - break; - case E_SS_BAD_PARAMS: - LOG("Wrong Firmware Update Package delivered to device based on current device characteristics\n"); - break; - case E_SS_MALLOC_ERROR: - LOG("The update fails because there isn't sufficient memory to update the device.\n"); - break; - case E_SS_FSSRCBACKUPFAILED: - case E_SS_WRITE_ERROR: - case E_SS_FSFAILEDTOBACKUPPATCHINFO: - case E_SS_FSBADATTRIBUTES: - LOG("The update failed because writing data to the device was unsuccessful.\n"); - break; - case E_SS_FSSRCCURRUPTED: - case E_SS_FSSHA_MISMATCH: - case E_SS_FSFAILEDTOPARSEDELTACNT: - case E_SS_FSFAILEDTOOPENPATCHINFO: - case E_SS_FSFAILEDTOPARSEDELTAINFO: - LOG("The update failed because data was corrupted during update of device.\n"); - break; - default: - LOG("another error\n"); - break; - } -} - -/* - -Corrupted firmware update package, did not store correctly. Detected, for example, by mismatched CRCs between actual and expected. -E_RB_PKG_CORRUPTED(0x8000000D) -E_RB_PKG_NOT_AUTHORIZED(0x8000000E): not used - - -Wrong Firmware Update Package delivered to device based on current device characteristics -E_RB_BAD_PARAMS(0x800000002) -E_RB_WRONG_UPI_VER(0x80000011):not used -E_RB_WRONG_UPI_UPDATE(0x80000012): not used -E_RB_UPDATE_SECTOR_SIG(0x80000013): not used - - -Failure to positively validate digital signature of firmware update package -E_RB_NON_DP_FORMAT_NOT_SUPPORTED(0x8001001A) -E_RB_INVALID_DP_HEADER(0x80010025) -E_RB_INVALID_DP_WRONG_SIGNATURE(0x80010026) -E_RB_INVALID_DP(0x80010027) - - -Firmware Update Package is Not Acceptable -E_RB_PKG_TOO_SHORT(0x8000000B) not used -E_RB_PKG_TOO_LONG(0x8000000C) not used -E_RB_PKG_NOT_AUTHORIZED(0x8000000F) - - -The update fails because there isn\A1\AFt sufficient memory to update the device. -E_RB_NOT_ENOUGH_RAM(0x8000001E) -*/ - -/*----------------------------------------------------------------------------- - save_cause - ----------------------------------------------------------------------------*/ -void save_cause(int cause) -{ - char return_char[20]; - FILE *result_fp; - - LOG("%s entered, 0x%x\n", __func__, cause); - - print_error_cause(cause); - - if ((result_fp = fopen(fota_cause, "w")) == NULL) { - LOG("cause file open fail\n"); - return; - } - - snprintf(return_char, sizeof(return_char), "%x", cause); - fwrite(return_char, strlen(return_char), 1, result_fp); - fclose(result_fp); - - LOG("%s leaved!\n", __func__); -} - -/*----------------------------------------------------------------------------- - save_result - ----------------------------------------------------------------------------*/ -void save_result(int result) -{ - char return_char[20]; - FILE *result_fp; - - LOG("%s entered, result=0x%x\n", __func__, result); - - if ((result_fp = fopen(fota_result, "w")) == NULL) { - LOG("result file open fail\n"); - return; - } - - snprintf(return_char, sizeof(return_char), "%x", result); - fwrite(return_char, strlen(return_char), 1, result_fp); - fclose(result_fp); - - LOG("%s leaved!\n", __func__); - - return; -} - -/*----------------------------------------------------------------------------- - fota_path_init - ----------------------------------------------------------------------------*/ -int fota_path_init(void) -{ - if (strlen(delta_folder) > MAX_FILE_PATH - 15) { - LOG("FOTA path is too long\n"); - return FAIL; - } - - - s_update_data.ua_delta_path = malloc(MAX_FILE_PATH); - if (s_update_data.ua_delta_path == NULL) { - LOG("Memory allocation fail\n"); - return FAIL; - } - snprintf(s_update_data.ua_delta_path, MAX_FILE_PATH, "%s/%s", delta_folder, DEFAULT_DELTA_NAME); - snprintf(fota_cause, sizeof(fota_cause), "%s/%s", result_folder, "cause"); - snprintf(fota_status_path, sizeof(fota_status_path), "%s/%s", result_folder, UP_STATUS_FILE); - - LOG("s_part_info[UA_%s].ua_delta_path=%s\n", - s_part_info.ua_parti_name, - s_update_data.ua_delta_path); - - return SUCCESS; -} - -/*----------------------------------------------------------------------------- - fota_path_deinit - ----------------------------------------------------------------------------*/ -void fota_path_deinit(void) -{ - if (s_update_data.ua_delta_path) { - free(s_update_data.ua_delta_path); - s_update_data.ua_delta_path = NULL; - } - if (s_update_data.ua_temp_path) { - free(s_update_data.ua_temp_path); - s_update_data.ua_temp_path = NULL; - } -} - -/*----------------------------------------------------------------------------- - check_dm_verity_status - ----------------------------------------------------------------------------*/ -int check_dm_verity_status(void) -{ - int ret = 0; - - ret = access("/usr/bin/verityctl", F_OK); - if (ret == -1) { - if (errno == ENOENT) { - LOG("dm-verity status : disabled\n"); - dm_verity_status = DM_VERITY_DISABLED; - return 0; - } else { - LOG("access failed with errno: %d\n", errno); - return -errno; - } - } - - LOG("dm-verity status : enabled\n"); - dm_verity_status = DM_VERITY_ENABLED; - return 0; -} - -/*----------------------------------------------------------------------------- - remove_temp_files - ----------------------------------------------------------------------------*/ -void remove_temp_files(void) -{ - int ret = 0; - char *ua_temp_path; - struct stat sbuf; - - - ua_temp_path = s_update_data.ua_temp_path; - if (NULL == ua_temp_path) - return; - - ret = lstat(ua_temp_path, &sbuf); - if (ret < 0) { - ret = stat(ua_temp_path, &sbuf); - if (ret < 0) { - LOG("stat failed with return value: %d errno: %d\n", ret, errno); - return; - } - } - - if (S_ISDIR(sbuf.st_mode)) { - ret = rmdir(ua_temp_path); - if (ret < 0) - LOG("rmdir(%s) failed with return value: %d errno: %d\n", ua_temp_path, ret, errno); - } else { - ret = unlink(ua_temp_path); - if (ret < 0) - LOG("unlink(%s) failed with return value: %d errno: %d\n", ua_temp_path, ret, errno); - } -} - -/*----------------------------------------------------------------------------- - arg_parse - ----------------------------------------------------------------------------*/ -int arg_parse(int argc, char ** argv, temp_opt *my_opt) -{ - if (argc != 7) { - print_usage("Invalid parameter count"); - return -1; - } - const char * archive = NULL; - const char * archive_file = NULL; - const char * dest = NULL; - const struct option long_options[] = { - {"archive", required_argument, NULL, 0 }, - {"dest", required_argument, NULL, 1 }, - {"archive-file", required_argument, NULL, 2 }, - {0} - }; - while (1) { - int option = getopt_long(argc, argv, "", long_options, NULL); - if (option < 0) - break; - switch (option) { - case 0: - if (archive != NULL) { - print_usage("Parameters repeated"); - return -1; - } - archive = optarg; - break; - case 1: - if (dest != NULL) { - print_usage("Parameters repeated"); - return -1; - } - dest = optarg; - break; - case 2: - if (archive_file != NULL) { - print_usage("Parameters repeated"); - return -1; - } - archive_file = optarg; - break; - default: - print_usage("Invalid parameters"); - return -1; - } - } - if (archive_file == NULL || dest == NULL || archive == NULL) { - print_usage("Wrong parameters"); - return -1; - } - (*my_opt).archive = archive; - (*my_opt).dest = dest; - (*my_opt).archive_file = archive_file; - - return 0; -} - -/*----------------------------------------------------------------------------- - main - ----------------------------------------------------------------------------*/ -int main(int argc, char **argv) -{ - char ver_str[MAX_PATH]; - int ret = FAIL; - temp_opt my_opt; - log_init(); - if(arg_parse(argc, argv, &my_opt) < 0) { - ret = UPI_INVALID_PARAM_ERROR; - goto Results; - } - -#if defined(FEATURE_SUPPORT_CAPABILITY) - SS_set_feature_support_capability(1); -#endif - - memset(delta_folder, 0x00, sizeof(delta_folder)); - snprintf(delta_folder, sizeof(delta_folder)-1, "%s", my_opt.archive); - snprintf(delta_path, sizeof(delta_path)-1, "%s/%s", delta_folder, DEFAULT_DELTA_NAME); - s_update_data.ua_delta_folder = strdup(delta_folder); - - memset(temp_folder, 0x00, sizeof(temp_folder)); - snprintf(temp_folder, sizeof(temp_folder)-1, "%s", TEMP_FOLDER); - - memset(log_folder, 0x00, sizeof(log_folder)); - snprintf(log_folder, sizeof(log_folder)-1, "%s", SYSTEM_LOG_DIR); - - memcpy(result_folder, temp_folder, sizeof(result_folder)); - - snprintf(fota_result, sizeof(fota_result), "%s/%s", result_folder, "result"); - - fota_cfg_str_load(); - - if (check_dm_verity_status() < 0) { // to be removed - LOG("check_dm_verity_status fail\n"); - ret = UPI_CONFIG_ERROR; - goto Results; - } - - s_part_info.ua_parti_name = my_opt.dest; - s_part_info.ua_subject_name = my_opt.archive_file; - s_update_cfg.source_img_size = 0; // TODO lets see if 0 will work - - /* load block device number at run-time */ - - ret = fota_path_init(); - if (ret == FAIL) { - ret = UPI_DELTA_PATH_LENGTH_ERROR; - goto Results; - } - LOG("<<<<<<<<<<< log_init >>>>>>>>>>>>\n"); - - /* UPI version check */ - if (S_SS_SUCCESS == SS_GetUPIVersion((unsigned char*)ver_str)) { - LOG("<<<<<<<<< TOTA Update Agent %s >>>>>>>>>>>>\n", ver_str); - } else { - LOG("[SS_GetUPIVersion fail] \n"); - ret = UPI_VERSION_ERROR; - goto Results; - } - /* Main Update Routine : Scout & Update */ - ret = update_all(); - LOG("[update_all ret=%d]\n", ret); - - Results: - LOG("Result=%d\n", ret); - save_result(ret); - //remove_temp_files(); // TOTA - if (ret != SUCCESS) - print_error_code(ret); - - switch (ret) { - /* Before initialize fota path */ - case UPI_INVALID_PARAM_ERROR: - case UPI_DELTA_PATH_ERROR: - case UPI_CONFIG_ERROR: - case UPI_PARTINFO_ERROR: - case UPI_DELTA_PATH_LENGTH_ERROR: - log_deinit(); - _exit_stdio(); - return -1; - /* After initialize fota path */ - case UPI_VERSION_ERROR: - case UPI_DELTACOUNT_ERROR: - case UPI_VERIFY_ERROR: - case UPI_UPDATE_ERROR: - fota_path_deinit(); - log_deinit(); - _exit_stdio(); - return -1; - case SUCCESS: - fota_path_deinit(); - log_deinit(); - /* Preserve log file for debugging */ - _exit_stdio(); - return 0; - default: - LOG("!!! Not expected ret (= %d)\n", ret); - } - - if(s_part_info.ua_parti_name) free(s_part_info.ua_parti_name); - if(s_part_info.ua_subject_name) free(s_part_info.ua_subject_name); - - _exit_stdio(); - return -1; -} \ No newline at end of file diff --git a/src/delta-ua/ua.h b/src/delta-ua/ua.h deleted file mode 100755 index c5077fe..0000000 --- a/src/delta-ua/ua.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * delta-ua - * - * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __UA_H__ -#define __UA_H__ - -#include - -/* - * FEATURE - */ - -//#define USE_POST_UPDATE -//#define USE_DELTA_DOWNLOAD -//#define USE_DUALSBL - -#define LOG_FILE_PATH "/opt/data/update/last_update.log" -#define MAX_FILE_PATH 512 -#define MAX_FOLDER_PATH 384 - -/* - * FOTA Adaptaion header - */ - -#define ERROR -1 // 0XFFFFFFFF - -#define INVALID 0 -#define VALID 1 -#define TRUE 1 -#define FALSE 0 -#define OK 0 -#define SUCCESS 0 -#define FAIL 1 -#define RESTORING 2 - -#define UPI_ERROR(code) 0xFD##code - -#define UPI_CONFIG_ERROR UPI_ERROR(9A) - -#define UPI_DELTA_PATH_ERROR UPI_ERROR(AA) -#define UPI_DELTA_PATH_LENGTH_ERROR UPI_ERROR(AB) - -#define UPI_VERSION_ERROR UPI_ERROR(BB) - -#define UPI_VERIFY_ERROR UPI_ERROR(C0) -#define UPI_UPDATE_ERROR UPI_ERROR(D0) - -#define UPI_INVALID_PARAM_ERROR UPI_ERROR(EA) -#define UPI_DELTACOUNT_ERROR UPI_ERROR(EC) -#define UPI_PARTINFO_ERROR UPI_ERROR(ED) - -#define DEFAULT_DELTA_NAME "delta.tar" -#define UPDATTE_CFG_FILE "update.cfg" - -#define UP_STATUS_FILE "UP.STATUS" -#define UP_START_NONE 0 - -enum { - UA_OP_MODE_FG = 0, - UA_OP_MODE_BG -}; - -enum { - DM_VERITY_DISABLED = 0, - DM_VERITY_ENABLED = 1 -}; - -void log_deinit(void); - -#endif diff --git a/src/upgrade-apply-deltafs/CMakeLists.txt b/src/upgrade-apply-deltafs/CMakeLists.txt new file mode 100644 index 0000000..7944b59 --- /dev/null +++ b/src/upgrade-apply-deltafs/CMakeLists.txt @@ -0,0 +1,36 @@ +ADD_DEFINITIONS("-DFEATURE_SUPPORT_CAPABILITY") +ADD_DEFINITIONS("-D_FILE_OFFSET_BITS=64") + +SET(SRCS + fota_cfg.c + fota_util.c + ua.c + engine/SS_Common.c + ../upgrade-apply/sha1/sha1.c + engine/SS_UPI.c + engine/SS_FSUpdate.c + engine/fota_tar.c + engine/SS_ApplyPatch.c + engine/SS_PatchDelta.c + engine/fota_log.c + engine/fota_tar.c + engine/ss_bspatch_common.c +) + +INCLUDE_DIRECTORIES(../upgrade-apply/sha1) + +INCLUDE(FindPkgConfig) +pkg_check_modules(${PROJECT_NAME}_pkgs REQUIRED liblzma-tool libbrotlienc hal-api-device zlib) + +FOREACH(flag ${${PROJECT_NAME}_pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -I./include") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") + +SET(EXECNAME "upgrade-apply-deltafs") +SET(BINDIR "/usr/bin") +ADD_EXECUTABLE(${EXECNAME} ${SRCS}) +TARGET_LINK_LIBRARIES(${EXECNAME} ${${PROJECT_NAME}_pkgs_LDFLAGS} "-g" "-pthread") +INSTALL(TARGETS ${EXECNAME} DESTINATION ${BINDIR}) diff --git a/src/upgrade-apply-deltafs/engine/SS_ApplyPatch.c b/src/upgrade-apply-deltafs/engine/SS_ApplyPatch.c new file mode 100755 index 0000000..bc9e86b --- /dev/null +++ b/src/upgrade-apply-deltafs/engine/SS_ApplyPatch.c @@ -0,0 +1,115 @@ +/*- + * Copyright 2003-2005 Colin Percival + * Copyright 2012 Matthew Endsley + * All rights reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted providing that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Modifications are made in reimplementing suffix sort array generation + * and how the data is read and written to.Iterative part replaced the + * recursive implementation to avoid buffer overflow problems + */ +#include +#include +#include "SS_PatchDelta.h" +#include "fota_common.h" +#include "sha1.h" +#include "SS_Engine_Errors.h" +#include "SS_FSUpdate.h" + +#include "ss_bspatch_common.h" +#include +#include <7zFile.h> +#include <7zVersion.h> +#include +#include + + +int SS_ApplyBsdiff(char *oldfile, char *newfile, char *patch, SinkFn sink, void *token, SHA1_CTX * ctx1) +{ + UInt64 unpackSize = 0; + CFileSeqInStream inStream; + ISeqOutStream outStream; + unsigned char *buf_res = NULL; + unsigned char *new_data = NULL; + char buf[256]; + ssize_t new_size = 0; + int result = E_SS_FAILURE; + + FileSeqInStream_CreateVTable(&inStream); + File_Construct(&inStream.file); + FileOutStream_CreateVTable((CFileOutStream *) & outStream); + + if (InFile_Open(&inStream.file, patch) != 0) + return E_SS_FAILURE; + + UInt64 i; + CLzmaDec state; + unsigned char header[LZMA_PROPS_SIZE + 8]; + + RINOK(SeqInStream_Read(&inStream.s, header, sizeof(header))); + + unpackSize = 0; + for (i = 0; i < 8; i++) + unpackSize += (UInt64) header[LZMA_PROPS_SIZE + i] << (i * 8); + + LzmaDec_Construct(&state); + RINOK(LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc)); + + //decompress the patch file into buf_res + buf_res = (unsigned char *)SS_Malloc(unpackSize); + if (!buf_res) { + LOGE("Bad memory allocation\n"); + goto Cleanup; + } + result = Decode2(&state, &outStream, &inStream.s, &unpackSize, buf_res); + + LzmaDec_Free(&state, &g_Alloc); + File_Close(&inStream.file); + + if (result != S_SS_SUCCESS) { + LOGE("Error decompression failed with code : [%d]\n", result); + goto Cleanup; + } + //apply patch using buffer decoded by Decode2 + result = apply_patch(oldfile, buf_res, &new_data, &new_size); + if (result != S_SS_SUCCESS) + goto Cleanup; + + result = (sink(new_data, new_size, token) < new_size) ? E_SS_FAILURE : S_SS_SUCCESS; + if (result != S_SS_SUCCESS) { + strerror_r(errno, buf, sizeof(buf)); + LOGE("short write of output: %d (%s)\n", errno, buf); + goto Cleanup; + } + + if (ctx1) + SHA1Update(ctx1, new_data, new_size); +Cleanup: + if (new_data) + SS_Free(new_data); + if (buf_res) + SS_Free(buf_res); + File_Close(&inStream.file);//wgid: 27007 + return result; + +} diff --git a/src/upgrade-apply-deltafs/engine/SS_Common.c b/src/upgrade-apply-deltafs/engine/SS_Common.c new file mode 100755 index 0000000..605481e --- /dev/null +++ b/src/upgrade-apply-deltafs/engine/SS_Common.c @@ -0,0 +1,42 @@ +/* + * upgrade-apply-deltafs + * + * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "SS_Engine_Errors.h" +#include "SS_Common.h" + +#include "ua_types.h" +#include "fota_tar.h" +#include "fota_common.h" +#include "sha1.h" + +void hex_digest(char * sha1, char *buffer, int size) +{ + for (int i = 0; i < size; i++) { + snprintf(&buffer[i * 2], (size * 2) - (i * 2) + 1, "%02x", sha1[i]); + } +} diff --git a/src/upgrade-apply-deltafs/engine/SS_Common.h b/src/upgrade-apply-deltafs/engine/SS_Common.h new file mode 100755 index 0000000..20aae77 --- /dev/null +++ b/src/upgrade-apply-deltafs/engine/SS_Common.h @@ -0,0 +1,38 @@ +/* + * upgrade-apply-deltafs + * + * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "SS_FSUpdate.h" +#include "SS_Engine_Errors.h" +typedef enum { + FT_REGULAR_FILE, + FT_SYMBOLIC_LINK, + FT_FOLDER, + FT_MISSING +} enumFileType; + +#include "ua_types.h" + +#define MAX_PATH 256 + +#define SIZE_4GB (0Xffffffff) + +void SS_unicode_to_char(const char *src, char *dest, int size); + +void hex_digest(char * sha1, char *buffer, int size); diff --git a/src/upgrade-apply-deltafs/engine/SS_Engine_Errors.h b/src/upgrade-apply-deltafs/engine/SS_Engine_Errors.h new file mode 100755 index 0000000..bc6e25f --- /dev/null +++ b/src/upgrade-apply-deltafs/engine/SS_Engine_Errors.h @@ -0,0 +1,79 @@ +/* + * upgrade-apply-deltafs + * + * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + SS_Engine Errors + + 0xAxx Series define INPUT/UA Errors + + 0xBxx Series define Delta Errors + + 0xCxx Series define System Errors + + 0xDxx Series define Engine Errors + + 0xExx Series define any Other Errors + +*/ + +#ifndef __SS_Engine_ERRORS__ +#define __SS_Engine_ERRORS__ + +#define S_SS_SUCCESS (0) /*! Success Code */ +#define E_SS_FAILURE (1) /*! Failure Code */ + +/* INPUT Processing errors */ + +/* invocation errors */ +#define E_SS_BAD_PARAMS (0xA00) /**< error in a run parameter */ +#define E_SS_FSINVALIDNODEPARAMS (0xA01) /* Failed to Parse the Params to verify NODE */ +#define E_SS_FSBADNODES (0xA02) /* Failed to verify NODE for FS */ +#define E_SS_FSBADDELTA (0xA03) /* Delta File does NOT contain required information on FS */ +#define E_SS_FSBADATTRIBUTES (0xA04) /* Failed to parse attribute data */ +#define E_SS_FSFAILEDTOOPENPATCHINFO (0xA05) /*Failed to open patch list file having details of PATCH info */ +#define E_SS_FSFAILEDTOPARSEDELTACNT (0xA06) /* Failed to parse the PATCH count information */ +#define E_SS_FSFAILEDTOPARSEDELTAINFO (0xA07) /* Failed to parse the Delta patch information */ + +/*Delta Errors*/ +#define E_SS_FSSHA_MISMATCH (0xB00) /*Could NOT produce expected Target SHA for file */ + +/* Resources errors */ +#define E_SS_MALLOC_ERROR (0xC00) /**< memory allocation failure */ + +/* Image update Error codes */ +#define E_SS_WRITE_ERROR (0xC01) /**< flash writing failure */ +#define E_SS_READ_ERROR (0xC02) /**< flash reading failure */ + +/*File System Error codes */ +#define E_SS_OPENFILE_ONLYR (0xC03) /**< file does not exist */ +#define E_SS_OPENFILE_WRITE (0xC04) /**< RO or no access rights */ +#define E_SS_DELETEFILE (0xC05) /**< no access rights */ +#define E_SS_READFILE_SIZE (0xC06) /**< cannot read specified size*/ +#define E_SS_CLOSEFILE_ERROR (0xC07) /**< cannot close file handle */ +#define E_SS_CANNOT_CREATE_DIRECTORY (0xC08) /**< Failed creating directory */ +#define E_SS_FSMEMORYERROR (0xC09) /* Failed to allocate Memory */ +#define E_SS_FILENAMELENERROR (0xC10) /* Failed to serve filename length */ + +/*Engine errors */ +#define E_SS_FSFAILEDTOBACKUPPATCHINFO (0xD00) /* Failed to create backup file to write Delta patch info data */ +#define E_SS_FSUPDATEFAILED (0xD01) /*FS Failed during UPGRADE */ +#define E_SS_FSSRCBACKUPFAILED (0xD02) /*Failed to backup FS */ +#define E_SS_FSSRCCURRUPTED (0xD03) /*Could NOT update FS as SRC seems to be corrupted */ +#define E_SS_PATCHFILE_DEL_ERROR (0xD04) /*Failed to Clear/Del Patched SRC file */ + +#endif diff --git a/src/upgrade-apply-deltafs/engine/SS_FSUpdate.c b/src/upgrade-apply-deltafs/engine/SS_FSUpdate.c new file mode 100755 index 0000000..78ca0f3 --- /dev/null +++ b/src/upgrade-apply-deltafs/engine/SS_FSUpdate.c @@ -0,0 +1,1101 @@ +/* + * upgrade-apply-deltafs + * + * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define _XOPEN_SOURCE 600 +#define _POSIX_C_SOURCE 200809L +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "SS_Common.h" + +#include "fota_common.h" +#include "ua_types.h" + +static int feature_support_capability; + +enum smack_label_type { + SMACK_LABEL_ACCESS, + SMACK_LABEL_EXEC, + SMACK_LABEL_MMAP, + SMACK_LABEL_TRANSMUTE, + SMACK_LABEL_IPIN, + SMACK_LABEL_IPOUT, +}; + +#define SMACK_LABEL_LEN 255 + +/************************************************************ + * common functions + ************************************************************/ +void SS_create_dir(char *pathname, int mode) +{ + char *p; + int r; + + /* Strip trailing '/' */ + if (pathname[strlen(pathname) - 1] == '/') + pathname[strlen(pathname) - 1] = '\0'; + + /* Try creating the directory. */ + r = mkdir(pathname, mode); + + if (r != 0) { + /* On failure, try creating parent directory. */ + p = strrchr(pathname, '/'); + if (p != NULL) { + *p = '\0'; + SS_create_dir(pathname, 0755); + *p = '/'; + r = mkdir(pathname, mode); + } + } + if (r != 0) { + if (r != EEXIST && r != -1) + LOG("Could not create directory [%s] Error[%d]\n", pathname, r); + } +} + + +void SS_unicode_to_char(const char *src, char *dest, int size) +{ + if (src == NULL) + return; + + strncpy(dest, src, size); +} + +void SS_char_to_unicode(const char *src, char *dest, int size) +{ + if (src == NULL) + return; + + strncpy(dest, src, size); +} + +long SS_recursive_folder_creater(const char *path, const mode_t mode) { + + if (path == 0) { + LOGL(LOG_SSENGINE, "Bad path param value \n"); + return -E_SS_BAD_PARAMS; + } + + if (path[0] == '\0') { + LOGL(LOG_SSENGINE, "Path empty \n"); + return -E_SS_FILENAMELENERROR; + } + + char input_path[MAX_PATH] = {'\0'}; + char temppath[MAX_PATH] = {'\0'}; + + strncpy(input_path, path, MAX_PATH - 1); + + if (input_path[0] == '/') { + temppath[0] = '/'; + } + + char *path_token; + char *path_pos = input_path; + + int temppath_current_len = (temppath[0] == '/'); + + while((path_token = strtok_r(path_pos, "/", &path_pos))) { + + int path_token_len = strnlen(path_token, MAX_PATH-temppath_current_len); + strncat(temppath, path_token, path_token_len); + temppath_current_len += path_token_len; + + int mkd_res = mkdir(temppath, mode); + + if(mkd_res != 0 && errno != EEXIST) { + LOGL(LOG_SSENGINE,"cannot create dir %s\n system error: %d error: %m\n", temppath, errno); + return -E_SS_CANNOT_CREATE_DIRECTORY; + } + + if(temppath_current_len < (MAX_PATH - 1)) { + strncat(temppath, "/", 1); + } + } + return 0; +} + +long +SS_CopyFile(const char *strFromPath, const char *strToPath) +{ + int fd1, fd2; + int readCount = 0, writeCount = 0; + char buf[1 << 15]; // copy 32KB wise + int ret = 0; + + char path1[MAX_PATH] = { '\0' }; + char path2[MAX_PATH] = { '\0' }; + + if (!strFromPath || !strToPath) { + LOGE("NULL file name find. Abort.\n"); + return -1; + } + + SS_unicode_to_char((const char *)strFromPath, (char *)path1, MAX_PATH - 1); + SS_unicode_to_char((const char *)strToPath, (char *)path2, MAX_PATH - 1); + + //LOGL(LOG_SSENGINE, "%s -> %s \n", path1, path2); + + fd1 = open(path1, O_RDONLY); + if (fd1 < 0) + return E_SS_OPENFILE_ONLYR; + ret = SS_OpenFile(strToPath, ONLY_W, (long *)&fd2); + if (ret != S_SS_SUCCESS || fd2 < 0) { + close(fd1); + LOGE(" SS_OpenFile fail leaved path1:%s | path2:%s\n", path1, path1); + return E_SS_WRITE_ERROR; + } + + while ((readCount = read(fd1, buf, sizeof(buf))) > 0) { + writeCount = write(fd2, buf, readCount); + if (writeCount != readCount) { + LOGE(" read %d, but write %d, abort.\n", readCount, + writeCount); + ret = E_SS_WRITE_ERROR; + break; + } + } + + close(fd1); + fsync(fd2); + close(fd2); + //LOGL(LOG_INFO, " leaved path1:%s | path2:%s\n", path1, path2); + + return ret; +} + +long SS_DeleteFile(const char *strPath) +{ + char path[MAX_PATH] = { '\0' }; + int ret = 0; + + SS_unicode_to_char((const char *)strPath, (char *)path, MAX_PATH - 1); + //LOGL(LOG_SSENGINE, "%s\n", path); + ret = unlink(path); + if (ret == 0) + return S_SS_SUCCESS; + + LOGE("failed to delete path [%s] unlink value: %d, errno: %d\n", path, ret, errno); + if (ret < 0 && errno == ENOENT) + return S_SS_SUCCESS; + return E_SS_DELETEFILE; +} + +int SS_unlink_cbf(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf) +{ + int rv = remove(fpath);//returns zero on success and -1 on failure + + if (rv) { + perror(fpath); + LOGE("path : %s, remove value: %d, errno: %d\n", fpath, rv, errno); + } + return rv; +} +long SS_DeleteFolder(const char *strPath) +{ + //runs till either tree is exhausted or when unlink_cbf returns non zero value. + return ((long)nftw(strPath, SS_unlink_cbf, 64, FTW_DEPTH | FTW_PHYS) == 0) ? S_SS_SUCCESS : E_SS_FAILURE; +} + +long SS_CreateFolder(const char *strPath) +{ + mode_t mode = 0; + int ret = 0; + char path[MAX_PATH] = { '\0' }; + + SS_unicode_to_char((const char *)strPath, (char *)path, MAX_PATH - 1); + mode = S_IRUSR /*Read by owner */ | + S_IWUSR /*Write by owner */ | + S_IXUSR /*Execute by owner */ | + S_IRGRP /*Read by group */ | + S_IWGRP /*Write by group */ | + S_IXGRP /*Execute by group */ | + S_IROTH /*Read by others */ | + S_IWOTH /*Write by others */ | + S_IXOTH /*Execute by others */ ; + + LOGL(LOG_SSENGINE, "%s, mode:0x%x\n", path, mode); + + ret = mkdir(path, mode); + + if (ret == 0 || ((ret == -1) && (errno == EEXIST))) { + return S_SS_SUCCESS; + } else if ((ret == -1) && (errno == ENOENT)) { //maybe multi directory problem + //do//Recursive Function + //{ + ret = SS_recursive_folder_creater(path, mode); + if (ret == S_SS_SUCCESS) { + ret = mkdir(path, mode); //After creating all the depth Directories we try to create the Original one again. + if (ret == 0) + return S_SS_SUCCESS; + else + return E_SS_FAILURE; + } else { + return E_SS_FAILURE; + } + //} + //while(ret != 0); + + } else { + return E_SS_FAILURE; + } +} + +mode_t SS_get_mode(E_RW_TYPE wFlag) +{ + switch (wFlag) { + case ONLY_R: + //LOGL(LOG_SSENGINE, " RDONLY \n"); + return O_RDONLY; + case ONLY_W: + //LOGL(LOG_SSENGINE, " WRONLY \n"); + return O_WRONLY | O_CREAT; + case BOTH_RW: + //LOGL(LOG_SSENGINE, " RDWR \n"); + return O_RDWR | O_CREAT; + default: + //LOGL(LOG_SSENGINE, " Unknown \n"); + return 0; + } +} + +long +SS_OpenFile(const char *strPath, E_RW_TYPE wFlag, long *pwHandle) +{ + mode_t mode; + char path[MAX_PATH] = { '\0' }; + + SS_unicode_to_char((const char *)strPath, (char *)path, MAX_PATH - 1); + + mode = SS_get_mode(wFlag); + //LOGL(LOG_SSENGINE, "Path:%s wFlag:%d Mode:%d\n", path, wFlag, mode); + + if (mode & O_CREAT) { + //LOGL(LOG_SSENGINE, " open() S_IRWXU\n"); + *pwHandle = open(path, mode, S_IRWXU); + } else { + //LOGL(LOG_SSENGINE, " open() %d\n", mode); + *pwHandle = open(path, mode); + } + if (*pwHandle == -1) { + *pwHandle = 0; + LOGE(" First open() with error %d\n", errno); + if (wFlag == ONLY_R) { + LOGE(" error in ONLY_R return E_SS_OPENFILE_ONLYR\n"); + return E_SS_OPENFILE_ONLYR; + } + + //if we need to open the file for write or read/write then we need to create the folder (in case it does not exist) + if ((wFlag != ONLY_R) && (errno == ENOENT)) { + char dir[MAX_PATH] = { '\0' }; + char dirShort[MAX_PATH] = { '\0' }; + int i = 0; + //copy the full file path to directory path variable + while (path[i] != '\0') { + dir[i] = path[i]; + i++; + } + LOGL(LOG_SSENGINE, " copy dir[]=%s\n", dir); + //search for the last '/' char + while (dir[i--] != '/') ; + dir[i + 1] = '\0'; + + SS_char_to_unicode((const char *)dir, + (char *)dirShort, MAX_PATH - 1); + + if (SS_CreateFolder(dirShort)) { + LOGE(" Fail create folder, Leave SS_OpenFile\n"); + return E_SS_OPENFILE_WRITE; + } + + *pwHandle = open(path, mode); + if (*pwHandle == -1) { + *pwHandle = 0; + LOGE(" After successful creating folder, fail open() with error %d\n", errno); + return E_SS_OPENFILE_WRITE; + } + } else { + LOG(" fail open() *pwHandle:%ld\n", *pwHandle); + return E_SS_OPENFILE_WRITE; + } + } + + //LOGL(LOG_SSENGINE, " Successful open() *pwHandle:%ld\n", *pwHandle); + + return S_SS_SUCCESS; +} + +long SS_CloseFile(long wHandle) +{ + int ret = 0; + LOGL(LOG_SSENGINE, "wHandle = %ld\n", wHandle); + + if (wHandle) { + ret = fsync(wHandle); + if (ret < 0) { + LOG(" fsync Failed with return value: %d\n", ret); + return E_SS_WRITE_ERROR; + } + LOG(" fsync after write: %d\n", ret); + ret = close(wHandle); + } + + if (ret == 0) + return S_SS_SUCCESS; + + return E_SS_CLOSEFILE_ERROR; +} + +long +SS_WriteFile(long wHandle, + SS_UINT32 dwPosition, + unsigned char *pbBuffer, SS_UINT32 dwSize) +{ + int ret = 0; + + LOGL(LOG_SSENGINE, "Handle:%ld , Pos:%u , Size: %u\n", wHandle, + dwPosition, dwSize); + + ret = lseek(wHandle, dwPosition, SEEK_SET); + if (ret < 0) { + LOGE(" lseek failed with return value: %d\n", ret); + LOGL(LOG_SSENGINE, "lseek errno=%d\n", errno); + return E_SS_WRITE_ERROR; + } + + ret = write(wHandle, pbBuffer, dwSize); + if (ret < 0 || ret != dwSize) { + LOGE(" Failed with return value: %d\n", ret); + LOGL(LOG_SSENGINE, "ret=%d, dwSize=%u write errno=%d\n", + ret, (unsigned int)dwSize, errno); + return E_SS_WRITE_ERROR; + } + LOGL(LOG_SSENGINE, "leave Bytes Write: %d\n", ret); + + return S_SS_SUCCESS; +} + +long SS_MoveFile(const char *strFromPath, const char *strToPath) +{ + int ret = 0; + struct stat sbuf; + char path1[MAX_PATH] = { '\0' }; + char path2[MAX_PATH] = { '\0' }; + + if (!strFromPath || !strToPath) + return -1; //should never happen + + SS_unicode_to_char(strFromPath, (char *)path1, MAX_PATH - 1); + SS_unicode_to_char(strToPath, (char *)path2, MAX_PATH - 1); + + LOGL(LOG_INFO, "entered path1:%s | path2:%s\n", path1, path2); + ret = stat(path1, &sbuf); + if (ret < 0) { + LOGE("stat failed with return value: %d errno: %d\n", ret, errno); + return E_SS_FAILURE; + } + ret = rename(path1, path2); + if (ret < 0) { + LOGL(LOG_INFO, "rename fail with code [%d], try to create dir if errno is 2\n", errno); + if (errno == 2) { + char * file_name = strrchr(path2, '/'); + *file_name = '\0'; + SS_create_dir(path2, 0755); + *file_name = '/'; + ret = rename(path1, path2); + if (ret < 0) { + LOGE("Move failed, error code [%d]\n", errno); + return E_SS_WRITE_ERROR; + } + } else if (errno == 18) { //EXDEV 18 /* Cross-device link */ + //Moving file across partitions if mount point is different (Extremely rare) + ret = (int)SS_CopyFile(path1, path2); + if (ret != S_SS_SUCCESS) { + LOGE("failed to copy file [%s] result [%d]\n", path1, ret); + return E_SS_WRITE_ERROR; + } + ret = unlink(path1); + if (ret != 0) { + LOGE("failed to unlink [%s] code [%d]\n", path1, errno); + return E_SS_WRITE_ERROR; + } + } else { + LOGE("Move failed, error code [%d]\n", errno); + return E_SS_WRITE_ERROR; + } + } + LOGL(LOG_INFO, "leaved path1:%s | path2:%s\n", path1, path2); + return S_SS_SUCCESS; +} + +long +SS_ReadFile(long wHandle, + SS_UINT32 dwPosition, + unsigned char *pbBuffer, SS_UINT32 dwSize) +{ + int ret = 0; + +#if 0 + LOG(" %s: Handle:%ld , Pos:%u , Size: %u", __func__, wHandle, + dwPosition, dwSize); +#endif + ret = lseek(wHandle, dwPosition, SEEK_SET); + if (ret < 0) { + LOGE("Handle:%ld , Pos:%u , Size: %u\n", wHandle, dwPosition, + dwSize); + LOGE("lseek failed with return value: %d\n", ret); + return E_SS_READ_ERROR; + } + ret = read(wHandle, pbBuffer, dwSize); + if (ret < 0) { + LOGE("Handle:%ld , Pos:%u , Size: %u\n", wHandle, dwPosition, + dwSize); + LOGE("read failed with return value: %d\n", ret); + return E_SS_READ_ERROR; + } + + if (ret != dwSize && ((ret + dwPosition) != (unsigned long)SS_GetFileSize(wHandle))) + return E_SS_READ_ERROR; + + pbBuffer[ret] = '\0'; +#if 0 + LOGL(LOG_DEBUG, "Bytes Read: %d\n", ret); +#endif + return S_SS_SUCCESS; +} + +long SS_GetFileSize(long wHandle) +{ + int ret = 0; + + + ret = lseek(wHandle, 0, SEEK_END); + + if (ret == -1) { + LOGE(" lseek errno: %d\n", errno); + return E_SS_READFILE_SIZE; + } + LOGL(LOG_SSENGINE, "handle=%d Returning Size = %ld(0x%x)\n", + (int)wHandle, (long int)ret, ret); + + return ret; +} + +long SS_Unlink(char *pLinkName) +{ + int ret = 0; + char path[MAX_PATH] = { '\0' }; + //enumFileType fileType = FT_REGULAR_FILE; + + + SS_unicode_to_char((const char *)pLinkName, (char *)path, MAX_PATH - 1); + + ret = unlink(path); + if (ret < 0 && errno != ENOENT) { + LOGE("unlink failed with return value: %d\n", ret); + return E_SS_FAILURE; + } + LOGL(LOG_SSENGINE, "unlink with return value: %d\n", ret); + + return S_SS_SUCCESS; +} + +long +SS_VerifyLinkReference(char *pLinkName, char *pReferenceFileName) +{ + int ret = 0; + char path[MAX_PATH] = { '\0' }; + char linkedpath[MAX_PATH] = { '\0' }; + char refpath[MAX_PATH] = { '\0' }; + + + SS_unicode_to_char((const char *)pLinkName, (char *)path, MAX_PATH - 1); + SS_unicode_to_char((const char *)pReferenceFileName, (char *)refpath, MAX_PATH - 1); + + ret = readlink(path, linkedpath, MAX_PATH); + if (ret < 0) { + LOGE("readlink failed with return value: %d\n", ret); + return E_SS_FAILURE; + } + + if ((memcmp(&linkedpath, &refpath, ret)) != 0) { + LOGE("not same linked path\n"); + return E_SS_FAILURE; + } + LOGL(LOG_SSENGINE, "same linked path\n"); + + return S_SS_SUCCESS; +} + +long +SS_Link(void *pbUserData, char *pLinkName, char *pReferenceFileName) +{ + int ret = 0; + char sympath[MAX_PATH] = { '\0' }; + char refpath[MAX_PATH] = { '\0' }; + //enumFileType fileType = FT_SYMBOLIC_LINK; + struct stat sbuf; + + SS_unicode_to_char((const char *)pLinkName, (char *)sympath, MAX_PATH - 1); + SS_unicode_to_char((const char *)pReferenceFileName, (char *)refpath, MAX_PATH - 1); + + ret = symlink(refpath, sympath); + if (ret != 0) { + LOGE(" symlink failed with return value: %d, errno: %d\n", ret, errno); + + if (errno == EEXIST) { + ret = lstat(sympath, &sbuf); + LOGL(LOG_SSENGINE, "symlink LSTAT with return value: %d\n", ret); + if (ret >= 0) { + if (S_ISREG(sbuf.st_mode)) { + LOGL(LOG_SSENGINE, " stat->st_mode = regular file, To be deleted and create a LINK \n"); + SS_DeleteFile(sympath); + SS_Link(pbUserData, pLinkName, pReferenceFileName); + } + } + if (SS_VerifyLinkReference(pLinkName + , pReferenceFileName) == S_SS_SUCCESS) { + return S_SS_SUCCESS; + } else { + return E_SS_FAILURE; + } + } else if (errno == ENOENT) {//to handle cases where new symlink points to a new symlink yet to be created + return errno; + } else { + return E_SS_FAILURE; + } + } + //LOGL(LOG_SSENGINE, "symlink with return value: %d\n", ret); + + return S_SS_SUCCESS; +} + +long +SS_HardLink(char *hardLinkName, char *referenceName) +{ + int ret = 0; + char hardpath[MAX_PATH] = { '\0' }; + char refpath[MAX_PATH] = { '\0' }; + + SS_unicode_to_char((const char *)hardLinkName, (char *)hardpath, MAX_PATH - 1); + SS_unicode_to_char((const char *)referenceName, (char *)refpath, MAX_PATH - 1); + + ret = link(refpath, hardpath); + if (ret != 0) { + LOGE("Linking failed for hardlink %s with errno: %d\n", hardpath, errno); + return E_SS_FAILURE; + } + return S_SS_SUCCESS; +} + +long SS_GetFileType(char *pLinkName, enumFileType * fileType) +{ + int ret = 0; + char path[MAX_PATH] = { '\0' }; + struct stat sbuf; + + //LOGL(LOG_SSENGINE, "\n"); + SS_unicode_to_char((const char *)pLinkName, (char *)path, MAX_PATH - 1); + + ret = lstat(path, &sbuf); + if (ret < 0) { + ret = stat(path, &sbuf); + if (ret < 0) { + LOGE("stat failed with return value: %d errno: %d\n", + ret, errno); + *fileType = FT_MISSING; + return S_SS_SUCCESS; + } + } + //LOGL(LOG_SSENGINE, " sbuf.st_mode: %d\n", sbuf.st_mode); + //LOGL(LOG_SSENGINE, " S_ISREG(sbuf.st_mode): %d\n", S_ISREG(sbuf.st_mode)); + //LOGL(LOG_SSENGINE, " S_ISLNK(sbuf.st_mode): %d\n", S_ISLNK(sbuf.st_mode)); + + if (S_ISLNK(sbuf.st_mode)) { + //LOGL(LOG_SSENGINE, " stat->st_mode = symbolic link file\n"); + *fileType = FT_SYMBOLIC_LINK; + return S_SS_SUCCESS; + } + + if (S_ISREG(sbuf.st_mode)) { + //LOGL(LOG_SSENGINE, " stat->st_mode = regular file\n"); + *fileType = FT_REGULAR_FILE; + return S_SS_SUCCESS; + } + + if (S_ISDIR(sbuf.st_mode)) { + //LOGL(LOG_SSENGINE, " stat->st_mode = regular file\n"); + *fileType = FT_FOLDER; + return S_SS_SUCCESS; + } + LOGE("failed to lstat, err : %d\n", ret); + return E_SS_FAILURE; +} + +static inline char *SS_get_xattr_name(enum smack_label_type type) +{ + switch (type) { + case SMACK_LABEL_ACCESS: + return "security.SMACK64"; + case SMACK_LABEL_EXEC: + return "security.SMACK64EXEC"; + case SMACK_LABEL_MMAP: + return "security.SMACK64MMAP"; + case SMACK_LABEL_TRANSMUTE: + return "security.SMACK64TRANSMUTE"; + case SMACK_LABEL_IPIN: + return "security.SMACK64IPIN"; + case SMACK_LABEL_IPOUT: + return "security.SMACK64IPOUT"; + default: + /* Should not reach this point */ + return NULL; + } +} + +int SS_smack_lsetlabel(const char *path, const char *label, enum smack_label_type type) +{ + if (path == NULL) { + LOGE("Path is NULL\n"); + return -1; + } + + char *xattr_name = SS_get_xattr_name(type); + if (xattr_name == NULL) { + LOGE("Failed get xattr name\n"); + return -1; + } + + /* Check validity of labels for LABEL_TRANSMUTE */ + if (type == SMACK_LABEL_TRANSMUTE && label != NULL) { + if (!strncmp(label, "0", strlen("0"))) { + label = NULL; + } else if (!strncmp(label, "1", strlen("0"))) { + label = "TRUE"; + } else { + return -1; + } + } + + if (label == NULL || label[0] == '\0') { + return lremovexattr(path, xattr_name); + } else { + int len = strnlen(label, SMACK_LABEL_LEN + 1); + if (len > SMACK_LABEL_LEN) { + return -1; + } + return lsetxattr(path, xattr_name, label, len, 0); + } +} + +/*! + ******************************************************************************* + * Set file attributes.

+ * + * The file attributes token (\a ui8pAttribs) is defined at generation time. + * If attributes are not defined explicitly, they are given the following, + * OS-dependent values: + * \li Windows: _foo_ro_ for R/O files, _foo_rw_ for R/W files + * \li Linux: _foo_oooooo:xxxx:yyyy indicating the file mode, uid, and gid + * (uid and gid use capitalized hex digits as required) + * + * \param pbUserData Optional opaque data-structure to pass to IPL + * functions + * \param ui16pFilePath File path + * \param ui32AttribSize Size of \a ui8pAttribs + * \param ui8pAttribs Attributes to set + * + * \return S_SS_SUCCESS on success or < 0 on error + ******************************************************************************* + */ + +long SS_SetFileAttributes(const char *ui16pFilePath, + const SS_UINT32 ui32AttribSize, + const unsigned char *ui8pAttribs) +{ + static char tmpAttribs[512]; + static char tmpSmackAttribs[512]; + char *tp; + char *endstr; + char *saveptr; + char *smack_value, *psmack; + uid_t setUserID = 0; + gid_t setGroupID = 0; + mode_t setFileMode = 0; + const char attrDelim[2] = ":"; + + char setFilePath[MAX_PATH] = { '\0' }; + struct stat sbuf; + int ret = 0; + char *smack_attr_pos = NULL; + int has_cap = 0; + char cap_raw[100]; + int cap_len; + /*ACL */ + int has_acl = 0; + char acl_raw[256]; + int acl_len; + + if (NULL == ui16pFilePath) { + LOGL(LOG_SSENGINE, "ui16pFilePath NULL [error]\n"); + return E_SS_BAD_PARAMS; + } else if (NULL == ui8pAttribs) { + LOGL(LOG_SSENGINE, "ui8pAttribs NULL [error]\n"); + return E_SS_BAD_PARAMS; + } else if (0 == ui32AttribSize) { + LOGL(LOG_SSENGINE, "ui32AttribSize 0\n"); + return S_SS_SUCCESS; + } + + SS_unicode_to_char((const char *)ui16pFilePath, (char *)setFilePath, MAX_PATH - 1); + + ret = lstat(setFilePath, &sbuf); + if (ret < 0) { + ret = stat(setFilePath, &sbuf); + if (ret < 0) { + LOGL(LOG_SSENGINE, " stat failed with return value: %d\n", ret); + return E_SS_FAILURE; + } else { + if (S_ISLNK(sbuf.st_mode)) { + LOGL(LOG_SSENGINE, " stat->st_mode = symbolic link file\n"); +// return S_RB_SUCCESS; // sybolic link should be set mode. + } + if (S_ISREG(sbuf.st_mode)) + LOGL(LOG_SSENGINE, " stat->st_mode = regular file\n"); + if (S_ISDIR(sbuf.st_mode)) + LOGL(LOG_SSENGINE, " stat->st_mode = directory\n"); + } + + LOGL(LOG_SSENGINE, "ui16pFilePath = %s\n", setFilePath); + LOGL(LOG_SSENGINE, "ui32AttribSize = %u\n", ui32AttribSize); + LOGL(LOG_SSENGINE, "ui8pAttribs = %s\n", ui8pAttribs); + + } + memset(tmpAttribs, 0x0, sizeof(tmpAttribs)); + memcpy(tmpAttribs, ui8pAttribs, (size_t) ui32AttribSize-1); + smack_attr_pos = tmpAttribs; + tp = strtok_r(tmpAttribs, attrDelim, &saveptr); + + // Get FileMode + if (tp != NULL) { + smack_attr_pos += strlen(tp); + smack_attr_pos++; + setFileMode = strtol(tp, &endstr, 8); + tp = strtok_r(NULL, attrDelim, &saveptr); + } + // Get UserID + if (tp != NULL) { + smack_attr_pos += strlen(tp); + smack_attr_pos++; + setUserID = (uid_t) strtol(tp, &endstr, 10); + tp = strtok_r(NULL, attrDelim, &saveptr); + } + // Get GroupID + if (tp != NULL) { + smack_attr_pos += strlen(tp); + smack_attr_pos++; + setGroupID = (gid_t) strtol(tp, &endstr, 10); + } + + if (feature_support_capability) { + // Get Capability + has_cap = 0; + if (*smack_attr_pos != '\0') { + char *cap_mark = "capability=0x"; + int cap_mark_len = strlen(cap_mark); + psmack = strstr(smack_attr_pos, cap_mark); + if (psmack) { + int cap_hex_len; + int i; + char ch1, ch2; + int raw1, raw2; + + tp = strstr(psmack, ":"); + smack_attr_pos = tp + 1; + memset(tmpSmackAttribs, 0x0, sizeof(tmpSmackAttribs)); + memcpy(tmpSmackAttribs, psmack+cap_mark_len, + (int)tp - (int)psmack - cap_mark_len); + + // convert hexadecimal into raw data + cap_hex_len = strlen(tmpSmackAttribs); + cap_len = cap_hex_len/2; + memset(cap_raw, 0x00, sizeof(cap_raw)); + for (i = 0; i < cap_len; i++) { + ch1 = tmpSmackAttribs[i*2]; + ch2 = tmpSmackAttribs[i*2+1]; + if ((ch1 >= '0') && (ch1 <= '9')) raw1 = ch1 - '0'; + else if ((ch1 >= 'a') && (ch1 <= 'f')) raw1 = ch1 - 'a' + 10; + else if ((ch1 >= 'A') && (ch1 <= 'F')) raw1 = ch1 - 'A' + 10; + else raw1 = 0; + if ((ch2 >= '0') && (ch2 <= '9')) raw2 = ch2 - '0'; + else if ((ch2 >= 'a') && (ch2 <= 'f')) raw2 = ch2 - 'a' + 10; + else if ((ch2 >= 'A') && (ch2 <= 'F')) raw2 = ch2 - 'A' + 10; + else raw2 = 0; + + cap_raw[i] = raw1*16 + raw2; + } + LOGL(LOG_SSENGINE, "[Cap] %s (cap_len=%d)\n", tmpSmackAttribs, cap_len); + has_cap = 1; + } + + } + // Get ACL + has_acl = 0; + if (*smack_attr_pos != '\0') { + char *acl_mark = "acl_access=0x"; + int acl_mark_len = strlen(acl_mark); + psmack = strstr(smack_attr_pos, acl_mark); + if (psmack) { + int acl_hex_len; + int i; + char ch1, ch2; + int raw1, raw2; + + tp = strstr(psmack, ":"); + smack_attr_pos = tp + 1; + memset(tmpSmackAttribs, 0x0, sizeof(tmpSmackAttribs)); + memcpy(tmpSmackAttribs, psmack+acl_mark_len, + (int)tp - (int)psmack - acl_mark_len); + + // convert hexadecimal into raw data + acl_hex_len = strlen(tmpSmackAttribs); + acl_len = acl_hex_len/2; + memset(acl_raw, 0x00, sizeof(acl_raw)); + for (i = 0; i < acl_len; i++) { + ch1 = tmpSmackAttribs[i*2]; + ch2 = tmpSmackAttribs[i*2+1]; + if ((ch1 >= '0') && (ch1 <= '9')) raw1 = ch1 - '0'; + else if ((ch1 >= 'a') && (ch1 <= 'f')) raw1 = ch1 - 'a' + 10; + else if ((ch1 >= 'A') && (ch1 <= 'F')) raw1 = ch1 - 'A' + 10; + else raw1 = 0; + if ((ch2 >= '0') && (ch2 <= '9')) raw2 = ch2 - '0'; + else if ((ch2 >= 'a') && (ch2 <= 'f')) raw2 = ch2 - 'a' + 10; + else if ((ch2 >= 'A') && (ch2 <= 'F')) raw2 = ch2 - 'A' + 10; + else raw2 = 0; + + acl_raw[i] = raw1*16 + raw2; + } + LOG("[ACL] %s (acl_len=%d)\n", tmpSmackAttribs, acl_len); + has_acl = 1; + } + + } + } + + // Get Smack value -> Set Smack value + if (*smack_attr_pos != '\0') { + SS_smack_lsetlabel(setFilePath, NULL, SMACK_LABEL_ACCESS); + SS_smack_lsetlabel(setFilePath, NULL, SMACK_LABEL_EXEC); + SS_smack_lsetlabel(setFilePath, NULL, SMACK_LABEL_MMAP); + SS_smack_lsetlabel(setFilePath, NULL, SMACK_LABEL_TRANSMUTE); + + psmack = strstr(smack_attr_pos, "access=\""); + if (psmack) { + memset(tmpSmackAttribs, 0x0, sizeof(tmpSmackAttribs)); + memcpy(tmpSmackAttribs, psmack, sizeof(tmpSmackAttribs) - 1); + smack_value = strtok_r(tmpSmackAttribs, "\"", &saveptr); + if (smack_value) { + smack_value = strtok_r(NULL, "\"", &saveptr); + //LOGL(LOG_SSENGINE, "[SMACK_LABEL_ACCESS] smack_value=%s\n", smack_value); + if (smack_value) { + ret = SS_smack_lsetlabel(setFilePath, smack_value, SMACK_LABEL_ACCESS); + if (ret < 0) + LOGL(LOG_SSENGINE, "SS_smack_lsetlabel() failed\n"); + } + } + } + psmack = strstr(smack_attr_pos, "execute=\""); + if (psmack) { + memset(tmpSmackAttribs, 0x0, sizeof(tmpSmackAttribs)); + memcpy(tmpSmackAttribs, psmack, sizeof(tmpSmackAttribs) - 1); + smack_value = strtok_r(tmpSmackAttribs, "\"", &saveptr); + if (smack_value) { + smack_value = strtok_r(NULL, "\"", &saveptr); + //LOGL(LOG_SSENGINE, "[SMACK_LABEL_EXEC] smack_value=%s\n", smack_value); + if (smack_value) { + ret = SS_smack_lsetlabel(setFilePath, smack_value, SMACK_LABEL_EXEC); + if (ret < 0) + LOGL(LOG_SSENGINE, "SS_smack_lsetlabel() failed\n"); + } + } + } + psmack = strstr(smack_attr_pos, "mmap=\""); + if (psmack) { + memset(tmpSmackAttribs, 0x0, sizeof(tmpSmackAttribs)); + memcpy(tmpSmackAttribs, psmack, sizeof(tmpSmackAttribs) - 1); + smack_value = strtok_r(tmpSmackAttribs, "\"", &saveptr); + if (smack_value) { + smack_value = strtok_r(NULL, "\"", &saveptr); + //LOGL(LOG_SSENGINE, "[SMACK_LABEL_MMAP] smack_value=%s\n", smack_value); + if (smack_value) { + ret = SS_smack_lsetlabel(setFilePath, smack_value, SMACK_LABEL_MMAP); + if (ret < 0) + LOGL(LOG_SSENGINE, "SS_smack_lsetlabel() failed\n"); + } + } + } + psmack = strstr(smack_attr_pos, "transmute=\""); + if (psmack) { + memset(tmpSmackAttribs, 0x0, sizeof(tmpSmackAttribs)); + memcpy(tmpSmackAttribs, psmack, sizeof(tmpSmackAttribs) - 1); + smack_value = strtok_r(tmpSmackAttribs, "\"", &saveptr); + if (smack_value) { + smack_value = strtok_r(NULL, "\"", &saveptr); + //LOGL(LOG_SSENGINE, "[SMACK_LABEL_TRANSMUTE] smack_value=%s\n", smack_value); + if (smack_value) { + if (strcasecmp(smack_value, "TRUE") == 0) + ret = SS_smack_lsetlabel(setFilePath, "1", SMACK_LABEL_TRANSMUTE); + else + ret = SS_smack_lsetlabel(setFilePath, "0", SMACK_LABEL_TRANSMUTE); + if (ret < 0) + LOGL(LOG_SSENGINE, "SS_smack_lsetlabel() failed\n"); + } + } + } + } + + // Set UserID,GroupID + if (lchown(setFilePath, setUserID, setGroupID)) { + // debug start + LOGL(LOG_SSENGINE, "%s chown error\n", __func__); + LOGL(LOG_SSENGINE, "%s setUserID = %d\n", __func__, setUserID); + LOGL(LOG_SSENGINE, "%s setGroupID = %d\n", __func__, setGroupID); + LOGL(LOG_SSENGINE, "%s chown errno = %d\n", __func__, errno); + // debug end + + return E_SS_FAILURE; + } + + // mode is always 0777 at symlink file. It doesn't need to call chmod(). + if (S_ISLNK(sbuf.st_mode)) { + LOGL(LOG_SSENGINE, " stat->st_mode = symbolic link file\n"); + return S_SS_SUCCESS; + } + + if (chmod(setFilePath, setFileMode)) { + LOGL(LOG_SSENGINE, "%s chmod error\n", __func__); + return E_SS_FAILURE; + } + + if (feature_support_capability) { + char buf[256]; + if (has_cap) { + if (setxattr(setFilePath, "security.capability", (void*)cap_raw, cap_len, 0) < 0) { + strerror_r(errno, buf, sizeof(buf)); + LOGL(LOG_SSENGINE, "cap setxattr() failed: %s\n", buf); + } + } + + if (has_acl) { + if (setxattr(setFilePath, "system.posix_acl_access", (void*)acl_raw, acl_len, 0) < 0) { + strerror_r(errno, buf, sizeof(buf)); + LOGL(LOG_SSENGINE, "Acl setxattr() failed: %s\n", buf); + } + //LOG("Acl setxattr() :")asfd + } + } + + //LOGL(LOG_SSENGINE, "%s SUCCESS\n", __func__); + + return S_SS_SUCCESS; +} + +/* vrm functions */ +long +SS_GetAvailableFreeSpace(const char *partition_name, + SS_UINT32 *available_flash_size) +{ + int result = 0; + char path[MAX_PATH] = { '\0' }; + + SS_unicode_to_char(partition_name, (char *)path, MAX_PATH - 1); + //LOGL(LOG_SSENGINE, "Enter %s path=%s\n", __func__, path); + struct statfs vfs; + + //LOGL(LOG_SSENGINE, "path=%s\n", path); + result = statfs(path, &vfs); + if (result < 0) { + LOGE("failed to fstatfs, err : %d errno: %d\n", result, errno); + return -1; + } + + *available_flash_size = ((long long)vfs.f_bsize * (long long)vfs.f_bavail >= (long long)SIZE_4GB) ? SIZE_4GB : vfs.f_bsize * vfs.f_bavail; + if (*available_flash_size == 0) { + *available_flash_size = 0x80000; //Same as Legecy RB + LOGE("available_flash_size=%u(vfs.f_bsize=%d vfs.f_bavail=%d\n", + (unsigned int)*available_flash_size, (int)vfs.f_bsize, (int)vfs.f_bavail); + return 0; // Same as Legecy RB + } + return 0; +} + +#ifdef HEAP_PROFILING + int max_mem; + int cur_mem; +#endif +/*******[ Multiprocess API sample implementation ]******/ +void *SS_Malloc(SS_UINT32 size) +{ + void *p = malloc(size); + + if (p) + memset(p, 0, size); +#ifdef HEAP_PROFILING + cur_mem += size; + if (cur_mem > max_mem) { + max_mem = cur_mem; + LOGL(LOG_SSENGINE, "New chunk [%d] assigned making heap [%d]\n", size, cur_mem); + } +#endif + + return p; +} + +void SS_Free(void *pMemBlock) +{ +#ifdef HEAP_PROFILING + cur_mem -= malloc_usable_size(pMemBlock); + LOGL(LOG_SSENGINE, "Old chunk [%d] removed making heap [%d]\n", malloc_usable_size(pMemBlock), cur_mem); +#endif + if (pMemBlock) + free(pMemBlock); +} +int SS_get_feature_support_capability(void) +{ + return feature_support_capability; +} + +void SS_set_feature_support_capability(int val) +{ + feature_support_capability = val; +} \ No newline at end of file diff --git a/src/upgrade-apply-deltafs/engine/SS_FSUpdate.h b/src/upgrade-apply-deltafs/engine/SS_FSUpdate.h new file mode 100755 index 0000000..5d40d2c --- /dev/null +++ b/src/upgrade-apply-deltafs/engine/SS_FSUpdate.h @@ -0,0 +1,324 @@ +/* + * upgrade-apply-deltafs + * + * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*! + ******************************************************************************* + * \file SS_FileSystemUpdate.h + * + * \brief UPI FS Update API + ******************************************************************************* + */ +#ifndef _SS_FILESYSTEM_UPDATE_H_ +#define _SS_FILESYSTEM_UPDATE_H_ + +#include "SS_Engine_Errors.h" +#include "ua_types.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*! + * File access modes + */ + typedef enum tag_RW_TYPE { + ONLY_R, //!< Read-only + ONLY_W, //!< Write-only + BOTH_RW //!< Read-write + } E_RW_TYPE; +/*! + ******************************************************************************* + * Copy file.

+ * + * Must create the path to the new file as required. Must overwrite any contents + * in the old file, if any. Must check if the source file is a symbolic link. + * If it is, instead create a new symbolic link using \ref SS_Link. + * + * \param strFromPath Path to old file + * \param strToPath Path to new file + * + * \return S_SS_SUCCESS on success or an \ref SS_vRM_Errors.h error code + ******************************************************************************* + */ + + long SS_CopyFile(const char *strFromPath, const char *strToPath); + +/*! + ******************************************************************************* + * Move (rename) file.

+ * + * \param strFromPath Path to old file location + * \param strToPath Path to new file location + * + * \return S_SS_SUCCESS on success or an \ref SS_vRM_Errors.h error code + ******************************************************************************* + */ + + long SS_MoveFile(const char *strFromPath, const char *strToPath); + +/*! + ******************************************************************************* + * Delete file.

+ * + * Must return success if the file is deleted or didn't exist. + * + * \param strPath Path to file + * + * \return S_SS_SUCCESS on success, E_SS_DELETEFILE if the file cannot be + * deleted, or an \ref SS_vRM_Errors.h error code + ******************************************************************************* + */ + + long SS_DeleteFile(const char *strPath); + +/*! + ******************************************************************************* + * Delete folder.

+ * + * Must return success if the folder is now deleted or didn't exist. + * + * \param strPath Path to folder + * + * \return S_SS_SUCCESS on success or an \ref SS_vRM_Errors.h error code + ******************************************************************************* + */ + + long SS_DeleteFolder(const char *strPath); + +/*! + ******************************************************************************* + * Create folder.

+ * + * Must return success if the folder is created or already existsed. It is + * recommended that the new folder's attributes are a copy of its parent's + * attributes. + * + * \param strPath Path to folder + * + * \return S_SS_SUCCESS on success or an \ref SS_vRM_Errors.h error code + ******************************************************************************* + */ + + long SS_CreateFolder(const char *strPath); + +/*! + ******************************************************************************* + * Open file.

+ * + * Must create the the file (and the path to the file) if it doesn't exist. Must + * open in binary mode. + * + * \param strPath Path to file + * \param wFlag Read/write mode, an \ref E_RW_TYPE value + * \param pwHandle (out) File handle + * + * \return S_SS_SUCCESS on success, E_SS_OPENFILE_ONLYR if attempting to open a + * non-existant file in R/O mode, E_SS_OPENFILE_WRITE if there is an + * error opening a file for writing, or an \ref SS_vRM_Errors.h error code + ******************************************************************************* + */ + + long SS_OpenFile(const char *strPath, E_RW_TYPE wFlag, long *pwHandle); + +/*! + ******************************************************************************* + * Close file. + * + * \param wHandle File handle + * + * \return S_SS_SUCCESS on success or an \ref SS_vRM_Errors.h error code + ******************************************************************************* + */ + + long SS_CloseFile(long wHandle); + +/*! + ******************************************************************************* + * Write data to a specified position within a file.

+ * + * Must return success if the block is written or at least resides in + * non-volatile memory. Use \ref SS_SyncFile to commit the file to storage. + * + * \param wHandle File handle + * \param dwPosition Position within the file to which to write + * \param pbBuffer Data to write + * \param dwSize Size of \a pbBuffer + * + * \return S_SS_SUCCESS on success, or an \ref SS_vRM_Errors.h error code + ******************************************************************************* + */ + + long SS_WriteFile(long wHandle, SS_UINT32 dwPosition, unsigned char *pbBuffer, SS_UINT32 dwSize); + +/*! + ******************************************************************************* + * Read data from a specified position within a file. + * If fewer bytes than requested are available in the specified position, this + * function should read up to the end of file and return S_SS_SUCCESS. + * + * \param wHandle File handle + * \param dwPosition Position within the file from which to read + * \param pbBuffer Buffer to contain data + * \param dwSize Size of data to read + * + * \return S_SS_SUCCESS on success or an \ref SS_vRM_Errors.h error code + ******************************************************************************* + */ + + long SS_ReadFile(long wHandle, SS_UINT32 dwPosition, unsigned char *pbBuffer, SS_UINT32 dwSize); + +/*! + ******************************************************************************* + * Get file size. + * + * \param wHandle File handle + * + * \return File size, -1 if file not found, or < -1 on error + ******************************************************************************* + */ + long SS_GetFileSize(long wHandle); + +/*! + ******************************************************************************* + * Get free space of a mounted file system. + * + * \param path Name of any directory within the mounted + * file system + * \param available_flash_size (out) Available space + * + * \return S_SS_SUCCESS on success or an \ref SS_vRM_Errors.h error code + ******************************************************************************* + */ + long SS_GetAvailableFreeSpace(const char *path, SS_UINT32 * available_flash_size); + +/*! + ******************************************************************************* + * Remove symbolic link.

+ * + * Must return an error if the file does not exist or is not a symbolic link.

+ * + * If your platform does not support symbolic links, you do not need to + * implement this. + * + * \param pLinkName Link + * + * \return S_SS_SUCCESS on success or an \ref SS_vRM_Errors.h error code + ******************************************************************************* + */ + long SS_Unlink(char *pLinkName); + +/*! + ******************************************************************************* + * Create symbolic link.

+ * + * Must create the path to the link as required. If a file already exists at the + * named location, must return success if the file is a symbolic link or an + * error if the file is a regular file. The non-existance of the target of the + * link must NOT cause an error.

+ * + * If your platform does not support symbolic links, you do not need to + * implement this. + * + * \param pbUserData Optional opaque data-structure to pass to IPL + * functions + * \param pLinkName Path to the link file to create + * \param pReferenceFileName Path to which to point the link + * + * \return S_SS_SUCCESS on success or an \ref SS_vRM_Errors.h error code + ******************************************************************************* + */ + long SS_Link(void *pbUserData, char *pLinkName, char *pReferenceFileName); + +/*! + ******************************************************************************* + * Set file attributes.

+ * + * The file attributes token (\a ui8pAttribs) is defined at generation time. + * If attributes are not defined explicitly, they are given the following, + * OS-dependent values: + * \li Windows: _foo_ro_ for R/O files, _foo_rw_ for R/W files + * \li Linux: _foo_oooooo:xxxx:yyyy indicating the file mode, uid, and gid + * (uid and gid use capitalized hex digits as required) + * + * \param pbUserData Optional opaque data-structure to pass to IPL + * functions + * \param ui16pFilePath File path + * \param ui32AttribSize Size of \a ui8pAttribs + * \param ui8pAttribs Attributes to set + * + * \return S_SS_SUCCESS on success or < 0 on error + ******************************************************************************* + */ + + long SS_SetFileAttributes(const char *ui16pFilePath, + const SS_UINT32 ui32AttribSize, const unsigned char *ui8pAttribs); + +/** + ******************************************************************************* + * Allocate a memory block. + * + * \param size Memory block size, in blocks + * + * \return A pointer to the memory block on success, NULL on failure + ******************************************************************************* + */ + void *SS_Malloc(SS_UINT32 size); + +/** + ******************************************************************************* + * Free a memory block. + * + * \param pMemBlock Pointer to the memory block + ******************************************************************************* + */ + void SS_Free(void *pMemBlock); +/** + ******************************************************************************* + * Get capability feature flag value + * + * \return The value of feature_support_capability + ******************************************************************************* + */ + int SS_get_feature_support_capability(void); + +/** + ******************************************************************************* + * Set capability feature flag + * + * \param val The value to set feature_support_capability + ******************************************************************************* + */ + void SS_set_feature_support_capability(int val); + +/** + ******************************************************************************* + * Create a hardlink to a file + * + * \param hardLinkName Name of the hardlink to be created + * \param referenceName Name of the file that we link to + * + * \return S_SS_SUCCESS on success, E_SS_FAILURE otherwise + ******************************************************************************* + */ + + long SS_HardLink(char *hardLinkName, char *referenceName); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/src/upgrade-apply-deltafs/engine/SS_PatchDelta.c b/src/upgrade-apply-deltafs/engine/SS_PatchDelta.c new file mode 100755 index 0000000..299f126 --- /dev/null +++ b/src/upgrade-apply-deltafs/engine/SS_PatchDelta.c @@ -0,0 +1,402 @@ +/* + * upgrade-apply-deltafs + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../upgrade-apply/sha1/sha1.h" +#include "SS_PatchDelta.h" +#include "fota_common.h" +#include "SS_Engine_Errors.h" +#include "SS_Common.h" + +extern void *SS_Malloc(unsigned int size); + +typedef struct { + unsigned char *buffer; + ssize_t size; + ssize_t pos; +} MemorySinkInfo; + +ssize_t ss_fileSink(unsigned char *data, ssize_t len, void *token) +{ + int ss_fd = *(int *)token; + char buf[256]; + ssize_t done = 0; + ssize_t wrote; + while (done < (ssize_t) len) { + wrote = write(ss_fd, data + done, len - done); + if (wrote <= 0) { + if (errno == EINTR || errno == EAGAIN) + continue; // try again + strerror_r(errno, buf, sizeof(buf)); + LOGE("error writing %d bytes: %s\n", (int)(len - done), buf); + return done; + } + done += wrote; + } + return done; +} + +// Take a string 'str' of 40 hex digits and parse it into the 20 +// byte array 'digest'. 'str' may contain only the digest or be of +// the form ":". Return 0 on success, -1 on any +// error. +int ParseSha1(const char *str, uint8_t * digest) +{ + int i; + const char *ps = str; + uint8_t *pd = digest; + for (i = 0; i < SHA_DIGEST_SIZE * 2; ++i, ++ps) { + int digit; + if (*ps >= '0' && *ps <= '9') + digit = *ps - '0'; + else if (*ps >= 'a' && *ps <= 'f') + digit = *ps - 'a' + 10; + else if (*ps >= 'A' && *ps <= 'F') + digit = *ps - 'A' + 10; + else + return -1; + if (i % 2 == 0) { + *pd = digit << 4; + } else { + *pd |= digit; + ++pd; + } + } + if (*ps != '\0') + return -1; + return 0; +} + +int SS_LoadFile(const char *filename, FileInfo * file) +{ + char buf[256]; + + file->data = NULL; + //LOGL(LOG_SSENGINE,"SS_LoadFile --- [File name %s]\n",filename); + + if (stat(filename, &file->st) != 0) { + strerror_r(errno, buf, sizeof(buf)); + LOGE("failed to stat \"%s\": %s\n", filename, buf); + return -1; + } + + file->size = file->st.st_size; + file->data = SS_Malloc(file->size); + if (!file->data) { + strerror_r(errno, buf, sizeof(buf)); + LOGE("failed to allocate memory for \"%s\": %s\n", filename, buf); + return -1; + } + + FILE *f = fopen(filename, "rb"); + if (f == NULL) { + strerror_r(errno, buf, sizeof(buf)); + LOGE("failed to open \"%s\": %s\n", filename, buf); + SS_Free(file->data); + file->data = NULL; + return -1; + } + + ssize_t bytes_read = fread(file->data, 1, file->size, f); + if (bytes_read != file->size) { + LOGE("short read of \"%s\" (%ld bytes of %ld)\n", filename, (long)bytes_read, (long)file->size); + SS_Free(file->data); + file->data = NULL; + fclose(f); + return -1; + } + fclose(f); + //LOGL(LOG_SSENGINE,"SS_LoadFile --- [bytes_read %d]\n",bytes_read); + SHA1(file->sha1, file->data, file->size); + return 0; +} + +extern int gvalid_session; +extern void create_dir(char *pathname, int mode); + +/*! + ********************************************************************************* + * SS_UpdateDeltaFS + ********************************************************************************* + * + * @brief + * This is used to apply patch for a file during delta FS upgrade + * + * + * @param + * + * @return 0 - in case of success + * 1 - in case of error during patch application + * + ********************************************************************************* + */ + +int SS_UpdateDeltaFS(const char *source_filename, const char *target_filename, + const char *source_sha1_str, const char *target_sha1_str, int patch_data_size, char *delta_folder) +{ + char backup_path[MAX_FILE_PATH], patchfile_source_path[MAX_FILE_PATH]; + snprintf(backup_path, MAX_FILE_PATH, "%s/%s", delta_folder, SS_BACKUP_SOURCE); + snprintf(patchfile_source_path, MAX_FILE_PATH, "%s/%s", delta_folder, SS_PATCHFILE_SOURCE); + uint8_t target_sha1[SHA_DIGEST_SIZE] = { 0, }; + uint8_t source_sha1[SHA_DIGEST_SIZE] = { 0, }; + SHA1_CTX ctx1; + int output; + int retry = 1; + int use_backup = 0; + char *outname = NULL; + int backupsrc = -1; + int result = 0; + char buf[256]; + FileInfo source_file; + FileInfo target_file; + + if (ParseSha1(target_sha1_str, target_sha1) != 0) { + LOGE("failed to parse tgt-sha1 \"%s\"\n", target_sha1_str); + return E_SS_FAILURE; + } + + /* + if battery removed in between update gvalid_session becomes 0 + need to check file integrity in that case + */ + if (0 == gvalid_session) { + if (ParseSha1(source_sha1_str, source_sha1) != 0) { + LOGE("failed to parse tgt-sha1 \"%s\"\n", source_sha1_str); + return E_SS_FAILURE; + } + if (SS_LoadFile(source_filename, &source_file) == 0) { + SS_Free(source_file.data); + + if (memcmp(source_file.sha1, source_sha1, SHA_DIGEST_SIZE) == 0) { + LOGL(LOG_SSENGINE, "Patch Can be applied\n"); + } else if (memcmp(source_file.sha1, target_sha1, SHA_DIGEST_SIZE) == 0) { + LOGL(LOG_SSENGINE, "Patch Already applied\n"); + return S_SS_SUCCESS; + } else { + //Check for backup file SHA + LOGL(LOG_SSENGINE, "Source was currupted, Try loading from backup source\n"); + + if (SS_LoadFile(target_filename, &target_file) == 0) { + SS_Free(target_file.data); + + if (memcmp(target_file.sha1, target_sha1, SHA_DIGEST_SIZE) == 0) { + LOGL(LOG_SSENGINE, "Patch Already applied\n"); + return S_SS_SUCCESS; + } + } + + if (SS_LoadFile(backup_path, &source_file) == 0) { + SS_Free(source_file.data); + + if (memcmp(source_file.sha1, source_sha1, SHA_DIGEST_SIZE) == 0) { + if (SS_CopyFile(backup_path, source_filename) != S_SS_SUCCESS) { + strerror_r(errno, buf, sizeof(buf)); + LOGE("copy of backup to \"%s\" failed: %s\n", source_filename, buf); + SS_SetUpgradeState(E_SS_FSUPDATEFAILED); + return E_SS_FAILURE; + } + LOGL(LOG_SSENGINE, + "Patch Can be applied from using backup file as source\n"); + } else { + SS_SetUpgradeState(E_SS_FSSRCCURRUPTED); + return E_SS_FAILURE; + } + } else { + SS_SetUpgradeState(E_SS_FSSRCCURRUPTED); + return E_SS_FAILURE; + } + } + } else { + LOGL(LOG_SSENGINE, "Source was deleted!!\n"); + if (SS_LoadFile(target_filename, &target_file) == 0) { + SS_Free(target_file.data); + + if (memcmp(target_file.sha1, target_sha1, SHA_DIGEST_SIZE) == 0) { + LOGL(LOG_SSENGINE, "Patch Already applied\n"); + return S_SS_SUCCESS; + } + } + + LOGL(LOG_SSENGINE, "Try loading from backup source\n"); + if (SS_LoadFile(backup_path, &source_file) == 0) { + SS_Free(source_file.data); + + if (memcmp(source_file.sha1, source_sha1, SHA_DIGEST_SIZE) == 0) { + use_backup = 1; + LOGL(LOG_SSENGINE, "Patch Can be applied from using backup file as source\n"); + } else { + SS_SetUpgradeState(E_SS_FSSRCCURRUPTED); + return E_SS_FAILURE; + } + } else { + LOGE(" SS_LoadFile from backup source failed!!\n"); + SS_SetUpgradeState(E_SS_FSSRCCURRUPTED); + return E_SS_FAILURE; + } + } + } + //Now proceed wit patch application since patch can be applied + do { + int enough_space = 0; + size_t free_space = 0; + char *tok; + + if (retry > 0) { + if (use_backup) { + tok = strrchr(source_filename, '/'); + *tok = '\0'; + } + SS_GetAvailableFreeSpace(source_filename, &free_space); + enough_space = (free_space > (256 << 10)) && // 256k (two-block) minimum + (free_space > (patch_data_size * 3 / 2)); // 50% margin of error + if (use_backup) + *tok = '/'; + } + + if (!use_backup) { +#ifndef ENHANCED_BSDIFF + backupsrc = SS_BackupSource(source_filename, backup_path); + if (backupsrc != 0) { + LOGE("failed to Backup source File:[%s] \n", source_filename); + SS_SetUpgradeState(E_SS_FSSRCBACKUPFAILED); + return E_SS_FAILURE; + } +#endif + } + if (!enough_space) { + LOGL(LOG_SSENGINE, "For %s: free space %ld bytes; enough %d\n", source_filename, (long)free_space, + enough_space); + retry = 0; + use_backup = 1; + unlink(source_filename); + } + //LOGL(LOG_SSENGINE, "For %s: target %ld bytes; free space %ld bytes; enough %d\n", + // source_filename, (long)patch_data_size, (long)free_space, enough_space); + //LOGL(LOG_SSENGINE,"Generate Target Space availabitiy [%d]\n", enough_space); + + SinkFn sink = NULL; + void *token = NULL; + output = -1; + outname = NULL; + + { + // We write the decoded output to ".patch". + //allocate some extra space to allow for concatinating ".patch" with the name + outname = (char *)SS_Malloc(strlen(target_filename) + 10); + if (outname == NULL) { + LOGE("SS_Malloc failed!!\n"); + return E_SS_FAILURE; + } + snprintf(outname, strlen(target_filename) + 10, + "%s.patch", target_filename); + + output = open(outname, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU); + if (output < 0) { + if (errno == 2) { + char *dir_path = strrchr(outname, '/'); + *dir_path = '\0'; + // need to create directory as the target may be different from source + LOGL(LOG_SSENGINE, "need to create directory [%s]\n", outname); + create_dir(outname, 0755); + *dir_path = '/'; + output = open(outname, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU); + if (output < 0) { + strerror_r(errno, buf, sizeof(buf)); + LOGE("failed to open output file %s: %s\n", outname, buf); + SS_Free(outname); + return E_SS_FAILURE; + } + } + } + sink = ss_fileSink; + token = &output; + } + SHA1Init(&ctx1); + if (use_backup) + result = SS_ApplyBsdiff(backup_path, outname, patchfile_source_path, sink, token, &ctx1); + else + result = SS_ApplyBsdiff((char *)source_filename, outname, patchfile_source_path, sink, token, &ctx1); + if (output >= 0) { + fsync(output); + close(output); + } + + if (result != S_SS_SUCCESS) { + if (retry == 0) { + LOGE("applying patch failed result : [%d]\n", result); + SS_Free(outname);//wgid: 20739 + SS_SetUpgradeState(E_SS_FSUPDATEFAILED); + return E_SS_FAILURE; + } else { + LOGE("applying patch failed; retrying\n"); + SS_Free(outname);//wgid: 20739 + } + } else { + // succeeded; no need to retry + break; + } + } while (retry-- > 0); + + unsigned char current_target_sha1[SHA_DIGEST_SIZE] = { 0, }; + SHA1Final(current_target_sha1, &ctx1); + if (memcmp(current_target_sha1, target_sha1, SHA_DIGEST_SIZE) != 0) { + LOGE("patch did not produce expected sha1\n"); + SS_SetUpgradeState(E_SS_FSSHA_MISMATCH); + if (outname != NULL) + SS_Free(outname); + return E_SS_FAILURE; + } + + // Finally, rename the .patch file to replace the target file. +#ifdef ENHANCED_BSDIFF + if (SS_rename1(outname, target_filename) != 0) { + strerror_r(errno, buf, sizeof(buf)); + LOGE("rename of .patch to \"%s\" failed: %s\n", target_filename, buf); + SS_SetUpgradeState(E_SS_FSUPDATEFAILED); + if (outname != NULL) + SS_Free(outname); + return E_SS_FAILURE; + } +#else + if (rename(outname, target_filename) != 0) { + strerror_r(errno, buf, sizeof(buf)); + LOGE("rename of .patch to \"%s\" failed: %s\n", target_filename, buf); + SS_SetUpgradeState(E_SS_FSUPDATEFAILED); + if (outname != NULL) + SS_Free(outname); + return E_SS_FAILURE; + } + //remove source file if target is not same + if (strcmp(source_filename, target_filename) != 0) + unlink(source_filename); + SS_BackupSourceClear(backup_path); +#endif + SS_PatchSourceClear(patchfile_source_path); + SS_Free(outname); + + return result; +} \ No newline at end of file diff --git a/src/upgrade-apply-deltafs/engine/SS_PatchDelta.h b/src/upgrade-apply-deltafs/engine/SS_PatchDelta.h new file mode 100755 index 0000000..09e5b9d --- /dev/null +++ b/src/upgrade-apply-deltafs/engine/SS_PatchDelta.h @@ -0,0 +1,56 @@ +/* + * upgrade-apply-deltafs + * + * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _SS_PATCHDELTA_H +#define _SS_PATCHDELTA_H + +#include +#include "sha1.h" +#include "unistd.h" +#include "fcntl.h" +#include "errno.h" +#include "ua_types.h" + +#define SHA_DIGEST_SIZE 20 + +typedef struct _FileInfo { + unsigned char sha1[20]; //SHA_DIGEST_SIZE 20 + unsigned char *data; + int size; + struct stat st; +} FileInfo; +typedef ssize_t(*SinkFn) (unsigned char *, ssize_t, void *); + +int ParseSha1(const char *str, uint8_t * digest); + +int SS_LoadFile(const char *filename, FileInfo * file); +extern void SS_SetUpgradeState(int Val); +extern long SS_GetAvailableFreeSpace(const char *partition_name, SS_UINT32 * available_flash_size); +extern int SS_BackupSource(const char *source_filename, char *backup_path); +extern int SS_ApplyBsdiff(char *oldfile, char *newfile, char *patch, SinkFn sink, void *token, SHA1_CTX * ctx1); +extern int SS_BackupSourceClear(char * backup_path); +extern int SS_PatchSourceClear(char *patch_path); +extern long SS_WriteFile(long wHandle, SS_UINT32 dwPosition, unsigned char *pbBuffer, SS_UINT32 dwSize); +extern void SS_Free(void * pMemBlock); +extern long SS_CopyFile(const char * strFromPath, const char * strToPath); +extern long SS_DeleteFolder(const char * strPath); +extern long SS_DeleteFile(const char * strPath); +extern int tar_get_item_size(char * tar, char * item); +extern int tar_extract_file(char * tar, char * item, char * pathname); +extern int _system_cmd_wait(const char * command); +#endif diff --git a/src/upgrade-apply-deltafs/engine/SS_UPI.c b/src/upgrade-apply-deltafs/engine/SS_UPI.c new file mode 100755 index 0000000..b6f5ec8 --- /dev/null +++ b/src/upgrade-apply-deltafs/engine/SS_UPI.c @@ -0,0 +1,2207 @@ +/* + * upgrade-apply-deltafs + * + * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*HEADER */ + +/* + +Function Prototypes Mandatory + +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ua_types.h" +#include "SS_Common.h" +#include "fota_common.h" +#include "SS_UPI.h" +#include "SS_PatchDelta.h" +#include "SS_Engine_Errors.h" +#include "SS_FSUpdate.h" + +int gtotalFSCnt = 0; +int FS_UpgradeState = E_SS_FAILURE; +int gvalid_session = 0; //used as fail-safe in case device is turmed off or battery removed during update +fs_list *headptr_list; +tar_Data_t *tar_cfg_data = NULL; + +#ifdef MEM_PROFILING +/* + Description: + Create script file , set it executable, execute script in child process + Only works if valid delta.tar is present for upgrade + Summary: + If MEM_PROFILING is activated, + we can see the result of memory profiling after delta upgrade + in file defined by macro - SS_MEMORY_PROFILING_SCRIPT +*/ +int mem_profiling_start = 0; +int SS_Do_Memory_Profiling() +{ + int ret = -1; + pid_t pid; + char memory_usage_script[1024] = "#!/bin/bash\nlog_file=$1\npid=$2\nmaxmem=0\nwhile [[ -d \"/proc/${pid}\" ]]; do\n\ + mem=`cat /proc/${pid}/smaps | grep Pss | grep -v Swap|awk '{print $2}'|awk '{s+=$1} END {print s}'`\n\ + if [[ ${mem} -gt ${maxmem} ]]; then\nmaxmem=${mem}\n\ + echo -e \"Memory usage till now is: ${maxmem} KB.\" >> $log_file\n fi\n sleep 0.01\ndone\n\ + echo -e \"Max was : ${maxmem} KB.\" >> $log_file\n"; + char cmd[1024] = { 0, }; + + //Open a file and write the script contents in it + FILE *fp = fopen(SS_MEMORY_PROFILING_SCRIPT, "w+"); + fwrite(memory_usage_script, strlen(memory_usage_script), 1, fp); + fclose(fp); + //make the file executable - Octal 495 is 757 decimal + if (chmod(SS_MEMORY_PROFILING_SCRIPT, 495) < 0) { + LOGE("Error in chmod(%s, 495) - %d (%s)\n", SS_MEMORY_PROFILING_SCRIPT, errno, strerror(errno)); + return E_SS_FAILURE; + } + //calling mem_use.sh + //Usage : + pid = getpid(); + snprintf(cmd, sizeof(cmd) - 1, "%s %s %d", SS_MEMORY_PROFILING_SCRIPT, SS_MEMORY_USAGE_LOG, pid); + ret = _system_cmd_nowait(cmd); + sleep(1); + LOG("ret for memory profiling cmd is %d\n", ret); + if (ret == 0) { + mem_profiling_start = 1; + return S_SS_SUCCESS; + } else { + LOGE("Could not start Memory Profiling\n"); + return E_SS_FAILURE; + } +} +#endif +#ifdef TIME_PROFILING +static char ts1[256]; +static double ts2; +double t1; +double t2; +double fast_tar_get_item_size_time = 0.0; +double SS_LoadFile_time = 0.0; +double SS_FSBuildNodes_time = 0.0; + +static void get_time_stamp1(void) +{ + struct timeval tv; + int sec, msec; + + gettimeofday(&tv, NULL); + sec = (int)tv.tv_sec; + msec = (int)(tv.tv_usec / 1000); + snprintf(ts1, 256, "%06d.%03d", sec % 100000, msec); +} +#endif + +//Check SS function if available +int file_exist(char *filename) +{ + struct stat buf; + int ret = 0; + + ret = lstat(filename, &buf); + if (ret < 0) + ret = stat(filename, &buf); + + return (ret >= 0) ? (1) : (0); +} + +#ifdef POWER_FAIL_TEST + +static int SS_Get_power_fail_flag(void) +{ + int fd; + char buf[256]; + char *ptr = NULL; + int result = 0; + int ret_val = 0; + + if (file_exist(SS_POWER_FAIL_TEST_FLAG) == 0) { + LOGE("No exist file!!\n"); + return -1; + } + + fd = open(SS_POWER_FAIL_TEST_FLAG, O_RDWR, S_IRWXU); + if (fd == -1) { + LOGE("Could not open status file!!\n"); + return -1; + } + + result = SS_ReadFile(fd, 0, buf, sizeof(buf)); + if (result != 0) { + LOGE("SS_ReadFile failed!!\n"); + return -1; + } + + ret_val = atoi(buf); + + result = SS_CloseFile(fd); + if (result != 0) + LOGE("SS_CloseFile failed!!\n"); + + return ret_val; +} + +static void SS_Set_power_fail_flag(int del_type) +{ + int fd; + int result = 0; + char num_str[16]; + LOG("del_type:[%d]\n", del_type); + + fd = open(SS_POWER_FAIL_TEST_FLAG, O_RDWR | O_CREAT, S_IRWXU); + if (fd == -1) { + LOGE("Could not open status file!!\n"); + return; + } + + sprintf(num_str, "%d", del_type); + result = SS_WriteFile(fd, 0, num_str, strlen(num_str)); + if (result != 0) + LOGE("SS_WriteFile failed!!\n"); + + result = SS_CloseFile(fd); + if (result != 0) + LOGE("SS_CloseFile failed!!\n"); + + sync(); + +} + +int SS_Do_Power_fail_test(int del_type) +{ + int ret = -1; + char cmd[1024] = { 0, }; + + SS_Set_power_fail_flag(del_type); + + snprintf(cmd, sizeof(cmd) - 1, "%s", "/usr/sbin/reboot fota"); + ret = _system_cmd_nowait(cmd); + sleep(1); + LOG("ret for SS_Do_Power_fail_test cmd is %d\n", ret); + if (ret == 0) { + return S_SS_SUCCESS; + } else { + LOGE("Could not start Memory Profiling\n"); + return E_SS_FAILURE; + } +} +#endif + +int SS_GetProgressResolution(int ultotalFSCnt) +{ + if (ultotalFSCnt < DISPLAYRESOLUTION_SIZE) + return 1; + else + return (ultotalFSCnt / DISPLAYRESOLUTION_SIZE); +} + +void SS_SetUpgradeState(int Val) +{ + LOGE("FAILED to upgrade Cause:[0x%x]\n", Val); + FS_UpgradeState = Val; + return; +} + +int SS_GetUpgradeState() +{ + return FS_UpgradeState; +} + +int SS_Get_last_update_status(int* last_update_status, int* del_type, char* status_path) +{ + int fd; + unsigned char buf[257]; + char *ptr = NULL; + char *saveptr = NULL; + int result = 0; + + if (file_exist(status_path) == 0) { + LOG("No exist file!! - File_path:[%s]\n", status_path); + return -1; + } + + fd = open(status_path, O_RDWR, S_IRWXU); + if (fd == -1) { + LOGE("Could not open status file!!, File_path:[%s]\n", status_path); + return -1; + } + + result = SS_ReadFile(fd, 0, buf, sizeof(buf)-1); + if (result != 0) { + LOGE("SS_ReadFile failed!!\n"); + result = SS_CloseFile(fd); + if (result != 0) + LOGE("SS_CloseFile failed!!\n"); + return -1; + } + + ptr = strtok_r((char *)buf, " ", &saveptr); + + if (ptr != NULL) { + *last_update_status = atoi(ptr); + ptr = strtok_r(NULL, " ", &saveptr); + } + + if (ptr != NULL) { + *del_type = atoi(ptr); + } + + result = SS_CloseFile(fd); + if (result != 0) + LOGE("SS_CloseFile failed!!\n"); + + return 0; +} + +void SS_Set_last_update_status(int last_update_status, int del_type, char *status_path) +{ + int fd; + int result = 0; + char num_str[16]; + LOG("last_update_status:[%d], del_type:[%d]\n", last_update_status, del_type); + + fd = open(status_path, O_RDWR | O_CREAT, S_IRWXU); + if (fd == -1) { + LOGE("Could not open status file!!, File_path:[%s]\n", status_path); + return; + } + + snprintf(num_str, sizeof(num_str), "%d %d", last_update_status, del_type); + result = SS_WriteFile(fd, 0, (unsigned char *)num_str, strlen(num_str)); + if (result != 0) + LOGE("SS_WriteFile failed!!\n"); + + result = SS_CloseFile(fd); + if (result != 0) + LOGE("SS_CloseFile failed!!\n"); + + sync(); + +} + +int SS_rename1(const char *old_file_name, const char *new_file_name) +{ + int result = E_SS_FAILURE; + char *temp_name = NULL; + temp_name = (char *)SS_Malloc(strlen(new_file_name) + 10); + if (temp_name == NULL) + return E_SS_FAILURE; + snprintf(temp_name, strlen(new_file_name) + 10, "%s.temp", new_file_name); + result = rename(new_file_name, temp_name); + if (result != 0) + goto Cleanup; + result = rename(old_file_name, new_file_name); + if (result != 0) + goto Cleanup; + result = unlink(temp_name); + Cleanup: + if (temp_name) + SS_Free(temp_name); + return result; +} + +/*! + ********************************************************************************* + * SS_FSVerifyNode + ********************************************************************************* + * + * @brief + * This is to verify nodes being added to global control structure for diff and delete cases. + * gvalid_session global is used to check if nodes are already verified. + * + * + * @param + * + * @return returns S_SS_SUCCESS and + * returns E_SS_FAILURE in case any error occurs + * + ********************************************************************************* + */ +int SS_FSVerifyNode(const char *path, const char *patchname, const char *sha1src, int type, + char *patchpath_name, int *data_size, int *data_offset) +{ + char patch[MAX_FILE_PATH] = { 0 }; + FileInfo source_file; + uint8_t source_sha1[SHA_DIGEST_SIZE]; + + if (gvalid_session) { + if ((type == DIFFS || type == DELETES || type == MOVES) && !file_exist((char *)path)) { + LOGE("failed to verifyNodes [does not exist], Path : [%s] Type[%d]\n", path, type); + SS_SetUpgradeState(E_SS_FSBADNODES); + return E_SS_FAILURE; + } + snprintf(patch, MAX_FILE_PATH, "%s%s%s", patchpath_name, "/", patchname); + if ((type == DIFFS/*||type == NEWFILES */)) { // allowing size 0 also for folders + if (tar_get_item_size_from_struct(&tar_cfg_data, patchname, data_size, data_offset) + != S_SS_SUCCESS) { + LOGE("failed to get item size from struct, Patch : [%s]\n", patchname); + SS_SetUpgradeState(E_SS_FSBADNODES); + return E_SS_FAILURE; + } + if (*data_size < 0) { + LOGE("failed to verifyNodes [delta absent], Patch : [%s] Type[%d]\n", patch, type); + SS_SetUpgradeState(E_SS_FSBADNODES); + return E_SS_FAILURE; + } + } + //For other types (NEWs, SYMs, Folders), SHA check not required + if ((type == DIFFS || type == MOVES/* ||type == DELETES */) && + (strcmp(sha1src, SS_NULLENTRY) != 0)) { + if (ParseSha1(sha1src, source_sha1) != 0) { + LOGE("Failed to parse Src-sha1 \"%s\"\n", sha1src); + return E_SS_FAILURE; + } + if (SS_LoadFile(path, &source_file) == 0) { + if (memcmp(source_file.sha1, source_sha1, SHA_DIGEST_SIZE) != 0) { + SS_Free(source_file.data); + unsigned char actualShaBuffer[41] = { 0, }; + hex_digest(source_file.sha1, actualShaBuffer, SHA_DIGEST_SIZE); + LOGE("SS_FSVerifyNode - SHA mismatch with SRC - PATH [%s] Expected [%s] Actual [%s]\n", + path, sha1src, actualShaBuffer); + SS_SetUpgradeState(E_SS_FSSRCCURRUPTED); // Define other error + return E_SS_FAILURE; + } + } + SS_Free(source_file.data); + } + } else { + LOGL(LOG_SSENGINE, "FS partition Already verified - Filling only size and offset \n"); + snprintf(patch, MAX_FILE_PATH, "%s%s%s", patchpath_name, "/", patchname); + if ((type == DIFFS/* ||type == NEWFILES */)) { // allowing size 0 also for folders + if (tar_get_item_size_from_struct(&tar_cfg_data, patchname, data_size, data_offset) + != S_SS_SUCCESS) { + LOGE("failed to get item size from struct, Patch : [%s] \n", patchname); + SS_SetUpgradeState(E_SS_FSBADNODES); + return E_SS_FAILURE; + } + if (*data_size < 0) { + LOGE("failed to verifyNodes [delta absent], Patch : [%s] Type[%d]\n", patch, type); + SS_SetUpgradeState(E_SS_FSBADNODES); + return E_SS_FAILURE; + } + } + } + return S_SS_SUCCESS; +} + +/*! + ********************************************************************************* + * SS_AppendNode + ********************************************************************************* + * + * @brief + * This is to append node to the global control structure for delta files. + * + * + * @param + * + * @return returns S_SS_SUCCESS and + * returns E_SS_FAILURE in case any error occurs + * + ********************************************************************************* + */ +int SS_AppendNode(const char *ubDeltaPath, fs_params ** headparam, fs_params ** tailparam, const char *old_path, + const char *new_path, const char *patchname, const char *sha1src, const char *sha1trg, int type, + char *patchpath_name) +{ + fs_params *newnode = NULL; + int data_size = 0; + int data_offset = 0; + + if (!ubDeltaPath || !old_path || !new_path || !patchname || !sha1src || !sha1trg || !patchpath_name) { + LOGE("Bad Nodes, NULL params passed for Appending Nodes \n"); + SS_SetUpgradeState(E_SS_FSINVALIDNODEPARAMS); + return E_SS_FAILURE; + } + if ((E_SS_FAILURE == + SS_FSVerifyNode(old_path, patchname, sha1src, type, patchpath_name, &data_size, &data_offset))) { + LOGE("Bad Nodes, Failed to pass verification - [Delta Path - %s][OldPath - %s] [NewPath - %s] \n", ubDeltaPath, + old_path, new_path); + return E_SS_FAILURE; + } + newnode = (fs_params *) SS_Malloc(sizeof(fs_params)); + if (!newnode) + return E_SS_FAILURE; + strncpy(newnode->file_old_path, old_path, SS_MAX_NAMELENSUPPORTED);//wgid: 29483 + strncpy(newnode->file_new_path, new_path, SS_MAX_NAMELENSUPPORTED);//wgid: 29482 + strncpy(newnode->patch_name, patchname, SS_MAX_NAMELENSUPPORTED);//wgid: 28033 + strncpy(newnode->sha1src, sha1src, sizeof(newnode->sha1src) -1);//wgid: 25282 + strncpy(newnode->sha1trg, sha1trg, sizeof(newnode->sha1trg) - 1);//wgid: 25283 + newnode->type = type; + newnode->data_size = data_size; + newnode->data_offset = data_offset; + newnode->nextnode = NULL; + + //LOG("%s %s %d %s %s \n",newnode->file_path,newnode->patch_name,newnode->type, newnode->sha1src, newnode->sha1trg); + + if (*headparam == NULL) { + *headparam = newnode; + *tailparam = newnode; + } else { + (*tailparam)->nextnode = newnode; + (*tailparam) = (*tailparam)->nextnode; + } + return S_SS_SUCCESS; + +} + +void SS_UpdateUIProgress(ua_dataSS_t * ua_dataSS, int ulTotalFsCnt, int ulDone) +{ + static int ss_count = 1; + int res_val = SS_GetProgressResolution(ulTotalFsCnt); + if (!ua_dataSS) { + LOGE("Error ua_dataSS\n"); + return; + } +//LOG("\nvalues are ss_count[%d] total_file_cnt[%d]",ss_count,ulTotalFsCnt); + if (ulDone == 1) { + if (ua_dataSS->ui_progress) + ua_dataSS->ui_progress(ua_dataSS, 100); + ss_count = 1; + } else if (ss_count < ulTotalFsCnt) { + if (ss_count % res_val == 0) { //Max 50 times display + double data = (double)ss_count / (double)ulTotalFsCnt; + if (ua_dataSS->ui_progress) + ua_dataSS->ui_progress(ua_dataSS, data * 100); + } + ss_count++; + } else { + if (ua_dataSS->ui_progress) + ua_dataSS->ui_progress(ua_dataSS, 100); + ss_count = 1; + } + +} + +/*! + ********************************************************************************* + * SS_FSClearNodes + ********************************************************************************* + * + * @brief + * This is to clear the global control structure for delta files. + * + * + * @param + * + * @return + * + ********************************************************************************* + */ +void SS_FSClearNodes() +{ + fs_params *local_temp = NULL; + fs_params *local_next = NULL; + LOGL(LOG_SSENGINE, "Free Nodes\n"); + if (headptr_list) { + if (headptr_list->del_ref) { + local_temp = headptr_list->del_ref; + while (local_temp) { + local_next = local_temp->nextnode; + SS_Free(local_temp); + local_temp = local_next; + } + } + if (headptr_list->dif_ref) { + local_temp = headptr_list->dif_ref; + while (local_temp) { + local_next = local_temp->nextnode; + SS_Free(local_temp); + local_temp = local_next; + } + } + if (headptr_list->move_ref) { + local_temp = headptr_list->move_ref; + while (local_temp) { + local_next = local_temp->nextnode; + SS_Free(local_temp); + local_temp = local_next; + } + } + if (headptr_list->new_ref) { + local_temp = headptr_list->new_ref; + while (local_temp) { + local_next = local_temp->nextnode; + SS_Free(local_temp); + local_temp = local_next; + } + } + if (headptr_list->sym_difref) { + local_temp = headptr_list->sym_difref; + while (local_temp) { + local_next = local_temp->nextnode; + SS_Free(local_temp); + local_temp = local_next; + } + } + if (headptr_list->sym_newref) { + local_temp = headptr_list->sym_newref; + while (local_temp) { + local_next = local_temp->nextnode; + SS_Free(local_temp); + local_temp = local_next; + } + } + if (headptr_list->hard_newref) { + local_temp = headptr_list->hard_newref; + while (local_temp) { + local_next = local_temp->nextnode; + SS_Free(local_temp); + local_temp = local_next; + } + } + if (headptr_list->hard_difref) { + local_temp = headptr_list->hard_difref; + while (local_temp) { + local_next = local_temp->nextnode; + SS_Free(local_temp); + local_temp = local_next; + } + } + SS_Free(headptr_list); + headptr_list = NULL; + } +} + +/*! + ********************************************************************************* + * SS_FSGetDeltaCount + ********************************************************************************* + * + * @brief + * This is to get the delta count for diffs , deletes etc. + * + * + * @param + * + * @return returns structure with delta count info + * NULL in case of error + * + ********************************************************************************* + */ + +struct details *SS_FSGetDeltaCount(char *ubDeltaPath, char *ubDeltaInfoFile, char *patchlist_backup_patch) +{ + int size = 0, bckupsize = 0, ret = 1; + char *token = NULL; + char *FileData = NULL; + int data_size = -1; + char *line = NULL; + char *saveptr = NULL; + char buf[256]; + struct details *refer_copy = NULL; + FILE *filename_bkup = NULL; + + if (!(ubDeltaPath && ubDeltaInfoFile)) { + LOGE("failed to Parse DELTA count information: \n"); + SS_SetUpgradeState(E_SS_BAD_PARAMS); + return NULL; + } + refer_copy = (struct details *)SS_Malloc(sizeof(struct details)); + + if (refer_copy == NULL) { + LOGE("failed to allocate memory\n"); + return NULL; + } + + LOGL(LOG_SSENGINE, "Delta File Info =%s\n", ubDeltaInfoFile); + + size = tar_get_item_size(ubDeltaPath, ubDeltaInfoFile); + if (size < 0) { + LOGE("failed to Access DELTA info file DPath:[%s] File: [%s]\n", ubDeltaPath, ubDeltaInfoFile); + SS_SetUpgradeState(E_SS_FSBADDELTA); + ret = 0; + goto cleanup; + } + + FileData = SS_Malloc(size + 1); + if (FileData == NULL) { + LOGE("Failed to Allocate Memory\n"); + SS_SetUpgradeState(E_SS_MALLOC_ERROR); + ret = 0; + goto cleanup; + } + + memset(FileData, 0, size + 1); + data_size = tar_get_cfg_data(ubDeltaPath, ubDeltaInfoFile, FileData, size); + if (data_size <= 0) { // == 0 is NOT okay?? + LOGE("Failed to read cfg data from Delta\n"); + SS_SetUpgradeState(E_SS_FSBADDELTA); + ret = 0; + goto cleanup; + } + filename_bkup = fopen(patchlist_backup_patch, "wb+"); + if (filename_bkup == NULL) { + strerror_r(errno, buf, sizeof(buf)); + LOGE("Failed to create BACKUP file Error:[%s]\n", buf); + SS_SetUpgradeState(E_SS_FSFAILEDTOBACKUPPATCHINFO); + ret = 0; + goto cleanup; + } + + bckupsize = fwrite(FileData, 1, data_size, filename_bkup); //RECHECK SIZE 1 + if (bckupsize <= 0) { + SS_SetUpgradeState(E_SS_FSFAILEDTOBACKUPPATCHINFO); + ret = 0; + goto cleanup; + } + LOGL(LOG_SSENGINE, " Size [%d] DataSize [%d] BakUpSize [%d]\n", size, data_size, bckupsize); + + line = strstr(FileData, SS_FSCOUNT_MAGIC_KEY); + if (line) { + LOGL(LOG_SSENGINE, "SS_FSGetDeltaCount() last line %s \n", line); + + token = strtok_r(&line[SS_FSCOUNT_MAGIG_KEYLEN], SS_TOKEN_SPACE, &saveptr); + if (token) + refer_copy->diffs = atoi(token); + else { + SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT); + ret = 0; + goto cleanup; + } + token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr); + if (token) + refer_copy->moves = atoi(token); + else { + SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT); + ret = 0; + goto cleanup; + } + + token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr); + if (token) + refer_copy->news = atoi(token); + else { + SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT); + ret = 0; + goto cleanup; + } + + token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr); + if (token) + refer_copy->deletes = atoi(token); + else { + SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT); + ret = 0; + goto cleanup; + } + + token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr); + if (token) + refer_copy->symdiffs = atoi(token); + else { + SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT); + ret = 0; + goto cleanup; + } + + token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr); + if (token) + refer_copy->symnews = atoi(token); + else { + SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT); + ret = 0; + goto cleanup; + } + + token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr); + if (token) + refer_copy->harddiffs = atoi(token); + else { + SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT); + ret = 0; + goto cleanup; + } + + token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr); + if (token) + refer_copy->hardnews = atoi(token); + else { + SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT); + ret = 0; + goto cleanup; + } + + gtotalFSCnt = + refer_copy->diffs + refer_copy->moves + refer_copy->news + refer_copy->deletes + refer_copy->symdiffs + + refer_copy->symnews + refer_copy->harddiffs + refer_copy->hardnews; + LOG("SS_FSGetDeltaCount() total no of file %d\n", gtotalFSCnt); + + } else { + SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT); + LOG("SS_FSGetDeltaCount() Failed to read last line\n"); + } + if (gtotalFSCnt < 0) { + ret = 0; + goto cleanup; + } + + cleanup: + if (ret) { + SS_Free(FileData); + if (filename_bkup) + fclose(filename_bkup); + return refer_copy; + } else { + SS_Free(FileData); + SS_Free(refer_copy); + if (filename_bkup) + fclose(filename_bkup); + return NULL; + } + +} + +/*! + ********************************************************************************* + * SS_FSBuildNodes + ********************************************************************************* + * + * @brief + * This is used to build the gobal control structure for diffs, deletes etc. + * For all the entries in config file (which has info) the information is parsed to the global control struct + * + * + * @param + * + * @return returns fs_list structure filled with details of all the files to be diff-ed ,deleted etc. + * NULL in case of error + * + ********************************************************************************* + */ +fs_list *SS_FSBuildNodes(ua_dataSS_t * ua_dataSS) +{ + FILE *fp = NULL; + char line[SS_TOKEN_MAXLINE_LEN] = { '\0' }; + char patchlist_backup_patch[MAX_FILE_PATH]; + snprintf(patchlist_backup_patch, MAX_FILE_PATH, "%s/%s",ua_dataSS->update_data->ua_delta_folder, SS_PATCHLIST_BKUPLOC); + char string_na[] = "NA"; + char *patch_name = NULL; + char *source_name = NULL; + char *target_name = NULL; + char *sha1src = NULL; + char *sha1trg = NULL; + char *change_type = NULL; + char *file_type = NULL; + char *saveptr = NULL; + uint32_t ulPatchCount = 0, del_type = DELETES; + fs_params *fs_diffhead = NULL; + fs_params *fs_difftail = NULL; + fs_params *fs_movehead = NULL; + fs_params *fs_movetail = NULL; + fs_params *fs_newhead = NULL; + fs_params *fs_delhead = NULL; + fs_params *fs_deltail = NULL; + fs_params *fs_symlinkdiffhead = NULL; + fs_params *fs_symlinkdifftail = NULL; + fs_params *fs_symlinknewhead = NULL; + fs_params *fs_symlinknewtail = NULL; + fs_params *fs_hardlinkdiffhead = NULL; + fs_params *fs_hardlinkdifftail = NULL; + fs_params *fs_hardlinknewhead = NULL; + fs_params *fs_hardlinkdnewtail = NULL; + + struct details *local = NULL; + fs_list *fs_head_node = NULL; + int i = 0, retval = 0; + if (!ua_dataSS) { + LOGE("Bad structure ua_dataSS\n"); + SS_SetUpgradeState(E_SS_BAD_PARAMS); + return NULL; + } + LOGL(LOG_SSENGINE, " Build Nodes Entry \n"); + if (tar_cfg_data == NULL) + tar_cfg_data = tar_build_cfg_table(ua_dataSS->update_data->ua_delta_path); + if (!tar_cfg_data) { + LOGE(" tar_build_cfg_table Failed \n"); + SS_SetUpgradeState(E_SS_BAD_PARAMS); + return NULL; + } + local = SS_FSGetDeltaCount(ua_dataSS->update_data->ua_delta_path, ua_dataSS->update_delta->ua_patch_info, patchlist_backup_patch); + if (local == NULL) { + LOGE(" Build Nodes Failed \n"); + if (tar_cfg_data) + tar_free_cfg_table(&tar_cfg_data); + SS_SetUpgradeState(E_SS_BAD_PARAMS); + return NULL; + } + + fp = fopen(patchlist_backup_patch, "r"); + if (!fp) { + SS_SetUpgradeState(E_SS_FSFAILEDTOOPENPATCHINFO); + if (tar_cfg_data) + tar_free_cfg_table(&tar_cfg_data); + SS_Free(local); + return NULL; + } + + ulPatchCount = local->diffs + local->deletes + local->news + local->moves + local->symdiffs + + local->symnews + local->harddiffs + local->hardnews; + LOG("Total FS count [%d].\n", ulPatchCount); +/* +************************************************************************ +Parsing logic implemented for patchlist +************************************************************************ +Sample entries in patchlist as below : +:: +************************************************************************ +DIFF:REG:system/bin/vi:system/bin/vi:2f2f3dc6d3ee06af0080ac7975f22941660f2480:78b2d44af32d854c70f1cb7431a60c2682a320cc:diff1_vi.delta +DIFF:TPK:system/usr/packages/removable/com.samsung.calculator.tpk:system/usr/packages/removable/com.samsung.calculator.tpk: + 96fc1bcde30d501ba65ef0038e05da46d255a7b3:fa1d5d9daa4097ac302b69244297f508577c3a01:diff1598_com.samsung.calculator.tpk.delta/ +MOVE:REG:system/etc/smack/accesses.d/heremaps-engine-devel:system/usr/apps/com.samsung.contacts/res/temp:da39a3ee5e6b4b0d3255bfef95601890afd80709 +DEL:REG:system/usr/ug/res/images/ug-phone/contacts/favorites_icon_remove.PNG:38ad8be378506d19b1c769d46be262cf100f6c59 +DEL:SYM:system/usr/apps/com.samsung.message-lite/lib/libmsg-common.so +DEL:HARD:system/usr/apps/com.samsung.message-lite/lib/libmsg-common.so +SYM:DIFF:system/usr/lib/sync-agent/kies-private/libplugin-na-mobex.so.0:system/usr/lib/sync-agent/kies-private/libplugin-na-mobex.so.0: + libplugin-na-mobex.so.0.3.57 +SYM:NEW:system/lib/firmware/vbc_eq:/opt/system/vbc_eq +HARD:DIFF:system/usr/lib/sync-agent/kies-private/libplugin-na-mobex.so.0:system/usr/lib/sync-agent/kies-private/libplugin-na-mobex.so.0: + libplugin-na-mobex.so.0.3.57 +HARD:NEW:system/lib/firmware/vbc_eq:/opt/system/vbc_eq +*********************************************************************** +*/ + if (local && ((local->diffs) > 0 || (local->moves > 0))) { + LOGL(LOG_SSENGINE, "%ss [%d] %ss [%d]\n", SS_STRING_DIFF, local->diffs, SS_STRING_MOVE, local->moves); + for (i = 0; i < (local->diffs + local->moves); i++) { + if (fgets(line, SS_TOKEN_MAXLINE_LEN, fp) == NULL) { + SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO); + break; + } + //LOGL(LOG_SSENGINE, "DIFF LINE:[%d] [%s] \n",i+1,line); + + change_type = strtok_r(line, SS_TOEKN_COLON, &saveptr); + file_type = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); + if (!file_type) { + LOGE("Unexpected null in strtok_r"); + goto CleanUp; + } + + if (change_type && strcmp(change_type, SS_STRING_MOVE) == 0) { // && strcmp(file_type,"TPK") == 0){ + source_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); + target_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); + sha1src = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr); + //LOGL(LOG_SSENGINE, "%s Index [%d]\n", SS_STRING_MOVE, i); + + if (!source_name || !target_name || !sha1src) { + SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO); + //LOGE("Failed to extract Patch Info Type:DELETES \n"); + LOGE("Failed to parse DIFFS - LINE:[%d] [%s] \n", i + 1, line); + goto CleanUp; + } + retval = + SS_AppendNode(ua_dataSS->update_data->ua_delta_path, &fs_movehead, &fs_movetail, source_name, + target_name, string_na, sha1src, string_na, MOVES, + ua_dataSS->update_delta->ua_patch_path); + if (retval == E_SS_FAILURE) // ONLY test purpose, should enable this + goto CleanUp; + + if (ua_dataSS->ua_operation == UI_OP_SCOUT) { + SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0); + } + } else if (change_type && strcmp(change_type, SS_STRING_DIFF) == 0) { // && strcmp(file_type,"TPK") == 0){ + source_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); + target_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); + sha1src = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); + sha1trg = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); + patch_name = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr); + //LOGL(LOG_SSENGINE, "%s Index [%d]\n", SS_STRING_DIFF, i); + + if (patch_name && (strlen(patch_name) <= SS_MAX_NAMELENSUPPORTED)) { + retval = + SS_AppendNode(ua_dataSS->update_data->ua_delta_path, &fs_diffhead, &fs_difftail, + source_name, target_name, patch_name, sha1src, sha1trg, DIFFS, + ua_dataSS->update_delta->ua_patch_path); + if (retval == E_SS_FAILURE) // ONLY test purpose, should enable this + goto CleanUp; + } else { + SS_SetUpgradeState(E_SS_FILENAMELENERROR); + LOGE("File Name length Limitation Error File:[%s]\n", patch_name); + goto CleanUp; + } + + if (ua_dataSS->ua_operation == UI_OP_SCOUT) { + SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0); + } + } else { + SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO); + LOGE("Patch Name format Error File\n"); + goto CleanUp; + } + } + } + if (local && (local->news) > 0) { //check if new files archive is present in the delta + char new_patch_path[MAX_FILE_PATH] = { 0, }; + snprintf(new_patch_path, MAX_FILE_PATH, "%s%s", ua_dataSS->parti_info->ua_subject_name, SS_COMPRESSED_FILE); + if (tar_get_item_size(ua_dataSS->update_data->ua_delta_path, new_patch_path) <= 0) { + SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO); + LOGE("New files not present in Patch\n"); + goto CleanUp; + } + } + if (local && (local->deletes) > 0) { //this is to group to delete list + LOGL(LOG_SSENGINE, "%ss [%d]\n", SS_STRING_DEL, local->deletes); + for (i = 0; i < (local->deletes); i++) { + if (fgets(line, SS_TOKEN_MAXLINE_LEN, fp) == NULL) { + SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO); + break; + } + + change_type = strtok_r(line, SS_TOEKN_COLON, &saveptr); + if (!change_type) { + LOGE("Unexpected null in strtok_r"); + goto CleanUp; + } + file_type = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); + + if (file_type && strcmp(file_type, SS_STRING_REG) == 0) { + source_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); + sha1src = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr); + del_type = DELETES; + } else if (file_type && ((strcmp(file_type, SS_STRING_SYM) == 0) || (strcmp(file_type, SS_STRING_HARD) == 0))) { + source_name = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr); + sha1src = string_na; + del_type = DELETES; + } else if (file_type && strcmp(file_type, SS_STRING_END) == 0) { + source_name = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr); + sha1src = string_na; + del_type = DELETE_END; + } else { + LOGE("Failed to parse DELETES - LINE:[%d] [%s] \n", i + 1, line); + goto CleanUp; + } + + if (!source_name || !sha1src) { + SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO); + //LOGE("Failed to extract Patch Info Type:DELETES \n"); + LOGE("Failed to parse DELETES - LINE:[%d] [%s] \n", i + 1, line); + goto CleanUp; + } + //LOGL(LOG_SSENGINE, "%s Index [%d]\n", SS_STRING_DEL, i); + retval = + SS_AppendNode(ua_dataSS->update_data->ua_delta_path, &fs_delhead, &fs_deltail, source_name, + string_na, string_na, sha1src, string_na, del_type, + ua_dataSS->update_delta->ua_patch_path); + if (retval == E_SS_FAILURE) // ONLY test purpose, should enable this + goto CleanUp; + if (ua_dataSS->ua_operation == UI_OP_SCOUT) { + SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0); + } + + } + } //For symlink files + + if (local && (local->symdiffs) > 0) { + LOGL(LOG_SSENGINE, "%s %ss [%d]\n", SS_STRING_SYM, SS_STRING_DIFF, local->symdiffs); + for (i = 0; i < (local->symdiffs); i++) { //get the count from below function + if (fgets(line, SS_TOKEN_MAXLINE_LEN, fp) == NULL) { + SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO); + break; + } + //LOGL(LOG_SSENGINE, "SYMDIFF LINE:[%d] [%s] \n",i+1,line); + + change_type = strtok_r(line, SS_TOEKN_COLON, &saveptr); + file_type = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); + + if ((change_type && file_type) && + strcmp(change_type, SS_STRING_SYM) == 0 && strcmp(file_type, SS_STRING_DIFF) == 0) { // && strcmp(file_type,"TPK") == 0){ + source_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); + target_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); + patch_name = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr); + //LOGL(LOG_SSENGINE, "%s %s Index [%d]\n", SS_STRING_SYM, SS_STRING_DIFF, i); + + if (!source_name || !target_name || !patch_name) { + SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO); + //LOGE("Failed to extract Patch Info Type:DELETES \n"); + LOGE("Failed to parse SymDiffs - LINE:[%d] [%s] \n", i + 1, line); + goto CleanUp; + } + retval = + SS_AppendNode(ua_dataSS->update_data->ua_delta_path, &fs_symlinkdiffhead, &fs_symlinkdifftail, + source_name, target_name, patch_name, string_na, string_na, SYMDIFFS, + ua_dataSS->update_delta->ua_patch_path); + if (retval == E_SS_FAILURE) // ONLY test purpose, should enable this + goto CleanUp; + if (ua_dataSS->ua_operation == UI_OP_SCOUT) { + SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0); + } + } + } + } + if (local && (local->symnews) > 0) { + LOGL(LOG_SSENGINE, "%s %ss [%d]n", SS_STRING_SYM, SS_STRING_NEW, local->symnews); + for (i = 0; i < (local->symnews); i++) { + if (fgets(line, SS_TOKEN_MAXLINE_LEN, fp) == NULL) { + SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO); + break; + } + //LOGL(LOG_SSENGINE, "SYMNEWS LINE:[%d] [%s] \n",i+1,line); + + change_type = strtok_r(line, SS_TOEKN_COLON, &saveptr); + file_type = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); + + if ((change_type && file_type) && + (strcmp(change_type, SS_STRING_SYM) == 0 && strcmp(file_type, SS_STRING_NEW) == 0)) { + source_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); + patch_name = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr); + //LOGL(LOG_SSENGINE, "%s %s Index [%d]\n", SS_STRING_SYM, SS_STRING_NEW, i); + + if (!source_name || !patch_name) { + SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO); + //LOGE("Failed to extract Patch Info Type:DELETES \n"); + LOGE("Failed to parse SymNews - LINE:[%d] [%s] \n", i + 1, line); + goto CleanUp; + } + retval = + SS_AppendNode(ua_dataSS->update_data->ua_delta_path, &fs_symlinknewhead, &fs_symlinknewtail, + source_name, string_na, patch_name, string_na, string_na, SYMNEWFILES, + ua_dataSS->update_delta->ua_patch_path); + if (retval == E_SS_FAILURE) // ONLY test purpose, should enable this + goto CleanUp; + if (ua_dataSS->ua_operation == UI_OP_SCOUT) { + SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0); + } + } + } + } // For hardlinks + if (local && (local->hardnews) > 0) { + LOGL(LOG_SSENGINE, "%s %ss [%d]\n", SS_STRING_HARD, SS_STRING_NEW, local->hardnews); + for (i = 0; i < (local->hardnews); i++) { + if (fgets(line, SS_TOKEN_MAXLINE_LEN, fp) == NULL) { + SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO); + break; + } + //LOGL(LOG_SSENGINE, "HARDNEWS LINE:[%d] [%s] \n",i+1,line); + + change_type = strtok_r(line, SS_TOEKN_COLON, &saveptr); + file_type = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); + + if ((change_type && file_type) && + (strcmp(change_type, SS_STRING_HARD) == 0 && strcmp(file_type, SS_STRING_NEW) == 0)) { + source_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); + patch_name = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr); + //LOGL(LOG_SSENGINE, "%s %s Index [%d]\n", SS_STRING_SYM, SS_STRING_NEW, i); + + if (!source_name || !patch_name) { + SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO); + //LOGE("Failed to extract Patch Info Type:DELETES \n"); + LOGE("Failed to parse HardNews - LINE:[%d] [%s] \n", i + 1, line); + goto CleanUp; + } + retval = + SS_AppendNode(ua_dataSS->update_data->ua_delta_path, &fs_hardlinknewhead, &fs_hardlinkdnewtail, + source_name, string_na, patch_name, string_na, string_na, HARDNEWFILES, + ua_dataSS->update_delta->ua_patch_path); + if (retval == E_SS_FAILURE) // ONLY test purpose, should enable this + goto CleanUp; + if (ua_dataSS->ua_operation == UI_OP_SCOUT) { + SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0); + } + } + } + } + + if (local && (local->harddiffs) > 0) { + LOGL(LOG_SSENGINE, "%s %ss [%d]\n", SS_STRING_HARD, SS_STRING_DIFF, local->harddiffs); + for (i = 0; i < (local->harddiffs); i++) { //get the count from below function + if (fgets(line, SS_TOKEN_MAXLINE_LEN, fp) == NULL) { + SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO); + break; + } + //LOGL(LOG_SSENGINE, "HARDIFFS LINE:[%d] [%s] \n",i+1,line); + + change_type = strtok_r(line, SS_TOEKN_COLON, &saveptr); + file_type = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); + + if ((change_type && file_type) && + strcmp(change_type, SS_STRING_HARD) == 0 && strcmp(file_type, SS_STRING_DIFF) == 0) { // && strcmp(file_type,"TPK") == 0){ + source_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); + target_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr); + patch_name = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr); + //LOGL(LOG_SSENGINE, "%s %s Index [%d]\n", SS_STRING_SYM, SS_STRING_DIFF, i); + + if (!source_name || !target_name || !patch_name) { + SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO); + //LOGE("Failed to extract Patch Info Type:DELETES \n"); + LOGE("Failed to parse HardDiffs - LINE:[%d] [%s] \n", i + 1, line); + goto CleanUp; + } + retval = + SS_AppendNode(ua_dataSS->update_data->ua_delta_path, &fs_hardlinkdiffhead, &fs_hardlinkdifftail, + source_name, target_name, patch_name, string_na, string_na, HARDDIFFS, + ua_dataSS->update_delta->ua_patch_path); + if (retval == E_SS_FAILURE) // ONLY test purpose, should enable this + goto CleanUp; + if (ua_dataSS->ua_operation == UI_OP_SCOUT) { + SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0); + } + } + } + } + + fs_head_node = (fs_list *) SS_Malloc(sizeof(fs_list)); + if (!fs_head_node) { + SS_SetUpgradeState(E_SS_MALLOC_ERROR); + goto CleanUp; + } + fs_head_node->dif_ref = fs_diffhead; + fs_head_node->move_ref = fs_movehead; + fs_head_node->new_ref = fs_newhead; + fs_head_node->del_ref = fs_delhead; + fs_head_node->sym_difref = fs_symlinkdiffhead; + fs_head_node->sym_newref = fs_symlinknewhead; + fs_head_node->hard_difref = fs_hardlinkdiffhead; + fs_head_node->hard_newref = fs_hardlinknewhead; + fs_head_node->ulPatchCount = ulPatchCount; + + if (ua_dataSS->ua_operation == UI_OP_SCOUT) { + SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 1); + } + + CleanUp: + fclose(fp); + SS_Free(local); + unlink(patchlist_backup_patch); + if (retval == E_SS_FAILURE) + if (tar_cfg_data) + tar_free_cfg_table(&tar_cfg_data); + return fs_head_node; +} + +void SS_GetPartition_LocDetails(ua_dataSS_t * ua_dataSS) +{ + LOGL(LOG_SSENGINE, "PART NAME: [%s] \n", ua_dataSS->parti_info->ua_parti_name); + snprintf(ua_dataSS->update_delta->ua_patch_path, MAX_FILE_PATH, "%s", ua_dataSS->parti_info->ua_subject_name); + snprintf(ua_dataSS->update_delta->ua_patch_info, MAX_FILE_PATH, "%s%s%s", ua_dataSS->parti_info->ua_subject_name, + ua_dataSS->parti_info->ua_parti_name, SS_PATCHLISTFORMAT); + snprintf(ua_dataSS->update_delta->ua_attrib_path, MAX_FILE_PATH, "%s%s%s", ua_dataSS->parti_info->ua_subject_name, + ua_dataSS->parti_info->ua_parti_name, SS_PATCH_ATTR_FORMAT); + LOGL(LOG_SSENGINE, "PatchPath[%s] PatchInfo [%s] Attributes [%s]\n", ua_dataSS->update_delta->ua_patch_path, + ua_dataSS->update_delta->ua_patch_info, ua_dataSS->update_delta->ua_attrib_path); + + return; +} + +//Support functions//Change Struct format details (Can include total file count also???)/*! +/* +******************************************************************************** * +SS_FSSetAttributes + ********************************************************************************* + * *@brief + * This is used to set the file attributes at the end of application of patches in FS + * + * *@param + * + *@return returns S_SS_SUCCESS + * E_SS_FAILURE in case of error + * + ********************************************************************************* + */ +int SS_FSSetAttributes(ua_dataSS_t * ua_dataSS) +{ + char *pline = NULL; + char *psaveptr = NULL; + char *pfilePath = NULL; + char *pfiletype = NULL; + char *attributSize = NULL; + char *pattribs = NULL; + int ulAttribSize = 0; + int result = S_SS_SUCCESS; + int fail_cnt = 0; + + if (!(ua_dataSS && ua_dataSS->update_delta && ua_dataSS->update_data->ua_delta_path)) { + LOGE("Bad params for SS_FSSetAttributes\n"); + SS_SetUpgradeState(E_SS_BAD_PARAMS); + return E_SS_FAILURE; + } + LOGL(LOG_SSENGINE, "ATTRIB PATH: [%s] \n", ua_dataSS->update_delta->ua_attrib_path); + + int item_size = tar_get_item_size(ua_dataSS->update_data->ua_delta_path, ua_dataSS->update_delta->ua_attrib_path); + + if (item_size <= 0) { + LOGL(LOG_SSENGINE, "No Attributes to SET\n"); + return S_SS_SUCCESS; // Delta with ONLY deletes + } + char *item_data = SS_Malloc(item_size + 1); + if (item_data == NULL) { + LOGE("SS_Malloc failed!! - item_data\n"); + SS_SetUpgradeState(E_SS_MALLOC_ERROR); + return E_SS_FAILURE; + } + int read_data = + tar_get_cfg_data(ua_dataSS->update_data->ua_delta_path, ua_dataSS->update_delta->ua_attrib_path, item_data, + item_size); + if (read_data <= 0) { + LOGE("read_data failed!!\n"); + SS_SetUpgradeState(E_SS_FSBADDELTA); + if (item_data != NULL) { + SS_Free(item_data); + item_data = NULL; + } + return E_SS_FAILURE; + } + item_data[read_data] = '\0'; + + pline = strtok_r(item_data, "\n", &psaveptr); + if (pline == NULL) { + LOGL(LOG_SSENGINE, "No Attributes to SET as no lines in file\n"); + if (item_data != NULL) { + SS_Free(item_data); + item_data = NULL; + } + return E_SS_FAILURE; + } + + while (pline) { + char *saveptr_pline = NULL; + pfilePath = strtok_r(pline, "\"", &saveptr_pline); + + if (pfilePath && strcmp(pfilePath, SS_FWSLASH) == 0) { + LOGE("skip root: it is RO\n"); + pline = strtok_r(NULL, SS_TOKEN_NEWLINE, &psaveptr); + continue; + } + + pfiletype = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr_pline); + attributSize = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr_pline); + pattribs = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr_pline); + //LOG("\nSS_FSSetAttributes [%s][%s][%s]", pfiletype, attributSize, pattribs); + if (pattribs && pfilePath && pfiletype && attributSize) { + ulAttribSize = strlen(pattribs); + //LOG("\nSS_SetFileAttributes [%s][%s][%d][%s]",pfilePath,pfiletype,ulAttribSize, pattribs ); + //LOG("SS_SetFileAttributes [%s]\n", pfilePath); + + result = SS_SetFileAttributes(pfilePath, ulAttribSize, (const unsigned char *)pattribs); + if (result != S_SS_SUCCESS) { + LOGE("Failed to set Attributes %s\n", pfilePath); + SS_SetUpgradeState(E_SS_FSBADATTRIBUTES); + if (item_data) { + SS_Free(item_data); + item_data = NULL; + } + fail_cnt++; + } + } else { + LOGE("Failed to Parse Attributes - LINE %s\n", pline); + SS_SetUpgradeState(E_SS_FSBADATTRIBUTES); + if (item_data) { + SS_Free(item_data); + item_data = NULL; + } + fail_cnt++; + } + pline = strtok_r(NULL, SS_TOKEN_NEWLINE, &psaveptr); + } + + if (item_data != NULL) { + SS_Free(item_data); + item_data = NULL; + } + + if (fail_cnt > 0) + result = E_SS_FAILURE; + else + result = S_SS_SUCCESS; + + return result; +} + +/*! + ********************************************************************************* + * SS_FSUpdateFile + ********************************************************************************* + * + * @brief + * This is used to update individual files on case basis + * + * + * @param + * + * @return returns S_SS_SUCCESS + * E_SS_FAILURE in case of error + * + ********************************************************************************* + */ +int SS_FSUpdateFile(int ubFileType, ua_dataSS_t * ua_dataSS, int ulPatchCount, fs_params * pFsNode, + const char *patch_path) +{ + int ulFileIndex = 1; + char ubPatch[SS_MAX_FILE_PATH] = { 0, }; + int ulReadCnt = 0; + int ulResult = S_SS_SUCCESS; + FileInfo source_file; + FileInfo target_file; + uint8_t target_sha1[SHA_DIGEST_SIZE] = { 0, }; + char new_compressed_path[MAX_FILE_PATH], patchfile_source_path[MAX_FILE_PATH]; + snprintf(new_compressed_path, MAX_FILE_PATH, "%s/%s", ua_dataSS->update_data->ua_delta_folder, SS_NEW_COMPRESSED_FILE); + snprintf(patchfile_source_path, MAX_FILE_PATH, "%s/%s", ua_dataSS->update_data->ua_delta_folder, SS_PATCHFILE_SOURCE); + + if (!patch_path) { + LOGE("Bad patch_path name\n"); + return E_SS_FAILURE; + } + switch (ubFileType) { + case DIFFS: + { + LOGL(LOG_SSENGINE, "DIFFS mode start\n"); +#ifdef TIME_PROFILING + get_time_stamp1(); //total time capturing + t1 = atof(ts1); + LOGL(LOG_SSENGINE, "DIFFS mode start time = [%lf]\n", + t1); +#endif + tar_open(ua_dataSS->update_data->ua_delta_path); + while (pFsNode) { + //LOGL(LOG_SSENGINE, "DIFFS update Index: [%d] \n", ulFileIndex++); + snprintf(ubPatch, SS_MAX_FILE_PATH, "%s%s", patch_path, pFsNode->patch_name); + //LOGL(LOG_SSENGINE, "DIFF list --- [File Name %s]\n [Patch Name %s]",pFsNode->file_path, ubPatch); + if (pFsNode->data_size > 0) { + ulReadCnt = + fast_tar_extract_file(ua_dataSS->update_data->ua_delta_path, ubPatch, patchfile_source_path, + pFsNode->data_size, pFsNode->data_offset); + if (ulReadCnt < 0) { + ulResult = E_SS_FAILURE; + tar_close(); + SS_SetUpgradeState(E_SS_FSUPDATEFAILED); + LOGE("Delta Read Failed\n"); + break; + } + //LOGL(LOG_SSENGINE,"Updating [Item - %s]and size is[%d] Read Count[%d]\n",ubPatch, pFsNode->data_size, ulReadCnt); + + if (ulReadCnt > 0) + ulResult = + SS_UpdateDeltaFS(pFsNode->file_old_path, pFsNode->file_new_path, pFsNode->sha1src, + pFsNode->sha1trg, pFsNode->data_size, ua_dataSS->update_data->ua_delta_folder); + if (ulResult != S_SS_SUCCESS) { + LOGE("FS update Failed Result : [%d], [Item - %s]and size is[%d] Read Count[%d], index = [%d]\n", ulResult, + ubPatch, pFsNode->data_size, ulReadCnt, ulFileIndex); + tar_close(); + SS_SetUpgradeState(E_SS_FSUPDATEFAILED); + break; + } + SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0); + pFsNode = pFsNode->nextnode; + } + else { + ulResult = E_SS_FAILURE; + tar_close(); + LOGE("size is invalid, index = [%d]\n", + ulFileIndex); + SS_SetUpgradeState(E_SS_FSUPDATEFAILED); + break; + } + ulFileIndex++; + } + LOGL(LOG_SSENGINE, "DIFFS : Total index = [%d]\n", + ulFileIndex - 1); +#ifdef TIME_PROFILING + get_time_stamp1(); //total time capturing + t2 = atof(ts1); + LOGL(LOG_SSENGINE, + "DIFFS mode end time = [%lf], diff = [%lf]\n", t2, + (t2 - t1)); +#endif + tar_close(); + LOGL(LOG_SSENGINE, "DIFFS mode end\n"); + } + break; + case MOVES: + { + LOGL(LOG_SSENGINE, "MOVES mode start\n"); + +#ifdef TIME_PROFILING + get_time_stamp1(); //total time capturing + t1 = atof(ts1); + LOGL(LOG_SSENGINE, "MOVES mode start time = [%lf]\n", + t1); +#endif + while (pFsNode) { + //LOGL(LOG_SSENGINE, "MOVES update Index: [%d] \n", ulFileIndex++); + int skip_flag = 0; + if (SS_LoadFile(pFsNode->file_old_path, &source_file) == 0) { + LOGL(LOG_SSENGINE, "Patch Can be applied\n"); + if (source_file.data) + SS_Free(source_file.data); + } else if (SS_LoadFile(pFsNode->file_new_path, &target_file) == 0) { + LOGL(LOG_SSENGINE, "source deleted!!, file_old_path: [%s]\n", pFsNode->file_old_path); + if (ParseSha1(pFsNode->sha1src, target_sha1) != 0) { + LOGE("failed to parse sha1 \"%s\"\n", pFsNode->sha1src); + ulResult = E_SS_FAILURE; + SS_SetUpgradeState(E_SS_FSUPDATEFAILED); + if (target_file.data) + SS_Free(target_file.data); + break; + } + if (memcmp(target_file.sha1, target_sha1, SHA_DIGEST_SIZE) == 0) { + LOGL(LOG_SSENGINE, "Patch already applied\n"); + skip_flag = 1; + if (target_file.data) + SS_Free(target_file.data); + } else { + LOGL(LOG_SSENGINE, "target_sha1 diff!!: [%s]\n", target_sha1); + ulResult = E_SS_FAILURE; + SS_SetUpgradeState(E_SS_FSUPDATEFAILED); + if (target_file.data) + SS_Free(target_file.data); + break; + } + } else { + LOGE("No exist files. - file_old_path: [%s] file_new_path: [%s]\n", pFsNode->file_old_path, pFsNode->file_new_path); + ulResult = E_SS_FAILURE; + SS_SetUpgradeState(E_SS_FSUPDATEFAILED); + break; + } + + if (skip_flag == 0) { + ulResult = SS_MoveFile(pFsNode->file_old_path, pFsNode->file_new_path); + if (ulResult != S_SS_SUCCESS) { + LOGE("Move Failed for [%s] to [%s], result = [%d], index = [%d]\n", pFsNode->file_old_path, pFsNode->file_new_path, ulResult, ulFileIndex); + SS_SetUpgradeState(ulResult); + break; + } else { + // Verification + if (SS_LoadFile(pFsNode->file_new_path, &target_file) == 0) { + if (ParseSha1(pFsNode->sha1src, target_sha1) != 0) { + LOGE("failed to parse sha1 \"%s\"\n", pFsNode->sha1src); + ulResult = E_SS_FAILURE; + SS_SetUpgradeState(E_SS_FSUPDATEFAILED); + if (target_file.data) + SS_Free(target_file.data); + break; + } + if (memcmp(target_file.sha1, target_sha1, SHA_DIGEST_SIZE) == 0) { + LOGL(LOG_SSENGINE, "Patch success!!\n"); + if (target_file.data) + SS_Free(target_file.data); + } else { + LOGL(LOG_SSENGINE, "target_sha1 diff!!: [%s]\n", target_sha1); + ulResult = E_SS_FAILURE; + SS_SetUpgradeState(E_SS_FSUPDATEFAILED); + if (target_file.data) + SS_Free(target_file.data); + break; + } + } + } + } + SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0); + pFsNode = pFsNode->nextnode; + ulFileIndex++; + } + LOGL(LOG_SSENGINE, "MOVES : Total index = [%d]\n", + ulFileIndex - 1); +#ifdef TIME_PROFILING + get_time_stamp1(); //total time capturing + t2 = atof(ts1); + LOGL(LOG_SSENGINE, + "MOVES mode end time = [%lf], diff = [%lf]\n", t2, + (t2 - t1)); +#endif + LOGL(LOG_SSENGINE, "MOVES mode end\n"); + } + break; + case DELETES: + { + LOGL(LOG_SSENGINE, "DELETES mode start\n"); + + int ulFiletype = 0; +#ifdef TIME_PROFILING + get_time_stamp1(); //total time capturing + t1 = atof(ts1); + LOGL(LOG_SSENGINE, "DELETES mode start time = [%lf]\n", + t1); +#endif + while (pFsNode) { + if (pFsNode->type == DELETES) { + //LOGL(LOG_SSENGINE, "DELETES update Index: [%d] \n", ulFileIndex++); + SS_GetFileType(pFsNode->file_old_path, (enumFileType *) & ulFiletype); + if (ulFiletype == 2) //FT_FOLDER + ulResult = SS_DeleteFolder(pFsNode->file_old_path); + else + ulResult = SS_DeleteFile(pFsNode->file_old_path); + if (ulResult != S_SS_SUCCESS) { + LOGE("Delete Failed, result = [%d], index = [%d]\n", ulResult, ulFileIndex); + SS_SetUpgradeState(ulResult); + break; + } + ulFileIndex++; + } + SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0); + pFsNode = pFsNode->nextnode; + } + LOGL(LOG_SSENGINE, "DELETES : Total index = [%d]\n", + ulFileIndex - 1); +#ifdef TIME_PROFILING + get_time_stamp1(); //total time capturing + t2 = atof(ts1); + LOGL(LOG_SSENGINE, + "DELETES mode end time = [%lf], diff = [%lf]\n", + t2, (t2 - t1)); +#endif + LOGL(LOG_SSENGINE, "DELETES mode end\n"); + } + break; + case DELETE_END: + { + LOGL(LOG_SSENGINE, "DELETE_END mode start\n"); + + int ulFiletype = 0; +#ifdef TIME_PROFILING + get_time_stamp1(); //total time capturing + t1 = atof(ts1); + LOGL(LOG_SSENGINE, + "DELETE_END mode start time = [%lf]\n", t1); +#endif + while (pFsNode) { + if (pFsNode->type == DELETE_END) { + LOGL(LOG_SSENGINE, "DELETE_END update Index: [%d] \n", ulFileIndex++); + SS_GetFileType(pFsNode->file_old_path, (enumFileType *) & ulFiletype); + if (ulFiletype == 2) //FT_FOLDER + ulResult = SS_DeleteFolder(pFsNode->file_old_path); + else + ulResult = SS_DeleteFile(pFsNode->file_old_path); + if (ulResult != S_SS_SUCCESS) { + LOGE("Delete Failed, result = [%d], index = [%d]\n", ulResult, ulFileIndex); + SS_SetUpgradeState(ulResult); + break; + } + ulFileIndex++; + } + pFsNode = pFsNode->nextnode; + } + LOGL(LOG_SSENGINE, "DELETE_END : Total index = [%d]\n", + ulFileIndex - 1); +#ifdef TIME_PROFILING + get_time_stamp1(); //total time capturing + t2 = atof(ts1); + LOGL(LOG_SSENGINE, + "DELETE_END mode start time = [%lf], diff = [%lf]\n", + t2, (t2 - t1)); +#endif + LOGL(LOG_SSENGINE, "DELETE_END mode end\n"); + } + break; + + case NEWFILES: + { + LOGL(LOG_SSENGINE, "NEWFILES mode start\n"); + +#ifdef TIME_PROFILING + get_time_stamp1(); //total time capturing + t1 = atof(ts1); + LOGL(LOG_SSENGINE, "NEWFILES mode start time = [%lf]\n", + t1); +#endif + LOGL(LOG_SSENGINE, "Starting New file upgrade for [%s]\n", patch_path); + if (tar_extract_file(ua_dataSS->update_data->ua_delta_path, (char *)patch_path, new_compressed_path) >= + 0) + if (_7zdecompress(new_compressed_path) == 0) + LOGL(LOG_SSENGINE, "7zip extracted successfully %s\n", ua_dataSS->parti_info->ua_parti_name); + else + LOGL(LOG_SSENGINE, "7zip extraction error for %s\n", ua_dataSS->parti_info->ua_parti_name); + else + LOGL(LOG_SSENGINE, "tar extraction error for %s\n", ua_dataSS->parti_info->ua_parti_name); + SS_DeleteFile(new_compressed_path); +#ifdef TIME_PROFILING + get_time_stamp1(); //total time capturing + t2 = atof(ts1); + LOGL(LOG_SSENGINE, + "NEWFILES mode end time = [%lf], diff = [%lf]\n", + t2, (t2 - t1)); +#endif + LOGL(LOG_SSENGINE, "NEWFILES mode end\n"); + } + break; + case SYMDIFFS: + { + LOGL(LOG_SSENGINE, "SYMDIFFS mode start\n"); + +#ifdef TIME_PROFILING + get_time_stamp1(); //total time capturing + t1 = atof(ts1); + LOGL(LOG_SSENGINE, "SYMDIFFS mode start time = [%lf]\n", + t1); +#endif + while (pFsNode) { + //LOGL(LOG_SSENGINE, "SYMDIFFS update Index: [%d] \n", ulFileIndex++); + //LOG("Sym Diff file paths: [Linkname - %s] [reference file name- %s][]\n", pFsNode->file_path,pFsNode->patch_name); + ulResult = SS_Unlink(pFsNode->file_old_path); + if (ulResult == S_SS_SUCCESS) { + ulResult = SS_Link(NULL, pFsNode->file_new_path, pFsNode->patch_name); + if (ulResult != S_SS_SUCCESS) { + LOGE("SS_Link Failed, Linkname:[%s], reference file name, index = [%d]:[%s]\n", + pFsNode->file_new_path, ulFileIndex, pFsNode->patch_name); + } + } else { + LOGE("Unlink Failed, result = [%d], index = [%d]\n", ulResult, ulFileIndex); + SS_SetUpgradeState(E_SS_FSUPDATEFAILED); + break; + } + SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0); + pFsNode = pFsNode->nextnode; + ulFileIndex++; + } + LOGL(LOG_SSENGINE, "SYMDIFFS : Total index = [%d]\n", + ulFileIndex - 1); +#ifdef TIME_PROFILING + get_time_stamp1(); //total time capturing + t2 = atof(ts1); + LOGL(LOG_SSENGINE, + "SYMDIFFS mode end time = [%lf], diff = [%lf]\n", + t2, (t2 - t1)); +#endif + LOGL(LOG_SSENGINE, "SYMDIFFS mode end\n"); + } + break; + case SYMNEWFILES: + { + LOGL(LOG_SSENGINE, "SYMNEWFILES mode start\n"); + + fs_params *head_node; + int retry_count = 0, do_retry = 0; +#ifdef TIME_PROFILING + get_time_stamp1(); //total time capturing + t1 = atof(ts1); + LOGL(LOG_SSENGINE, + "SYMNEWFILES mode start time = [%lf]\n", t1); +#endif + SYMLINK_CREATE: + head_node = pFsNode; + while (head_node) { + //LOGL(LOG_SSENGINE, "SYMNEWS update Index: [%d] \n", ulFileIndex++); + snprintf(ubPatch, SS_MAX_FILE_PATH, "%s%s%s", patch_path, "/", head_node->patch_name); + LOGL(LOG_SSENGINE, "Sym New file paths: [Linkname - %s] [reference file name- %s][]\n", + head_node->file_old_path, head_node->patch_name); + ulResult = SS_Link(NULL, head_node->file_old_path, head_node->patch_name); + if (ulResult == E_SS_FAILURE) { + LOGE("Link Failed, result = [%d], index = [%d]\n", ulResult, ulFileIndex); + SS_SetUpgradeState(E_SS_FSUPDATEFAILED); + break; + } else if (ulResult == ENOENT) { //to handle cases where new symlink points to a new symlink yet to be created + do_retry = 1; //we will retry the failed symlinks with error 2 (no file or dir) again after this cycle + //SS_UpdateUIProgress(ua_dataSS,ulPatchCount); + head_node = head_node->nextnode; + continue; + } + SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0); + head_node = head_node->nextnode; + ulFileIndex++; + } + LOGL(LOG_SSENGINE, "SYMNEWFILES : Total index = [%d]\n", + ulFileIndex - 1); + if (do_retry && (retry_count < 4)) { + retry_count++; + ulFileIndex = 0; + do_retry = 0; + goto SYMLINK_CREATE; + } else if (do_retry && (retry_count >= 4)) { //retry to be done maximum 4 times + LOGE("Link Failed after %d retrys\n", retry_count); + //SS_SetUpgradeState(E_SS_FSUPDATEFAILED); + break; + } +#ifdef TIME_PROFILING + get_time_stamp1(); //total time capturing + t2 = atof(ts1); + LOGL(LOG_SSENGINE, + "SYMNEWFILES mode end time = [%lf], diff = [%lf]\n", + t2, (t2 - t1)); +#endif + LOGL(LOG_SSENGINE, "SYMNEWFILES mode end\n"); + } + break; + case HARDDIFFS: + { + LOGL(LOG_SSENGINE, "HARDDIFFS mode start\n"); + +#ifdef TIME_PROFILING + get_time_stamp1(); //total time capturing + t1 = atof(ts1); + LOGL(LOG_SSENGINE, "HARDDIFFS mode start time = [%lf]\n", + t1); +#endif + while (pFsNode) { + //LOGL(LOG_SSENGINE, "SYMDIFFS update Index: [%d] \n", ulFileIndex++); + //LOG("Sym Diff file paths: [Linkname - %s] [reference file name- %s][]\n", pFsNode->file_path,pFsNode->patch_name); + ulResult = SS_DeleteFile(pFsNode->file_old_path); + if (ulResult == S_SS_SUCCESS) { + ulResult = SS_HardLink(pFsNode->file_new_path, pFsNode->patch_name); + if (ulResult != S_SS_SUCCESS) { + LOGE("SS_HardLink Failed, Linkname:[%s], reference file name, index = [%d]:[%s]\n", + pFsNode->file_new_path, ulFileIndex, pFsNode->patch_name); + } + } else { + LOGE("Removing old hardlink Failed, result = [%d], index = [%d]\n", ulResult, ulFileIndex); + SS_SetUpgradeState(E_SS_FSUPDATEFAILED); + break; + } + SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0); + pFsNode = pFsNode->nextnode; + ulFileIndex++; + } + LOGL(LOG_SSENGINE, "HARDDIFFS : Total index = [%d]\n", + ulFileIndex - 1); +#ifdef TIME_PROFILING + get_time_stamp1(); //total time capturing + t2 = atof(ts1); + LOGL(LOG_SSENGINE, + "HARDDIFFS mode end time = [%lf], diff = [%lf]\n", + t2, (t2 - t1)); +#endif + LOGL(LOG_SSENGINE, "HARDDIFFS mode end\n"); + } + break; + case HARDNEWFILES: + { + LOGL(LOG_SSENGINE, "HARDNEWFILES mode start\n"); + +#ifdef TIME_PROFILING + get_time_stamp1(); //total time capturing + t1 = atof(ts1); + LOGL(LOG_SSENGINE, + "HARDNEWFILES mode start time = [%lf]\n", t1); +#endif + fs_params *head_node = pFsNode; + while (head_node) { + //LOGL(LOG_SSENGINE, "SYMNEWS update Index: [%d] \n", ulFileIndex++); + LOGL(LOG_SSENGINE, "Hardlink New file paths: [Linkname - %s] [reference file name- %s][]\n", + head_node->file_old_path, head_node->patch_name); + ulResult = SS_HardLink(head_node->file_old_path, head_node->patch_name); + if (ulResult == E_SS_FAILURE) { + LOGE("Link Failed, result = [%d], index = [%d]\n", ulResult, ulFileIndex); + SS_SetUpgradeState(E_SS_FSUPDATEFAILED); + break; + } + SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0); + head_node = head_node->nextnode; + ulFileIndex++; + } + LOGL(LOG_SSENGINE, "HARDNEWFILES : Total index = [%d]\n", + ulFileIndex - 1); + +#ifdef TIME_PROFILING + get_time_stamp1(); //total time capturing + t2 = atof(ts1); + LOGL(LOG_SSENGINE, + "HARDNEWFILES mode end time = [%lf], diff = [%lf]\n", + t2, (t2 - t1)); +#endif + LOGL(LOG_SSENGINE, "HARDNEWFILES mode end\n"); + + } + break; + default: + break; + } + return ulResult; +} + +#ifdef MEM_PROFILING +extern int max_mem; +extern int cur_mem; +#endif +/*! + ********************************************************************************* + * SS_FSUpdatemain + ********************************************************************************* + * + * @brief + * This is the API exposed from the engine to update FS. + * + * + * @param + * + * @return returns S_SS_SUCCESS + * E_SS_FAILURE in case of error + * + ********************************************************************************* + */ + +int SS_FSUpdatemain(ua_dataSS_t * ua_dataSS) +{ + int ulResult = S_SS_SUCCESS; + int last_update_status = 0; + int del_type = 0; + fs_list *head_ptr_node = NULL; + char new_patch_path[SS_MAX_FILE_PATH] = { + 0 + }; + char status_path[MAX_FILE_PATH]; + snprintf(status_path, MAX_FILE_PATH, "%s/%s",ua_dataSS->update_data->ua_delta_folder, SS_UPDATE_STATUS_PATH); + + if (!ua_dataSS) + return E_SS_BAD_PARAMS; // Set error ?? + head_ptr_node = headptr_list; + + if (!head_ptr_node) { //in case of power failure, try rebilding nodes again + SS_FSVerifyPartition(ua_dataSS); + head_ptr_node = headptr_list; + } + + if (!head_ptr_node) + return E_SS_FSBADNODES; + + SS_GetPartition_LocDetails(ua_dataSS); + + LOGL(LOG_SSENGINE, "FS Update Entry\n"); + +#ifdef POWER_FAIL_TEST + int fail_test_flag = 0; + fail_test_flag = SS_Get_power_fail_flag(); + LOGL(LOG_SSENGINE, "fail_test_flag: [%d]\n", fail_test_flag); +#endif + + if(SS_Get_last_update_status(&last_update_status, &del_type, status_path) == -1) + LOGE("SS_Get_last_update_status failed!!\n"); + + LOGL(LOG_SSENGINE, "last_update_status: [%d], del_type: [%d]\n", last_update_status, del_type); + + // for now, we don't want to read last del_type as the logic doesn't work + del_type = 0; + + if (head_ptr_node->del_ref == NULL) { + LOGL(LOG_SSENGINE, "No DEL header\n"); + } else if (ulResult == S_SS_SUCCESS) { + if (del_type < DELETES) { + ulResult = SS_FSUpdateFile(DELETES, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->del_ref, + ua_dataSS->update_delta->ua_patch_path); + if (ulResult == S_SS_SUCCESS) { + LOGL(LOG_SSENGINE, "SS_FSUpdateFile - DELETES success!!\n"); + +#ifdef POWER_FAIL_TEST + if (fail_test_flag < DELETES) { + if (SS_Do_Power_fail_test(DELETES) == E_SS_FAILURE) { + LOGE("SS_Do_Power_fail_test failed!!\n"); + } + } +#endif + SS_Set_last_update_status(0, DELETES, status_path); + } + } else { + LOGL(LOG_SSENGINE, "SS_FSUpdateFile - DELETES already applied!!\n"); + } + } + + if (head_ptr_node->dif_ref == NULL) { + LOGL(LOG_SSENGINE, "No DIFF header\n"); + } else if (ulResult == S_SS_SUCCESS) { + ulResult = + SS_FSUpdateFile(DIFFS, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->dif_ref, + ua_dataSS->update_delta->ua_patch_path); + if (ulResult == S_SS_SUCCESS) { + LOGL(LOG_SSENGINE, "SS_FSUpdateFile - DIFFS success!!\n"); +#ifdef POWER_FAIL_TEST + if (fail_test_flag < DIFFS) { + if (SS_Do_Power_fail_test(DIFFS) == E_SS_FAILURE) { + LOGE("SS_Do_Power_fail_test failed!!\n"); + } + } +#endif + } + } + + if (head_ptr_node->move_ref == NULL) { + LOGL(LOG_SSENGINE, "No MOVE header\n"); + } else if (ulResult == S_SS_SUCCESS) { + if (del_type < MOVES) { + ulResult = + SS_FSUpdateFile(MOVES, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->move_ref, + ua_dataSS->update_delta->ua_patch_path); + if (ulResult == S_SS_SUCCESS) { + LOGL(LOG_SSENGINE, "SS_FSUpdateFile - MOVES success!!\n"); +#ifdef POWER_FAIL_TEST + if (fail_test_flag < MOVES) { + if (SS_Do_Power_fail_test(MOVES) == E_SS_FAILURE) { + LOGE("SS_Do_Power_fail_test failed!!\n"); + } + } +#endif + SS_Set_last_update_status(0, MOVES, status_path); + } + } else { + LOGL(LOG_SSENGINE, "SS_FSUpdateFile - MOVES already applied!!\n"); + } + } + + if (head_ptr_node->del_ref == NULL) { + LOGL(LOG_SSENGINE, "No DEL header\n"); + } else if (ulResult == S_SS_SUCCESS) { + if (del_type < DELETE_END) { + ulResult = SS_FSUpdateFile(DELETE_END, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->del_ref, + ua_dataSS->update_delta->ua_patch_path); + if (ulResult == S_SS_SUCCESS) { + LOGL(LOG_SSENGINE, "SS_FSUpdateFile - DELETE_END success!!\n"); +#ifdef POWER_FAIL_TEST + if (fail_test_flag < DELETE_END) { + if (SS_Do_Power_fail_test(DELETE_END) == E_SS_FAILURE) { + LOGE("SS_Do_Power_fail_test failed!!\n"); + } + } +#endif + SS_Set_last_update_status(0, DELETE_END, status_path); + } + } else { + LOGL(LOG_SSENGINE, "SS_FSUpdateFile - DELETE_END already applied!!\n"); + } + } + + if (ulResult == S_SS_SUCCESS) { + //new file extraction start + snprintf(new_patch_path, SS_MAX_FILE_PATH, "%s%s", ua_dataSS->parti_info->ua_subject_name, SS_COMPRESSED_FILE); // subject name wil have fw slash as part of cfg file + LOGL(LOG_SSENGINE, "File path created to extract new files : [%s]\n", new_patch_path); + ulResult = + SS_FSUpdateFile(NEWFILES, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->new_ref, new_patch_path); + //new file extraction end + if (ulResult == S_SS_SUCCESS) { + LOGL(LOG_SSENGINE, "SS_FSUpdateFile - NEWFILES success!!\n"); + } + } + + if (head_ptr_node->sym_difref == NULL) { + LOGL(LOG_SSENGINE, "No SYMDIFF header\n"); + } else if (ulResult == S_SS_SUCCESS) { + ulResult = + SS_FSUpdateFile(SYMDIFFS, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->sym_difref, + ua_dataSS->update_delta->ua_patch_path); + if (ulResult == S_SS_SUCCESS) { + LOGL(LOG_SSENGINE, "SS_FSUpdateFile - SYMDIFFS success!!\n"); +#ifdef POWER_FAIL_TEST + if (fail_test_flag < SYMDIFFS) { + if (SS_Do_Power_fail_test(SYMDIFFS) == E_SS_FAILURE) { + LOGE("SS_Do_Power_fail_test failed!!\n"); + } + } +#endif + } + } + + if (head_ptr_node->sym_newref == NULL) { + LOGL(LOG_SSENGINE, "No SYMNEW header\n"); + } else if (ulResult == S_SS_SUCCESS) { + ulResult = + SS_FSUpdateFile(SYMNEWFILES, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->sym_newref, + ua_dataSS->update_delta->ua_patch_path); + if (ulResult == S_SS_SUCCESS) { + LOGL(LOG_SSENGINE, "SS_FSUpdateFile - SYMNEWFILES success!!\n"); +#ifdef POWER_FAIL_TEST + if (fail_test_flag < SYMNEWFILES) { + if (SS_Do_Power_fail_test(SYMNEWFILES) == E_SS_FAILURE) { + LOGE("SS_Do_Power_fail_test failed!!\n"); + } + } +#endif + } + } + + if (head_ptr_node->hard_newref == NULL) { + LOGL(LOG_SSENGINE, "No HARDNEW header\n"); + } else if (ulResult == S_SS_SUCCESS) { + ulResult = + SS_FSUpdateFile(HARDNEWFILES, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->hard_newref, + ua_dataSS->update_delta->ua_patch_path); + if (ulResult == S_SS_SUCCESS) { + LOGL(LOG_SSENGINE, "SS_FSUpdateFile - HARDNEWFILES success!!\n"); +#ifdef POWER_FAIL_TEST + if (fail_test_flag < HARDNEWFILES) { + if (SS_Do_Power_fail_test(HARDNEWFILES) == E_SS_FAILURE) { + LOGE("SS_Do_Power_fail_test failed!!\n"); + } + } +#endif + } + } + + if (head_ptr_node->hard_difref == NULL) { + LOGL(LOG_SSENGINE, "No HARDDIFF header\n"); + } else if (ulResult == S_SS_SUCCESS) { + ulResult = + SS_FSUpdateFile(HARDDIFFS, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->hard_difref, + ua_dataSS->update_delta->ua_patch_path); + if (ulResult == S_SS_SUCCESS) { + LOGL(LOG_SSENGINE, "SS_FSUpdateFile - HARDDIFFs success!!\n"); +#ifdef POWER_FAIL_TEST + if (fail_test_flag < HARDDIFFS) { + if (SS_Do_Power_fail_test(HARDDIFFS) == E_SS_FAILURE) { + LOGE("SS_Do_Power_fail_test failed!!\n"); + } + } +#endif + } + } + + if (ulResult == S_SS_SUCCESS) { + ulResult = SS_FSSetAttributes(ua_dataSS); + } else { + SS_FSSetAttributes(ua_dataSS); // To prevent boot failures by smack. + } + + sync(); + sleep(1); + SS_FSClearNodes(); + + if (ulResult == S_SS_SUCCESS) { + SS_UpdateUIProgress(ua_dataSS, 0, 1); //fix WGID : 51963, When all updates are done to FS , patchcount is not needed, passing 1 to 3rd arg is enough + SS_Set_last_update_status(0, DEL_TYPE_MAX, status_path); + } + + LOGL(LOG_SSENGINE, "FS update Complete\n"); +#ifdef MEM_PROFILING + LOGL(LOG_SSENGINE, "Stats are : Cur Max : [%d] Global Max : [%d]\n", cur_mem, max_mem); +#endif +#ifdef POWER_FAIL_TEST + unlink(SS_POWER_FAIL_TEST_FLAG); +#endif + if (ulResult == S_SS_SUCCESS) + return ulResult; + else + return SS_GetUpgradeState(); +} + +/*! + ********************************************************************************* + * SS_FSUpdatemain + ********************************************************************************* + * + * @brief + * This is the API exposed from the engine to update FS. + * FS entry function for updating FS partition. Should be invoked only after verification of the partition + * + * + * @param Requires common data structure having all details & Partition Index. + * (Used for getting right NODES information that built during verification) + * (Configuration, Delta info, Partition Info, UI link , Kind of operation.(Verify or Updates)) + * + * @return returns S_SS_SUCCESS + * E_SS_FAILURE in case of error + * + ********************************************************************************* + */ +size_t SS_FSAvailiableFreeSpace(char *block_name) +{ + + struct mntent *ent; + FILE *aFile; + struct statfs sb; + aFile = setmntent("/proc/mounts", "r"); + if (aFile == NULL) { + LOGE("setmntent error\n"); + return E_SS_FAILURE; + } + while (NULL != (ent = getmntent(aFile))) { + if (strcmp(ent->mnt_fsname, block_name) == 0) { + if (statfs(ent->mnt_dir, &sb) == 0) + LOGL(LOG_SSENGINE, "Total free space = %" PRIu64 ", blocks free = %" PRIu64 "\n", sb.f_bsize * sb.f_bavail, sb.f_bfree); + } + } + endmntent(aFile); + return ((long long)sb.f_bsize * (long long)sb.f_bavail >= (long long)SIZE_4GB) ? SIZE_4GB : sb.f_bsize * sb.f_bavail ; +} + +int SS_FSVerifyPartition(ua_dataSS_t * ua_dataSS) +{ + int ulResult = S_SS_SUCCESS; + if (!ua_dataSS) { + LOGE("Wrong Param for fs verification\n"); + SS_SetUpgradeState(E_SS_BAD_PARAMS); + return E_SS_FAILURE; + } + +#ifdef MEM_PROFILING + if (!mem_profiling_start) + if (!(S_SS_SUCCESS == SS_Do_Memory_Profiling())) + return E_SS_FAILURE; +#endif + SS_GetPartition_LocDetails(ua_dataSS); + LOGL(LOG_SSENGINE, "FS Verification Start\n"); + if (ua_dataSS->ua_operation == UI_OP_SCOUT) + gvalid_session = 1; // (shd b true if called during verification) + headptr_list = SS_FSBuildNodes(ua_dataSS); +#ifdef TIME_PROFILING + LOGL(LOG_SSENGINE, "fast_tar_get_item_size_time :[%lf]\n", fast_tar_get_item_size_time); + LOGL(LOG_SSENGINE, "SS_LoadFile_time :[%lf]\n", SS_LoadFile_time); + LOGL(LOG_SSENGINE, "SS_FSBuildNodes_time :[%lf]\n", SS_FSBuildNodes_time); +#endif + if (!headptr_list) { + LOGE("FS Verification Failed\n"); + SS_FSClearNodes(); + ulResult = E_SS_FAILURE; + } + + if (ulResult == S_SS_SUCCESS) + return ulResult; + else + return SS_GetUpgradeState(); +} + +//Should check if space is available???? +int SS_BackupSource(const char *source_filename, char *backup_path) +{ + int ret = E_SS_FAILURE; + + if (source_filename) { + ret = (int)SS_CopyFile(source_filename, backup_path); + if (ret != S_SS_SUCCESS) { + LOGE("failed to back up source file Error [%d]\n", ret); + SS_SetUpgradeState(E_SS_FSSRCBACKUPFAILED); + } + } + return ret; +} + +int SS_BackupSourceClear(char *backup_path) +{ + int ret = E_SS_FAILURE; + ret = (int)SS_DeleteFile(backup_path); + if (ret != S_SS_SUCCESS) { + LOGE("failed to delete BACKUP file\n"); + SS_SetUpgradeState(E_SS_FSSRCBACKUPFAILED); + } + return ret; +} + +int SS_PatchSourceClear(char *patch_path) +{ + int ret = E_SS_FAILURE; + ret = (int)SS_DeleteFile(patch_path); + if (ret != S_SS_SUCCESS) { + LOGE("failed to delete PATCHFILE file\n"); + SS_SetUpgradeState(E_SS_PATCHFILE_DEL_ERROR); + } + return ret; +} + +long SS_GetUPIVersion(unsigned char *ver_str) +{ + if (ver_str) { + strncpy((char *)ver_str, SS_TOTA_VERSION, MAX_PATH); +#ifdef MEM_PROFILING + if (!mem_profiling_start) + if (!(S_SS_SUCCESS == SS_Do_Memory_Profiling())) + LOGE("Unable to start Memory_Profiling\n"); +#endif + return S_SS_SUCCESS;//wgid: 2456 + } else + return E_SS_FAILURE; +} \ No newline at end of file diff --git a/src/upgrade-apply-deltafs/engine/SS_UPI.h b/src/upgrade-apply-deltafs/engine/SS_UPI.h new file mode 100755 index 0000000..b9cb744 --- /dev/null +++ b/src/upgrade-apply-deltafs/engine/SS_UPI.h @@ -0,0 +1,91 @@ +/* + * upgrade-apply-deltafs + * + * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _SS_UPI_H_ +#define _SS_UPI_H_ +#include +#include "fota_common.h" + +#define DISPLAYRESOLUTION_SIZE 50 + +struct details { + int diffs; + int moves; + int news; + int deletes; + int symdiffs; + int symnews; + int harddiffs; + int hardnews; +}; + +enum DEL_TYPE { DELETES = 1, DIFFS, MOVES, DELETE_END, NEWFILES, SYMDIFFS, SYMNEWFILES, HARDDIFFS, HARDNEWFILES, DEL_TYPE_MAX }; +struct fs_params { // Use Macros + char file_old_path[512]; + char file_new_path[512]; + char patch_name[256]; + char sha1src[64]; + char sha1trg[64]; + int data_size; + int data_offset; + int type; //0 is for diff and 1 is for verbatim + struct fs_params *nextnode; +}; +typedef struct fs_params fs_params; + +struct fs_list { + fs_params *dif_ref; + fs_params *move_ref; + fs_params *new_ref; + fs_params *del_ref; + fs_params *sym_difref; + fs_params *sym_newref; + fs_params *hard_difref; + fs_params *hard_newref; + int ulPatchCount; +}; +typedef struct fs_list fs_list; + +int SS_AppendNode(const char *ubDeltaPath, fs_params ** headparam, fs_params ** tailparam, const char *old_path, + const char *new_path, const char *patchname, const char *sha1src, const char *sha1trg, int type, + char *patchpath_name); +long SS_GetUPIVersion(unsigned char *ver_str); +extern int SS_FSUpdatemain(ua_dataSS_t * ua_dataSS); +extern int SS_FSVerifyPartition(ua_dataSS_t * ua_dataSS); + +//extra functions +extern void *SS_Malloc(unsigned int size); +extern int tar_get_item_size_from_struct(tar_Data_t **, const char *, int *, int *); +extern void SS_Free(void *pMemBlock); +extern int tar_get_item_size(char *tar, char *item); +extern int tar_get_cfg_data(char *tar, char *item, char *buf, int buflen); +extern tar_Data_t *tar_build_cfg_table(char *tar); +extern int tar_open(char *tar); +extern int fast_tar_extract_file(char *tar, char *item, char *pathname, int size, int offset); +extern int tar_close(); +extern int SS_UpdateDeltaFS(const char *source_filename, const char *target_filename, + const char *source_sha1_str, const char *target_sha1_str, int patch_data_size, char *delta_folder); +extern int tar_extract_file(char *tar, char *item, char *pathname); +extern int _7zdecompress(char *path); +extern void tar_free_cfg_table(tar_Data_t ** delta_tar); +extern long SS_GetFileType(char *pLinkName, enumFileType * fileType); + +extern int SS_Get_last_update_status(int* last_update_status, int* del_type, char *status_path); +extern void SS_Set_last_update_status(int last_update_status, int del_type, char *status_path); + +#endif //_SS_UPI_H_ diff --git a/src/upgrade-apply-deltafs/engine/fota_common.h b/src/upgrade-apply-deltafs/engine/fota_common.h new file mode 100755 index 0000000..38a6ec9 --- /dev/null +++ b/src/upgrade-apply-deltafs/engine/fota_common.h @@ -0,0 +1,105 @@ +/* + * upgrade-apply-deltafs + * + * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __FOTA_COMMON_H__ +#define __FOTA_COMMON_H__ + +#include +#include "fota_log.h" + +typedef unsigned int u32; +#ifndef __size_t /* typedef check for x86 env: stddef.h */ +#define __size_t +typedef u32 size_t; +#endif /* __size_t */ + +#define MAX_FILE_PATH 512 + +#ifndef TIME_PROFILING + //#define TIME_PROFILING +#endif +#ifndef HEAP_PROFILING + //#define HEAP_PROFILING; +#endif +#ifndef MEM_PROFILING + //#define MEM_PROFILING +#endif +#ifndef POWER_FAIL_TEST + //#define POWER_FAIL_TEST +#endif + +#define UNUSED(x) (void)(x) + +#define SS_TOTA_VERSION "1.0.19" +#define BSDIFF "BSDIFF40" +#define IMGDIFF "IMGDIFF2" +#define SECTOR_SIZE 512F +#define SS_KERNEL_DELTA_HEADER 128 + +#define SS_BACKUP_SOURCE "/saved.file" //How to make sure there is SPACE +#define SS_PATCHFILE_SOURCE "/patchfile.file" //define in common place +#define SS_PATCHLIST_BKUPLOC "/patchlist.txt" +#define SS_NEW_COMPRESSED_FILE "/system.7z" +#define SS_UPDATE_STATUS_PATH "/UP.STATUS" + +#define SS_PATCHLISTFORMAT ".txt" +#define SS_PATCH_ATTR_FORMAT "_attr.txt" +#define SS_FSCOUNT_MAGIC_KEY "PaTcHCoUnT:" +#define SS_FSCOUNT_MAGIG_KEYLEN (11) //length of SS_FSCOUNT_MAGIC_KEY + +#define SS_TOKEN_SPACE " " +#define SS_TOKEN_NEWLINE "\n" +#define SS_TOEKN_COLON ":" +#define SS_FWSLASH "/" +#define SS_NULLENTRY "0" +#define SS_MAX_NAMELENSUPPORTED (200) //(Tar supports 256, But extra space is used for PartitionName, .delta, /p, so restricting filename max to 200) +#define SS_MAX_FILE_PATH (512) +#define SS_TOKEN_MAXLINE_LEN (1024) +#define SS_COMPRESSED_FILE "system.7z" + +#define SS_STRING_DIFF "DIFF" +#define SS_STRING_MOVE "MOVE" +#define SS_STRING_DEL "DEL" +#define SS_STRING_SYM "SYM" +#define SS_STRING_HARD "HARD" +#define SS_STRING_NEW "NEW" +#define SS_STRING_REG "REG" +#define SS_STRING_TPK "TPK" +#define SS_STRING_ZIP "ZIP" +#define SS_STRING_END "END" + +#define SS_COMMON_WORKSPACE "/run/upgrade-sysroot/opt/usr/data/fota" + +#ifdef MEM_PROFILING +#define SS_MEMORY_USAGE_LOG SS_COMMON_WORKSPACE "/log_memory" +#define SS_MEMORY_PROFILING_SCRIPT SS_COMMON_WORKSPACE "/mem_use.sh" +#endif + +#ifdef POWER_FAIL_TEST +#define SS_POWER_FAIL_TEST_FLAG SS_COMMON_WORKSPACE "/power_fail_test_flag" +#endif + +struct tar_Data { + int itemSize; + int itemOffset; + int itemName[256]; + struct tar_Data *nextnode; +}; +typedef struct tar_Data tar_Data_t; + +#endif /* __FOTA_COMMON_H__ */ diff --git a/src/upgrade-apply-deltafs/engine/fota_log.c b/src/upgrade-apply-deltafs/engine/fota_log.c new file mode 100755 index 0000000..93c42ed --- /dev/null +++ b/src/upgrade-apply-deltafs/engine/fota_log.c @@ -0,0 +1,168 @@ +/* + * upgrade-apply-deltafs + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOG_SIZE_OPT_PATH "/opt/data/recovery/.ua_log_size" +#define DEF_MAX_LOG_SIZE (2*1024*1024) +#define MAX_FILE_PATH 512 + +long curr_offset = 0; +long next_offset = 0; +long backup_offset = 0; +long max_logfile_size = DEF_MAX_LOG_SIZE; + +/*----------------------------------------------------------------------------- + __check_existence + ----------------------------------------------------------------------------*/ +static long __check_existence(const char *file_path) +{ + struct stat statbuf; + char filename[MAX_FILE_PATH]; + + if (strncpy(filename, file_path, strlen(file_path) + 1) == NULL) + return 0; + if (stat(filename, &statbuf)) { + if (ENOENT == errno) + return 0; + } + return statbuf.st_size; +} + +/*----------------------------------------------------------------------------- + __read_from_file + ----------------------------------------------------------------------------*/ +static int __read_from_file(const char *path, char *buf, size_t size) +{ + int fd; + ssize_t count; + + if (!path) + return -1; + + if (size == 0) + return 0; + + fd = open(path, O_RDONLY, 0); + if (fd == -1) + return -1; + + count = read(fd, buf, size); + if (count > 0) { + count = (count < (ssize_t)size) ? count : ((ssize_t)size - 1); + while (count > 0 && buf[count - 1] == '\n') + count--; + buf[count] = '\0'; + } else { + buf[0] = '\0'; + } + + close(fd); + + return (int)count; +} + +/*----------------------------------------------------------------------------- + get_opt_logfile_size + ----------------------------------------------------------------------------*/ +static int get_opt_logfile_size(void) +{ + /* + if status file does not exist, status = UP_START_NONE. + if status file exist, read status from file. + */ + char buf[256]; + + if (__check_existence(LOG_SIZE_OPT_PATH) == 0) + return -1; + + if (__read_from_file(LOG_SIZE_OPT_PATH, buf, sizeof(buf)) < 0) + return -1; + + return atoi(buf); +} + +/*----------------------------------------------------------------------------- + set_max_logfile_size + ----------------------------------------------------------------------------*/ +void set_max_logfile_size(void) +{ + int size = get_opt_logfile_size(); + + if (size <= 0) + size = DEF_MAX_LOG_SIZE; + + max_logfile_size = size; +} + +/*----------------------------------------------------------------------------- + log_printf + ----------------------------------------------------------------------------*/ +int log_printf(FILE* log_fp, char* format_str, ...) +{ + int ret = 0; + char log_str[4096]; + char backup_ch; + int len; + va_list list; + + va_start(list, format_str); + vsnprintf(log_str, sizeof(log_str), format_str, list); + va_end(list); + + len = strlen(log_str); + next_offset = curr_offset + len; + + if (next_offset <= max_logfile_size) { + if (fprintf(log_fp, "%s", log_str) < 0) { + ret = -1; + goto exit; + } + curr_offset = next_offset; + if (curr_offset == max_logfile_size) { + rewind(log_fp); + curr_offset = 0; + } + } else { + backup_offset = max_logfile_size - curr_offset; + backup_ch = log_str[backup_offset]; + log_str[backup_offset] = 0x00; + if (fprintf(log_fp, "%s", log_str) < 0) { + ret = -1; + goto exit; + } + rewind(log_fp); + log_str[backup_offset] = backup_ch; + if (fprintf(log_fp, "%s", log_str+backup_offset) < 0) { + ret = -1; + goto exit; + } + curr_offset = next_offset - max_logfile_size; + } + +exit: + return ret; +} \ No newline at end of file diff --git a/src/upgrade-apply-deltafs/engine/fota_log.h b/src/upgrade-apply-deltafs/engine/fota_log.h new file mode 100755 index 0000000..7e460c6 --- /dev/null +++ b/src/upgrade-apply-deltafs/engine/fota_log.h @@ -0,0 +1,75 @@ +/* + * upgrade-apply-deltafs + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __FOTA_LOG_H__ +#define __FOTA_LOG_H__ + +#include + +/* + * DEBUGGING FEATURE + */ + +extern unsigned int __log_level__; +extern FILE *__log_out_file__; +extern int log_printf(FILE* log_fp, char* format_str, ...); +extern void set_max_logfile_size(void); + +#define LOG_INFO (1<<8) +#define LOG_ENGINE (1<<7) +#define LOG_FUNCS (1<<6) +#define LOG_GUI (1<<5) +#define LOG_DEBUG (1<<4) +#define LOG_FILE (1<<3) +#define LOG_FLASH (1<<2) +#define LOG_SSENGINE LOG_ENGINE + +//#define DEBUG_STDOUT +#define DEBUG_FILE + +#ifdef DEBUG_STDOUT +#define LOGE(s, args...) printf("UA/ERROR(%s) " s, __func__, ##args) // Error log +#define LOGL(mask, s, args...) do { if ((mask) & __log_level__) printf("UA/(%s): " s, __func__, ##args); } while (0) +#define LOG(s, args...) LOGL(LOG_DEBUG, s, ##args) + +#elif defined(DEBUG_FILE) +#define LOGE(s, args...) (void)log_printf(__log_out_file__, "UA/ERROR(%s) " s, __func__, ##args) +#define LOGL(mask, s, args...) do { if ((mask) & __log_level__) (void)log_printf(__log_out_file__, "UA/(%s): " s , __func__, ##args); } while (0) +#define LOG(s, args...) LOGL(LOG_DEBUG, s, ##args) + +#elif defined(DEBUG_STDOUT_FILE) // debug printf +#define LOGE(s, args...) do {\ + printf("UA/ERROR(%s) " s, __func__, ##args);\ + (void)log_printf(__log_out_file__, "UA/ERROR(%s) " s, __func__, ##args);\ + } while (0) +#define LOGL(mask, s, args...) do { \ + if ((mask) & __log_level__) {\ + printf("UA/(%s): " s , __func__, ##args);\ + (void)log_printf(__log_out_file__, "UA/(%s): " s, __func__, ##args);\ + } \ + } while (0) +#define LOG(s, args...) LOGL(LOG_DEBUG, s, ##args) + +#else +#define LOGE(s, args...) +#define LOGL(mask, s, args...) +#define LOG(s, args...) + +#endif + +#endif /* __FOTA_LOG_H__ */ diff --git a/src/upgrade-apply-deltafs/engine/fota_tar.c b/src/upgrade-apply-deltafs/engine/fota_tar.c new file mode 100755 index 0000000..ff7233a --- /dev/null +++ b/src/upgrade-apply-deltafs/engine/fota_tar.c @@ -0,0 +1,843 @@ +/* + * upgrade-apply-deltafs + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "SS_Engine_Errors.h" +#include "SS_FSUpdate.h" +#include "fota_common.h" +#include "fota_tar.h" +#include "ua_types.h" + +/* tar Header Block, from POSIX 1003.1-1990. for reference */ +#if 0 + /* POSIX header. */ + +struct posix_header { /* byte offset */ + char name[100]; /* 0 */ + char mode[8]; /* 100 */ + char uid[8]; /* 108 */ + char gid[8]; /* 116 */ + char size[12]; /* 124 */ + char mtime[12]; /* 136 */ + char chksum[8]; /* 148 */ + char typeflag; /* 156 */ + char linkname[100]; /* 157 */ + char magic[6]; /* 257 */ + char version[2]; /* 263 */ + char uname[32]; /* 265 */ + char gname[32]; /* 297 */ + char devmajor[8]; /* 329 */ + char devminor[8]; /* 337 */ + char prefix[155]; /* 345 */ + /* 500 */ +}; +#endif + +#define MAX_ITEM_SIZE 0x7FFFFFFF +#define TAR_ITEM_SIZE_POSITION 124 +#define TAR_SIZE_OF_ITEM_SIZE 8 +#define TAR_SIZE_OF_HEADER 12 +#define TAR_BLOCK_SIZE 512 +#define TAR_ITEM_NAME_SIZE 100 +#define TAR_LONG_NAME_SIZE 256 +#define TAR_ITEM_TYPE_FLAG_POS 156 +/*** The byte that indicates whether the prefix is present or not */ +#define PREFIX_INDICATOR_BYTE 345 +#define PREFIX_LEN 155 + +/** the rest heavily based on (ie mostly) untgz.c from zlib **/ + +/* Values used in typeflag field. */ + +#define REGTYPE '0' /* regular file */ +#define AREGTYPE '\0' /* regular file */ +#define LNKTYPE '1' /* link */ +#define SYMTYPE '2' /* reserved */ +#define CHRTYPE '3' /* character special */ +#define BLKTYPE '4' /* block special */ +#define DIRTYPE '5' /* directory */ +#define FIFOTYPE '6' /* FIFO special */ +#define CONTTYPE '7' /* reserved, for compatibility with gnu tar, + treat as regular file, where it represents + a regular file, but saved contiguously on disk */ + +/* GNU tar extensions */ + +#define GNUTYPE_DUMPDIR 'D' /* file names from dumped directory */ +#define GNUTYPE_LONGLINK 'K' /* long link name */ +#define GNUTYPE_LONGNAME 'L' /* long file name */ +#define GNUTYPE_MULTIVOL 'M' /* continuation of file from another volume */ +#define GNUTYPE_NAMES 'N' /* file name that does not fit into main hdr */ +#define GNUTYPE_SPARSE 'S' /* sparse file */ +#define GNUTYPE_VOLHDR 'V' /* tape/volume header */ + +extern void *SS_Malloc(SS_UINT32 size); + +int gTarFd = -1; // Currenlty this logic supports only one tar file + +void create_dir(char *pathname, int mode) +{ + char *p; + int r; + + /* Strip trailing '/' */ + if (pathname[strlen(pathname) - 1] == '/') + pathname[strlen(pathname) - 1] = '\0'; + + /* Try creating the directory. */ + r = mkdir(pathname, mode); + + if (r != 0) { + /* On failure, try creating parent directory. */ + p = strrchr(pathname, '/'); + if (p != NULL) { + *p = '\0'; + create_dir(pathname, 0755); + *p = '/'; + r = mkdir(pathname, mode); + } + } + if (r != 0) { + if (r != EEXIST && r != -1) + LOG("Could not create directory [%s] Error[%d]\n", pathname, r); + } +} + +/*----------------------------------------------------------------------------- + tar_get_item_offset + ----------------------------------------------------------------------------*/ +int tar_get_item_offset(char *tar, char *item) +{ + int ret = -1; + int fd = -1; + char header[TAR_BLOCK_SIZE] = { 0, }; + char uExtendedName[MAX_FILE_PATH + 1] = { 0, }; + char size_oct[TAR_SIZE_OF_HEADER] = { 0, }; + unsigned long size_dec = 0; + int blknum = 0; + off_t pos = 0; + off_t tar_len = 0; + ssize_t rdcnt = 0; + + if (!item || !tar){ + LOG("Invalid params\n"); + return -1; + }; + //check if gTarFd was opened by tar_open during SS_FSUpdateFile then use it + if (gTarFd >= 0) + fd = gTarFd; + else { + fd = open(tar, O_RDONLY); + if (fd < 0) { + LOGE("can't open file(%s).\n", tar); + return -1; + } + } + + tar_len = lseek(fd, 0, SEEK_END); + if (tar_len < 0) { + LOGL(LOG_SSENGINE, "can't read tar_len (%s).\n", tar); + goto Cleanup; + } + pos = lseek(fd, 0, SEEK_SET); + if (pos < 0) { + LOGL(LOG_SSENGINE, "can't read pos (%s).\n", tar); + goto Cleanup; + } + while (pos < tar_len) { + /* read file header */ + rdcnt = read(fd, header, sizeof(header)); + if (rdcnt <= 0) { + LOG("read failed. (rdcnt=%d)\n", rdcnt); + break; + } + + /* get file name and file size */ + if (header[TAR_ITEM_TYPE_FLAG_POS] == GNUTYPE_LONGNAME || header[TAR_ITEM_TYPE_FLAG_POS] == GNUTYPE_LONGLINK) { + //rdcnt = read(fd, header, sizeof(header)); + memset(uExtendedName, 0, sizeof(uExtendedName)); + rdcnt = read(fd, uExtendedName, sizeof(uExtendedName) - 1); + if (rdcnt <= 0) { + LOG("read failed. (rdcnt=%d)\n", rdcnt); + break; + } + rdcnt = read(fd, header, sizeof(header)); + if (rdcnt <= 0) { + LOG("read failed. (rdcnt=%d)\n", rdcnt); + break; + } + } else { + memset(uExtendedName, 0, sizeof(uExtendedName)); + memcpy(uExtendedName, header, TAR_ITEM_NAME_SIZE); + } + memcpy(size_oct, header + TAR_ITEM_SIZE_POSITION, sizeof(size_oct)); + size_dec = strtoul(size_oct, NULL, TAR_SIZE_OF_ITEM_SIZE); + if (size_dec > MAX_ITEM_SIZE) { + LOG("ITEM : [%s]\n", item); + LOG("size too big. (size_dec=0x%08X)\n", size_dec); + break; + } + + /* check if the file is what we are looking for */ + if (strncmp(uExtendedName, item, sizeof(uExtendedName) - 1) == 0) { + ret = (int)lseek(fd, 0, SEEK_CUR); + break; + } + + /* move file pointer to next file header */ + blknum = size_dec / TAR_BLOCK_SIZE; + if (size_dec % TAR_BLOCK_SIZE) + blknum++; + + pos = lseek(fd, (off_t) (blknum * TAR_BLOCK_SIZE), SEEK_CUR); + if (pos < 0) { + LOGE("can't read next block (%s).\n", tar); + close(fd); + return -1; + } + } + + Cleanup: + if (gTarFd < 0) + close(fd); + + return ret; +} + +/*----------------------------------------------------------------------------- + tar_get_item_size + ----------------------------------------------------------------------------*/ +int tar_get_item_size(char *tar, char *item) +{ + int ret = -1; + int fd = -1; + char header[TAR_BLOCK_SIZE] = { 0, }; + char uExtendedName[MAX_FILE_PATH + 1] = { 0, }; + char size_oct[TAR_SIZE_OF_HEADER] = { 0, }; + unsigned long size_dec = 0; + int blknum = 0; + off_t pos = 0; + off_t tar_len = 0; + ssize_t rdcnt = 0; + + if (!item || !tar){ + LOG("Invalid params\n"); + return -1; + } + LOGL(LOG_SSENGINE, "Tar file Looking for (%s)\n", item); + fd = open(tar, O_RDONLY); + if (fd < 0) { + LOG("can't open file(%s).\n", tar); + return -1; + } + + tar_len = lseek(fd, 0, SEEK_END); + if (tar_len < 0) { + LOGL(LOG_SSENGINE, "can't read tar_len (%s).\n", tar); + goto Cleanup; + } + pos = lseek(fd, 0, SEEK_SET); + if (pos < 0) { + LOGL(LOG_SSENGINE, "can't read pos (%s).\n", tar); + goto Cleanup; + } + + while (pos < tar_len) { + /* read file header */ + rdcnt = read(fd, header, sizeof(header)); + if (rdcnt <= 0) { + LOG("read failed. (rdcnt=%d)\n", rdcnt); + break; + } + + /* get file name and file size */ + if (header[TAR_ITEM_TYPE_FLAG_POS] == GNUTYPE_LONGNAME || header[TAR_ITEM_TYPE_FLAG_POS] == GNUTYPE_LONGLINK) { + //rdcnt = read(fd, header, sizeof(header)); + memset(uExtendedName, 0, sizeof(uExtendedName)); + rdcnt = read(fd, uExtendedName, sizeof(uExtendedName) - 1); + if (rdcnt <= 0) { + LOG("read failed. (rdcnt=%d)\n", rdcnt); + break; + } + rdcnt = read(fd, header, sizeof(header)); + if (rdcnt <= 0) { + LOG("read failed. (rdcnt=%d)\n", rdcnt); + break; + } + } else { + memset(uExtendedName, 0, sizeof(uExtendedName)); + memcpy(uExtendedName, header, TAR_ITEM_NAME_SIZE); + } + memcpy(size_oct, header + TAR_ITEM_SIZE_POSITION, sizeof(size_oct)); + size_dec = strtoul(size_oct, NULL, TAR_SIZE_OF_ITEM_SIZE); + if (size_dec > MAX_ITEM_SIZE) { + LOG("ITEM : [%s]\n", item); + LOG("size too big. (size_dec=0x%08X)\n", (unsigned int)size_dec); + break; + } + + /* check if the file is what we are looking for */ + if (strncmp(uExtendedName, item, sizeof(uExtendedName) - 1) == 0) { + ret = (int)size_dec; + if ((ret == 0) && (header[TAR_ITEM_TYPE_FLAG_POS] == DIRTYPE)) + ret = tar_get_folder_size(tar, item); + break; + } + /* move file pointer to next file header */ + //LOGL(LOG_SSENGINE,"Item in Tar (%s)\n", uExtendedName); + blknum = size_dec / TAR_BLOCK_SIZE; + if (size_dec % TAR_BLOCK_SIZE) + blknum++; + + pos = lseek(fd, (off_t) (blknum * TAR_BLOCK_SIZE), SEEK_CUR); + if (pos < 0) { + LOGL(LOG_SSENGINE, "can't read next block (%s).\n", tar); + close(fd); + return -1; + } + } + + Cleanup: + close(fd); + + return ret; +} + +/*----------------------------------------------------------------------------- + tar_get_cfg_data + ----------------------------------------------------------------------------*/ +int tar_get_cfg_data(char *tar, char *item, char *buf, int buflen) +{ + int fd = -1; + int data_size = -1; + int data_offset = -1; + off_t pos = 0; + ssize_t rdcnt = 0; + + if (!buf){ + LOG("Invalid params\n"); + return -1; + } + data_size = tar_get_item_size(tar, item); + if (data_size <= 0) + return -1; + + if (data_size > buflen) + data_size = buflen; + + data_offset = tar_get_item_offset(tar, item); + if (data_offset < 0) + return -1; + + fd = open(tar, O_RDONLY); + if (fd < 0) { + LOG("can't open file(%s).\n", tar); + return -1; + } + + pos = lseek(fd, data_offset, SEEK_SET); + if (pos < 0) { + LOG("lseek fail (%s offset %d).\n", tar, data_offset); + close(fd); + return -1; + } + + rdcnt = read(fd, buf, data_size); + if (rdcnt != (ssize_t) data_size) { + LOG("read fail(%s from %s).\n", item, tar); + close(fd); + return -1; + } + + close(fd); + + return rdcnt; +} + +tar_Data_t *tar_build_cfg_table(char *tar) +{ + + int fd = -1; + int ret = 0; + char header[TAR_BLOCK_SIZE] = { 0, }; + char uExtendedName[MAX_FILE_PATH + 1] = { 0, }; + char size_oct[TAR_SIZE_OF_HEADER] = { 0, }; + unsigned long size_dec = 0; + int blknum = 0; + off_t pos = 0; + off_t tar_len = 0; + ssize_t rdcnt = 0; + + int itemSize; + int itemOffset; + tar_Data_t *headparam = NULL, *tailparam = NULL, *newnode = NULL; + tar_Data_t *local_temp = NULL; + tar_Data_t *local_next = NULL; + if (!tar) { + LOGE("Bad param tar\n"); + return NULL; + } + //check if gTarFd was opened by tar_open during SS_FSUpdateFile then use it + if (gTarFd >= 0) + fd = gTarFd; + else { + fd = open(tar, O_RDONLY); + if (fd < 0) { + LOG("can't open file(%s).\n", tar); + return NULL; + } + } + + tar_len = lseek(fd, 0, SEEK_END); + if (tar_len < 0) { + LOGL(LOG_SSENGINE, "can't read tar_len (%s).\n", tar); + goto Cleanup; + } + pos = lseek(fd, 0, SEEK_SET); + if (pos < 0) { + LOGL(LOG_SSENGINE, "can't read pos (%s).\n", tar); + goto Cleanup; + } + while (pos < tar_len) { + /* read file header */ + rdcnt = read(fd, header, sizeof(header)); + if (rdcnt <= 0) { + LOG("read failed. (rdcnt=%d)\n", rdcnt); + ret = -1; + break; + } + /* get file name and file size */ + if (header[TAR_ITEM_TYPE_FLAG_POS] == GNUTYPE_LONGNAME || header[TAR_ITEM_TYPE_FLAG_POS] == GNUTYPE_LONGLINK) { + //rdcnt = read(fd, header, sizeof(header)); + memset(uExtendedName, 0, sizeof(uExtendedName)); + rdcnt = read(fd, uExtendedName, sizeof(uExtendedName) - 1); + if (rdcnt <= 0) { + LOG("read failed. (rdcnt=%d)\n", rdcnt); + ret = -1; + break; + } + rdcnt = read(fd, header, sizeof(header)); + if (rdcnt <= 0) { + LOG("read failed. (rdcnt=%d)\n", rdcnt); + ret = -1; + break; + } + } else { + memset(uExtendedName, 0, sizeof(uExtendedName)); + memcpy(uExtendedName, header, TAR_ITEM_NAME_SIZE); + } + memcpy(size_oct, header + TAR_ITEM_SIZE_POSITION, sizeof(size_oct)); + size_dec = strtoul(size_oct, NULL, TAR_SIZE_OF_ITEM_SIZE); + if (size_dec > MAX_ITEM_SIZE) { + LOG("uExtendedName is : [%s]\n", uExtendedName); + LOG("size too big. (size_dec=0x%08X)\n", (unsigned int)size_dec); + ret = -1; + break; + } + //fix WGID : 51254 , size_dec comparison is not required + if ((strstr(uExtendedName, "/diff") != NULL)) { //add only delta files from rootfs and csc, hardcoding shd b removed.. + + /* check if the file is what we are looking for */ + //strncpy(itemName, name,100); + itemSize = (int)size_dec; + itemOffset = (int)lseek(fd, 0, SEEK_CUR); + newnode = (tar_Data_t *) SS_Malloc(sizeof(tar_Data_t)); + if (!newnode) { + ret = -1; + break; + } + memset(newnode->itemName, 0, sizeof(newnode->itemName)); + strncpy((char *)newnode->itemName, uExtendedName, sizeof(newnode->itemName) - 1); + newnode->itemOffset = itemOffset; + newnode->itemSize = itemSize; + newnode->nextnode = NULL; + if (headparam == NULL) { + headparam = newnode; + tailparam = newnode; + } else { + (tailparam)->nextnode = newnode; + (tailparam) = (tailparam)->nextnode; + } + } + + /* move file pointer to next file header */ + blknum = size_dec / TAR_BLOCK_SIZE; + if (size_dec % TAR_BLOCK_SIZE) + blknum++; + + pos = lseek(fd, (off_t) (blknum * TAR_BLOCK_SIZE), SEEK_CUR); + if (pos < 0) { + LOGL(LOG_SSENGINE, "can't read next block (%s).\n", tar); + ret = -1; + break; + } + } + Cleanup: + //if gTarFd was opened by tar_open during SS_FSUpdateFile we do not close it + if (gTarFd < 0) + close(fd); + if (ret != -1) + return headparam; + else { + if (headparam != newnode && newnode) + SS_Free(newnode); + if (headparam) { + local_temp = headparam; + while (local_temp) { + local_next = local_temp->nextnode; + SS_Free(local_temp); + local_temp = local_next; + } + } + return NULL; + } +} + +void tar_free_cfg_table(tar_Data_t ** delta_tar) +{ + tar_Data_t *local_temp = NULL; + tar_Data_t *local_next = NULL; + LOGL(LOG_SSENGINE, "Free TAR CFG TABLE\n"); + if (*delta_tar) { + local_temp = *delta_tar; + while (local_temp) { + local_next = local_temp->nextnode; + //LOGL(LOG_SSENGINE,"freeing [%s]\n",local_temp->itemName); + SS_Free(local_temp); + local_temp = local_next; + } + } +} + +void deleteNode(tar_Data_t * head, tar_Data_t * n) +{ + tar_Data_t *prev = head; + if (head == n) { + if (head->nextnode == NULL) { + LOG("There is only one node. The list can't be made empty\n"); + return; + } + strncpy((char *)head->itemName, (const char *)head->nextnode->itemName, TAR_ITEM_NAME_SIZE); //head->itemName = head->nextnode->itemName; + head->itemSize = head->nextnode->itemSize; + head->itemOffset = head->nextnode->itemOffset; + n = head->nextnode; + head->nextnode = head->nextnode->nextnode; + SS_Free(n); + return; + } + while (prev->nextnode != NULL && prev->nextnode != n) + prev = prev->nextnode; + if (prev->nextnode == NULL) { + LOG("Given node is not present in Linked List\n"); + return; + } + prev->nextnode = prev->nextnode->nextnode; + SS_Free(n); + return; +} + +int tar_get_item_size_from_struct(tar_Data_t ** delta_tar, const char *patchname, int *data_size, int *data_offset) +{ + tar_Data_t *head = *delta_tar; + tar_Data_t *base = *delta_tar; + if (head == NULL) + return 1; + else { + //LOG("fast_tar_get_item_size- looking for [%s] [%s]\n",patchname,head->itemName); + while (1) { + if (strstr((const char *)head->itemName, patchname) != 0) { + //LOG("fast_tar_get_item_size found [%s] in [%s]\n",patchname, head->itemName); + *data_size = head->itemSize; + *data_offset = head->itemOffset; + deleteNode(base, head); + return 0; + + } else if (head->nextnode != NULL) { + head = head->nextnode; + //LOG("fast_tar_get_item_size current node [%s] \n",head->itemName); + } else { + LOGE("fast_tar_get_item_size FAILED TO GET [%s] in [%s]\n", patchname, (char *)head->itemName); + break; + } + } + return 1; + } +} + +int tar_open(char *tar) +{ + if (gTarFd >= 0) + close(gTarFd); + gTarFd = open(tar, O_RDONLY); + if (gTarFd < 0) { + LOG("can't open TAR file(%s).\n", tar); + return -1; + } + return 0; +} + +int tar_close() +{ + if (gTarFd >= 0) + close(gTarFd); + gTarFd = -1; + return 0; +} + +int tar_get_folder_size(char *tar, char *item) +{ + int ret = -1; + int fd = -1; + char header[TAR_BLOCK_SIZE] = { 0, }; + char name[TAR_LONG_NAME_SIZE + 1] = { 0, }; + char *lastfolder = NULL; + int folderpathlen = 0; + char size_oct[TAR_SIZE_OF_HEADER] = { 0, }; + unsigned long size_dec = 0; + int blknum = 0; + off_t pos = 0; + off_t tar_len = 0; + ssize_t rdcnt = 0; + + if (!item || !tar){ + LOG("Invalid params\n"); + return -1; + } + LOG("Tar folder Looking for (%s)\n", item); + fd = open(tar, O_RDONLY); + if (fd < 0) { + LOG("can't open file(%s).\n", tar); + return -1; + } + + tar_len = lseek(fd, 0, SEEK_END); + if (tar_len < 0) { + LOGL(LOG_SSENGINE, "can't read tar_len (%s).\n", tar); + goto Cleanup; + } + pos = lseek(fd, 0, SEEK_SET); + if (pos < 0) { + LOGL(LOG_SSENGINE, "can't read pos (%s).\n", tar); + goto Cleanup; + } + + while (pos < tar_len) { + /* read file header */ + rdcnt = read(fd, header, sizeof(header)); + if (rdcnt <= 0) { + LOG("read failed. (rdcnt=%d)\n", rdcnt); + ret = -1; + break; + } + + /* get file name and file size */ + memcpy(name, header, sizeof(name) - 1); + memcpy(size_oct, header + TAR_ITEM_SIZE_POSITION, sizeof(size_oct)); + errno = 0; + size_dec = strtoul(size_oct, NULL, TAR_SIZE_OF_ITEM_SIZE); + if (errno != 0) { + LOG("strtoul failed. (errno=%d)\n", errno); + ret = -1; + break; + } else if (size_dec > MAX_ITEM_SIZE) { + LOG("size too big. (size_dec=0x%08X)\n", (unsigned int)size_dec); + ret = -1; + break; + } + + /* check if the file is what we are looking for */ + //Get until folder name + + lastfolder = strrchr(name, '/'); + if (lastfolder) + folderpathlen = strlen(name) - strlen(lastfolder); + + if (strncmp(name, item, folderpathlen) == 0) { + ret += (int)size_dec; + //LOG("Tar Files under folder [%s]\n", name); + //break; + } + + /* move file pointer to next file header */ + blknum = size_dec / TAR_BLOCK_SIZE; + if (size_dec % TAR_BLOCK_SIZE) + blknum++; + + pos = lseek(fd, (off_t) (blknum * TAR_BLOCK_SIZE), SEEK_CUR); + if (pos < 0) { + LOGL(LOG_SSENGINE, "can't read next block (%s).\n", tar); + close(fd); + return -1; + } + } + + Cleanup: + close(fd); + LOG("ret=%d\n", ret); + + return ret; //Should return +1?? or Ignore?? +} + +int fast_tar_extract_file(char *tar, char *item, char *pathname, int size, int offset) +{ + int fd = -1; + int data_size = size; + int data_offset = offset; + off_t pos = 0; + ssize_t rdcnt = 0; + ssize_t writeCount = 0; + char *buf = NULL; + char err_buf[256]; + int fd2; + + if (!item || !tar || !pathname){ + LOG("Invalid params\n"); + return -1; + } + if (gTarFd >= 0) + fd = gTarFd; + else { + fd = open(tar, O_RDONLY); + if (fd < 0) { + LOG("can't open file(%s).\n", tar); + return -1; + } + } + + pos = lseek(fd, data_offset, SEEK_SET); + if (pos < 0) { + LOG("lseek fail (%s offset %d).\n", tar, data_offset); + close(fd); + return -1; + } + buf = SS_Malloc(data_size + 1); + if (buf == NULL) { + close(fd); + LOGE("Failed to Allocate Memory\n"); + return -1; + } + rdcnt = read(fd, buf, data_size); + if (rdcnt != (ssize_t) data_size) { + LOG(" rdcnt read fail(%s from %s).\n", item, tar); + SS_Free(buf); + close(fd); + return -1; + } + fd2 = open(pathname, O_CREAT | O_WRONLY, S_IRWXU); // Directory where file is required should be created already. + if (fd2 < 0) { + LOG("can't open file(%s).\n", pathname); + SS_Free(buf); + close(fd); + return -1; + } + writeCount = write(fd2, buf, rdcnt); + if (writeCount != rdcnt) { + LOG("writeCount write fail(%s from %s).\n", item, tar); + strerror_r(errno, err_buf, sizeof(err_buf)); + LOG("Oh dear, something went wrong with read()! %s\n", err_buf); + close(fd); + close(fd2); + SS_Free(buf); + return -1; + } + SS_Free(buf); + if (gTarFd < 0) + close(fd); + fsync(fd2); + close(fd2); + return rdcnt; // or jus return success? +} + +int tar_extract_file(char *tar, char *item, char *pathname) +{ + int fd = -1; + int data_size = -1; + int data_offset = -1; + off_t pos = 0; + ssize_t rdcnt = 0; + ssize_t writeCount = 0; + char *buf = NULL; + char err_buf[256]; + int fd2; + + if (!item || !tar || !pathname){ + LOG("Invalid params\n"); + return -1; + } + data_size = tar_get_item_size(tar, item); + data_offset = tar_get_item_offset(tar, item); + + if (data_size <= 0 || data_offset < 0) { + LOGE("Error Not a file , size is [%d], offset [%d] for item [%s]\n", data_size, data_offset, item); + return -1; + } else + LOGL(LOG_SSENGINE, "extracting file [%s] size [%d]\n", item, data_size); + fd = open(tar, O_RDONLY); + if (fd < 0) { + LOG("can't open file(%s).\n", tar); + return -1; + } + pos = lseek(fd, data_offset, SEEK_SET); + if (pos < 0) { + LOG("lseek fail (%s offset %d).\n", tar, data_offset); + close(fd); + return -1; + } + buf = SS_Malloc(data_size + 1); + if (buf == NULL) { + close(fd); + LOGE("Failed to Allocate Memory\n"); + return -1; + } + rdcnt = read(fd, buf, data_size); + if (rdcnt != (ssize_t) data_size) { + LOG(" rdcnt read fail(%s from %s).\n", item, tar); + SS_Free(buf); + close(fd); + return -1; + } + fd2 = open(pathname, O_CREAT | O_WRONLY, S_IRWXU); // Directory where file is required should be created already. + if (fd2 < 0) { + LOG("can't open file(%s).\n", pathname); + SS_Free(buf); + close(fd); + return -1; + } + writeCount = write(fd2, buf, rdcnt); + if (writeCount != rdcnt) { + LOG("writeCount write fail(%s from %s).\n", item, tar); + strerror_r(errno, err_buf, sizeof(err_buf)); + LOG("Oh dear, something went wrong with read()! %s\n", err_buf); + close(fd); + close(fd2); + SS_Free(buf); + return -1; + } + SS_Free(buf); + close(fd); + fsync(fd2); + close(fd2); + return rdcnt; // or jus return success? +} diff --git a/src/upgrade-apply-deltafs/engine/fota_tar.h b/src/upgrade-apply-deltafs/engine/fota_tar.h new file mode 100755 index 0000000..a774836 --- /dev/null +++ b/src/upgrade-apply-deltafs/engine/fota_tar.h @@ -0,0 +1,30 @@ +/* + * upgrade-apply-deltafs + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _FOTA_TAR_H_ +#define _FOTA_TAR_H_ + +int tar_get_item_offset(char *tar, char *item); + +int tar_get_item_size(char *tar, char *item); + +int tar_get_cfg_data(char *tar, char *item, char *buf, int buflen); + +int tar_get_folder_size(char *tar, char *item); + +#endif /* _FOTA_TAR_H_ */ diff --git a/src/upgrade-apply-deltafs/engine/ss_bspatch_common.c b/src/upgrade-apply-deltafs/engine/ss_bspatch_common.c new file mode 100755 index 0000000..e7bd45e --- /dev/null +++ b/src/upgrade-apply-deltafs/engine/ss_bspatch_common.c @@ -0,0 +1,291 @@ +/*- + * Copyright 2003-2005 Colin Percival + * Copyright 2012 Matthew Endsley + * All rights reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted providing that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * Modifications are made in reimplementing suffix sort array generation + * and how the data is read and written to.Iterative part replaced the + * recursive implementation to avoid buffer overflow problems + */ +//#define ZLIB_MOD //not stable yet. +//#define MAX_MATCH_SIZE // define ( MAX_MATCH_SIZE or CONST_MEMORY_USAGE ) or ( none of them ) +#define CONST_MEMORY_USAGE (64*1024) //tests show smallest time when using 64 kb +#define PATCH_FILE_FORMAT_MOD +#define BSDIFF_HEADER "BSDIFF40" +#define SSDIFF_HEADER "SSDIFF40" +//#define MULTI_THREADING +#include +#include +#include + +#include +#include +#include + +#include +#include <7zFile.h> +#include <7zVersion.h> +#include +#include + +static void *SzAlloc(void *p, size_t size) +{ + p = p; + return MyAlloc(size); +} + +static void SzFree(void *p, void *address) +{ + p = p; + MyFree(address); +} +ISzAlloc g_Alloc = { SzAlloc, SzFree }; + +static off_t offtin(u_char *buf) +{ + off_t y; + + y = buf[7] & 0x7F; + y = y * 256; + y += buf[6]; + y = y * 256; + y += buf[5]; + y = y * 256; + y += buf[4]; + y = y * 256; + y += buf[3]; + y = y * 256; + y += buf[2]; + y = y * 256; + y += buf[1]; + y = y * 256; + y += buf[0]; + + if (buf[7] & 0x80) + y = -y; + + return y; +} + +#define IN_BUF_SIZE (1 << 16) +#define OUT_BUF_SIZE (1 << 16) + +SRes Decode2(CLzmaDec *state, ISeqOutStream *outStream, ISeqInStream *inStream, + UInt64 *unpackSize, unsigned char *dec_data) +{ + int thereIsSize = (*unpackSize != (UInt64)(Int64) - 1); + UInt64 offset = 0; + Byte inBuf[IN_BUF_SIZE]; + Byte outBuf[OUT_BUF_SIZE]; + size_t inPos = 0, inSize = 0, outPos = 0; + + LzmaDec_Init(state); + + offset = 0; + + for (;;) { + if (inPos == inSize) { + inSize = IN_BUF_SIZE; + RINOK(inStream->Read(inStream, inBuf, &inSize)); + inPos = 0; + } + + SRes res; + SizeT inProcessed = inSize - inPos; + SizeT outProcessed = OUT_BUF_SIZE - outPos; + ELzmaFinishMode finishMode = LZMA_FINISH_ANY; + ELzmaStatus status; + + if (thereIsSize && outProcessed > *unpackSize) { + outProcessed = (SizeT) * unpackSize; + finishMode = LZMA_FINISH_END; + } + + res = LzmaDec_DecodeToBuf(state, outBuf + outPos, &outProcessed, + inBuf + inPos, &inProcessed, finishMode, &status); + inPos += inProcessed; + outPos += outProcessed; + *unpackSize -= outProcessed; + memcpy(dec_data + offset, outBuf, outProcessed); + offset += outProcessed; + + outPos = 0; + + if ((res != SZ_OK) || (thereIsSize && *unpackSize == 0)) + return res; + + if (inProcessed == 0 && outProcessed == 0) { + if (thereIsSize || status != LZMA_STATUS_FINISHED_WITH_MARK) + return SZ_ERROR_DATA; + return res; + } + } +} + +int apply_patch(const char *oldfile, unsigned char *patch_buffer, unsigned char **dest_buf, ssize_t *dest_size) +{ + int fd = -1, result = 0; + off_t oldsize, newsize; + u_char header[16], buf[8]; + u_char *old = NULL; + off_t oldpos, newpos; + off_t ctrl[4]; /////////////////////////////////////THREAD + off_t total_write; /////////////////////////////////////////THREAD + off_t j; + off_t memory_usage = CONST_MEMORY_USAGE; + off_t match_size; + off_t patch_buffer_offset = 0; + bool flag; + + /* + File format: + 0 8 "BSDIFF40" + 8 8 X + 16 8 Y + 24 8 sizeof(newfile) + 32 X bzip2(control block) + 32+X Y bzip2(diff block) + 32+X+Y ??? bzip2(extra block) + with control block a set of triples (x,y,z) meaning "add x bytes + from oldfile to x bytes from the diff block; copy y bytes from the + extra block; seek forwards in oldfile by z bytes". + */ + // Read header + if (patch_buffer) + memcpy(header, patch_buffer, 16); + else { + printf("%s().%d Corrupt decoded patch buffer\n", __FUNCTION__, __LINE__); + return 1; + } + + /* Check for appropriate magic */ + if (memcmp(header, BSDIFF_HEADER, 8) != 0 && memcmp(header, SSDIFF_HEADER, 8) != 0) { + printf("%s().%d Patch buffer header corrupt\n", __FUNCTION__, __LINE__); + return 1; + } + + /* Read lengths from header */ + newsize = offtin(header + 8); + + if ((newsize < 0)) { + printf("%s().%d Patch buffer corrupt\n", __FUNCTION__, __LINE__); + return 1; + } + + /* Cset patch_buffer_offset at the right place */ + patch_buffer_offset += 16; + + if (((fd = open(oldfile, O_RDONLY, 0)) < 0) || + ((oldsize = lseek(fd, 0, SEEK_END)) == -1) || + ((old = malloc(memory_usage + 1)) == NULL) || + (lseek(fd, 0, SEEK_SET) != 0)) { + printf("Corruption in old file %s\n", oldfile); + result = 1; + goto Cleanup; + } + + if ((*dest_buf = malloc(newsize + 1)) == NULL) { + printf("Corruption in old file %s\n", oldfile); + result = 1; + goto Cleanup; + } + oldpos = 0; + newpos = 0; + + total_write = 0; + + while (total_write != newsize) { + /* Read control data */ + for (j = 0; j <= 3; j++) { + memcpy(buf, patch_buffer + patch_buffer_offset, 8); + patch_buffer_offset += 8; + ctrl[j] = offtin(buf); + }; + + total_write += (ctrl[0] + ctrl[1]); + newpos = ctrl[3]; + oldpos = ctrl[2]; + + ////////////////////////////////////////////////////////////////////////////////// + flag = true; + match_size = ctrl[0]; + while (flag == true) { + if (match_size <= memory_usage) { + if (pread(fd, old, match_size, oldpos) != match_size) { + printf("Corruption in old file %s\n", oldfile); + result = 1; + goto Cleanup; + } + if (newpos + match_size > newsize) { + printf("%s().%d Corrupt patch\n", __FUNCTION__, __LINE__); + result = 1; + goto Cleanup; + } + memcpy((*dest_buf) + newpos, patch_buffer + patch_buffer_offset, match_size); + patch_buffer_offset += match_size; + for (j = 0; j < match_size; j++) + (*dest_buf)[newpos + j] += old[j]; + newpos += match_size; + flag = false; + } else { + if (pread(fd, old, memory_usage, oldpos) != memory_usage) { + printf("%s().%d Corruption in old file %s\n", __FUNCTION__, __LINE__ , oldfile); + result = 1; + goto Cleanup; + } + if (newpos + memory_usage > newsize) { + printf("%s().%d Corrupt patch\n", __FUNCTION__, __LINE__); + result = 1; + goto Cleanup; + } + memcpy((*dest_buf) + newpos, patch_buffer + patch_buffer_offset, memory_usage); + patch_buffer_offset += memory_usage; + for (j = 0; j < memory_usage; j++) + (*dest_buf)[newpos + j] += old[j]; + match_size -= memory_usage; + oldpos += memory_usage; + newpos += memory_usage; + } + } + + //////////////////////////////////////////////////////////////////////////////////////// + /* Sanity-check */ + if (newpos + ctrl[1] > newsize) { + printf("%s().%d Corrupt patch\n", __FUNCTION__, __LINE__); + result = 1; + goto Cleanup; + } + /* Read extra string */ + memcpy((*dest_buf) + newpos, patch_buffer + patch_buffer_offset, ctrl[1]); + patch_buffer_offset += ctrl[1]; + }; + *dest_size = newsize; +Cleanup: + //close old file + if (fd >= 0) + close(fd); + if (old) + free(old); + return result; +} diff --git a/src/upgrade-apply-deltafs/engine/ss_bspatch_common.h b/src/upgrade-apply-deltafs/engine/ss_bspatch_common.h new file mode 100644 index 0000000..3075ea2 --- /dev/null +++ b/src/upgrade-apply-deltafs/engine/ss_bspatch_common.h @@ -0,0 +1,17 @@ +#ifndef _SS_BSPATCH_COMMON_H +#define _SS_BSPATCH_COMMON_H 1 + +#include +#include <7zFile.h> +#include <7zVersion.h> +#include +#include + +extern ISzAlloc g_Alloc; + +SRes Decode2(CLzmaDec *state, ISeqOutStream *outStream, ISeqInStream *inStream, + UInt64 *unpackSize, unsigned char *dec_data); + +int apply_patch(const char *oldfile, unsigned char *patch_buffer, unsigned char **dest_buf, ssize_t *dest_size); + +#endif /* _SS_BSPATCH_COMMON_H */ diff --git a/src/upgrade-apply-deltafs/engine/ua_types.h b/src/upgrade-apply-deltafs/engine/ua_types.h new file mode 100755 index 0000000..9d00a9d --- /dev/null +++ b/src/upgrade-apply-deltafs/engine/ua_types.h @@ -0,0 +1,85 @@ +/* + * upgrade-apply-deltafs + * + * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UA_TYPES_H__ +#define __UA_TYPES_H__ + +#include + +#define MAX_FILE_PATH 512 + +/* + * FOTA Adaptaion header + */ + +#define UI_OP_SCOUT_UPDATE 0 +#define UI_OP_SCOUT 1 +#define UI_OP_UPDATE 3 + +typedef struct _ua_update_data_t { + unsigned int weight; // the sum of weight should be 100 + unsigned int weight_offset; // start offset + unsigned int data_size; // byte + char *ua_delta_path; // it will be allocated to copy delta file path, need to free memory + char *ua_temp_path; // it will be allocated to copy delta file path, need to free memory + char *ua_delta_folder; +} ua_update_data_t; + +typedef struct _ua_update_cfg_t { + int skip_verify; + int skip_update; + int source_img_size; //TOTA +} ua_update_cfg_t; + +typedef struct _ua_part_info_t { + char *ua_parti_name; + char *ua_subject_name; +} ua_part_info_t; + +// User data structure +typedef struct _ua_data_t { // partition operations + ua_part_info_t *parti_info; + ua_update_cfg_t *update_cfg; + ua_update_data_t *update_data; + unsigned long ua_operation; + + int (*ua_op_read_block)(void *, unsigned char *, unsigned long, unsigned long); + int (*ua_op_write_block)(void *, unsigned char *, unsigned long); + void (*ui_progress)(void *, unsigned long); +} ua_data_t; + +typedef struct _ua_delta_info_t { + char ua_patch_path[MAX_FILE_PATH]; + char ua_patch_info[MAX_FILE_PATH]; + char ua_delta_path[MAX_FILE_PATH]; + char ua_attrib_path[MAX_FILE_PATH]; +} ua_delta_info_t; + +typedef struct _ua_dataSS_t { // partition operations + ua_part_info_t *parti_info; + ua_update_cfg_t *update_cfg; + ua_update_data_t *update_data; + ua_delta_info_t *update_delta; + unsigned long ua_operation; + void (*ui_progress)(void *, unsigned long); + int (*write_data_to_blkdev)(char *, int, int, char *); +} ua_dataSS_t; + +typedef unsigned int SS_UINT32; + +#endif diff --git a/src/upgrade-apply-deltafs/fota_cfg.c b/src/upgrade-apply-deltafs/fota_cfg.c new file mode 100755 index 0000000..803b37f --- /dev/null +++ b/src/upgrade-apply-deltafs/fota_cfg.c @@ -0,0 +1,32 @@ +/* + * upgrade-apply-deltafs + * + * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "fota_cfg.h" + +char fota_cfg_str[EN_CFG_MAX][CFG_MAX_LEN]; + +void fota_cfg_str_load(void) +{ + strncpy(fota_cfg_str[EN_CFG_SUPPORT_FB], "1", CFG_MAX_LEN-1); + strncpy(fota_cfg_str[EN_CFG_SUPPORT_DRM], "0", CFG_MAX_LEN-1); + strncpy(fota_cfg_str[EN_CFG_DEV_FB], "/dev/fb0", CFG_MAX_LEN-1); + strncpy(fota_cfg_str[EN_CFG_DEV_DRM_NAME], "exynos", CFG_MAX_LEN-1); +} + diff --git a/src/upgrade-apply-deltafs/fota_cfg.h b/src/upgrade-apply-deltafs/fota_cfg.h new file mode 100755 index 0000000..a72fb32 --- /dev/null +++ b/src/upgrade-apply-deltafs/fota_cfg.h @@ -0,0 +1,41 @@ +/* + * upgrade-apply-deltafs + * + * Copyright (c) 2017 -2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __FOTA_CFG_H__ +#define __FOTA_CFG_H__ + +#define CFG_MAX_LEN 1024 + +enum { + EN_CFG_SUPPORT_FB, + EN_CFG_SUPPORT_DRM, + EN_CFG_DEV_FB, + EN_CFG_DEV_DRM_NAME, + EN_CFG_MAX +}; + +extern char fota_cfg_str[EN_CFG_MAX][CFG_MAX_LEN]; + + +extern void fota_cfg_str_load(void); + + + +#endif /* __FOTA_FB_H__ */ + + diff --git a/src/upgrade-apply-deltafs/fota_util.c b/src/upgrade-apply-deltafs/fota_util.c new file mode 100755 index 0000000..a4bb78c --- /dev/null +++ b/src/upgrade-apply-deltafs/fota_util.c @@ -0,0 +1,116 @@ +/* + * upgrade-apply-deltafs + * + * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "engine/fota_common.h" + +int s_fd_stdin = -1; +int s_fd_stdout = -1; +int s_fd_stderr = -1; + +/*----------------------------------------------------------------------------- + _exit_stdio + ----------------------------------------------------------------------------*/ +void _exit_stdio(void) +{ + if (s_fd_stdin >= 0) + close(s_fd_stdin); + + if (s_fd_stdout >= 0) + close(s_fd_stdout); + + if (s_fd_stderr >= 0) + close(s_fd_stderr); +} + +/*----------------------------------------------------------------------------- + _system_cmd_wait + ----------------------------------------------------------------------------*/ +int _system_cmd_wait(const char *command) +{ + + int pid = 0; + int status = 0; + char* const environ[2] = {"DISPLAY=:0", NULL }; + + if (command == NULL) + return -1; + + pid = fork(); + + if (pid == -1) + return -1; + + if (pid == 0) { + char *argv[4]; + argv[0] = "sh"; + argv[1] = "-c"; + argv[2] = (char*)command; + argv[3] = 0; + execve("/bin/sh", argv, environ); + exit(127); + } + + do { + if (waitpid(pid, &status, 0) == -1) { + if (errno != EINTR) + return -1; + } else { + return status; + } + } while (1); +} + +/*----------------------------------------------------------------------------- + _system_cmd_nowait + ----------------------------------------------------------------------------*/ +int _system_cmd_nowait(const char *command) +{ + + int pid = 0; + char* const environ[2] = {"DISPLAY=:0", NULL }; + + if (command == NULL) + return -1; + + pid = fork(); + + if (pid == -1) + return -1; + + if (pid == 0) { + char *argv[4]; + argv[0] = "sh"; + argv[1] = "-c"; + argv[2] = (char*)command; + argv[3] = 0; + execve("/bin/sh", argv, environ); + exit(127); + } + + return 0; +} diff --git a/src/upgrade-apply-deltafs/fota_util.h b/src/upgrade-apply-deltafs/fota_util.h new file mode 100755 index 0000000..df1b9c9 --- /dev/null +++ b/src/upgrade-apply-deltafs/fota_util.h @@ -0,0 +1,27 @@ +/* + * upgrade-apply-deltafs + * + * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _FOTA_UTIL_H_ +#define _FOTA_UTIL_H_ + +extern void _exit_stdio(void); +extern int _system_cmd_wait(const char *command); +extern int _system_cmd_nowait(const char *command); + +#endif /* _FOTA_UTIL_H_ */ + diff --git a/src/upgrade-apply-deltafs/ua.c b/src/upgrade-apply-deltafs/ua.c new file mode 100755 index 0000000..55af7e3 --- /dev/null +++ b/src/upgrade-apply-deltafs/ua.c @@ -0,0 +1,857 @@ +/* + * upgrade-apply-deltafs + * + * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "fota_cfg.h" +#include "ua.h" +#include "fota_util.h" +#include "engine/SS_Common.h" +#include "engine/SS_UPI.h" +#include "engine/fota_common.h" +#include "engine/fota_tar.h" +#include "engine/ua_types.h" + + +#define SYSTEM_LOG_DIR "/opt/var/log" +#define TEMP_FOLDER "/tmp" // TODO + +//char ua_slot_mode = 0; +int dm_verity_status = DM_VERITY_DISABLED; + +// TODO: Consider changing all to PATH_MAX +static char fota_result[MAX_FILE_PATH]; +static char fota_cause[MAX_FILE_PATH]; +static char fota_status_path[MAX_FILE_PATH]; +static char delta_folder[MAX_FOLDER_PATH]; +static char delta_path[MAX_FILE_PATH]; +static char log_folder[MAX_FOLDER_PATH]; +static char result_folder[MAX_FOLDER_PATH]; +static char temp_folder[MAX_FOLDER_PATH]; +static char log_path[MAX_FILE_PATH]; + +static ua_part_info_t s_part_info; + +static ua_update_cfg_t s_update_cfg; + +static ua_update_data_t s_update_data; + +typedef struct temp_opt{ + char * archive; + char * archive_file; + char * dest; +}temp_opt; + +static ua_delta_info_t s_delta_info; + +unsigned int __log_level__ = + (LOG_DEBUG | LOG_FLASH | LOG_FILE | LOG_FUNCS | LOG_GUI | LOG_ENGINE | LOG_INFO); +FILE *__log_out_file__; + +static void save_result(int result); +static void save_cause(int cause); + +#define TMP_DIR "/tmp/upgrade" +#define PROGRESS_FILE TMP_DIR "/ro_progress" + +#define HAL_PROGRESS_MIN 40 +#define HAL_PROGRESS_MAX 80 + +void print_usage(const char *msg) +{ + if (msg) { + printf("%s\n", msg); + } + printf("print_usage: upgrade-apply-deltafs --archive delta_dir --dest label --archive-file label.img\n" + "delta_dir: directory path where delta.tar file is located\n" + "label: label of the partition to be updated\n" + "label.img: name of the file inside of delta that is to be used during upgrade\n" + ); +} + +void print_error_code(int err) +{ + char msg[]="upgrade-apply-deltafs error:"; + switch (err) { + case UPI_CONFIG_ERROR: + printf("%s config error.\n", msg); + break; + case UPI_DELTA_PATH_ERROR: + printf("%s delta path error.\n", msg); + break; + case UPI_DELTA_PATH_LENGTH_ERROR: + printf("%s delta path length error.\n", msg); + break; + case UPI_VERSION_ERROR: + printf("%s version error.\n", msg); + break; + case UPI_VERIFY_ERROR: + printf("%s verify error.\n", msg); + break; + case UPI_UPDATE_ERROR: + printf("%s update error.\n", msg); + break; + case UPI_INVALID_PARAM_ERROR: + printf("%s invalid parameter error.\n", msg); + break; + case UPI_DELTACOUNT_ERROR: + printf("%s delta count error.\n", msg); + break; + case UPI_PARTINFO_ERROR: + printf("%s partition information error.\n", msg); + break; + default: + printf("upgrade-apply-deltafs unable to determine error code: %d\n", err); + } +} + +void fota_gui_update_progress(int percent) +{ + int ret; + int fd; + struct stat s; + + // Check directory + ret = stat(TMP_DIR, &s); + if (ret == 0) { + // TMP_DIR exists but it is not directory + if (!S_ISDIR(s.st_mode)) + goto remove_file; + else + goto update_progress; + } else if (errno == ENOENT) // TMP_DIR not exists + goto make_directory; + else { + LOG("stat failed : %m\n"); + return; + } + +remove_file: + ret = remove(TMP_DIR); + if (ret != 0) { + LOG("remove failed : %m\n"); + return; + } + +make_directory: + ret = mkdir(TMP_DIR, 0755); + if (ret != 0) { + LOG("mkdir failed : %m\n"); + return; + } + +update_progress: + fd = creat(PROGRESS_FILE, 0644); + if (fd < 0) { + LOG("creat failed : %m\n"); + return; + } + + ret = dprintf(fd, "%d\n", percent); + if (close(fd) != 0) { + LOG("close failed : %m\n"); + return; + } + if (ret < 2) { + LOG("write failed (%d) : %m\n", ret); + return; + } + + LOG("Succeed to write\n"); +} + +static void set_upgrade_progress(int percent) +{ + int relative_precent = HAL_PROGRESS_MIN + ((HAL_PROGRESS_MAX - HAL_PROGRESS_MIN) * percent)/100; + if (hal_device_board_set_upgrade_status(relative_precent) < 0) { + LOG("set_upgrade_status failed: %d\n", relative_precent); + return; + } + + LOG("set_upgrade_status success: %d\n", relative_precent); +} + +/*----------------------------------------------------------------------------- + fota_gui_progress + ----------------------------------------------------------------------------*/ + // TODO - remove this mechanism, only makes log less readable +void fota_gui_progress(void * pbUserData, unsigned long uPercent) +{ + int percent; + int from, to; + ua_dataSS_t *ua_data = (ua_dataSS_t *)pbUserData; + ua_update_data_t *ua_update_data = ua_data->update_data; + + LOGL(LOG_FUNCS|LOG_GUI, "%s: ++ uPercent(%lu%%), config->weight=%lu\n", __func__, + uPercent, (long unsigned int)ua_update_data->weight); + + if (uPercent == 100) + percent = ua_update_data->weight_offset + ua_update_data->weight; + else + percent = ua_update_data->weight_offset + (ua_update_data->weight * uPercent / 100); + + set_upgrade_progress(percent); + /** + * re-arrange progress percentage between scout & update + * + * 0 ~ 100 -> from ~ to + */ + switch (ua_data->ua_operation) { + case UI_OP_SCOUT: + from = 0; + to = 20; + break; + case UI_OP_SCOUT_UPDATE: + case UI_OP_UPDATE: + from = 20; + to = (dm_verity_status == DM_VERITY_ENABLED) ? 80 : 100; + break; + default: + from = 0; + to = 100; + break; + } + + percent = from + ((to - from) * percent / 100); + + fota_gui_update_progress(percent); /* update progress bar and text */ + + LOGL(LOG_FUNCS|LOG_GUI, "-- uPercent=%lu, Print Percent(%d%%)\n", uPercent, percent); +} + +/*----------------------------------------------------------------------------- + verify_Delta_FS + ----------------------------------------------------------------------------*/ +int verify_Delta_FS() +{ + int ret = SUCCESS; + ua_dataSS_t ua_dataSS; + ua_part_info_t *ua_part_info = &s_part_info; + ua_update_cfg_t *ua_update_cfg = &s_update_cfg; + ua_update_data_t *ua_update_data = &s_update_data; + ua_delta_info_t *ua_delta_info = &s_delta_info; + ua_dataSS.parti_info = ua_part_info; + ua_dataSS.update_cfg = ua_update_cfg; + ua_dataSS.update_data = ua_update_data; + ua_dataSS.update_delta = ua_delta_info; + ua_dataSS.ua_operation = UI_OP_SCOUT; + ua_dataSS.ui_progress = fota_gui_progress; + + if (ua_update_data->ua_delta_path != NULL) { + LOG("Verifying %s \n", ua_dataSS.parti_info->ua_parti_name); + ret = SS_FSVerifyPartition(&ua_dataSS); + } + + return ret; +} + +/*----------------------------------------------------------------------------- + update_Delta_FS + ----------------------------------------------------------------------------*/ +int update_Delta_FS(unsigned long ui32Operation) +{ + int ret = SUCCESS; + ua_dataSS_t ua_dataSS; + ua_part_info_t *ua_part_info = &s_part_info; + ua_update_cfg_t *ua_update_cfg = &s_update_cfg; + ua_update_data_t *ua_update_data = &s_update_data; + ua_delta_info_t *ua_delta_info = &s_delta_info; + ua_dataSS.parti_info = ua_part_info; + ua_dataSS.update_cfg = ua_update_cfg; + ua_dataSS.update_data = ua_update_data; + ua_dataSS.update_delta = ua_delta_info; + ua_dataSS.ua_operation = ui32Operation; + ua_dataSS.ui_progress = fota_gui_progress; + + if (ua_update_data->ua_delta_path != NULL) + ret = SS_FSUpdatemain(&ua_dataSS); + + return ret; +} + +/*----------------------------------------------------------------------------- + set_data_weight + ----------------------------------------------------------------------------*/ +/* set data weight using data size minimum:1 total: 100 */ +// TODO - remove +static void set_data_weight(unsigned int total_data_size) +{ + LOG("%s entered, total_data_size=%u\n", __func__, total_data_size); + s_update_data.weight = 100; + LOG("%s leaved\n", __func__); +} + +/*----------------------------------------------------------------------------- + set_data_weight_offset + ----------------------------------------------------------------------------*/ + // TODO - remove +static void set_data_weight_offset(void) +{ + LOG("%s entered\n", __func__); + s_update_data.weight_offset = 0; // not sure what it does, keep it like this for now + LOG("s_update_data.weight_offset=%u\n", s_update_data.weight_offset); + LOG("%s leaved\n", __func__); +} + +/*----------------------------------------------------------------------------- + get_time_stamp + ----------------------------------------------------------------------------*/ +static char ts[256]; +static void get_time_stamp(void) +{ + struct timeval tv; + int sec, msec; + + gettimeofday(&tv, NULL); + sec = (int) tv.tv_sec; + msec = (int) (tv.tv_usec / 1000); + snprintf(ts, sizeof(ts), "%06d.%03d", sec % 100000, msec); +} + +/*----------------------------------------------------------------------------- + update_all + ----------------------------------------------------------------------------*/ +int update_all() +{ + int ret = OK; + int cause = 0, item_size = 0; + int last_update_status = UP_START_NONE; + int update_status = UP_START_NONE; + unsigned long ui32Operation = UI_OP_SCOUT; + int del_type = 0; // TODO, for clarity + char status_path[MAX_FILE_PATH]; + snprintf(status_path, MAX_FILE_PATH, "%s/%s",s_update_data.ua_delta_folder, SS_UPDATE_STATUS_PATH); + + item_size = tar_get_item_size(s_update_data.ua_delta_path, s_part_info.ua_subject_name); + if (item_size > 0) + s_update_data.data_size = (unsigned int)item_size; + else + s_update_data.data_size = 0; + + LOGL(LOG_DEBUG, "s_update_data.data_size=%lu, ua_delta_path=%s, " + "ua_subject_name=%s\n", + (long unsigned int)s_update_data.data_size, + s_update_data.ua_delta_path, + s_part_info.ua_subject_name); + + if (s_update_data.data_size <= 0) { + ret = UPI_DELTACOUNT_ERROR; + sleep(3); + + goto CleanUp; + } + LOG(" set weight to draw progressive bar.....\n"); + set_data_weight(s_update_data.data_size); + set_data_weight_offset(); + + LOG("s_part_info.ua_parti_name = %s ua_delta_path = %s ua_subject_name=%s\n", + s_part_info.ua_parti_name, + s_update_data.ua_delta_path, + s_part_info.ua_subject_name); + + if (SS_Get_last_update_status(&last_update_status, &del_type, status_path) == -1) + LOG("No last_update_status. Go normal update scenario.\n"); + else + LOG("Get last_update_status. Go Power safe update scenario.\n"); + + LOG("last_update_status: [%d], del_type: [%d] \n", last_update_status, del_type); + /* Verify */ + if (last_update_status == UP_START_NONE) { + + if (s_update_data.data_size > 0) { + get_time_stamp(); + LOG("[%s] Verify %s ..............................................................\n", ts, + s_part_info.ua_parti_name); + + ret = verify_Delta_FS(); + LOG("return form verify : %d\n", ret); + if (ret != OK) { + cause = ret; + ret = UPI_VERIFY_ERROR; + LOG("%s verify fail\n", s_part_info.ua_parti_name); + goto CleanUp; + } + } + + } + + get_time_stamp(); + LOG("[%s] Verify End ..............................................................\n", ts); + + /* Update */ + ui32Operation = UI_OP_SCOUT_UPDATE; + + + if (s_update_data.data_size > 0) { + get_time_stamp(); + LOG("[%s] Update %s ..............................................................\n", ts, + s_part_info.ua_parti_name); + + SS_Set_last_update_status(update_status, del_type, status_path); // i have to look into what it does + + ret = update_Delta_FS(ui32Operation); + LOG("return form update : %d\n", ret); + if (ret != OK) { + cause = ret; + ret = UPI_UPDATE_ERROR; + LOG("%s update fail\n", s_part_info.ua_parti_name); + goto CleanUp; + } + } + + get_time_stamp(); + LOG("[%s] Update End ..............................................................\n", ts); + + CleanUp: + if (ret != OK) + save_cause(cause); + + return ret; +} + +/*----------------------------------------------------------------------------- + log_init + ----------------------------------------------------------------------------*/ +void log_init(void) +{ + memset(log_path, 0x00, sizeof(log_path)); + snprintf(log_path, sizeof(log_path), "%s", LOG_FILE_PATH); + + __log_out_file__ = fopen(log_path, "w"); + if (__log_out_file__ == NULL) { + perror("file open error\n"); + return; + } + get_time_stamp(); + LOG("===== log start [%s] =====\n", ts); +} + +/*----------------------------------------------------------------------------- + log_deinit + ----------------------------------------------------------------------------*/ +void log_deinit(void) +{ + get_time_stamp(); + LOG("===== log end [%s] =====\n", ts); + + if (__log_out_file__) { + fclose(__log_out_file__); + __log_out_file__ = NULL; + } + + sync(); +} + +/*----------------------------------------------------------------------------- + print_error_cause + ----------------------------------------------------------------------------*/ +static void print_error_cause(int error) +{ + switch (error) { + case E_SS_FSBADDELTA: + LOG("Corrupted firmware update package, did not store correctly. Detected, for example, by mismatched CRCs between actual and expected.\n"); + break; + case E_SS_BAD_PARAMS: + LOG("Wrong Firmware Update Package delivered to device based on current device characteristics\n"); + break; + case E_SS_MALLOC_ERROR: + LOG("The update fails because there isn't sufficient memory to update the device.\n"); + break; + case E_SS_FSSRCBACKUPFAILED: + case E_SS_WRITE_ERROR: + case E_SS_FSFAILEDTOBACKUPPATCHINFO: + case E_SS_FSBADATTRIBUTES: + LOG("The update failed because writing data to the device was unsuccessful.\n"); + break; + case E_SS_FSSRCCURRUPTED: + case E_SS_FSSHA_MISMATCH: + case E_SS_FSFAILEDTOPARSEDELTACNT: + case E_SS_FSFAILEDTOOPENPATCHINFO: + case E_SS_FSFAILEDTOPARSEDELTAINFO: + LOG("The update failed because data was corrupted during update of device.\n"); + break; + default: + LOG("another error\n"); + break; + } +} + +/* + +Corrupted firmware update package, did not store correctly. Detected, for example, by mismatched CRCs between actual and expected. +E_RB_PKG_CORRUPTED(0x8000000D) +E_RB_PKG_NOT_AUTHORIZED(0x8000000E): not used + + +Wrong Firmware Update Package delivered to device based on current device characteristics +E_RB_BAD_PARAMS(0x800000002) +E_RB_WRONG_UPI_VER(0x80000011):not used +E_RB_WRONG_UPI_UPDATE(0x80000012): not used +E_RB_UPDATE_SECTOR_SIG(0x80000013): not used + + +Failure to positively validate digital signature of firmware update package +E_RB_NON_DP_FORMAT_NOT_SUPPORTED(0x8001001A) +E_RB_INVALID_DP_HEADER(0x80010025) +E_RB_INVALID_DP_WRONG_SIGNATURE(0x80010026) +E_RB_INVALID_DP(0x80010027) + + +Firmware Update Package is Not Acceptable +E_RB_PKG_TOO_SHORT(0x8000000B) not used +E_RB_PKG_TOO_LONG(0x8000000C) not used +E_RB_PKG_NOT_AUTHORIZED(0x8000000F) + + +The update fails because there isn\A1\AFt sufficient memory to update the device. +E_RB_NOT_ENOUGH_RAM(0x8000001E) +*/ + +/*----------------------------------------------------------------------------- + save_cause + ----------------------------------------------------------------------------*/ +void save_cause(int cause) +{ + char return_char[20]; + FILE *result_fp; + + LOG("%s entered, 0x%x\n", __func__, cause); + + print_error_cause(cause); + + if ((result_fp = fopen(fota_cause, "w")) == NULL) { + LOG("cause file open fail\n"); + return; + } + + snprintf(return_char, sizeof(return_char), "%x", cause); + fwrite(return_char, strlen(return_char), 1, result_fp); + fclose(result_fp); + + LOG("%s leaved!\n", __func__); +} + +/*----------------------------------------------------------------------------- + save_result + ----------------------------------------------------------------------------*/ +void save_result(int result) +{ + char return_char[20]; + FILE *result_fp; + + LOG("%s entered, result=0x%x\n", __func__, result); + + if ((result_fp = fopen(fota_result, "w")) == NULL) { + LOG("result file open fail\n"); + return; + } + + snprintf(return_char, sizeof(return_char), "%x", result); + fwrite(return_char, strlen(return_char), 1, result_fp); + fclose(result_fp); + + LOG("%s leaved!\n", __func__); + + return; +} + +/*----------------------------------------------------------------------------- + fota_path_init + ----------------------------------------------------------------------------*/ +int fota_path_init(void) +{ + if (strlen(delta_folder) > MAX_FILE_PATH - 15) { + LOG("FOTA path is too long\n"); + return FAIL; + } + + + s_update_data.ua_delta_path = malloc(MAX_FILE_PATH); + if (s_update_data.ua_delta_path == NULL) { + LOG("Memory allocation fail\n"); + return FAIL; + } + snprintf(s_update_data.ua_delta_path, MAX_FILE_PATH, "%s/%s", delta_folder, DEFAULT_DELTA_NAME); + snprintf(fota_cause, sizeof(fota_cause), "%s/%s", result_folder, "cause"); + snprintf(fota_status_path, sizeof(fota_status_path), "%s/%s", result_folder, UP_STATUS_FILE); + + LOG("s_part_info[UA_%s].ua_delta_path=%s\n", + s_part_info.ua_parti_name, + s_update_data.ua_delta_path); + + return SUCCESS; +} + +/*----------------------------------------------------------------------------- + fota_path_deinit + ----------------------------------------------------------------------------*/ +void fota_path_deinit(void) +{ + if (s_update_data.ua_delta_path) { + free(s_update_data.ua_delta_path); + s_update_data.ua_delta_path = NULL; + } + if (s_update_data.ua_temp_path) { + free(s_update_data.ua_temp_path); + s_update_data.ua_temp_path = NULL; + } +} + +/*----------------------------------------------------------------------------- + check_dm_verity_status + ----------------------------------------------------------------------------*/ +int check_dm_verity_status(void) +{ + int ret = 0; + + ret = access("/usr/bin/verityctl", F_OK); + if (ret == -1) { + if (errno == ENOENT) { + LOG("dm-verity status : disabled\n"); + dm_verity_status = DM_VERITY_DISABLED; + return 0; + } else { + LOG("access failed with errno: %d\n", errno); + return -errno; + } + } + + LOG("dm-verity status : enabled\n"); + dm_verity_status = DM_VERITY_ENABLED; + return 0; +} + +/*----------------------------------------------------------------------------- + remove_temp_files + ----------------------------------------------------------------------------*/ +void remove_temp_files(void) +{ + int ret = 0; + char *ua_temp_path; + struct stat sbuf; + + + ua_temp_path = s_update_data.ua_temp_path; + if (NULL == ua_temp_path) + return; + + ret = lstat(ua_temp_path, &sbuf); + if (ret < 0) { + ret = stat(ua_temp_path, &sbuf); + if (ret < 0) { + LOG("stat failed with return value: %d errno: %d\n", ret, errno); + return; + } + } + + if (S_ISDIR(sbuf.st_mode)) { + ret = rmdir(ua_temp_path); + if (ret < 0) + LOG("rmdir(%s) failed with return value: %d errno: %d\n", ua_temp_path, ret, errno); + } else { + ret = unlink(ua_temp_path); + if (ret < 0) + LOG("unlink(%s) failed with return value: %d errno: %d\n", ua_temp_path, ret, errno); + } +} + +/*----------------------------------------------------------------------------- + arg_parse + ----------------------------------------------------------------------------*/ +int arg_parse(int argc, char ** argv, temp_opt *my_opt) +{ + if (argc != 7) { + print_usage("Invalid parameter count"); + return -1; + } + const char * archive = NULL; + const char * archive_file = NULL; + const char * dest = NULL; + const struct option long_options[] = { + {"archive", required_argument, NULL, 0 }, + {"dest", required_argument, NULL, 1 }, + {"archive-file", required_argument, NULL, 2 }, + {0} + }; + while (1) { + int option = getopt_long(argc, argv, "", long_options, NULL); + if (option < 0) + break; + switch (option) { + case 0: + if (archive != NULL) { + print_usage("Parameters repeated"); + return -1; + } + archive = optarg; + break; + case 1: + if (dest != NULL) { + print_usage("Parameters repeated"); + return -1; + } + dest = optarg; + break; + case 2: + if (archive_file != NULL) { + print_usage("Parameters repeated"); + return -1; + } + archive_file = optarg; + break; + default: + print_usage("Invalid parameters"); + return -1; + } + } + if (archive_file == NULL || dest == NULL || archive == NULL) { + print_usage("Wrong parameters"); + return -1; + } + (*my_opt).archive = archive; + (*my_opt).dest = dest; + (*my_opt).archive_file = archive_file; + + return 0; +} + +/*----------------------------------------------------------------------------- + main + ----------------------------------------------------------------------------*/ +int main(int argc, char **argv) +{ + char ver_str[MAX_PATH]; + int ret = FAIL; + temp_opt my_opt; + log_init(); + if(arg_parse(argc, argv, &my_opt) < 0) { + ret = UPI_INVALID_PARAM_ERROR; + goto Results; + } + +#if defined(FEATURE_SUPPORT_CAPABILITY) + SS_set_feature_support_capability(1); +#endif + + memset(delta_folder, 0x00, sizeof(delta_folder)); + snprintf(delta_folder, sizeof(delta_folder)-1, "%s", my_opt.archive); + snprintf(delta_path, sizeof(delta_path)-1, "%s/%s", delta_folder, DEFAULT_DELTA_NAME); + s_update_data.ua_delta_folder = strdup(delta_folder); + + memset(temp_folder, 0x00, sizeof(temp_folder)); + snprintf(temp_folder, sizeof(temp_folder)-1, "%s", TEMP_FOLDER); + + memset(log_folder, 0x00, sizeof(log_folder)); + snprintf(log_folder, sizeof(log_folder)-1, "%s", SYSTEM_LOG_DIR); + + memcpy(result_folder, temp_folder, sizeof(result_folder)); + + snprintf(fota_result, sizeof(fota_result), "%s/%s", result_folder, "result"); + + fota_cfg_str_load(); + + if (check_dm_verity_status() < 0) { // to be removed + LOG("check_dm_verity_status fail\n"); + ret = UPI_CONFIG_ERROR; + goto Results; + } + + s_part_info.ua_parti_name = my_opt.dest; + s_part_info.ua_subject_name = my_opt.archive_file; + s_update_cfg.source_img_size = 0; // TODO lets see if 0 will work + + /* load block device number at run-time */ + + ret = fota_path_init(); + if (ret == FAIL) { + ret = UPI_DELTA_PATH_LENGTH_ERROR; + goto Results; + } + LOG("<<<<<<<<<<< log_init >>>>>>>>>>>>\n"); + + /* UPI version check */ + if (S_SS_SUCCESS == SS_GetUPIVersion((unsigned char*)ver_str)) { + LOG("<<<<<<<<< TOTA Update Agent %s >>>>>>>>>>>>\n", ver_str); + } else { + LOG("[SS_GetUPIVersion fail] \n"); + ret = UPI_VERSION_ERROR; + goto Results; + } + /* Main Update Routine : Scout & Update */ + ret = update_all(); + LOG("[update_all ret=%d]\n", ret); + + Results: + LOG("Result=%d\n", ret); + save_result(ret); + //remove_temp_files(); // TOTA + if (ret != SUCCESS) + print_error_code(ret); + + switch (ret) { + /* Before initialize fota path */ + case UPI_INVALID_PARAM_ERROR: + case UPI_DELTA_PATH_ERROR: + case UPI_CONFIG_ERROR: + case UPI_PARTINFO_ERROR: + case UPI_DELTA_PATH_LENGTH_ERROR: + log_deinit(); + _exit_stdio(); + return -1; + /* After initialize fota path */ + case UPI_VERSION_ERROR: + case UPI_DELTACOUNT_ERROR: + case UPI_VERIFY_ERROR: + case UPI_UPDATE_ERROR: + fota_path_deinit(); + log_deinit(); + _exit_stdio(); + return -1; + case SUCCESS: + fota_path_deinit(); + log_deinit(); + /* Preserve log file for debugging */ + _exit_stdio(); + return 0; + default: + LOG("!!! Not expected ret (= %d)\n", ret); + } + + if(s_part_info.ua_parti_name) free(s_part_info.ua_parti_name); + if(s_part_info.ua_subject_name) free(s_part_info.ua_subject_name); + + _exit_stdio(); + return -1; +} \ No newline at end of file diff --git a/src/upgrade-apply-deltafs/ua.h b/src/upgrade-apply-deltafs/ua.h new file mode 100755 index 0000000..347159c --- /dev/null +++ b/src/upgrade-apply-deltafs/ua.h @@ -0,0 +1,85 @@ +/* + * upgrade-apply-deltafs + * + * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UA_H__ +#define __UA_H__ + +#include + +/* + * FEATURE + */ + +//#define USE_POST_UPDATE +//#define USE_DELTA_DOWNLOAD +//#define USE_DUALSBL + +#define LOG_FILE_PATH "/opt/data/update/last_update.log" +#define MAX_FILE_PATH 512 +#define MAX_FOLDER_PATH 384 + +/* + * FOTA Adaptaion header + */ + +#define ERROR -1 // 0XFFFFFFFF + +#define INVALID 0 +#define VALID 1 +#define TRUE 1 +#define FALSE 0 +#define OK 0 +#define SUCCESS 0 +#define FAIL 1 +#define RESTORING 2 + +#define UPI_ERROR(code) 0xFD##code + +#define UPI_CONFIG_ERROR UPI_ERROR(9A) + +#define UPI_DELTA_PATH_ERROR UPI_ERROR(AA) +#define UPI_DELTA_PATH_LENGTH_ERROR UPI_ERROR(AB) + +#define UPI_VERSION_ERROR UPI_ERROR(BB) + +#define UPI_VERIFY_ERROR UPI_ERROR(C0) +#define UPI_UPDATE_ERROR UPI_ERROR(D0) + +#define UPI_INVALID_PARAM_ERROR UPI_ERROR(EA) +#define UPI_DELTACOUNT_ERROR UPI_ERROR(EC) +#define UPI_PARTINFO_ERROR UPI_ERROR(ED) + +#define DEFAULT_DELTA_NAME "delta.tar" +#define UPDATTE_CFG_FILE "update.cfg" + +#define UP_STATUS_FILE "UP.STATUS" +#define UP_START_NONE 0 + +enum { + UA_OP_MODE_FG = 0, + UA_OP_MODE_BG +}; + +enum { + DM_VERITY_DISABLED = 0, + DM_VERITY_ENABLED = 1 +}; + +void log_deinit(void); + +#endif