2 * upgrade-apply-deltafs
4 * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the License);
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
23 Function Prototypes Mandatory
36 #include <sys/statfs.h>
38 #include <brotli/decode.h>
40 #include "SS_Common.h"
41 #include "fota_common.h"
43 #include "SS_PatchDelta.h"
44 #include "SS_Engine_Errors.h"
45 #include "SS_FSUpdate.h"
48 int FS_UpgradeState = E_SS_FAILURE;
49 int gvalid_session = 0; //used as fail-safe in case device is turmed off or battery removed during update
50 fs_list *headptr_list;
52 //Check SS function if available
53 int file_exist(char *filename)
58 ret = lstat(filename, &buf);
60 ret = stat(filename, &buf);
62 return (ret >= 0) ? (1) : (0);
65 int SS_GetProgressResolution(int ultotalFSCnt)
67 if (ultotalFSCnt < DISPLAYRESOLUTION_SIZE)
70 return (ultotalFSCnt / DISPLAYRESOLUTION_SIZE);
73 void SS_SetUpgradeState(int Val)
75 LOGE("FAILED to upgrade Cause:[0x%x]\n", Val);
76 FS_UpgradeState = Val;
80 int SS_GetUpgradeState()
82 return FS_UpgradeState;
85 int SS_rename1(const char *old_file_name, const char *new_file_name)
87 int result = E_SS_FAILURE;
88 char *temp_name = NULL;
89 temp_name = (char *)SS_Malloc(strlen(new_file_name) + 10);
90 if (temp_name == NULL)
92 snprintf(temp_name, strlen(new_file_name) + 10, "%s.temp", new_file_name);
93 result = rename(new_file_name, temp_name);
96 result = rename(old_file_name, new_file_name);
99 result = unlink(temp_name);
107 *********************************************************************************
109 *********************************************************************************
112 * This is to verify nodes being added to global control structure for diff and delete cases.
113 * gvalid_session global is used to check if nodes are already verified.
118 * @return returns S_SS_SUCCESS and
119 * returns E_SS_FAILURE in case any error occurs
121 *********************************************************************************
123 int SS_FSVerifyNode(const char *path, const char *patchname, const char *sha1src, int type,
124 char *patchpath_name, int *data_size, int *data_offset)
126 FileInfo source_file;
127 uint8_t source_sha1[SHA_DIGEST_SIZE];
129 if (gvalid_session) {
130 if ((type == DIFFS || type == DELETES || type == MOVES) && !file_exist((char *)path)) {
131 LOGE("failed to verifyNodes [does not exist], Path : [%s] Type[%d]\n", path, type);
132 SS_SetUpgradeState(E_SS_FSBADNODES);
135 //For other types (NEWs, SYMs, Folders), SHA check not required
136 if ((type == DIFFS || type == MOVES/* ||type == DELETES */) &&
137 (strcmp(sha1src, SS_NULLENTRY) != 0)) {
138 if (ParseSha1(sha1src, source_sha1) != 0) {
139 LOGE("Failed to parse Src-sha1 \"%s\"\n", sha1src);
142 if (SS_LoadFile(path, &source_file) == 0) {
143 if (memcmp(source_file.sha1, source_sha1, SHA_DIGEST_SIZE) != 0) {
144 SS_Free(source_file.data);
145 unsigned char actualShaBuffer[41] = { 0, };
146 hex_digest(source_file.sha1, actualShaBuffer, SHA_DIGEST_SIZE);
147 LOGE("SS_FSVerifyNode - SHA mismatch with SRC - PATH [%s] Expected [%s] Actual [%s]\n",
148 path, sha1src, actualShaBuffer);
149 SS_SetUpgradeState(E_SS_FSSRCCURRUPTED); // Define other error
153 SS_Free(source_file.data);
160 *********************************************************************************
162 *********************************************************************************
165 * This is to append node to the global control structure for delta files.
170 * @return returns S_SS_SUCCESS and
171 * returns E_SS_FAILURE in case any error occurs
173 *********************************************************************************
175 int SS_AppendNode(const char *ubDeltaPath, fs_params ** headparam, fs_params ** tailparam, const char *old_path,
176 const char *new_path, const char *patchname, const char *sha1src, const char *sha1trg, int type,
177 char *patchpath_name)
179 fs_params *newnode = NULL;
183 if (!ubDeltaPath || !old_path || !new_path || !patchname || !sha1src || !sha1trg || !patchpath_name) {
184 LOGE("Bad Nodes, NULL params passed for Appending Nodes \n");
185 SS_SetUpgradeState(E_SS_FSINVALIDNODEPARAMS);
190 SS_FSVerifyNode(old_path, patchname, sha1src, type, patchpath_name, &data_size, &data_offset))) {
191 LOGE("Bad Nodes, Failed to pass verification - [Delta Path - %s][OldPath - %s] [NewPath - %s] \n", ubDeltaPath,
195 newnode = (fs_params *) SS_Malloc(sizeof(fs_params));
198 strncpy(newnode->file_old_path, old_path, SS_MAX_NAMELENSUPPORTED);//wgid: 29483
199 strncpy(newnode->file_new_path, new_path, SS_MAX_NAMELENSUPPORTED);//wgid: 29482
200 strncpy(newnode->patch_name, patchname, SS_MAX_NAMELENSUPPORTED);//wgid: 28033
201 strncpy(newnode->sha1src, sha1src, sizeof(newnode->sha1src) -1);//wgid: 25282
202 strncpy(newnode->sha1trg, sha1trg, sizeof(newnode->sha1trg) - 1);//wgid: 25283
203 newnode->type = type;
204 newnode->data_size = data_size;
205 newnode->data_offset = data_offset;
206 newnode->nextnode = NULL;
208 //LOG("%s %s %d %s %s \n",newnode->file_path,newnode->patch_name,newnode->type, newnode->sha1src, newnode->sha1trg);
210 if (*headparam == NULL) {
211 *headparam = newnode;
212 *tailparam = newnode;
214 (*tailparam)->nextnode = newnode;
215 (*tailparam) = (*tailparam)->nextnode;
221 void SS_UpdateUIProgress(ua_dataSS_t * ua_dataSS, int ulTotalFsCnt, int ulDone)
223 static int ss_count = 1;
224 int res_val = SS_GetProgressResolution(ulTotalFsCnt);
226 LOGE("Error ua_dataSS\n");
229 //LOG("\nvalues are ss_count[%d] total_file_cnt[%d]",ss_count,ulTotalFsCnt);
231 if (ua_dataSS->ui_progress)
232 ua_dataSS->ui_progress(ua_dataSS, 100);
234 } else if (ss_count < ulTotalFsCnt) {
235 if (ss_count % res_val == 0) { //Max 50 times display
236 double data = (double)ss_count / (double)ulTotalFsCnt;
237 if (ua_dataSS->ui_progress)
238 ua_dataSS->ui_progress(ua_dataSS, data * 100);
242 if (ua_dataSS->ui_progress)
243 ua_dataSS->ui_progress(ua_dataSS, 100);
250 *********************************************************************************
252 *********************************************************************************
255 * This is to clear the global control structure for delta files.
262 *********************************************************************************
264 void SS_FSClearNodes()
266 fs_params *local_temp = NULL;
267 fs_params *local_next = NULL;
268 LOGL(LOG_SSENGINE, "Free Nodes\n");
270 if (headptr_list->del_ref) {
271 local_temp = headptr_list->del_ref;
273 local_next = local_temp->nextnode;
275 local_temp = local_next;
278 if (headptr_list->dif_ref) {
279 local_temp = headptr_list->dif_ref;
281 local_next = local_temp->nextnode;
283 local_temp = local_next;
286 if (headptr_list->move_ref) {
287 local_temp = headptr_list->move_ref;
289 local_next = local_temp->nextnode;
291 local_temp = local_next;
294 if (headptr_list->new_ref) {
295 local_temp = headptr_list->new_ref;
297 local_next = local_temp->nextnode;
299 local_temp = local_next;
302 if (headptr_list->sym_difref) {
303 local_temp = headptr_list->sym_difref;
305 local_next = local_temp->nextnode;
307 local_temp = local_next;
310 if (headptr_list->sym_newref) {
311 local_temp = headptr_list->sym_newref;
313 local_next = local_temp->nextnode;
315 local_temp = local_next;
318 if (headptr_list->hard_newref) {
319 local_temp = headptr_list->hard_newref;
321 local_next = local_temp->nextnode;
323 local_temp = local_next;
326 if (headptr_list->hard_difref) {
327 local_temp = headptr_list->hard_difref;
329 local_next = local_temp->nextnode;
331 local_temp = local_next;
334 SS_Free(headptr_list);
340 *********************************************************************************
342 *********************************************************************************
345 * This is to get the delta count for diffs , deletes etc.
350 * @return returns structure with delta count info
351 * NULL in case of error
353 *********************************************************************************
356 struct details *SS_FSGetDeltaCount(ua_dataSS_t *ua_dataSS)
358 char *ubDeltaPath = ua_dataSS->update_data->ua_delta_path;
359 char *ubDeltaInfoFile = ua_dataSS->update_delta->ua_patch_info;
360 int size = 0, read_size = 0, ret = 1;
362 char *FileData = NULL;
364 char *saveptr = NULL;
366 struct details *refer_copy = NULL;
367 FILE *filename_extract = NULL;
370 if (!(ubDeltaPath && ubDeltaInfoFile)) {
371 LOGE("failed to Parse DELTA count information: \n");
372 SS_SetUpgradeState(E_SS_BAD_PARAMS);
375 refer_copy = (struct details *)SS_Malloc(sizeof(struct details));
377 if (refer_copy == NULL) {
378 LOGE("failed to allocate memory\n");
382 LOGL(LOG_SSENGINE, "Delta File Info =%s\n", ubDeltaInfoFile);
384 filename_extract = fopen(ua_dataSS->tar_data->text_files_info[PATCHLIST_FILE].extracted_name, "r");
385 if (filename_extract == NULL) {
386 strerror_r(errno, buf, sizeof(buf));
387 LOGE("Failed to open file Error:[%s]\n", buf);
388 SS_SetUpgradeState(E_SS_FSFAILEDTOBACKUPPATCHINFO);
393 size = ua_dataSS->tar_data->text_files_info[PATCHLIST_FILE].size;
395 FileData = SS_Malloc(size + 1);
396 if (FileData == NULL) {
397 LOGE("Failed to Allocate Memory\n");
398 SS_SetUpgradeState(E_SS_MALLOC_ERROR);
403 read_size = fread(FileData, 1, size, filename_extract);
404 if (read_size < size) {
405 SS_SetUpgradeState(E_SS_FSFAILEDTOBACKUPPATCHINFO);
410 LOGL(LOG_SSENGINE, " Size [%d]\n", size);
412 line = strstr(FileData, SS_FSCOUNT_MAGIC_KEY);
414 LOGL(LOG_SSENGINE, "SS_FSGetDeltaCount() last line %s \n", line);
416 token = strtok_r(&line[SS_FSCOUNT_MAGIG_KEYLEN], SS_TOKEN_SPACE, &saveptr);
418 refer_copy->diffs = atoi(token);
420 SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT);
424 token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr);
426 refer_copy->moves = atoi(token);
428 SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT);
433 token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr);
435 refer_copy->news = atoi(token);
437 SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT);
442 token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr);
444 refer_copy->deletes = atoi(token);
446 SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT);
451 token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr);
453 refer_copy->symdiffs = atoi(token);
455 SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT);
460 token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr);
462 refer_copy->symnews = atoi(token);
464 SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT);
469 token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr);
471 refer_copy->harddiffs = atoi(token);
473 SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT);
478 token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr);
480 refer_copy->hardnews = atoi(token);
482 SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT);
488 refer_copy->diffs + refer_copy->moves + refer_copy->news + refer_copy->deletes + refer_copy->symdiffs +
489 refer_copy->symnews + refer_copy->harddiffs + refer_copy->hardnews;
490 LOG("SS_FSGetDeltaCount() total no of file %d\n", gtotalFSCnt);
493 SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT);
494 LOG("SS_FSGetDeltaCount() Failed to read last line\n");
496 if (gtotalFSCnt < 0) {
503 if (filename_extract)
504 fclose(filename_extract);
515 *********************************************************************************
517 *********************************************************************************
520 * This is used to build the gobal control structure for diffs, deletes etc.
521 * For all the entries in config file (which has info) the information is parsed to the global control struct
526 * @return returns fs_list structure filled with details of all the files to be diff-ed ,deleted etc.
527 * NULL in case of error
529 *********************************************************************************
531 fs_list *SS_FSBuildNodes(ua_dataSS_t * ua_dataSS)
534 char line[SS_TOKEN_MAXLINE_LEN] = { '\0' };
535 char string_na[] = "NA";
536 char *patch_name = NULL;
537 char *source_name = NULL;
538 char *target_name = NULL;
539 char *sha1src = NULL;
540 char *sha1trg = NULL;
541 char *change_type = NULL;
542 char *file_type = NULL;
543 char *saveptr = NULL;
544 uint32_t ulPatchCount = 0, del_type = DELETES;
545 fs_params *fs_diffhead = NULL;
546 fs_params *fs_difftail = NULL;
547 fs_params *fs_movehead = NULL;
548 fs_params *fs_movetail = NULL;
549 fs_params *fs_newhead = NULL;
550 fs_params *fs_delhead = NULL;
551 fs_params *fs_deltail = NULL;
552 fs_params *fs_symlinkdiffhead = NULL;
553 fs_params *fs_symlinkdifftail = NULL;
554 fs_params *fs_symlinknewhead = NULL;
555 fs_params *fs_symlinknewtail = NULL;
556 fs_params *fs_hardlinkdiffhead = NULL;
557 fs_params *fs_hardlinkdifftail = NULL;
558 fs_params *fs_hardlinknewhead = NULL;
559 fs_params *fs_hardlinkdnewtail = NULL;
561 struct details *local = NULL;
562 fs_list *fs_head_node = NULL;
563 int i = 0, retval = 0;
565 LOGE("Bad structure ua_dataSS\n");
566 SS_SetUpgradeState(E_SS_BAD_PARAMS);
569 LOGL(LOG_SSENGINE, " Build Nodes Entry \n");
571 local = SS_FSGetDeltaCount(ua_dataSS);
573 LOGE(" Build Nodes Failed \n");
574 SS_SetUpgradeState(E_SS_BAD_PARAMS);
578 fp = fopen(ua_dataSS->tar_data->text_files_info[PATCHLIST_FILE].extracted_name, "r");
580 SS_SetUpgradeState(E_SS_FSFAILEDTOOPENPATCHINFO);
585 ulPatchCount = local->diffs + local->deletes + local->news + local->moves + local->symdiffs +
586 local->symnews + local->harddiffs + local->hardnews;
587 LOG("Total FS count [%d].\n", ulPatchCount);
589 ************************************************************************
590 Parsing logic implemented for patchlist
591 ************************************************************************
592 Sample entries in patchlist as below :
593 <CHANGE-TYPE>:<FILE-TYPE>:<OTHER-DETAILS...>
594 ************************************************************************
595 DIFF:REG:system/bin/vi:system/bin/vi:2f2f3dc6d3ee06af0080ac7975f22941660f2480:78b2d44af32d854c70f1cb7431a60c2682a320cc:diff1_vi.delta
596 DIFF:TPK:system/usr/packages/removable/com.samsung.calculator.tpk:system/usr/packages/removable/com.samsung.calculator.tpk:
597 96fc1bcde30d501ba65ef0038e05da46d255a7b3:fa1d5d9daa4097ac302b69244297f508577c3a01:diff1598_com.samsung.calculator.tpk.delta/
598 MOVE:REG:system/etc/smack/accesses.d/heremaps-engine-devel:system/usr/apps/com.samsung.contacts/res/temp:da39a3ee5e6b4b0d3255bfef95601890afd80709
599 DEL:REG:system/usr/ug/res/images/ug-phone/contacts/favorites_icon_remove.PNG:38ad8be378506d19b1c769d46be262cf100f6c59
600 DEL:SYM:system/usr/apps/com.samsung.message-lite/lib/libmsg-common.so
601 DEL:HARD:system/usr/apps/com.samsung.message-lite/lib/libmsg-common.so
602 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:
603 libplugin-na-mobex.so.0.3.57
604 SYM:NEW:system/lib/firmware/vbc_eq:/opt/system/vbc_eq
605 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:
606 libplugin-na-mobex.so.0.3.57
607 HARD:NEW:system/lib/firmware/vbc_eq:/opt/system/vbc_eq
608 ***********************************************************************
610 if (local && ((local->diffs) > 0 || (local->moves > 0))) {
611 LOGL(LOG_SSENGINE, "%ss [%d] %ss [%d]\n", SS_STRING_DIFF, local->diffs, SS_STRING_MOVE, local->moves);
612 for (i = 0; i < (local->diffs + local->moves); i++) {
613 if (fgets(line, SS_TOKEN_MAXLINE_LEN, fp) == NULL) {
614 SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO);
617 //LOGL(LOG_SSENGINE, "DIFF LINE:[%d] [%s] \n",i+1,line);
619 change_type = strtok_r(line, SS_TOEKN_COLON, &saveptr);
620 file_type = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
622 LOGE("Unexpected null in strtok_r");
626 if (change_type && strcmp(change_type, SS_STRING_MOVE) == 0) { // && strcmp(file_type,"TPK") == 0){
627 source_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
628 target_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
629 sha1src = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr);
630 //LOGL(LOG_SSENGINE, "%s Index [%d]\n", SS_STRING_MOVE, i);
632 if (!source_name || !target_name || !sha1src) {
633 SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO);
634 //LOGE("Failed to extract Patch Info Type:DELETES \n");
635 LOGE("Failed to parse DIFFS - LINE:[%d] [%s] \n", i + 1, line);
639 SS_AppendNode(ua_dataSS->update_data->ua_delta_path, &fs_movehead, &fs_movetail, source_name,
640 target_name, string_na, sha1src, string_na, MOVES,
641 ua_dataSS->update_delta->ua_patch_path);
642 if (retval == E_SS_FAILURE) // ONLY test purpose, should enable this
645 if (ua_dataSS->ua_operation == UI_OP_SCOUT) {
646 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
648 } else if (change_type && strcmp(change_type, SS_STRING_DIFF) == 0) { // && strcmp(file_type,"TPK") == 0){
649 source_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
650 target_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
651 sha1src = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
652 sha1trg = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
653 patch_name = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr);
654 //LOGL(LOG_SSENGINE, "%s Index [%d]\n", SS_STRING_DIFF, i);
656 if (patch_name && (strlen(patch_name) <= SS_MAX_NAMELENSUPPORTED)) {
658 SS_AppendNode(ua_dataSS->update_data->ua_delta_path, &fs_diffhead, &fs_difftail,
659 source_name, target_name, patch_name, sha1src, sha1trg, DIFFS,
660 ua_dataSS->update_delta->ua_patch_path);
661 if (retval == E_SS_FAILURE) // ONLY test purpose, should enable this
664 SS_SetUpgradeState(E_SS_FILENAMELENERROR);
665 LOGE("File Name length Limitation Error File:[%s]\n", patch_name);
669 if (ua_dataSS->ua_operation == UI_OP_SCOUT) {
670 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
673 SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO);
674 LOGE("Patch Name format Error File\n");
679 if (local && (local->news) > 0) { //check if new files archive is present in the delta
680 char new_patch_path[MAX_FILE_PATH] = { 0, };
681 snprintf(new_patch_path, MAX_FILE_PATH, "%s%s", ua_dataSS->parti_info->ua_subject_name, SS_COMPRESSED_FILE);
682 if (ua_dataSS->tar_data->new_files_info.offset < 0) {
683 SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO);
684 LOGE("New files not present in Patch and they should be\n");
685 retval = E_SS_FAILURE;
689 if (local && (local->deletes) > 0) { //this is to group to delete list
690 LOGL(LOG_SSENGINE, "%ss [%d]\n", SS_STRING_DEL, local->deletes);
691 for (i = 0; i < (local->deletes); i++) {
692 if (fgets(line, SS_TOKEN_MAXLINE_LEN, fp) == NULL) {
693 SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO);
697 change_type = strtok_r(line, SS_TOEKN_COLON, &saveptr);
699 LOGE("Unexpected null in strtok_r");
702 file_type = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
704 if (file_type && strcmp(file_type, SS_STRING_REG) == 0) {
705 source_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
706 sha1src = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr);
708 } else if (file_type && ((strcmp(file_type, SS_STRING_SYM) == 0) || (strcmp(file_type, SS_STRING_HARD) == 0))) {
709 source_name = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr);
712 } else if (file_type && strcmp(file_type, SS_STRING_END) == 0) {
713 source_name = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr);
715 del_type = DELETE_END;
717 LOGE("Failed to parse DELETES - LINE:[%d] [%s] \n", i + 1, line);
721 if (!source_name || !sha1src) {
722 SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO);
723 //LOGE("Failed to extract Patch Info Type:DELETES \n");
724 LOGE("Failed to parse DELETES - LINE:[%d] [%s] \n", i + 1, line);
727 //LOGL(LOG_SSENGINE, "%s Index [%d]\n", SS_STRING_DEL, i);
729 SS_AppendNode(ua_dataSS->update_data->ua_delta_path, &fs_delhead, &fs_deltail, source_name,
730 string_na, string_na, sha1src, string_na, del_type,
731 ua_dataSS->update_delta->ua_patch_path);
732 if (retval == E_SS_FAILURE) // ONLY test purpose, should enable this
734 if (ua_dataSS->ua_operation == UI_OP_SCOUT) {
735 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
739 } //For symlink files
741 if (local && (local->symdiffs) > 0) {
742 LOGL(LOG_SSENGINE, "%s %ss [%d]\n", SS_STRING_SYM, SS_STRING_DIFF, local->symdiffs);
743 for (i = 0; i < (local->symdiffs); i++) { //get the count from below function
744 if (fgets(line, SS_TOKEN_MAXLINE_LEN, fp) == NULL) {
745 SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO);
748 //LOGL(LOG_SSENGINE, "SYMDIFF LINE:[%d] [%s] \n",i+1,line);
750 change_type = strtok_r(line, SS_TOEKN_COLON, &saveptr);
751 file_type = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
753 if ((change_type && file_type) &&
754 strcmp(change_type, SS_STRING_SYM) == 0 && strcmp(file_type, SS_STRING_DIFF) == 0) { // && strcmp(file_type,"TPK") == 0){
755 source_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
756 target_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
757 patch_name = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr);
758 //LOGL(LOG_SSENGINE, "%s %s Index [%d]\n", SS_STRING_SYM, SS_STRING_DIFF, i);
760 if (!source_name || !target_name || !patch_name) {
761 SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO);
762 //LOGE("Failed to extract Patch Info Type:DELETES \n");
763 LOGE("Failed to parse SymDiffs - LINE:[%d] [%s] \n", i + 1, line);
767 SS_AppendNode(ua_dataSS->update_data->ua_delta_path, &fs_symlinkdiffhead, &fs_symlinkdifftail,
768 source_name, target_name, patch_name, string_na, string_na, SYMDIFFS,
769 ua_dataSS->update_delta->ua_patch_path);
770 if (retval == E_SS_FAILURE) // ONLY test purpose, should enable this
772 if (ua_dataSS->ua_operation == UI_OP_SCOUT) {
773 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
778 if (local && (local->symnews) > 0) {
779 LOGL(LOG_SSENGINE, "%s %ss [%d]n", SS_STRING_SYM, SS_STRING_NEW, local->symnews);
780 for (i = 0; i < (local->symnews); i++) {
781 if (fgets(line, SS_TOKEN_MAXLINE_LEN, fp) == NULL) {
782 SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO);
785 //LOGL(LOG_SSENGINE, "SYMNEWS LINE:[%d] [%s] \n",i+1,line);
787 change_type = strtok_r(line, SS_TOEKN_COLON, &saveptr);
788 file_type = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
790 if ((change_type && file_type) &&
791 (strcmp(change_type, SS_STRING_SYM) == 0 && strcmp(file_type, SS_STRING_NEW) == 0)) {
792 source_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
793 patch_name = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr);
794 //LOGL(LOG_SSENGINE, "%s %s Index [%d]\n", SS_STRING_SYM, SS_STRING_NEW, i);
796 if (!source_name || !patch_name) {
797 SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO);
798 //LOGE("Failed to extract Patch Info Type:DELETES \n");
799 LOGE("Failed to parse SymNews - LINE:[%d] [%s] \n", i + 1, line);
803 SS_AppendNode(ua_dataSS->update_data->ua_delta_path, &fs_symlinknewhead, &fs_symlinknewtail,
804 source_name, string_na, patch_name, string_na, string_na, SYMNEWFILES,
805 ua_dataSS->update_delta->ua_patch_path);
806 if (retval == E_SS_FAILURE) // ONLY test purpose, should enable this
808 if (ua_dataSS->ua_operation == UI_OP_SCOUT) {
809 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
814 if (local && (local->hardnews) > 0) {
815 LOGL(LOG_SSENGINE, "%s %ss [%d]\n", SS_STRING_HARD, SS_STRING_NEW, local->hardnews);
816 for (i = 0; i < (local->hardnews); i++) {
817 if (fgets(line, SS_TOKEN_MAXLINE_LEN, fp) == NULL) {
818 SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO);
821 //LOGL(LOG_SSENGINE, "HARDNEWS LINE:[%d] [%s] \n",i+1,line);
823 change_type = strtok_r(line, SS_TOEKN_COLON, &saveptr);
824 file_type = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
826 if ((change_type && file_type) &&
827 (strcmp(change_type, SS_STRING_HARD) == 0 && strcmp(file_type, SS_STRING_NEW) == 0)) {
828 source_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
829 patch_name = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr);
830 //LOGL(LOG_SSENGINE, "%s %s Index [%d]\n", SS_STRING_SYM, SS_STRING_NEW, i);
832 if (!source_name || !patch_name) {
833 SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO);
834 //LOGE("Failed to extract Patch Info Type:DELETES \n");
835 LOGE("Failed to parse HardNews - LINE:[%d] [%s] \n", i + 1, line);
839 SS_AppendNode(ua_dataSS->update_data->ua_delta_path, &fs_hardlinknewhead, &fs_hardlinkdnewtail,
840 source_name, string_na, patch_name, string_na, string_na, HARDNEWFILES,
841 ua_dataSS->update_delta->ua_patch_path);
842 if (retval == E_SS_FAILURE) // ONLY test purpose, should enable this
844 if (ua_dataSS->ua_operation == UI_OP_SCOUT) {
845 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
851 if (local && (local->harddiffs) > 0) {
852 LOGL(LOG_SSENGINE, "%s %ss [%d]\n", SS_STRING_HARD, SS_STRING_DIFF, local->harddiffs);
853 for (i = 0; i < (local->harddiffs); i++) { //get the count from below function
854 if (fgets(line, SS_TOKEN_MAXLINE_LEN, fp) == NULL) {
855 SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO);
858 //LOGL(LOG_SSENGINE, "HARDIFFS LINE:[%d] [%s] \n",i+1,line);
860 change_type = strtok_r(line, SS_TOEKN_COLON, &saveptr);
861 file_type = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
863 if ((change_type && file_type) &&
864 strcmp(change_type, SS_STRING_HARD) == 0 && strcmp(file_type, SS_STRING_DIFF) == 0) { // && strcmp(file_type,"TPK") == 0){
865 source_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
866 target_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
867 patch_name = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr);
868 //LOGL(LOG_SSENGINE, "%s %s Index [%d]\n", SS_STRING_SYM, SS_STRING_DIFF, i);
870 if (!source_name || !target_name || !patch_name) {
871 SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO);
872 //LOGE("Failed to extract Patch Info Type:DELETES \n");
873 LOGE("Failed to parse HardDiffs - LINE:[%d] [%s] \n", i + 1, line);
877 SS_AppendNode(ua_dataSS->update_data->ua_delta_path, &fs_hardlinkdiffhead, &fs_hardlinkdifftail,
878 source_name, target_name, patch_name, string_na, string_na, HARDDIFFS,
879 ua_dataSS->update_delta->ua_patch_path);
880 if (retval == E_SS_FAILURE) // ONLY test purpose, should enable this
882 if (ua_dataSS->ua_operation == UI_OP_SCOUT) {
883 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
889 fs_head_node = (fs_list *) SS_Malloc(sizeof(fs_list));
891 SS_SetUpgradeState(E_SS_MALLOC_ERROR);
894 fs_head_node->dif_ref = fs_diffhead;
895 fs_head_node->move_ref = fs_movehead;
896 fs_head_node->new_ref = fs_newhead;
897 fs_head_node->del_ref = fs_delhead;
898 fs_head_node->sym_difref = fs_symlinkdiffhead;
899 fs_head_node->sym_newref = fs_symlinknewhead;
900 fs_head_node->hard_difref = fs_hardlinkdiffhead;
901 fs_head_node->hard_newref = fs_hardlinknewhead;
902 fs_head_node->ulPatchCount = ulPatchCount;
904 if (ua_dataSS->ua_operation == UI_OP_SCOUT) {
905 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 1);
911 unlink(ua_dataSS->tar_data->text_files_info[PATCHLIST_FILE].extracted_name);
912 ua_dataSS->tar_data->text_files_info[PATCHLIST_FILE].size = 0;
916 void SS_GetPartition_LocDetails(ua_dataSS_t * ua_dataSS)
918 LOGL(LOG_SSENGINE, "PART NAME: [%s] \n", ua_dataSS->parti_info->ua_parti_name);
919 snprintf(ua_dataSS->update_delta->ua_patch_path, MAX_FILE_PATH, "%s", ua_dataSS->parti_info->ua_subject_name);
920 snprintf(ua_dataSS->update_delta->ua_patch_info, MAX_FILE_PATH, "%s%s%s", ua_dataSS->parti_info->ua_subject_name,
921 ua_dataSS->parti_info->ua_parti_name, SS_PATCHLISTFORMAT);
922 snprintf(ua_dataSS->update_delta->ua_attrib_path, MAX_FILE_PATH, "%s%s%s", ua_dataSS->parti_info->ua_subject_name,
923 ua_dataSS->parti_info->ua_parti_name, SS_PATCH_ATTR_FORMAT);
924 LOGL(LOG_SSENGINE, "PatchPath[%s] PatchInfo [%s] Attributes [%s]\n", ua_dataSS->update_delta->ua_patch_path,
925 ua_dataSS->update_delta->ua_patch_info, ua_dataSS->update_delta->ua_attrib_path);
930 //Support functions//Change Struct format details (Can include total file count also???)/*!
932 ******************************************************************************** *
934 *********************************************************************************
936 * This is used to set the file attributes at the end of application of patches in FS
940 *@return returns S_SS_SUCCESS
941 * E_SS_FAILURE in case of error
943 *********************************************************************************
945 int SS_FSSetAttributes(ua_dataSS_t * ua_dataSS)
948 char *psaveptr = NULL;
949 char *pfilePath = NULL;
950 char *pfiletype = NULL;
951 char *attributSize = NULL;
952 char *pattribs = NULL;
953 int ulAttribSize = 0;
954 int result = S_SS_SUCCESS;
958 if (!(ua_dataSS && ua_dataSS->update_delta && ua_dataSS->update_data->ua_delta_path)) {
959 LOGE("Bad params for SS_FSSetAttributes\n");
960 SS_SetUpgradeState(E_SS_BAD_PARAMS);
963 LOGL(LOG_SSENGINE, "ATTRIB PATH: [%s] \n", ua_dataSS->tar_data->text_files_info[ATTR_FILE].extracted_name);
964 int item_size = ua_dataSS->tar_data->text_files_info[ATTR_FILE].size;
965 if (item_size <= 0) {
966 LOGL(LOG_SSENGINE, "No Attributes to SET\n");
967 return S_SS_SUCCESS; // Delta with ONLY deletes
970 char *item_data = SS_Malloc(item_size + 1);
971 if (item_data == NULL) {
972 LOGE("SS_Malloc failed!! - item_data\n");
973 SS_SetUpgradeState(E_SS_MALLOC_ERROR);
976 if ((fd = open(ua_dataSS->tar_data->text_files_info[ATTR_FILE].extracted_name, O_RDONLY)) < 0) {
977 LOGE("Cannot open attr file!\n");
978 unlink(ua_dataSS->tar_data->text_files_info[ATTR_FILE].extracted_name);
979 ua_dataSS->tar_data->text_files_info[ATTR_FILE].size = 0;
981 SS_SetUpgradeState(E_SS_FSBADATTRIBUTES);
984 int read_data = read(fd, item_data, item_size);
985 if (read_data <= 0) {
986 LOGE("read_data failed!!\n");
987 SS_SetUpgradeState(E_SS_FSBADDELTA);
988 if (item_data != NULL) {
993 unlink(ua_dataSS->tar_data->text_files_info[ATTR_FILE].extracted_name);
994 ua_dataSS->tar_data->text_files_info[ATTR_FILE].size = 0;
997 item_data[read_data] = '\0';
999 pline = strtok_r(item_data, "\n", &psaveptr);
1000 if (pline == NULL) {
1001 LOGL(LOG_SSENGINE, "No Attributes to SET as no lines in file\n");
1002 if (item_data != NULL) {
1007 unlink(ua_dataSS->tar_data->text_files_info[ATTR_FILE].extracted_name);
1008 ua_dataSS->tar_data->text_files_info[ATTR_FILE].size = 0;
1009 return E_SS_FAILURE;
1013 char *saveptr_pline = NULL;
1014 pfilePath = strtok_r(pline, "\"", &saveptr_pline);
1016 if (pfilePath && strcmp(pfilePath, SS_FWSLASH) == 0) {
1017 LOGE("skip root: it is RO\n");
1018 pline = strtok_r(NULL, SS_TOKEN_NEWLINE, &psaveptr);
1022 pfiletype = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr_pline);
1023 attributSize = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr_pline);
1024 pattribs = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr_pline);
1025 //LOG("\nSS_FSSetAttributes [%s][%s][%s]", pfiletype, attributSize, pattribs);
1026 if (pattribs && pfilePath && pfiletype && attributSize) {
1027 ulAttribSize = strlen(pattribs);
1028 //LOG("\nSS_SetFileAttributes [%s][%s][%d][%s]",pfilePath,pfiletype,ulAttribSize, pattribs );
1029 //LOG("SS_SetFileAttributes [%s]\n", pfilePath);
1031 result = SS_SetFileAttributes(pfilePath, ulAttribSize, (const unsigned char *)pattribs);
1032 if (result != S_SS_SUCCESS) {
1033 LOGE("Failed to set Attributes %s\n", pfilePath);
1034 SS_SetUpgradeState(E_SS_FSBADATTRIBUTES);
1042 LOGE("Failed to Parse Attributes - LINE %s\n", pline);
1043 SS_SetUpgradeState(E_SS_FSBADATTRIBUTES);
1050 pline = strtok_r(NULL, SS_TOKEN_NEWLINE, &psaveptr);
1053 if (item_data != NULL) {
1059 result = E_SS_FAILURE;
1061 result = S_SS_SUCCESS;
1064 unlink(ua_dataSS->tar_data->text_files_info[ATTR_FILE].extracted_name);
1065 ua_dataSS->tar_data->text_files_info[ATTR_FILE].size = 0;
1070 *********************************************************************************
1072 *********************************************************************************
1075 * This is used to update individual files on case basis
1080 * @return returns S_SS_SUCCESS
1081 * E_SS_FAILURE in case of error
1083 *********************************************************************************
1085 int SS_FSUpdateFile(int ubFileType, ua_dataSS_t * ua_dataSS, int ulPatchCount, fs_params * pFsNode,
1086 const char *patch_path)
1088 int ulFileIndex = 1;
1089 char ubPatch[SS_MAX_FILE_PATH] = { 0, };
1091 int ulResult = S_SS_SUCCESS;
1092 FileInfo source_file;
1093 FileInfo target_file;
1094 uint8_t target_sha1[SHA_DIGEST_SIZE] = { 0, };
1095 char patchfile_source_path[MAX_FILE_PATH];
1096 snprintf(patchfile_source_path, MAX_FILE_PATH, "%s/%s", ua_dataSS->update_data->ua_delta_folder, SS_PATCHFILE_SOURCE);
1099 LOGE("Bad patch_path name\n");
1100 return E_SS_FAILURE;
1102 switch (ubFileType) {
1105 LOGL(LOG_SSENGINE, "DIFFS mode start\n");
1106 diff_iterator diff_iter;
1107 if (tar_init_diff_iterations(ua_dataSS->tar_data, &diff_iter, pFsNode) < 0) {
1108 ulResult = E_SS_FAILURE;
1109 SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
1110 LOGE("Couldn't begin updating diffs!\n");
1115 //LOGL(LOG_SSENGINE, "DIFFS update Index: [%d] \n", ulFileIndex++);
1116 snprintf(ubPatch, SS_MAX_FILE_PATH, "%s%s", patch_path, pFsNode->patch_name);
1117 //LOGL(LOG_SSENGINE, "DIFF list --- [File Name %s]\n [Patch Name %s]",pFsNode->file_path, ubPatch);
1119 fs_params *temp_param;
1120 switch(tar_diff_iter_next_extract(ua_dataSS->tar_data, &diff_iter, patchfile_source_path, &temp_param))
1124 ulResult = E_SS_FAILURE;
1125 SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
1126 LOGE("Delta Read Failed\n");
1130 ulResult = S_SS_SUCCESS;
1134 SS_UpdateDeltaFS(temp_param->file_old_path, temp_param->file_new_path, temp_param->sha1src,
1135 temp_param->sha1trg, temp_param->data_size, ua_dataSS->tar_data->tar);
1136 if (ulResult != S_SS_SUCCESS) {
1137 LOGE("FS update Failed Result : [%d], [Item - %s]and size is[%d] Read Count[%d], index = [%d]\n", ulResult,
1138 ubPatch, temp_param->data_size, ulReadCnt, ulFileIndex);
1139 SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
1147 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
1150 LOGL(LOG_SSENGINE, "DIFFS : Total index = [%d]\n",
1152 LOGL(LOG_SSENGINE, "DIFFS mode end\n");
1157 LOGL(LOG_SSENGINE, "MOVES mode start\n");
1159 //LOGL(LOG_SSENGINE, "MOVES update Index: [%d] \n", ulFileIndex++);
1161 if (SS_LoadFile(pFsNode->file_old_path, &source_file) == 0) {
1162 LOGL(LOG_SSENGINE, "Patch Can be applied\n");
1163 if (source_file.data)
1164 SS_Free(source_file.data);
1165 } else if (SS_LoadFile(pFsNode->file_new_path, &target_file) == 0) {
1166 LOGL(LOG_SSENGINE, "source deleted!!, file_old_path: [%s]\n", pFsNode->file_old_path);
1167 if (ParseSha1(pFsNode->sha1src, target_sha1) != 0) {
1168 LOGE("failed to parse sha1 \"%s\"\n", pFsNode->sha1src);
1169 ulResult = E_SS_FAILURE;
1170 SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
1171 if (target_file.data)
1172 SS_Free(target_file.data);
1175 if (memcmp(target_file.sha1, target_sha1, SHA_DIGEST_SIZE) == 0) {
1176 LOGL(LOG_SSENGINE, "Patch already applied\n");
1178 if (target_file.data)
1179 SS_Free(target_file.data);
1181 LOGL(LOG_SSENGINE, "target_sha1 diff!!: [%s]\n", target_sha1);
1182 ulResult = E_SS_FAILURE;
1183 SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
1184 if (target_file.data)
1185 SS_Free(target_file.data);
1189 LOGE("No exist files. - file_old_path: [%s] file_new_path: [%s]\n", pFsNode->file_old_path, pFsNode->file_new_path);
1190 ulResult = E_SS_FAILURE;
1191 SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
1195 if (skip_flag == 0) {
1196 ulResult = SS_MoveFile(pFsNode->file_old_path, pFsNode->file_new_path);
1197 if (ulResult != S_SS_SUCCESS) {
1198 LOGE("Move Failed for [%s] to [%s], result = [%d], index = [%d]\n", pFsNode->file_old_path, pFsNode->file_new_path, ulResult, ulFileIndex);
1199 SS_SetUpgradeState(ulResult);
1203 if (SS_LoadFile(pFsNode->file_new_path, &target_file) == 0) {
1204 if (ParseSha1(pFsNode->sha1src, target_sha1) != 0) {
1205 LOGE("failed to parse sha1 \"%s\"\n", pFsNode->sha1src);
1206 ulResult = E_SS_FAILURE;
1207 SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
1208 if (target_file.data)
1209 SS_Free(target_file.data);
1212 if (memcmp(target_file.sha1, target_sha1, SHA_DIGEST_SIZE) == 0) {
1213 LOGL(LOG_SSENGINE, "Patch success!!\n");
1214 if (target_file.data)
1215 SS_Free(target_file.data);
1217 LOGL(LOG_SSENGINE, "target_sha1 diff!!: [%s]\n", target_sha1);
1218 ulResult = E_SS_FAILURE;
1219 SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
1220 if (target_file.data)
1221 SS_Free(target_file.data);
1227 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
1228 pFsNode = pFsNode->nextnode;
1231 LOGL(LOG_SSENGINE, "MOVES : Total index = [%d]\n",
1233 LOGL(LOG_SSENGINE, "MOVES mode end\n");
1238 LOGL(LOG_SSENGINE, "DELETES mode start\n");
1242 if (pFsNode->type == DELETES) {
1243 //LOGL(LOG_SSENGINE, "DELETES update Index: [%d] \n", ulFileIndex++);
1244 SS_GetFileType(pFsNode->file_old_path, (enumFileType *) & ulFiletype);
1245 if (ulFiletype == 2) //FT_FOLDER
1246 ulResult = SS_DeleteFolder(pFsNode->file_old_path);
1248 ulResult = SS_DeleteFile(pFsNode->file_old_path);
1249 if (ulResult != S_SS_SUCCESS) {
1250 LOGE("Delete Failed, result = [%d], index = [%d]\n", ulResult, ulFileIndex);
1251 SS_SetUpgradeState(ulResult);
1256 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
1257 pFsNode = pFsNode->nextnode;
1259 LOGL(LOG_SSENGINE, "DELETES : Total index = [%d]\n",
1261 LOGL(LOG_SSENGINE, "DELETES mode end\n");
1266 LOGL(LOG_SSENGINE, "DELETE_END mode start\n");
1270 if (pFsNode->type == DELETE_END) {
1271 LOGL(LOG_SSENGINE, "DELETE_END update Index: [%d] \n", ulFileIndex++);
1272 SS_GetFileType(pFsNode->file_old_path, (enumFileType *) & ulFiletype);
1273 if (ulFiletype == 2) //FT_FOLDER
1274 ulResult = SS_DeleteFolder(pFsNode->file_old_path);
1276 ulResult = SS_DeleteFile(pFsNode->file_old_path);
1277 if (ulResult != S_SS_SUCCESS) {
1278 LOGE("Delete Failed, result = [%d], index = [%d]\n", ulResult, ulFileIndex);
1279 SS_SetUpgradeState(ulResult);
1284 pFsNode = pFsNode->nextnode;
1286 LOGL(LOG_SSENGINE, "DELETE_END : Total index = [%d]\n",
1288 LOGL(LOG_SSENGINE, "DELETE_END mode end\n");
1294 LOGL(LOG_SSENGINE, "NEWFILES mode start\n");
1295 LOGL(LOG_SSENGINE, "Starting New file upgrade for [%s]\n", patch_path);
1296 if (ua_dataSS->tar_data->new_files_info.offset >= 0) {
1297 if (tar_extract_newfiles_archive(ua_dataSS->tar_data) < 0) {
1298 LOGE("newfiles extraction error!\n");
1299 SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
1300 ulResult = E_SS_FAILURE;
1303 if (decompress_tar_brotli(ua_dataSS->tar_data->new_files_info.extracted_name) == 0) {
1304 LOGL(LOG_SSENGINE, "7zip extracted successfully %s\n", ua_dataSS->parti_info->ua_parti_name);
1306 LOGL(LOG_SSENGINE, "7zip extraction error for %s\n", ua_dataSS->parti_info->ua_parti_name);
1307 SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
1308 ulResult = E_SS_FAILURE;
1311 SS_DeleteFile(ua_dataSS->tar_data->new_files_info.extracted_name);
1313 LOGL(LOG_SSENGINE, "No %s in %s, because there are no new files\n", SS_COMPRESSED_FILE, ua_dataSS->parti_info->ua_parti_name);
1315 LOGL(LOG_SSENGINE, "NEWFILES mode end\n");
1320 LOGL(LOG_SSENGINE, "SYMDIFFS mode start\n");
1322 //LOGL(LOG_SSENGINE, "SYMDIFFS update Index: [%d] \n", ulFileIndex++);
1323 //LOG("Sym Diff file paths: [Linkname - %s] [reference file name- %s][]\n", pFsNode->file_path,pFsNode->patch_name);
1324 ulResult = SS_Unlink(pFsNode->file_old_path);
1325 if (ulResult == S_SS_SUCCESS) {
1326 ulResult = SS_Link(NULL, pFsNode->file_new_path, pFsNode->patch_name);
1327 if (ulResult != S_SS_SUCCESS) {
1328 LOGE("SS_Link Failed, Linkname:[%s], reference file name, index = [%d]:[%s]\n",
1329 pFsNode->file_new_path, ulFileIndex, pFsNode->patch_name);
1332 LOGE("Unlink Failed, result = [%d], index = [%d]\n", ulResult, ulFileIndex);
1333 SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
1336 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
1337 pFsNode = pFsNode->nextnode;
1340 LOGL(LOG_SSENGINE, "SYMDIFFS : Total index = [%d]\n",
1342 LOGL(LOG_SSENGINE, "SYMDIFFS mode end\n");
1347 LOGL(LOG_SSENGINE, "SYMNEWFILES mode start\n");
1349 fs_params *head_node;
1350 int retry_count = 0, do_retry = 0;
1353 head_node = pFsNode;
1355 //LOGL(LOG_SSENGINE, "SYMNEWS update Index: [%d] \n", ulFileIndex++);
1356 snprintf(ubPatch, SS_MAX_FILE_PATH, "%s%s%s", patch_path, "/", head_node->patch_name);
1357 LOGL(LOG_SSENGINE, "Sym New file paths: [Linkname - %s] [reference file name- %s][]\n",
1358 head_node->file_old_path, head_node->patch_name);
1359 ulResult = SS_Link(NULL, head_node->file_old_path, head_node->patch_name);
1360 if (ulResult == E_SS_FAILURE) {
1361 LOGE("Link Failed, result = [%d], index = [%d]\n", ulResult, ulFileIndex);
1362 SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
1364 } else if (ulResult == ENOENT) { //to handle cases where new symlink points to a new symlink yet to be created
1365 do_retry = 1; //we will retry the failed symlinks with error 2 (no file or dir) again after this cycle
1366 //SS_UpdateUIProgress(ua_dataSS,ulPatchCount);
1367 head_node = head_node->nextnode;
1370 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
1371 head_node = head_node->nextnode;
1374 LOGL(LOG_SSENGINE, "SYMNEWFILES : Total index = [%d]\n",
1376 if (do_retry && (retry_count < 4)) {
1380 goto SYMLINK_CREATE;
1381 } else if (do_retry && (retry_count >= 4)) { //retry to be done maximum 4 times
1382 LOGE("Link Failed after %d retrys\n", retry_count);
1383 //SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
1386 LOGL(LOG_SSENGINE, "SYMNEWFILES mode end\n");
1391 LOGL(LOG_SSENGINE, "HARDDIFFS mode start\n");
1393 //LOGL(LOG_SSENGINE, "SYMDIFFS update Index: [%d] \n", ulFileIndex++);
1394 //LOG("Sym Diff file paths: [Linkname - %s] [reference file name- %s][]\n", pFsNode->file_path,pFsNode->patch_name);
1395 ulResult = SS_DeleteFile(pFsNode->file_old_path);
1396 if (ulResult == S_SS_SUCCESS) {
1397 ulResult = SS_HardLink(pFsNode->file_new_path, pFsNode->patch_name);
1398 if (ulResult != S_SS_SUCCESS) {
1399 LOGE("SS_HardLink Failed, Linkname:[%s], reference file name, index = [%d]:[%s]\n",
1400 pFsNode->file_new_path, ulFileIndex, pFsNode->patch_name);
1403 LOGE("Removing old hardlink Failed, result = [%d], index = [%d]\n", ulResult, ulFileIndex);
1404 SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
1407 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
1408 pFsNode = pFsNode->nextnode;
1411 LOGL(LOG_SSENGINE, "HARDDIFFS : Total index = [%d]\n",
1413 LOGL(LOG_SSENGINE, "HARDDIFFS mode end\n");
1418 LOGL(LOG_SSENGINE, "HARDNEWFILES mode start\n");
1419 fs_params *head_node = pFsNode;
1421 //LOGL(LOG_SSENGINE, "SYMNEWS update Index: [%d] \n", ulFileIndex++);
1422 LOGL(LOG_SSENGINE, "Hardlink New file paths: [Linkname - %s] [reference file name- %s][]\n",
1423 head_node->file_old_path, head_node->patch_name);
1424 ulResult = SS_HardLink(head_node->file_old_path, head_node->patch_name);
1425 if (ulResult == E_SS_FAILURE) {
1426 LOGE("Link Failed, result = [%d], index = [%d]\n", ulResult, ulFileIndex);
1427 SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
1430 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
1431 head_node = head_node->nextnode;
1434 LOGL(LOG_SSENGINE, "HARDNEWFILES : Total index = [%d]\n",
1436 LOGL(LOG_SSENGINE, "HARDNEWFILES mode end\n");
1447 *********************************************************************************
1449 *********************************************************************************
1452 * This is the API exposed from the engine to update FS.
1457 * @return returns S_SS_SUCCESS
1458 * E_SS_FAILURE in case of error
1460 *********************************************************************************
1463 int SS_FSUpdatemain(ua_dataSS_t * ua_dataSS)
1465 int ulResult = S_SS_SUCCESS;
1467 fs_list *head_ptr_node = NULL;
1468 char new_patch_path[SS_MAX_FILE_PATH] = {0};
1471 return E_SS_BAD_PARAMS; // Set error ??
1472 head_ptr_node = headptr_list;
1474 SS_GetPartition_LocDetails(ua_dataSS);
1476 LOGL(LOG_SSENGINE, "FS Update Entry\n");
1478 if (head_ptr_node->del_ref == NULL) {
1479 LOGL(LOG_SSENGINE, "No DEL header\n");
1480 } else if (ulResult == S_SS_SUCCESS) {
1481 ulResult = SS_FSUpdateFile(DELETES, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->del_ref,
1482 ua_dataSS->update_delta->ua_patch_path);
1483 if (ulResult == S_SS_SUCCESS) {
1484 LOGL(LOG_SSENGINE, "SS_FSUpdateFile - DELETES success!!\n");
1487 LOGL(LOG_SSENGINE, "SS_FSUpdateFile - DELETES fail!!\n");
1492 if (head_ptr_node->dif_ref == NULL) {
1493 LOGL(LOG_SSENGINE, "No DIFF header\n");
1494 } else if (ulResult == S_SS_SUCCESS) {
1495 ulResult = SS_FSUpdateFile(DIFFS, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->dif_ref,
1496 ua_dataSS->update_delta->ua_patch_path);
1497 if (ulResult == S_SS_SUCCESS) {
1498 LOGL(LOG_SSENGINE, "SS_FSUpdateFile - DIFFS success!!\n");
1501 LOGL(LOG_SSENGINE, "SS_FSUpdateFile - DIFFS fail!!\n");
1506 if (head_ptr_node->move_ref == NULL) {
1507 LOGL(LOG_SSENGINE, "No MOVE header\n");
1508 } else if (ulResult == S_SS_SUCCESS) {
1509 ulResult = SS_FSUpdateFile(MOVES, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->move_ref,
1510 ua_dataSS->update_delta->ua_patch_path);
1511 if (ulResult == S_SS_SUCCESS) {
1512 LOGL(LOG_SSENGINE, "SS_FSUpdateFile - MOVES success!!\n");
1515 LOGL(LOG_SSENGINE, "SS_FSUpdateFile - MOVES fail!!\n");
1520 if (head_ptr_node->del_ref == NULL) {
1521 LOGL(LOG_SSENGINE, "No DEL header\n");
1522 } else if (ulResult == S_SS_SUCCESS) {
1523 ulResult = SS_FSUpdateFile(DELETE_END, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->del_ref,
1524 ua_dataSS->update_delta->ua_patch_path);
1525 if (ulResult == S_SS_SUCCESS) {
1526 LOGL(LOG_SSENGINE, "SS_FSUpdateFile - DELETE_END success!!\n");
1529 LOGL(LOG_SSENGINE, "SS_FSUpdateFile - DELETE_END fail!!\n");
1534 if (ulResult == S_SS_SUCCESS) {
1535 //new file extraction start
1536 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
1537 LOGL(LOG_SSENGINE, "File path to extract new files : [%s]\n", new_patch_path);
1539 SS_FSUpdateFile(NEWFILES, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->new_ref, new_patch_path);
1540 //new file extraction end
1541 if (ulResult == S_SS_SUCCESS) {
1542 LOGL(LOG_SSENGINE, "SS_FSUpdateFile - NEWFILES success!!\n");
1544 LOGL(LOG_SSENGINE, "SS_FSUpdateFile - NEWFILES fail!!\n");
1549 if (head_ptr_node->sym_difref == NULL) {
1550 LOGL(LOG_SSENGINE, "No SYMDIFF header\n");
1551 } else if (ulResult == S_SS_SUCCESS) {
1553 SS_FSUpdateFile(SYMDIFFS, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->sym_difref,
1554 ua_dataSS->update_delta->ua_patch_path);
1555 if (ulResult == S_SS_SUCCESS) {
1556 LOGL(LOG_SSENGINE, "SS_FSUpdateFile - SYMDIFFS success!!\n");
1559 LOGL(LOG_SSENGINE, "SS_FSUpdateFile - SYMDIFFS fail!!\n");
1564 if (head_ptr_node->sym_newref == NULL) {
1565 LOGL(LOG_SSENGINE, "No SYMNEW header\n");
1566 } else if (ulResult == S_SS_SUCCESS) {
1568 SS_FSUpdateFile(SYMNEWFILES, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->sym_newref,
1569 ua_dataSS->update_delta->ua_patch_path);
1570 if (ulResult == S_SS_SUCCESS) {
1571 LOGL(LOG_SSENGINE, "SS_FSUpdateFile - SYMNEWFILES success!!\n");
1574 LOGL(LOG_SSENGINE, "SS_FSUpdateFile - SYMNEWFILES fail!!\n");
1579 if (head_ptr_node->hard_newref == NULL) {
1580 LOGL(LOG_SSENGINE, "No HARDNEW header\n");
1581 } else if (ulResult == S_SS_SUCCESS) {
1583 SS_FSUpdateFile(HARDNEWFILES, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->hard_newref,
1584 ua_dataSS->update_delta->ua_patch_path);
1585 if (ulResult == S_SS_SUCCESS) {
1586 LOGL(LOG_SSENGINE, "SS_FSUpdateFile - HARDNEWFILES success!!\n");
1589 LOGL(LOG_SSENGINE, "SS_FSUpdateFile - HARDNEWFILES fail!!\n");
1594 if (head_ptr_node->hard_difref == NULL) {
1595 LOGL(LOG_SSENGINE, "No HARDDIFF header\n");
1596 } else if (ulResult == S_SS_SUCCESS) {
1598 SS_FSUpdateFile(HARDDIFFS, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->hard_difref,
1599 ua_dataSS->update_delta->ua_patch_path);
1600 if (ulResult == S_SS_SUCCESS) {
1601 LOGL(LOG_SSENGINE, "SS_FSUpdateFile - HARDDIFFs success!!\n");
1604 LOGL(LOG_SSENGINE, "SS_FSUpdateFile - HARDDIFFs fail!!\n");
1610 if (ulResult == S_SS_SUCCESS)
1611 ulResult = SS_FSSetAttributes(ua_dataSS);
1617 if (ulResult == S_SS_SUCCESS) {
1618 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
1619 LOGL(LOG_SSENGINE, "FS update complete - success!\n");
1623 LOGL(LOG_SSENGINE, "FS update complete - fail!\n");
1624 return SS_GetUpgradeState();
1628 *********************************************************************************
1630 *********************************************************************************
1633 * This is the API exposed from the engine to update FS.
1634 * FS entry function for updating FS partition. Should be invoked only after verification of the partition
1637 * @param Requires common data structure having all details & Partition Index.
1638 * (Used for getting right NODES information that built during verification)
1639 * (Configuration, Delta info, Partition Info, UI link , Kind of operation.(Verify or Updates))
1641 * @return returns S_SS_SUCCESS
1642 * E_SS_FAILURE in case of error
1644 *********************************************************************************
1646 size_t SS_FSAvailiableFreeSpace(char *block_name)
1652 aFile = setmntent("/proc/mounts", "r");
1653 if (aFile == NULL) {
1654 LOGE("setmntent error\n");
1655 return E_SS_FAILURE;
1657 while (NULL != (ent = getmntent(aFile))) {
1658 if (strcmp(ent->mnt_fsname, block_name) == 0) {
1659 if (statfs(ent->mnt_dir, &sb) == 0)
1660 LOGL(LOG_SSENGINE, "Total free space = %" PRIu64 ", blocks free = %" PRIu64 "\n", sb.f_bsize * sb.f_bavail, sb.f_bfree);
1664 return ((long long)sb.f_bsize * (long long)sb.f_bavail >= (long long)SIZE_4GB) ? SIZE_4GB : sb.f_bsize * sb.f_bavail ;
1667 int SS_FSVerifyPartition(ua_dataSS_t * ua_dataSS)
1669 int ulResult = S_SS_SUCCESS;
1671 LOGE("Wrong Param for fs verification\n");
1672 SS_SetUpgradeState(E_SS_BAD_PARAMS);
1673 return E_SS_FAILURE;
1676 SS_GetPartition_LocDetails(ua_dataSS);
1677 LOGL(LOG_SSENGINE, "FS Verification Start\n");
1678 if (ua_dataSS->ua_operation == UI_OP_SCOUT)
1679 gvalid_session = 1; // (shd b true if called during verification)
1680 headptr_list = SS_FSBuildNodes(ua_dataSS);
1682 if (!headptr_list) {
1683 LOGE("FS Verification Failed\n");
1685 ulResult = E_SS_FAILURE;
1688 if (ulResult == S_SS_SUCCESS)
1691 return SS_GetUpgradeState();
1694 int SS_PatchSourceClear(char *patch_path)
1696 int ret = E_SS_FAILURE;
1697 ret = (int)SS_DeleteFile(patch_path);
1698 if (ret != S_SS_SUCCESS) {
1699 LOGE("failed to delete PATCHFILE file\n");
1700 SS_SetUpgradeState(E_SS_PATCHFILE_DEL_ERROR);
1705 long SS_GetUPIVersion(unsigned char *ver_str)
1708 strncpy((char *)ver_str, SS_TOTA_VERSION, MAX_PATH);
1709 return S_SS_SUCCESS;//wgid: 2456
1711 return E_SS_FAILURE;
1715 BrotliDecoderState *state;
1717 size_t available_in;
1718 size_t available_out;
1720 const uint8_t *compressed_pos;
1721 unsigned char buff_in[T_BLOCKSIZE];
1724 struct BrotliFile *brotli_file = NULL;
1726 int brotli_open(const char *path, __attribute__((unused)) int oflat, ...)
1729 if (brotli_file != NULL) {
1730 LOGE("Cannot open another brotli file.");
1733 brotli_file = (struct BrotliFile*)malloc(sizeof(struct BrotliFile));
1734 if (brotli_file == NULL) {
1735 LOGE("Memory allocation error: %m (%d)", errno);
1738 brotli_file->fd = open(path, O_RDONLY);
1739 if (brotli_file->fd == -1) {
1742 LOGE("Failed to open compressed file %s: %m (%d)", path, errno);
1745 brotli_file->available_in = 0;
1746 brotli_file->compressed_pos = brotli_file->buff_in;
1747 brotli_file->total_size = 0;
1748 brotli_file->state = BrotliDecoderCreateInstance(NULL, NULL, NULL);
1752 ssize_t brotli_read(__attribute__((unused)) int fd, void *buff, size_t len)
1755 assert(brotli_file);
1756 uint8_t *out_pos = buff;
1757 size_t available_out = len;
1758 while (available_out > 0) {
1759 int result = BrotliDecoderDecompressStream(brotli_file->state,
1760 &brotli_file->available_in,
1761 &brotli_file->compressed_pos,
1764 &brotli_file->total_size);
1766 case BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT:
1768 if (brotli_file->available_in > 0) {
1769 // If there is anything left in the buffer we move it to the beginning.
1770 // Altough usually such a situation does not occur.
1771 memmove(brotli_file->buff_in,
1772 brotli_file->compressed_pos,
1773 brotli_file->available_in);
1775 ssize_t r_read = read(brotli_file->fd,
1776 brotli_file->buff_in + brotli_file->available_in,
1777 T_BLOCKSIZE - brotli_file->available_in);
1778 brotli_file->compressed_pos = brotli_file->buff_in;
1780 LOGE("Error reading compressed file: %m (%d)", errno);
1784 brotli_file->available_in += r_read;
1787 case BROTLI_DECODER_RESULT_ERROR:
1789 BrotliDecoderErrorCode code = BrotliDecoderGetErrorCode(brotli_file->state);
1790 const char *err_str = BrotliDecoderErrorString(code);
1791 LOGE("Brotli decoder error: %d %s", code, err_str);
1796 return len - available_out;
1799 int brotli_close(__attribute__((unused)) int fd)
1801 if (brotli_file != NULL) {
1802 if (brotli_file->fd > 0)
1803 close(brotli_file->fd);
1804 BrotliDecoderDestroyInstance(brotli_file->state);
1812 ssize_t brotli_write(__attribute__((unused)) int fd,
1813 __attribute__((unused)) const void *buff,
1814 __attribute__((unused)) size_t len)
1819 int decompress_tar_brotli(const char *path)
1823 .openfunc = brotli_open,
1824 .closefunc = brotli_close,
1825 .readfunc = brotli_read,
1826 .writefunc = brotli_write
1829 if (tar_open(&tar, path, &type, O_RDONLY, 0, 0) != 0) {
1830 LOGL(LOG_SSENGINE, "Cannot open %s file: %m (%d)", path, errno);
1831 return E_SS_FAILURE;
1833 if (tar_extract_all(tar, ".") == -1) {
1834 LOGL(LOG_SSENGINE, "Tar %s extract error: %m (%d)", path, errno);
1835 return E_SS_FAILURE;
1837 if (tar_close(tar) == -1) {
1838 LOGL(LOG_SSENGINE, "Tar %s close error: %m (%d)", path, errno);
1841 return S_SS_SUCCESS;