../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
SET(EXECNAME "upgrade-apply-deltafs")
SET(BINDIR "/usr/bin")
ADD_EXECUTABLE(${EXECNAME} ${SRCS})
-TARGET_LINK_LIBRARIES(${EXECNAME} ${${PROJECT_NAME}_pkgs_LDFLAGS} "-g" "-pthread")
+
+TARGET_LINK_LIBRARIES(${EXECNAME} PRIVATE ${${PROJECT_NAME}_pkgs_LDFLAGS} "-g" "-pthread")
+TARGET_LINK_LIBRARIES(${EXECNAME} PRIVATE libtar.a)
INSTALL(TARGETS ${EXECNAME} DESTINATION ${BINDIR})
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
-#include "../../upgrade-apply/sha1/sha1.h"
+#include "sha1.h"
#include "SS_PatchDelta.h"
#include "fota_common.h"
#include "SS_Engine_Errors.h"
}
extern int gvalid_session;
-extern void create_dir(char *pathname, int mode);
+static 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);
+ }
+}
/*!
*********************************************************************************
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);
+ char patchfile_source_path[MAX_FILE_PATH];
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",
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);
+ result = SS_ApplyBsdiff((char *)source_filename, outname, patchfile_source_path, sink, token, &ctx1);
if (output >= 0) {
fsync(output);
close(output);
//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);
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
#include "SS_PatchDelta.h"
#include "SS_Engine_Errors.h"
#include "SS_FSUpdate.h"
+#include "fota_tar.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;
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];
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)) {
}
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_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))) {
+ 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;
*********************************************************************************
*/
-struct details *SS_FSGetDeltaCount(char *ubDeltaPath, char *ubDeltaInfoFile, char *patchlist_backup_patch)
+struct details *SS_FSGetDeltaCount(ua_dataSS_t *ua_dataSS)
{
- int size = 0, bckupsize = 0, ret = 1;
+ char *ubDeltaPath = ua_dataSS->update_data->ua_delta_path;
+ char *ubDeltaInfoFile = ua_dataSS->update_delta->ua_patch_info;
+ int size = 0, read_size = 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;
+ FILE *filename_extract = NULL;
+ int gtotalFSCnt = 0;
if (!(ubDeltaPath && ubDeltaInfoFile)) {
LOGE("failed to Parse DELTA count information: \n");
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);
+ filename_extract = fopen(ua_dataSS->tar_data->text_files_info[PATCHLIST_FILE].extracted_name, "r");
+ if (filename_extract == NULL) {
+ strerror_r(errno, buf, sizeof(buf));
+ LOGE("Failed to open file Error:[%s]\n", buf);
+ SS_SetUpgradeState(E_SS_FSFAILEDTOBACKUPPATCHINFO);
ret = 0;
goto cleanup;
}
+ size = ua_dataSS->tar_data->text_files_info[PATCHLIST_FILE].size;
+
FileData = SS_Malloc(size + 1);
if (FileData == NULL) {
LOGE("Failed to Allocate Memory\n");
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);
+ read_size = fread(FileData, 1, size, filename_extract);
+ if (read_size < size) {
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);
+ LOGL(LOG_SSENGINE, " Size [%d]\n", size);
line = strstr(FileData, SS_FSCOUNT_MAGIC_KEY);
if (line) {
}
cleanup:
+ SS_Free(FileData);
+ if (filename_extract)
+ fclose(filename_extract);
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;
}
{
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;
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);
+
+ local = SS_FSGetDeltaCount(ua_dataSS);
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");
+ fp = fopen(ua_dataSS->tar_data->text_files_info[PATCHLIST_FILE].extracted_name, "r");
if (!fp) {
SS_SetUpgradeState(E_SS_FSFAILEDTOOPENPATCHINFO);
- if (tar_cfg_data)
- tar_free_cfg_table(&tar_cfg_data);
SS_Free(local);
return NULL;
}
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) {
+ if (ua_dataSS->tar_data->new_files_info.offset <= 0) {
SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO);
LOGE("New files not present in Patch and they should be\n");
retval = E_SS_FAILURE;
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);
+ unlink(ua_dataSS->tar_data->text_files_info[PATCHLIST_FILE].extracted_name);
+ ua_dataSS->tar_data->text_files_info[PATCHLIST_FILE].size = 0;
return fs_head_node;
}
int ulAttribSize = 0;
int result = S_SS_SUCCESS;
int fail_cnt = 0;
+ int fd = -1;
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);
-
+ LOGL(LOG_SSENGINE, "ATTRIB PATH: [%s] \n", ua_dataSS->tar_data->text_files_info[ATTR_FILE].extracted_name);
+ int item_size = ua_dataSS->tar_data->text_files_info[ATTR_FILE].size;
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 ((fd = open(ua_dataSS->tar_data->text_files_info[ATTR_FILE].extracted_name, O_RDONLY)) < 0) {
+ LOGE("Cannot open attr file!\n");
+ unlink(ua_dataSS->tar_data->text_files_info[ATTR_FILE].extracted_name);
+ ua_dataSS->tar_data->text_files_info[ATTR_FILE].size = 0;
+ }
+ int read_data = read(fd, item_data, item_size);
if (read_data <= 0) {
LOGE("read_data failed!!\n");
SS_SetUpgradeState(E_SS_FSBADDELTA);
SS_Free(item_data);
item_data = NULL;
}
+ close(fd);
+ unlink(ua_dataSS->tar_data->text_files_info[ATTR_FILE].extracted_name);
+ ua_dataSS->tar_data->text_files_info[ATTR_FILE].size = 0;
return E_SS_FAILURE;
}
item_data[read_data] = '\0';
SS_Free(item_data);
item_data = NULL;
}
+ close(fd);
+ unlink(ua_dataSS->tar_data->text_files_info[ATTR_FILE].extracted_name);
+ ua_dataSS->tar_data->text_files_info[ATTR_FILE].size = 0;
return E_SS_FAILURE;
}
else
result = S_SS_SUCCESS;
+ close(fd);
+ unlink(ua_dataSS->tar_data->text_files_info[ATTR_FILE].extracted_name);
+ ua_dataSS->tar_data->text_files_info[ATTR_FILE].size = 0;
return result;
}
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);
+ char patchfile_source_path[MAX_FILE_PATH];
snprintf(patchfile_source_path, MAX_FILE_PATH, "%s/%s", ua_dataSS->update_data->ua_delta_folder, SS_PATCHFILE_SOURCE);
if (!patch_path) {
case DIFFS:
{
LOGL(LOG_SSENGINE, "DIFFS mode start\n");
- tar_open(ua_dataSS->update_data->ua_delta_path);
- while (pFsNode) {
+ diff_iterator diff_iter;
+ if (tar_init_diff_iterations(ua_dataSS->tar_data, &diff_iter, pFsNode) < 0) {
+ ulResult = E_SS_FAILURE;
+ SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
+ LOGE("Couldn't begin updating diffs!\n");
+ break;
+ }
+ for (;;)
+ {
//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);
+ int broken = 0;
+ fs_params *temp_param;
+ switch(tar_diff_iter_next_extract(ua_dataSS->tar_data, &diff_iter, patchfile_source_path, &temp_param))
+ {
+ case -1:
+ broken = 1;
+ ulResult = E_SS_FAILURE;
+ SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
+ LOGE("Delta Read Failed\n");
+ break;
+ case 1:
+ broken = 1;
+ ulResult = S_SS_SUCCESS;
+ break;
+ case 0:
+ ulResult =
+ SS_UpdateDeltaFS(temp_param->file_old_path, temp_param->file_new_path, temp_param->sha1src,
+ temp_param->sha1trg, temp_param->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();
+ ubPatch, temp_param->data_size, ulReadCnt, ulFileIndex);
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);
+ if (broken == 1)
break;
- }
+
+ SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
ulFileIndex++;
}
LOGL(LOG_SSENGINE, "DIFFS : Total index = [%d]\n",
ulFileIndex - 1);
- tar_close();
LOGL(LOG_SSENGINE, "DIFFS mode end\n");
}
break;
{
LOGL(LOG_SSENGINE, "NEWFILES mode start\n");
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)
+ if (ua_dataSS->tar_data->new_files_info.offset > 0) {
+ if (tar_extract_7z_file(ua_dataSS->tar_data) < 0) {
+ LOGE("newfiles extraction error!\n");
+ ulResult = E_SS_FAILURE;
+ break;
+ }
+ if (_7zdecompress(ua_dataSS->tar_data->new_files_info.extracted_name) == 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);
- SS_DeleteFile(new_compressed_path);
+ SS_DeleteFile(ua_dataSS->tar_data->new_files_info.extracted_name);
} else {
- LOGL(LOG_SSENGINE, "No %s in %s, becouse there are no new files\n", SS_COMPRESSED_FILE, ua_dataSS->parti_info->ua_parti_name);
+ LOGL(LOG_SSENGINE, "No %s in %s, because there are no new files\n", SS_COMPRESSED_FILE, ua_dataSS->parti_info->ua_parti_name);
}
LOGL(LOG_SSENGINE, "NEWFILES mode end\n");
}
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");
#ifndef _SS_UPI_H_
#define _SS_UPI_H_
-#include <stdbool.h>
#include "fota_common.h"
+#include "SS_Common.h"
#define DISPLAYRESOLUTION_SIZE 50
//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);
#endif //_SS_UPI_H_
#define SS_PATCHLISTFORMAT ".txt"
#define SS_PATCH_ATTR_FORMAT "_attr.txt"
+#define SS_GENERIC_FILE "file"
+#define SS_GENERIC_PATCHLIST SS_GENERIC_FILE SS_PATCHLISTFORMAT
+#define SS_GENERIC_ATTR SS_GENERIC_FILE SS_PATCH_ATTR_FORMAT
#define SS_FSCOUNT_MAGIC_KEY "PaTcHCoUnT:"
#define SS_FSCOUNT_MAGIG_KEYLEN (11) //length of SS_FSCOUNT_MAGIC_KEY
#define SS_STRING_ZIP "ZIP"
#define SS_STRING_END "END"
-#define SS_COMMON_WORKSPACE "/run/upgrade-sysroot/opt/usr/data/fota"
-
struct tar_Data {
int itemSize;
int itemOffset;
/*
* upgrade-apply-deltafs
*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * 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.
#include <string.h>
#include <errno.h>
#include <limits.h>
+#include "fota_log.h"
#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)
+
+#define VISITED_STRING "VISITED"
+#define DIFF_PREFIX "/diff"
+#define GENERIC_FILENAME "file.txt"
+
+// for the sake of simplicity this stays global
+static gzFile gz_tar = NULL;
+
+// the following 6 functions are copied from this same repo, upgrade-apply/main.c
+void fd_cleanup(int *fd)
{
- 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);
- }
+ if (!fd || *fd < 0)
+ return;
+ close(*fd);
}
-/*-----------------------------------------------------------------------------
- tar_get_item_offset
- ----------------------------------------------------------------------------*/
-int tar_get_item_offset(char *tar, char *item)
+int gzip_open(const char *pathname, int oflags, ...)
{
- 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");
+ if (gz_tar != NULL) {
+ errno = EALREADY;
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;
+ // We assume oflags == O_RDONLY, since that's what we actually use.
+ // Also we don't care about the mode since we are lazy.
+ if (oflags != O_RDONLY) {
+ errno = ENOTSUP;
+ return -1;
}
- 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;
- }
- }
+ __attribute__((cleanup(fd_cleanup))) int inner_fd = open(pathname, O_RDONLY);
+ if (inner_fd == -1)
+ return -1;
- Cleanup:
- if (gTarFd < 0)
- close(fd);
+ gz_tar = gzopen(pathname, "r");
+ if (gz_tar == NULL)
+ return -1;
+ inner_fd = -1;
- return ret;
+ return 1;
}
-/*-----------------------------------------------------------------------------
- tar_get_item_size
- ----------------------------------------------------------------------------*/
-int tar_get_item_size(char *tar, char *item)
+int gzip_close(__attribute__((unused)) int useless_fd)
{
- 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");
+ if (gz_tar == NULL) {
+ errno = EINVAL;
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;
+ return gzclose(gz_tar);
}
-/*-----------------------------------------------------------------------------
- tar_get_cfg_data
- ----------------------------------------------------------------------------*/
-int tar_get_cfg_data(char *tar, char *item, char *buf, int buflen)
+ssize_t gzip_read(__attribute__((unused)) int useless_fd, void *buf, size_t len)
{
- 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");
+ if (gz_tar == NULL) {
+ errno = EINVAL;
return -1;
}
- data_size = tar_get_item_size(tar, item);
- if (data_size <= 0)
- return -1;
- if (data_size > buflen)
- data_size = buflen;
+ return gzread(gz_tar, buf, len);
+}
- data_offset = tar_get_item_offset(tar, item);
- if (data_offset < 0)
- return -1;
+ssize_t gzip_write(__attribute__((unused)) int useless_fd, __attribute__((unused)) const void *buf, __attribute__((unused)) size_t len)
+{
+ // Again, we do not use this.
+ errno = ENOTSUP;
+ return -1;
+}
- fd = open(tar, O_RDONLY);
- if (fd < 0) {
- LOG("can't open file(%s).\n", tar);
- return -1;
- }
+int tar_get_tartype(char *tar_path, tartype_t **type)
+{
+ static tartype_t gzip_type = {gzip_open, gzip_close, gzip_read, gzip_write};
- pos = lseek(fd, data_offset, SEEK_SET);
- if (pos < 0) {
- LOG("lseek fail (%s offset %d).\n", tar, data_offset);
- close(fd);
+ if ((strlen(tar_path) > strlen(".tar")) && (strcmp(tar_path + strlen(tar_path) - strlen(".tar"), ".tar") == 0)) {
+ *type = NULL;
+ }
+ else if ((strlen(tar_path) > strlen(".tar.gz")) && (strcmp(tar_path + strlen(tar_path) - strlen(".tar.gz"), ".tar.gz") == 0)) {
+ *type = &gzip_type;
+ }
+ else if ((strlen(tar_path) > strlen(".tgz")) && (strcmp(tar_path + strlen(tar_path) - strlen(".tgz"), ".tgz") == 0)) {
+ *type = &gzip_type;
+ }
+ else {
+ LOGE("Unknown/unsupported file extension for delta!!!\n");
return -1;
}
+ return 0;
+}
- rdcnt = read(fd, buf, data_size);
- if (rdcnt != (ssize_t) data_size) {
- LOG("read fail(%s from %s).\n", item, tar);
- close(fd);
+int tar_init_with_type(TAR **tar, char *tar_path, tartype_t *type)
+{
+ if (tar_open(tar, tar_path, type, O_RDONLY, 0, 0) < 0) {
+ *tar = NULL;
+ LOGE("tar_open() fail!\n");
return -1;
}
-
- close(fd);
-
- return rdcnt;
+ return 0;
}
-tar_Data_t *tar_build_cfg_table(char *tar)
+static off_t tar_seek(TAR *tar, off_t offset, int whence)
{
+ if(!gz_tar)
+ return lseek(tar_fd(tar), offset, whence);
+ return gzseek(gz_tar, offset, whence);
+}
- 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;
+static int tar_reset_to_subject(TAR *tar, char *subject_name, off_t *offset)
+{
+ if (*offset > 0) {
+ if (tar_seek(tar, *offset, SEEK_SET) < 0) {
+ LOGE("seeking error!\n");
+ return -1;
}
+ if (th_read(tar) < 0) {
+ LOGE("unexpected th_read() return value!\n");
+ return -1;
+ }
+ return 0;
}
- 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;
+ off_t local_offset = 0;
+ if (tar_seek(tar, 0, SEEK_SET) < 0) {
+ LOGE("seeking error!\n");
+ return -1;
}
- 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;
+
+ for (;;)
+ {
+ // if 1 is returned we should fail as well
+ switch (th_read(tar))
+ {
+ case -1:
+ LOGE("th_read() fail!\n");
+ return -1;
+ case 1:
+ LOGE("EOF reached -> delta error!\n");
+ return -1;
+ case 0:
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;
+ char *pathname = th_get_pathname(tar);
+ if (strcmp(pathname, subject_name) == 0) {
+ *offset = local_offset;
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;
- }
+
+ if (TH_ISREG(tar) && (tar_skip_regfile(tar) < 0)) {
+ LOGE("tar_skip_regfile() error!\n");
+ return -1;
}
- 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;
+ if ((local_offset = tar_seek(tar, 0, SEEK_CUR)) < 0) {
+ LOGE("seeking error!\n");
+ return -1;
}
}
+ return 0;
}
-void deleteNode(tar_Data_t * head, tar_Data_t * n)
+static int tar_verify_and_extract_text(tar_info *tar_data, char *pathname, off_t last_seek)
{
- 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;
+ if (strcmp(tar_data->new_files_info.item_name, pathname) == 0) {
+ if (tar_data->new_files_info.offset > 0) {
+ LOGE("Dupicate file found in delta!\n");
+ return -1;
}
- 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;
+ tar_data->new_files_info.offset = last_seek;
+ LOGL(LOG_SSENGINE, "%s found in archive\n", tar_data->new_files_info.item_name);
+ return 0;
}
- 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;
+ for(int i = 0; i < NO_OF_TEXT_FILES; i++)
+ {
+ if (strcmp(tar_data->text_files_info[i].item_name, pathname) == 0) {
+ if (tar_data->text_files_info[i].size > 0) {
+ LOGE("Dupicate file found in delta!\n");
+ return -1;
+ }
+ tar_data->text_files_info[i].size = th_get_size(tar_data->tar);
+ if (tar_data->text_files_info[i].size == 0) {
+ LOGE("Needed file has size 0!");
+ return -1;
+ }
+ if (tar_extract_file(tar_data->tar, tar_data->text_files_info[i].extracted_name) != 0) {
+ tar_data->text_files_info[i].size = 0;
+ LOGE("tar extraction error!");
+ return -1;
}
+ LOGL(LOG_SSENGINE, "%s found in archive\n", tar_data->text_files_info[i].item_name);
+ return 1;
}
- 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()
+int tar_get_cfg_data(tar_info *tar_data)
{
- 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);
+ if (tar_reset_to_subject(tar_data->tar ,tar_data->subject_name, &(tar_data->subject_offset)) < 0) {
+ LOGE("tar_reset_to_subject() error!\n");
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;
- }
+ off_t last_seek = 0;
+ int ret;
- 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;
+ for(;;)
+ {
+ switch(th_read(tar_data->tar))
+ {
+ case -1:
+ LOGE("th_read() fail!\n");
+ return -1;
+ case 1:
+ LOGL(LOG_SSENGINE, "EOF reached -> end of tar configuration\n");
+ return 0;
+ case 0:
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;
+ char *curr_pathname = th_get_pathname(tar_data->tar);
+ char *pos = strchr(curr_pathname, '/');
+ if ((!pos) || (strncmp(tar_data->subject_name, curr_pathname, (pos - curr_pathname) + 1) != 0)) {
+ return 0;
}
+ tar_data->uncompressed_folder_size += th_get_size(tar_data->tar);
- /* 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;
+ if ((ret = tar_verify_and_extract_text(tar_data, curr_pathname, last_seek)) < 0) {
+ LOGE("Delta config error!\n");
+ return -1;
}
- /* move file pointer to next file header */
- blknum = size_dec / TAR_BLOCK_SIZE;
- if (size_dec % TAR_BLOCK_SIZE)
- blknum++;
+ if ((ret == 0) && TH_ISREG(tar_data->tar) && (tar_skip_regfile(tar_data->tar) < 0)) {
+ LOGE("tar_skip_regfile() error!\n");
+ return -1;
+ }
- 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);
+ if ((last_seek = tar_seek(tar_data->tar, 0, SEEK_CUR)) < 0) {
+ LOGE("seeking error!\n");
return -1;
}
}
-
- Cleanup:
- close(fd);
- LOG("ret=%d\n", ret);
-
- return ret; //Should return +1?? or Ignore??
+ return 0;
}
-int fast_tar_extract_file(char *tar, char *item, char *pathname, int size, int offset)
+int tar_extract_7z_file(tar_info *tar_data)
{
- 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");
+ if (tar_seek(tar_data->tar, tar_data->new_files_info.offset, SEEK_SET) < 0) {
+ LOGE("seeking error!\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");
+ if (th_read(tar_data->tar) != 0) {
+ LOGE("unexpected return value from th_read()!\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);
+
+ LOGL(LOG_SSENGINE, "extracting %s\n", th_get_pathname(tar_data->tar));
+
+ if (tar_extract_file(tar_data->tar, tar_data->new_files_info.extracted_name) < 0) {
+ LOGE("tar extraction error!\n");
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 0;
+}
+
+int tar_init_diff_iterations(tar_info *tar_data, diff_iterator *diff_iter, fs_params *head)
+{
+ if (tar_reset_to_subject(tar_data->tar, tar_data->subject_name, &(tar_data->subject_offset)) < 0) {
+ LOGE("tar_reset_to_subject() fail!\n");
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;
+ diff_iter->head = head;
+ diff_iter->sum = 0;
+ int patch_count = 0;
+ fs_params *tmp = head;
+ while(tmp)
+ {
+ patch_count++;
+ tmp = tmp->nextnode;
}
- SS_Free(buf);
- if (gTarFd < 0)
- close(fd);
- fsync(fd2);
- close(fd2);
- return rdcnt; // or jus return success?
+ diff_iter->sum_max = patch_count;
+
+ return 0;
}
-int tar_extract_file(char *tar, char *item, char *pathname)
+static int tar_check_diff_sum(diff_iterator *diff_iter)
{
- 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);
+ return (diff_iter->sum == diff_iter->sum_max) ? 1 : -1;
+}
- 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;
+static fs_params* tar_check_diff_iter_list(diff_iterator *diff_iter, char *pathname)
+{
+ fs_params *tmp = diff_iter->head;
+ while (tmp) {
+ if ((strcmp(tmp->patch_name, VISITED_STRING) !=0) && (strcmp(tmp->patch_name, pathname) == 0)) {
+ (diff_iter->sum)++;
+ // to signify that it has been visited
+ strcpy(tmp->patch_name, VISITED_STRING);
+ return tmp;
+ }
+ tmp = tmp->nextnode;
}
- SS_Free(buf);
- close(fd);
- fsync(fd2);
- close(fd2);
- return rdcnt; // or jus return success?
+ return tmp;
}
+
+int tar_diff_iter_next_extract(tar_info *tar_data, diff_iterator *diff_iter, char *target, fs_params **params)
+{
+ for (;;)
+ {
+ switch(th_read(tar_data->tar))
+ {
+ case -1:
+ LOGE("th_read() fail!\n");
+ return -1;
+ case 1:
+ LOGL(LOG_SSENGINE, "EOF reached -> end of tar configuration\n");
+ return tar_check_diff_sum(diff_iter);
+ case 0:
+ break;
+ }
+
+ char *curr_pathname = th_get_pathname(tar_data->tar);
+ char *pos = strchr(curr_pathname, '/');
+ if (!pos) {
+ return tar_check_diff_sum(diff_iter);
+ }
+ if (strncmp(tar_data->subject_name, curr_pathname, (pos - curr_pathname) + 1) != 0)
+ {
+ return tar_check_diff_sum(diff_iter);
+ }
+ if (strstr(curr_pathname, DIFF_PREFIX)) {
+ fs_params *tmp;
+ if (!(tmp = tar_check_diff_iter_list(diff_iter, pos + 1))) {
+ LOGE("Config file differs form delta!");
+ return -1;
+ }
+ *params = tmp;
+ (*params)->data_size = th_get_size(tar_data->tar);
+ if (tar_extract_file(tar_data->tar, target) < 0) {
+ LOGE("File extraction error!\n");
+ return -1;
+ }
+ return 0;
+ }
+ if (TH_ISREG(tar_data->tar) && (tar_skip_regfile(tar_data->tar) < 0)) {
+ LOGE("tar_skip_regfile() error!\n");
+ return -1;
+ }
+ }
+}
\ No newline at end of file
/*
* upgrade-apply-deltafs
*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * 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.
#ifndef _FOTA_TAR_H_
#define _FOTA_TAR_H_
-int tar_get_item_offset(char *tar, char *item);
+#include <zlib.h>
+#include <libtar.h>
+#include "ua_types.h"
+#include "SS_UPI.h"
+typedef struct _diff_iterator {
+ int sum;
+ fs_params *head;
+ char *subject_name;
+ int sum_max;
+} diff_iterator;
-int tar_get_item_size(char *tar, char *item);
+int tar_get_tartype(char *tar_path, tartype_t **type);
+int tar_init_with_type(TAR **tar, char *tar_path, tartype_t *type);
+int tar_get_cfg_data(tar_info *tar_data);
+int tar_extract_7z_file(tar_info *tar_data);
+int tar_init_diff_iterations(tar_info *tar_data, diff_iterator *diff_iter, fs_params *head);
+int tar_diff_iter_next_extract(tar_info *tar_data, diff_iterator *diff_iter, char *target, fs_params **params);
-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_ */
#define __UA_TYPES_H__
#include <stdio.h>
+#include <libtar.h>
#define MAX_FILE_PATH 512
+// every delta should have a patchlist text file, and can have
+// an attribute file additionally
+#define NO_OF_TEXT_FILES 2
+
+// the following macros define the meaning of indexes in tar_info.text_files_info array
+
+// this file has a list of diff files and the number of all operations (DIFFS, NEWS, MOVES etc.)
+// this file is required to be present in a delta
+#define PATCHLIST_FILE 0
+
+// this files lists files whose attributes changed and their new values
+#define ATTR_FILE 1
/*
* FOTA Adaptaion header
char ua_attrib_path[MAX_FILE_PATH];
} ua_delta_info_t;
+typedef struct _file_text_info {
+ int size;
+ char item_name[MAX_FILE_PATH];
+ char extracted_name[MAX_FILE_PATH];
+} text_file_info;
+
+typedef struct _file_7z_info {
+ off_t offset;
+ char item_name[MAX_FILE_PATH];
+ char extracted_name[MAX_FILE_PATH];
+} file_7z_info;
+
+typedef struct _tar_info {
+ TAR *tar;
+ char *subject_name;
+ int uncompressed_folder_size;
+ off_t subject_offset;
+ file_7z_info new_files_info;
+ // id = 0 -> config file, id = 1 -> attribute file
+ text_file_info text_files_info[NO_OF_TEXT_FILES];
+} tar_info;
+
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;
+ tar_info *tar_data;
unsigned long ua_operation;
void (*ui_progress)(void *, unsigned long);
int (*write_data_to_blkdev)(char *, int, int, char *);
// 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 ua_update_data_t s_update_data;
+static tar_info s_tar_data;
+
+static text_file_info s_text_files_info[NO_OF_TEXT_FILES];
+
+static file_7z_info s_new_files_info;
+
typedef struct temp_opt{
char * archive;
char * archive_file;
if (msg) {
printf("%s\n", msg);
}
- printf("print_usage: upgrade-apply-deltafs --archive delta_dir --dest directory --archive-file label.img\n"
- "delta_dir: directory path where delta.tar file is located\n"
+ printf("print_usage: upgrade-apply-deltafs --archive delta_path --dest directory --archive-file label.img\n"
+ "delta_path: filepath of delta (allowed file extensions: .tar, .tar.gz, .tgz)\n"
"directory: directory where partition to be upgraded is mounted\n"
"label.img: name of the directory inside of delta that is to be used during upgrade\n"
);
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;
+ tar_info *ua_tar_data = &s_tar_data;
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.tar_data = ua_tar_data;
ua_dataSS.ui_progress = fota_gui_progress;
if (ua_update_data->ua_delta_path != NULL) {
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;
+ tar_info *ua_tar_data = &s_tar_data;
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.tar_data = ua_tar_data;
ua_dataSS.ui_progress = fota_gui_progress;
if (ua_update_data->ua_delta_path != NULL)
}
/*-----------------------------------------------------------------------------
+ remove_cfg_file_files
+ ----------------------------------------------------------------------------*/
+void remove_extracted_files(void)
+{
+ for (int i = 0; i < NO_OF_TEXT_FILES; i++)
+ {
+ if (s_tar_data.text_files_info[i].size > 0) {
+ if (unlink(s_tar_data.text_files_info[i].extracted_name) < 0) {
+ LOGE("unlink error!\n");
+ }
+ }
+ }
+}
+
+/*-----------------------------------------------------------------------------
update_all
----------------------------------------------------------------------------*/
int update_all()
{
int ret = OK;
- int cause = 0, item_size = 0;
+ int cause = 0;
unsigned long ui32Operation = UI_OP_SCOUT;
char * org_dir = getcwd(NULL, 0);
cause = ret;
goto CleanUp;
}
+ if (tar_get_cfg_data(&s_tar_data) < 0) {
+ LOGE("Delta read error!\n");
+ ret = UPI_DELTACOUNT_ERROR;
+ goto CleanUp;
+ }
+ if (s_tar_data.text_files_info[PATCHLIST_FILE].size <= 0) {
+ LOGE("Patchlist file not present in delta -> aborting!\n");
+ ret = UPI_DELTACOUNT_ERROR;
+ goto CleanUp;
+ }
- 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;
-
+ s_update_data.data_size = s_tar_data.uncompressed_folder_size;
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,
goto CleanUp;
}
+
LOG(" set weight to draw progressive bar.....\n");
set_data_weight(s_update_data.data_size);
set_data_weight_offset();
CleanUp:
if (ret != OK)
save_cause(cause);
- free(org_dir);
+ remove_extracted_files();
+ free(org_dir);
return ret;
}
}
/*-----------------------------------------------------------------------------
- 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");
-
- 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)
}
/*-----------------------------------------------------------------------------
- remove_temp_files
+ set_delta_folder
----------------------------------------------------------------------------*/
-void remove_temp_files(void)
+int set_delta_folder(void)
{
- int ret = 0;
- char *ua_temp_path;
- struct stat sbuf;
+ char *pos = strrchr(delta_path, '/');
+ if ((pos == NULL) || ((pos - delta_path + 1) == strlen(delta_path))) {
+ print_usage("Invalid delta path");
+ return -1;
+ }
+ snprintf(delta_folder, (pos - delta_path) + 1, "%s", delta_path);
+ return 0;
+}
+/*-----------------------------------------------------------------------------
+ set_tar_info
+ ----------------------------------------------------------------------------*/
+void set_tar_info(TAR *tar)
+{
+ s_tar_data.subject_name = strdup(s_part_info.ua_subject_name);
+ s_tar_data.tar = tar;
+ s_tar_data.subject_offset = 0;
+ s_tar_data.uncompressed_folder_size = 0;
+ s_new_files_info.offset = 0;
+ snprintf(s_new_files_info.item_name, MAX_FILE_PATH, "%s%s", s_tar_data.subject_name, SS_NEW_COMPRESSED_FILE);
+ snprintf(s_new_files_info.extracted_name, MAX_FILE_PATH, "%s/%s", s_update_data.ua_delta_folder, SS_NEW_COMPRESSED_FILE);
- ua_temp_path = s_update_data.ua_temp_path;
- if (NULL == ua_temp_path)
- return;
+ s_text_files_info[PATCHLIST_FILE].size = 0;
+ s_text_files_info[ATTR_FILE].size = 0;
- 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;
- }
- }
+ snprintf(s_text_files_info[PATCHLIST_FILE].item_name, MAX_FILE_PATH, "%s%s%s", s_tar_data.subject_name, s_part_info.ua_parti_name, SS_PATCHLISTFORMAT);
+ snprintf(s_text_files_info[PATCHLIST_FILE].extracted_name, MAX_FILE_PATH, "%s/%s%s", s_update_data.ua_delta_folder, s_part_info.ua_parti_name, SS_PATCHLISTFORMAT);
- 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);
- }
-}
+ snprintf(s_text_files_info[ATTR_FILE].item_name, MAX_FILE_PATH, "%s%s%s", s_tar_data.subject_name, s_part_info.ua_parti_name, SS_PATCH_ATTR_FORMAT);
+ snprintf(s_text_files_info[ATTR_FILE].extracted_name, MAX_FILE_PATH, "%s/%s%s", s_update_data.ua_delta_folder, s_part_info.ua_parti_name, SS_PATCH_ATTR_FORMAT);
+ s_tar_data.text_files_info[PATCHLIST_FILE] = s_text_files_info[PATCHLIST_FILE];
+ s_tar_data.text_files_info[ATTR_FILE] = s_text_files_info[ATTR_FILE];
+ s_tar_data.new_files_info = s_new_files_info;
+}
/*-----------------------------------------------------------------------------
arg_parse
----------------------------------------------------------------------------*/
print_usage("Invalid parameter count");
return -1;
}
- const char * archive = NULL;
- const char * archive_file = NULL;
- const char * dest = NULL;
+ char * archive = NULL;
+ char * archive_file = NULL;
+ char * dest = NULL;
const struct option long_options[] = {
{"archive", required_argument, NULL, 0 },
{"dest", required_argument, NULL, 1 },
char *dot_pos;
int len;
temp_opt my_opt;
+ tartype_t *type;
+ TAR *tar;
log_init();
- if(arg_parse(argc, argv, &my_opt) < 0) {
+ if (arg_parse(argc, argv, &my_opt) < 0) {
ret = UPI_INVALID_PARAM_ERROR;
goto Results;
}
SS_set_feature_support_capability(1);
#endif
- 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);
+ snprintf(delta_path, sizeof(delta_folder)-1, "%s", my_opt.archive);
+ if (set_delta_folder() < 0) {
+ ret = UPI_INVALID_PARAM_ERROR;
+ goto Results;
+ }
s_update_data.ua_delta_folder = strdup(delta_folder);
-
+ s_update_data.ua_delta_path = strdup(delta_path);
snprintf(mnt_point, sizeof(mnt_point)-1, "%s", my_opt.dest);
snprintf(temp_folder, sizeof(temp_folder)-1, "%s", TEMP_FOLDER);
snprintf(log_folder, sizeof(log_folder)-1, "%s", SYSTEM_LOG_DIR);
s_part_info.ua_parti_name[len] = '\0';
s_part_info.ua_subject_name = my_opt.archive_file;
- s_update_cfg.source_img_size = 0; // TODO lets see if 0 will work
+ s_update_cfg.source_img_size = 0; // TODO lets see if 0 works
- /* load block device number at run-time */
+ if (tar_get_tartype(s_update_data.ua_delta_path, &type) < 0) {
+ ret = UPI_CONFIG_ERROR;
+ goto Results;
+ }
- ret = fota_path_init();
- if (ret == FAIL) {
- ret = UPI_DELTA_PATH_LENGTH_ERROR;
+ if (tar_init_with_type(&tar, s_update_data.ua_delta_path, type) < 0) {
+ ret = UPI_CONFIG_ERROR;
goto Results;
}
+
+ set_tar_info(tar);
+
+
+
LOG("<<<<<<<<<<< log_init >>>>>>>>>>>>\n");
/* UPI version check */
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_DELTACOUNT_ERROR:
case UPI_VERIFY_ERROR:
case UPI_UPDATE_ERROR:
- fota_path_deinit();
log_deinit();
+ if(s_tar_data.tar)
+ tar_close(s_tar_data.tar);
_exit_stdio();
return -1;
case SUCCESS:
- fota_path_deinit();
log_deinit();
/* Preserve log file for debugging */
+ if(s_tar_data.tar)
+ tar_close(s_tar_data.tar);
_exit_stdio();
return 0;
default:
#define UPI_DELTACOUNT_ERROR UPI_ERROR(EC)
#define UPI_PARTINFO_ERROR UPI_ERROR(ED)
-#define DEFAULT_DELTA_NAME "delta.tar"
-
enum {
UA_OP_MODE_FG = 0,
UA_OP_MODE_BG