extern int gvalid_session;
extern void create_dir(char *pathname, int mode);
-#ifdef SUPPORT_CONTAINER
-//unzip source archive , apply patch from extracted delta folder and repack the source archive
-int SS_UpdateArchive(ua_dataSS_t * ua_dataSS, const char *source_filename, const char *target_filename,
- const char *source_sha1_str, const char *target_sha1_str)
-{
- FILE *fp;
- char *line = NULL, *token = NULL, *source_file = NULL, *new_file = NULL, *dir_to_create = NULL, *patch_file = NULL;
- char patch_path_full[MAX_FILE_PATH] = { 0, }; //absolute path for patches
- char source_path_full[MAX_FILE_PATH] = { 0, }; //absolute path for uncompressed source files
- char target_path_full[MAX_FILE_PATH] = { 0, };
- char patchlist[MAX_FILE_PATH] = { 0, };
- char cmd[2 * MAX_FILE_PATH] = { 0, };
- size_t len = 0, read = 0;
- int result = S_SS_SUCCESS;
- uint8_t target_sha1[SHA_DIGEST_SIZE];
- uint8_t source_sha1[SHA_DIGEST_SIZE] = { 0, };
- FileInfo source_data = { 0, };
- int backupsrc = -1;
- SinkFn sink = NULL;
- void *tok = NULL;
- int output = -1;
- char *outname = NULL;
- if (ParseSha1(target_sha1_str, target_sha1) != 0) {
- LOGE("failed to parse tgt-sha1 \"%s\"\n", target_sha1_str);
- return E_SS_FAILURE;
- }
-
- 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_data) == 0) {
- if (memcmp(source_data.sha1, source_sha1, SHA_DIGEST_SIZE) == 0) {
- LOGL(LOG_SSENGINE, "SS_UpdateDeltaFS - Patch Can be applied\n");
- if (source_data.data)
- SS_Free(source_data.data);
- } else if (memcmp(source_data.sha1, target_sha1, SHA_DIGEST_SIZE) == 0) {
- LOGL(LOG_SSENGINE, "SS_UpdateDeltaFS - Patch Already applied\n");
- if (source_data.data)
- SS_Free(source_data.data);
- return S_SS_SUCCESS;
- } else {
- //Check for backup file SHA
- SS_Free(source_data.data);
- source_data.data = NULL;
- LOGL(LOG_SSENGINE, "SS_UpdateDeltaFS - Source was currupted, Try loading from backup source\n");
- if (SS_LoadFile(SS_BACKUP_SOURCE, &source_data) == 0) {
- if (memcmp(source_data.sha1, source_sha1, SHA_DIGEST_SIZE) == 0) {
- if (SS_CopyFile(NULL, SS_BACKUP_SOURCE, source_filename) != 0) {
- LOGE("copy of backup to \"%s\" failed: %s\n", source_filename, strerror(errno));
- SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
- if (source_data.data)
- SS_Free(source_data.data);
- return E_SS_FAILURE;
- }
- LOGL(LOG_SSENGINE,
- "SS_UpdateDeltaFS - Patch Can be applied from using backup file as source\n");
- } else {
- SS_SetUpgradeState(E_SS_FSSRCCURRUPTED);
- if (source_data.data)
- SS_Free(source_data.data);
- return E_SS_FAILURE;
- }
- } else {
- SS_SetUpgradeState(E_SS_FSSRCCURRUPTED);
- if (source_data.data)
- SS_Free(source_data.data);
- return E_SS_FAILURE;
- }
- }
- } else {
- LOGL(LOG_SSENGINE, "SS_UpdateDeltaFS - Source was deleted, Try loading from backup source\n");
- if (SS_LoadFile(SS_BACKUP_SOURCE, &source_data) == 0) {
- if (memcmp(source_data.sha1, source_sha1, SHA_DIGEST_SIZE) == 0) {
- if (SS_CopyFile(NULL, SS_BACKUP_SOURCE, source_filename) != 0) {
- LOGE("copy of backup to \"%s\" failed: %s\n", source_filename, strerror(errno));
- SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
- if (source_data.data)
- SS_Free(source_data.data);
- return E_SS_FAILURE;
- }
- LOGL(LOG_SSENGINE, "SS_UpdateDeltaFS - Patch Can be applied from using backup file as source\n");
- } else {
- SS_SetUpgradeState(E_SS_FSSRCCURRUPTED);
- if (source_data.data)
- SS_Free(source_data.data);
- return E_SS_FAILURE;
- }
- } else {
- SS_SetUpgradeState(E_SS_FSSRCCURRUPTED);
- if (source_data.data)
- SS_Free(source_data.data);
- return E_SS_FAILURE;
- }
- }
- }
-#ifndef ENHANCED_BSDIFF
- backupsrc = SS_BackupSource(source_filename);
- if (backupsrc != 0) {
- LOGE("failed to Backup source File:[%s] \n", source_filename);
- SS_SetUpgradeState(E_SS_FSSRCBACKUPFAILED);
- return E_SS_FAILURE;
- }
-#endif
- //create workspace for processing container upgrade
- SS_CreateFolder(NULL, SS_ARCHIVE_WORK_FOLDER);
- SS_CreateFolder(NULL, SS_ARCHIVE_UNPACK_FOLDER);
-
- //unpack the source container to the unpack workspace
- snprintf(cmd, sizeof(cmd) - 1, "%s -qo %s -d %s", SS_UNZIP_COMMAND, source_filename, SS_ARCHIVE_UNPACK_FOLDER);
- result = _system_cmd_wait(cmd);
- if (result != S_SS_SUCCESS) {
- LOGE("zip extraction for [%s] failed, code [%d]\n", cmd, result);
- return E_SS_FAILURE;
- }
- //extract unpack scipt from delta.tar to process containers later
- if (tar_get_item_size(ua_dataSS->update_data->ua_delta_path, SS_KERNEL_UNPACK_SCRIPT) > 0)
- if (tar_extract_file(ua_dataSS->update_data->ua_delta_path, SS_KERNEL_UNPACK_SCRIPT, SS_KERN_UNPK_SCRIPT_PATH) >
- 0)
- LOGL(LOG_SSENGINE, "Extracted %s successfully\n", SS_KERNEL_UNPACK_SCRIPT);
- else {
- LOGE("Error in fn tar_extract_file for item %s", SS_KERNEL_UNPACK_SCRIPT);
- SS_SetUpgradeState(E_SS_DELTA_IS_CORRUPT);
- result = E_SS_FAILURE;
- }
- //move new tpk extracted in the delta folder to the work folder
- new_file = strrchr(target_filename, '/');
- snprintf(source_path_full, sizeof(source_path_full) - 1, "%s/%s", SS_ARCHIVE_DELTA_FOLDER, new_file + 1);
- snprintf(target_path_full, sizeof(target_path_full) - 1, "%s/%s", SS_ARCHIVE_WORK_FOLDER, new_file + 1);
-
- result = rename(source_path_full, target_path_full);
- if (result != 0) {
- LOGE("fatal error in moving %s to %s\n", source_path_full, target_path_full);
- return E_SS_FAILURE;
- }
- snprintf(cmd, sizeof(cmd) - 1, "%s -qo %s -d %s", SS_UNZIP_COMMAND, target_path_full, SS_ARCHIVE_WORK_FOLDER);
- result = _system_cmd_wait(cmd);
- if (result != S_SS_SUCCESS) {
- LOGE("zip extraction for [%s] failed, code [%d]\n", cmd, result);
- return E_SS_FAILURE;
- } else
- LOGL(LOG_SSENGINE, "Thin zip extracted successfully\n");
- // open the patch list and start iterating through the changes and the same files
- snprintf(patchlist, MAX_FILE_PATH, "%s/%s", SS_ARCHIVE_DELTA_FOLDER, SS_CONTAINER_INFO_FILE);
- fp = fopen(patchlist, "r");
- if (!fp) {
- LOGE("file open error [%s]\n", patchlist);
- return E_SS_FAILURE;
- }
-
- while ((read = getline(&line, &len, fp)) != -1) {
-
- switch (line[0]) { // '-' == Delete File, 's' == same File, 'c' == Changed File
- case 's': //for same files case, just extract from old tpk to the work folder, update new tpk in the end
- token = strtok(line, SS_SEPARATOR_TOKEN);
-
- source_file = strtok(NULL, SS_NEWLINE_TOKEN);
-
- snprintf(source_path_full, sizeof(source_path_full) - 1, "%s/%s", SS_ARCHIVE_UNPACK_FOLDER, source_file);
- snprintf(target_path_full, sizeof(target_path_full) - 1, "%s/%s", SS_ARCHIVE_WORK_FOLDER, source_file);
- LOGL(LOG_SSENGINE, "copy %s\n", source_file);
- result = SS_MoveFile(NULL, source_path_full, target_path_full);
- if (result != S_SS_SUCCESS) {
- LOGE("fatal error [%d]\n", errno);
- goto Cleanup;
- }
- break;
- case 'c':
- token = strtok(line, SS_SEPARATOR_TOKEN);
-
- source_file = strtok(NULL, SS_SEPARATOR_TOKEN);
- patch_file = strtok(NULL, SS_NEWLINE_TOKEN);
-
- snprintf(source_path_full, sizeof(source_path_full) - 1, "%s/%s", SS_ARCHIVE_UNPACK_FOLDER, source_file);
- snprintf(target_path_full, sizeof(target_path_full) - 1, "%s/%s", SS_ARCHIVE_WORK_FOLDER, source_file);
- LOGL(LOG_SSENGINE, "copy %s\n", source_file);
- result = SS_MoveFile(NULL, source_path_full, target_path_full);
- if (result != S_SS_SUCCESS)
- LOGE("fatal error [%d]\n", errno);
-
- snprintf(patch_path_full, sizeof(patch_path_full) - 1, "%s/%s", SS_ARCHIVE_DELTA_FOLDER, patch_file);
- snprintf(source_path_full, sizeof(source_path_full) - 1, "%s/%s", SS_ARCHIVE_WORK_FOLDER, source_file);
-
- {
- // We write the decoded output to "<tgt-file>.patch".
- //allocate some extra space to allow for concatinating ".patch" with the name
- outname = (char *)SS_Malloc(strlen(source_path_full) + 10);
- if (outname == NULL)
- goto Cleanup;
- strcpy(outname, source_path_full);
- strcat(outname, ".patch");
-
- output = open(outname, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU);
- if (output < 0) {
- LOGE("failed to open output file %s: %s\n", outname, strerror(errno));
- SS_Free(outname);
- goto Cleanup;
- }
- sink = ss_fileSink;
- tok = &output;
- }
- result = SS_ApplyBsdiff((char *)source_path_full, outname, patch_path_full, sink, tok, NULL);
- LOGL(LOG_SSENGINE, "GenerateTarget Output is %d and result is %d\n", output, result);
- if (output >= 0) {
- fsync(output);
- close(output);
- }
-
- if (result != 0) {
- LOGE("applying patch failed %s\n", source_path_full);
- if (outname != NULL)
- unlink(outname);
- goto Cleanup;
- }
- result = rename(outname, source_path_full);
- if (result != 0) {
- LOGE("fatal error %s\n", source_path_full);
- goto Cleanup;
- } else {
- LOGL(LOG_SSENGINE, "Successfully applied patch for [%s]\n", source_path_full);
- }
- break;
- default:
- break;
- }
- }
-
- new_file = strrchr(target_filename, '/');
- snprintf(cmd, sizeof(cmd) - 1, "%s -p %s %s /opt/data/fota", SS_KERN_UNPK_SCRIPT_PATH, SS_ARCHIVE_WORK_FOLDER,
- new_file + 1);
- int ret = _system_cmd_wait(cmd);
- LOGL(LOG_SSENGINE, "ret for %s is %d\n", cmd, ret);
-
- //Apply diff between intermediate new tpk and the new tpk which contains central dir changes only
- snprintf(patch_path_full, sizeof(patch_path_full) - 1, "%s/New_%s.delta", SS_ARCHIVE_DELTA_FOLDER, new_file + 1);
- snprintf(source_path_full, sizeof(source_path_full) - 1, "%s/%s", SS_ARCHIVE_WORK_FOLDER, new_file + 1);
-
- {
- // We write the decoded output to "<tgt-file>.patch".
- //allocate some extra space to allow for concatinating ".patch" with the name
- outname = (char *)SS_Malloc(strlen(source_path_full) + 10);
- if (outname == NULL)
- return E_SS_FAILURE;
- strcpy(outname, source_path_full);
- strcat(outname, ".patch");
-
- output = open(outname, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU);
- if (output < 0) {
- LOGE("failed to open output file %s: %s\n", outname, strerror(errno));
- SS_Free(outname);
- goto Cleanup;
- }
- sink = ss_fileSink;
- tok = &output;
- }
- result = SS_ApplyBsdiff((char *)source_path_full, outname, patch_path_full, sink, tok, NULL);
- LOGL(LOG_SSENGINE, "GenerateTarget Output is %d and result is %d\n", output, result);
- if (output >= 0) {
- fsync(output);
- close(output);
- }
-
- if (result != 0) {
- LOGE("applying patch failed %s\n", source_path_full);
- if (outname != NULL)
- unlink(outname);
- goto Cleanup;
- }
-
- if (SS_LoadFile(outname, &source_data) == 0)
- result = memcmp(source_data.sha1, target_sha1, SHA_DIGEST_SIZE);
- if (result != S_SS_SUCCESS) {
- LOGE("patch did not produce expected sha1 \n");
- SS_SetUpgradeState(E_SS_IMGSHA_MISMATCH);
- goto Cleanup;
- }
-
- result = rename(outname, source_path_full);
- if (result != 0) {
- LOGE("fatal error %s\n", source_path_full);
- goto Cleanup;
- }
- //Delete old file and copy patched archive, cant use rename as partitions may be different
- unlink(source_filename);
- if (result != 0) {
- LOGE("failed to unlink [%s] code [%d]\n", source_filename, errno);
- goto Cleanup;
- }
- result = (int)SS_CopyFile(NULL, source_path_full, target_filename);
- if (result != S_SS_SUCCESS) {
- LOGE("failed to copy file [%s] result [%d]\n", source_path_full, result);
- goto Cleanup;
- }
-
- Cleanup:
- fclose(fp);
- if (line)
- SS_Free(line);
- if (outname)
- SS_Free(outname);
- SS_DeleteFile(NULL, SS_KERN_UNPK_SCRIPT_PATH);
- SS_DeleteFile(NULL, SS_FIND_CMD_TARGET);
- SS_DeleteFolder(NULL, SS_CONTAINER_WORKSPACE);
- return result;
-}
-#endif
/*!
*********************************************************************************
* SS_UpdateDeltaFS