d36b864e25700ac3b01b27bbbf592ef189591960
[platform/core/system/upgrade.git] / src / upgrade-apply-deltafs / engine / SS_UPI.c
1 /*
2  * upgrade-apply-deltafs
3  *
4  * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd.
5  *
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
9  *
10  *       http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  */
18
19 /*HEADER */
20
21 /*
22
23 Function Prototypes Mandatory
24
25 */
26
27 #include<stdio.h>
28 #include<ctype.h>
29 #include<stdlib.h>
30 #include<string.h>
31 #include<inttypes.h>
32 #include <assert.h>
33 #include <stdbool.h>
34 #include <sys/stat.h>
35 #include <unistd.h>
36 #include <sys/statfs.h>
37 #include <mntent.h>
38 #include <brotli/decode.h>
39 #include "ua_types.h"
40 #include "SS_Common.h"
41 #include "fota_common.h"
42 #include "SS_UPI.h"
43 #include "SS_PatchDelta.h"
44 #include "SS_Engine_Errors.h"
45 #include "SS_FSUpdate.h"
46 #include "fota_tar.h"
47
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;
51
52 //Check SS function if available
53 int file_exist(char *filename)
54 {
55         struct stat buf;
56         int ret = 0;
57
58         ret = lstat(filename, &buf);
59         if (ret < 0)
60                 ret = stat(filename, &buf);
61
62         return (ret >= 0) ? (1) : (0);
63 }
64
65 int SS_GetProgressResolution(int ultotalFSCnt)
66 {
67         if (ultotalFSCnt < DISPLAYRESOLUTION_SIZE)
68                 return 1;
69         else
70                 return (ultotalFSCnt / DISPLAYRESOLUTION_SIZE);
71 }
72
73 void SS_SetUpgradeState(int Val)
74 {
75         LOGE("FAILED to upgrade Cause:[0x%x]\n", Val);
76         FS_UpgradeState = Val;
77         return;
78 }
79
80 int SS_GetUpgradeState()
81 {
82         return FS_UpgradeState;
83 }
84
85 int SS_rename1(const char *old_file_name, const char *new_file_name)
86 {
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)
91                 return E_SS_FAILURE;
92         snprintf(temp_name, strlen(new_file_name) + 10, "%s.temp", new_file_name);
93         result = rename(new_file_name, temp_name);
94         if (result != 0)
95                 goto Cleanup;
96         result = rename(old_file_name, new_file_name);
97         if (result != 0)
98                 goto Cleanup;
99         result = unlink(temp_name);
100  Cleanup:
101         if (temp_name)
102                 SS_Free(temp_name);
103         return result;
104 }
105
106 /*!
107  *********************************************************************************
108  *                                       SS_FSVerifyNode
109  *********************************************************************************
110  *
111  * @brief
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.
114  *
115  *
116  *      @param
117  *
118  *      @return                         returns S_SS_SUCCESS and
119  *                                              returns E_SS_FAILURE in case any error occurs
120  *
121  *********************************************************************************
122  */
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)
125 {
126         FileInfo source_file;
127         uint8_t source_sha1[SHA_DIGEST_SIZE];
128
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);
133                         return E_SS_FAILURE;
134                 }
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);
140                                 return E_SS_FAILURE;
141                         }
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
150                                         return E_SS_FAILURE;
151                                 }
152                         }
153                         SS_Free(source_file.data);
154                 }
155         }
156         return S_SS_SUCCESS;
157 }
158
159 /*!
160  *********************************************************************************
161  *                                       SS_AppendNode
162  *********************************************************************************
163  *
164  * @brief
165  *      This is to append node to the global control structure for delta files.
166  *
167  *
168  *      @param
169  *
170  *      @return                         returns S_SS_SUCCESS and
171  *                                              returns E_SS_FAILURE in case any error occurs
172  *
173  *********************************************************************************
174  */
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)
178 {
179         fs_params *newnode = NULL;
180         int data_size = 0;
181         int data_offset = 0;
182
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);
186                 return E_SS_FAILURE;
187         }
188
189         if ((E_SS_FAILURE ==
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,
192                          old_path, new_path);
193                 return E_SS_FAILURE;
194         }
195         newnode = (fs_params *) SS_Malloc(sizeof(fs_params));
196         if (!newnode)
197                 return E_SS_FAILURE;
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;
207
208         //LOG("%s %s %d %s %s \n",newnode->file_path,newnode->patch_name,newnode->type, newnode->sha1src, newnode->sha1trg);
209
210         if (*headparam == NULL) {
211                 *headparam = newnode;
212                 *tailparam = newnode;
213         } else {
214                 (*tailparam)->nextnode = newnode;
215                 (*tailparam) = (*tailparam)->nextnode;
216         }
217         return S_SS_SUCCESS;
218
219 }
220
221 void SS_UpdateUIProgress(ua_dataSS_t * ua_dataSS, int ulTotalFsCnt, int ulDone)
222 {
223         static int ss_count = 1;
224         int res_val = SS_GetProgressResolution(ulTotalFsCnt);
225         if (!ua_dataSS) {
226                 LOGE("Error ua_dataSS\n");
227                 return;
228         }
229 //LOG("\nvalues are ss_count[%d] total_file_cnt[%d]",ss_count,ulTotalFsCnt);
230         if (ulDone == 1) {
231                 if (ua_dataSS->ui_progress)
232                         ua_dataSS->ui_progress(ua_dataSS, 100);
233                 ss_count = 1;
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);
239                 }
240                 ss_count++;
241         } else {
242                 if (ua_dataSS->ui_progress)
243                         ua_dataSS->ui_progress(ua_dataSS, 100);
244                 ss_count = 1;
245         }
246
247 }
248
249 /*!
250  *********************************************************************************
251  *                                       SS_FSClearNodes
252  *********************************************************************************
253  *
254  * @brief
255  *      This is to clear the global control structure for delta files.
256  *
257  *
258  *      @param
259  *
260  *      @return
261  *
262  *********************************************************************************
263  */
264 void SS_FSClearNodes()
265 {
266         fs_params *local_temp = NULL;
267         fs_params *local_next = NULL;
268         LOGL(LOG_SSENGINE, "Free Nodes\n");
269         if (headptr_list) {
270                 if (headptr_list->del_ref) {
271                         local_temp = headptr_list->del_ref;
272                         while (local_temp) {
273                                 local_next = local_temp->nextnode;
274                                 SS_Free(local_temp);
275                                 local_temp = local_next;
276                         }
277                 }
278                 if (headptr_list->dif_ref) {
279                         local_temp = headptr_list->dif_ref;
280                         while (local_temp) {
281                                 local_next = local_temp->nextnode;
282                                 SS_Free(local_temp);
283                                 local_temp = local_next;
284                         }
285                 }
286                 if (headptr_list->move_ref) {
287                         local_temp = headptr_list->move_ref;
288                         while (local_temp) {
289                                 local_next = local_temp->nextnode;
290                                 SS_Free(local_temp);
291                                 local_temp = local_next;
292                         }
293                 }
294                 if (headptr_list->new_ref) {
295                         local_temp = headptr_list->new_ref;
296                         while (local_temp) {
297                                 local_next = local_temp->nextnode;
298                                 SS_Free(local_temp);
299                                 local_temp = local_next;
300                         }
301                 }
302                 if (headptr_list->sym_difref) {
303                         local_temp = headptr_list->sym_difref;
304                         while (local_temp) {
305                                 local_next = local_temp->nextnode;
306                                 SS_Free(local_temp);
307                                 local_temp = local_next;
308                         }
309                 }
310                 if (headptr_list->sym_newref) {
311                         local_temp = headptr_list->sym_newref;
312                         while (local_temp) {
313                                 local_next = local_temp->nextnode;
314                                 SS_Free(local_temp);
315                                 local_temp = local_next;
316                         }
317                 }
318                 if (headptr_list->hard_newref) {
319                         local_temp = headptr_list->hard_newref;
320                         while (local_temp) {
321                                 local_next = local_temp->nextnode;
322                                 SS_Free(local_temp);
323                                 local_temp = local_next;
324                         }
325                 }
326                 if (headptr_list->hard_difref) {
327                         local_temp = headptr_list->hard_difref;
328                         while (local_temp) {
329                                 local_next = local_temp->nextnode;
330                                 SS_Free(local_temp);
331                                 local_temp = local_next;
332                         }
333                 }
334                 SS_Free(headptr_list);
335                 headptr_list = NULL;
336         }
337 }
338
339 /*!
340  *********************************************************************************
341  *                                       SS_FSGetDeltaCount
342  *********************************************************************************
343  *
344  * @brief
345  *      This is to get the delta count for diffs , deletes etc.
346  *
347  *
348  *      @param
349  *
350  *      @return                         returns structure with delta count info
351  *                                              NULL in case of error
352  *
353  *********************************************************************************
354  */
355
356 struct details *SS_FSGetDeltaCount(ua_dataSS_t *ua_dataSS)
357 {
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;
361         char *token = NULL;
362         char *FileData = NULL;
363         char *line = NULL;
364         char *saveptr = NULL;
365         char buf[256];
366         struct details *refer_copy = NULL;
367         FILE *filename_extract = NULL;
368         int gtotalFSCnt = 0;
369
370         if (!(ubDeltaPath && ubDeltaInfoFile)) {
371                 LOGE("failed to Parse DELTA count information: \n");
372                 SS_SetUpgradeState(E_SS_BAD_PARAMS);
373                 return NULL;
374         }
375         refer_copy = (struct details *)SS_Malloc(sizeof(struct details));
376
377         if (refer_copy == NULL) {
378                 LOGE("failed to allocate memory\n");
379                 return NULL;
380         }
381
382         LOGL(LOG_SSENGINE, "Delta File Info =%s\n", ubDeltaInfoFile);
383
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);
389                 ret = 0;
390                 goto cleanup;
391         }
392
393         size = ua_dataSS->tar_data->text_files_info[PATCHLIST_FILE].size;
394
395         FileData = SS_Malloc(size + 1);
396         if (FileData == NULL) {
397                 LOGE("Failed to Allocate Memory\n");
398                 SS_SetUpgradeState(E_SS_MALLOC_ERROR);
399                 ret = 0;
400                 goto cleanup;
401         }
402
403         read_size = fread(FileData, 1, size, filename_extract);
404         if (read_size < size) {
405                 SS_SetUpgradeState(E_SS_FSFAILEDTOBACKUPPATCHINFO);
406                 ret = 0;
407                 goto cleanup;
408         }
409
410         LOGL(LOG_SSENGINE, " Size [%d]\n", size);
411
412         line = strstr(FileData, SS_FSCOUNT_MAGIC_KEY);
413         if (line) {
414                 LOGL(LOG_SSENGINE, "SS_FSGetDeltaCount() last line %s \n", line);
415
416                 token = strtok_r(&line[SS_FSCOUNT_MAGIG_KEYLEN], SS_TOKEN_SPACE, &saveptr);
417                 if (token)
418                         refer_copy->diffs = atoi(token);
419                 else {
420                         SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT);
421                         ret = 0;
422                         goto cleanup;
423                 }
424                 token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr);
425                 if (token)
426                         refer_copy->moves = atoi(token);
427                 else {
428                         SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT);
429                         ret = 0;
430                         goto cleanup;
431                 }
432
433                 token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr);
434                 if (token)
435                         refer_copy->news = atoi(token);
436                 else {
437                         SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT);
438                         ret = 0;
439                         goto cleanup;
440                 }
441
442                 token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr);
443                 if (token)
444                         refer_copy->deletes = atoi(token);
445                 else {
446                         SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT);
447                         ret = 0;
448                         goto cleanup;
449                 }
450
451                 token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr);
452                 if (token)
453                         refer_copy->symdiffs = atoi(token);
454                 else {
455                         SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT);
456                         ret = 0;
457                         goto cleanup;
458                 }
459
460                 token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr);
461                 if (token)
462                         refer_copy->symnews = atoi(token);
463                 else {
464                         SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT);
465                         ret = 0;
466                         goto cleanup;
467                 }
468
469                 token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr);
470                 if (token)
471                         refer_copy->harddiffs = atoi(token);
472                 else {
473                         SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT);
474                         ret = 0;
475                         goto cleanup;
476                 }
477
478                 token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr);
479                 if (token)
480                         refer_copy->hardnews = atoi(token);
481                 else {
482                         SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT);
483                         ret = 0;
484                         goto cleanup;
485                 }
486
487                 gtotalFSCnt =
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);
491
492         } else {
493                 SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT);
494                 LOG("SS_FSGetDeltaCount() Failed to read last line\n");
495         }
496         if (gtotalFSCnt < 0) {
497                 ret = 0;
498                 goto cleanup;
499         }
500
501  cleanup:
502         SS_Free(FileData);
503         if (filename_extract)
504                 fclose(filename_extract);
505         if (ret) {
506                 return refer_copy;
507         } else {
508                 SS_Free(refer_copy);
509                 return NULL;
510         }
511
512 }
513
514 /*!
515  *********************************************************************************
516  *                                       SS_FSBuildNodes
517  *********************************************************************************
518  *
519  * @brief
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
522  *
523  *
524  *      @param
525  *
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
528  *
529  *********************************************************************************
530  */
531 fs_list *SS_FSBuildNodes(ua_dataSS_t * ua_dataSS)
532 {
533         FILE *fp = NULL;
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;
560
561         struct details *local = NULL;
562         fs_list *fs_head_node = NULL;
563         int i = 0, retval = 0;
564         if (!ua_dataSS) {
565                 LOGE("Bad structure ua_dataSS\n");
566                 SS_SetUpgradeState(E_SS_BAD_PARAMS);
567                 return NULL;
568         }
569         LOGL(LOG_SSENGINE, " Build Nodes Entry \n");
570
571         local = SS_FSGetDeltaCount(ua_dataSS);
572         if (local == NULL) {
573                 LOGE(" Build Nodes Failed \n");
574                 SS_SetUpgradeState(E_SS_BAD_PARAMS);
575                 return NULL;
576         }
577
578         fp = fopen(ua_dataSS->tar_data->text_files_info[PATCHLIST_FILE].extracted_name, "r");
579         if (!fp) {
580                 SS_SetUpgradeState(E_SS_FSFAILEDTOOPENPATCHINFO);
581                 SS_Free(local);
582                 return NULL;
583         }
584
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);
588 /*
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 ***********************************************************************
609 */
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);
615                                 break;
616                         }
617                         //LOGL(LOG_SSENGINE, "DIFF LINE:[%d] [%s] \n",i+1,line);
618
619                         change_type = strtok_r(line, SS_TOEKN_COLON, &saveptr);
620                         file_type = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
621                         if (!file_type) {
622                                 LOGE("Unexpected null in strtok_r");
623                                 goto CleanUp;
624                         }
625
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);
631
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);
636                                         goto CleanUp;
637                                 }
638                                 retval =
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
643                                         goto CleanUp;
644
645                                 if (ua_dataSS->ua_operation == UI_OP_SCOUT) {
646                                         SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
647                                 }
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);
655
656                                 if (patch_name && (strlen(patch_name) <= SS_MAX_NAMELENSUPPORTED)) {
657                                         retval =
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
662                                                 goto CleanUp;
663                                 } else {
664                                         SS_SetUpgradeState(E_SS_FILENAMELENERROR);
665                                         LOGE("File Name length Limitation Error File:[%s]\n", patch_name);
666                                         goto CleanUp;
667                                 }
668
669                                 if (ua_dataSS->ua_operation == UI_OP_SCOUT) {
670                                         SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
671                                 }
672                         } else {
673                                 SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO);
674                                 LOGE("Patch Name format Error File\n");
675                                 goto CleanUp;
676                         }
677                 }
678         }
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;
686                         goto CleanUp;
687                 }
688         }
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);
694                                 break;
695                         }
696
697                         change_type = strtok_r(line, SS_TOEKN_COLON, &saveptr);
698                         if (!change_type) {
699                                 LOGE("Unexpected null in strtok_r");
700                                 goto CleanUp;
701                         }
702                         file_type = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
703
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);
707                                 del_type = DELETES;
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);
710                                 sha1src = string_na;
711                                 del_type = DELETES;
712                         } else if (file_type && strcmp(file_type, SS_STRING_END) == 0) {
713                                 source_name = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr);
714                                 sha1src = string_na;
715                                 del_type = DELETE_END;
716                         } else {
717                                 LOGE("Failed to parse DELETES - LINE:[%d] [%s] \n", i + 1, line);
718                                 goto CleanUp;
719                         }
720
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);
725                                 goto CleanUp;
726                         }
727                         //LOGL(LOG_SSENGINE, "%s Index [%d]\n", SS_STRING_DEL, i);
728                         retval =
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
733                                 goto CleanUp;
734             if (ua_dataSS->ua_operation == UI_OP_SCOUT) {
735                         SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
736             }
737
738                 }
739         }                                                  //For symlink files
740
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);
746                                 break;
747                         }
748                         //LOGL(LOG_SSENGINE, "SYMDIFF LINE:[%d] [%s] \n",i+1,line);
749
750                         change_type = strtok_r(line, SS_TOEKN_COLON, &saveptr);
751                         file_type = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
752
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);
759
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);
764                                         goto CleanUp;
765                                 }
766                                 retval =
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
771                                         goto CleanUp;
772                 if (ua_dataSS->ua_operation == UI_OP_SCOUT) {
773                                 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
774                 }
775                         }
776                 }
777         }
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);
783                                 break;
784                         }
785                         //LOGL(LOG_SSENGINE, "SYMNEWS LINE:[%d] [%s] \n",i+1,line);
786
787                         change_type = strtok_r(line, SS_TOEKN_COLON, &saveptr);
788                         file_type = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
789
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);
795
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);
800                                         goto CleanUp;
801                                 }
802                                 retval =
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
807                                         goto CleanUp;
808                 if (ua_dataSS->ua_operation == UI_OP_SCOUT) {
809                                 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
810                 }
811                         }
812                 }
813         }                       // For hardlinks
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);
819                                 break;
820                         }
821                         //LOGL(LOG_SSENGINE, "HARDNEWS LINE:[%d] [%s] \n",i+1,line);
822
823                         change_type = strtok_r(line, SS_TOEKN_COLON, &saveptr);
824                         file_type = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
825
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);
831
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);
836                                         goto CleanUp;
837                                 }
838                                 retval =
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
843                                         goto CleanUp;
844                 if (ua_dataSS->ua_operation == UI_OP_SCOUT) {
845                                 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
846                 }
847                         }
848                 }
849         }
850
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);
856                                 break;
857                         }
858                         //LOGL(LOG_SSENGINE, "HARDIFFS LINE:[%d] [%s] \n",i+1,line);
859
860                         change_type = strtok_r(line, SS_TOEKN_COLON, &saveptr);
861                         file_type = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
862
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);
869
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);
874                                         goto CleanUp;
875                                 }
876                                 retval =
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
881                                         goto CleanUp;
882                 if (ua_dataSS->ua_operation == UI_OP_SCOUT) {
883                                 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
884                 }
885                         }
886                 }
887         }
888
889         fs_head_node = (fs_list *) SS_Malloc(sizeof(fs_list));
890         if (!fs_head_node) {
891                 SS_SetUpgradeState(E_SS_MALLOC_ERROR);
892                 goto CleanUp;
893         }
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;
903
904         if (ua_dataSS->ua_operation == UI_OP_SCOUT) {
905         SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 1);
906         }
907
908  CleanUp:
909         fclose(fp);
910         SS_Free(local);
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;
913         return fs_head_node;
914 }
915
916 void SS_GetPartition_LocDetails(ua_dataSS_t * ua_dataSS)
917 {
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);
926
927         return;
928 }
929
930 //Support functions//Change Struct format details (Can include total file count also???)/*!
931 /*
932 ******************************************************************************** *
933 SS_FSSetAttributes
934         *********************************************************************************
935         * *@brief
936         * This is used to set the file attributes at the end of application of patches in FS
937         *
938         * *@param
939         *
940         *@return returns S_SS_SUCCESS
941         * E_SS_FAILURE in case of error
942         *
943         *********************************************************************************
944  */
945 int SS_FSSetAttributes(ua_dataSS_t * ua_dataSS)
946 {
947         char *pline = NULL;
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;
955         int fail_cnt = 0;
956         int fd = -1;
957
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);
961                 return E_SS_FAILURE;
962         }
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
968         }
969
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);
974                 return E_SS_FAILURE;
975         }
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;
980                 SS_Free(item_data);
981                 SS_SetUpgradeState(E_SS_FSBADATTRIBUTES);
982                 return E_SS_FAILURE;
983         }
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) {
989                         SS_Free(item_data);
990                         item_data = NULL;
991                 }
992                 close(fd);
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;
995                 return E_SS_FAILURE;
996         }
997         item_data[read_data] = '\0';
998
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) {
1003                         SS_Free(item_data);
1004                         item_data = NULL;
1005                 }
1006                 close(fd);
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;
1010         }
1011
1012         while (pline) {
1013                 char *saveptr_pline = NULL;
1014                 pfilePath = strtok_r(pline, "\"", &saveptr_pline);
1015
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);
1019                         continue;
1020                 }
1021
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);
1030
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);
1035                                 if (item_data) {
1036                                         SS_Free(item_data);
1037                                         item_data = NULL;
1038                                 }
1039                                 fail_cnt++;
1040                         }
1041                 } else {
1042                         LOGE("Failed to Parse Attributes - LINE %s\n", pline);
1043                         SS_SetUpgradeState(E_SS_FSBADATTRIBUTES);
1044                         if (item_data) {
1045                                 SS_Free(item_data);
1046                                 item_data = NULL;
1047                         }
1048                         fail_cnt++;
1049                 }
1050                 pline = strtok_r(NULL, SS_TOKEN_NEWLINE, &psaveptr);
1051         }
1052
1053         if (item_data != NULL) {
1054                 SS_Free(item_data);
1055                 item_data = NULL;
1056         }
1057
1058         if (fail_cnt > 0)
1059                 result = E_SS_FAILURE;
1060         else
1061                 result = S_SS_SUCCESS;
1062
1063         close(fd);
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;
1066         return result;
1067 }
1068
1069 /*!
1070  *********************************************************************************
1071  *                                       SS_FSUpdateFile
1072  *********************************************************************************
1073  *
1074  * @brief
1075  *      This is used to update individual files on case basis
1076  *
1077  *
1078  *      @param
1079  *
1080  *      @return                         returns S_SS_SUCCESS
1081  *                                              E_SS_FAILURE in case of error
1082  *
1083  *********************************************************************************
1084  */
1085 int SS_FSUpdateFile(int ubFileType, ua_dataSS_t * ua_dataSS, int ulPatchCount, fs_params * pFsNode,
1086                                         const char *patch_path)
1087 {
1088         int ulFileIndex = 1;
1089         char ubPatch[SS_MAX_FILE_PATH] = { 0, };
1090         int ulReadCnt = 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);
1097
1098         if (!patch_path) {
1099                 LOGE("Bad patch_path name\n");
1100                 return E_SS_FAILURE;
1101         }
1102         switch (ubFileType) {
1103         case DIFFS:
1104                 {
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");
1111                                 break;
1112                         }
1113                         for (;;)
1114                         {
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);
1118                                 int broken = 0;
1119                                 fs_params *temp_param;
1120                                 switch(tar_diff_iter_next_extract(ua_dataSS->tar_data, &diff_iter, patchfile_source_path, &temp_param))
1121                                 {
1122                                 case -1:
1123                                         broken = 1;
1124                                         ulResult = E_SS_FAILURE;
1125                                         SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
1126                                         LOGE("Delta Read Failed\n");
1127                                         break;
1128                                 case 1:
1129                                         broken = 1;
1130                                         ulResult = S_SS_SUCCESS;
1131                                         break;
1132                                 case 0:
1133                                         ulResult =
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);
1140                                                 broken = 1;
1141                                                 break;
1142                                         }
1143                                 }
1144                                 if (broken == 1)
1145                                         break;
1146
1147                                 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
1148                                 ulFileIndex++;
1149                         }
1150                         LOGL(LOG_SSENGINE, "DIFFS : Total index = [%d]\n",
1151                              ulFileIndex - 1);
1152                         LOGL(LOG_SSENGINE, "DIFFS mode end\n");
1153                 }
1154                 break;
1155         case MOVES:
1156                 {
1157                         LOGL(LOG_SSENGINE, "MOVES mode start\n");
1158                         while (pFsNode) {
1159                                 //LOGL(LOG_SSENGINE, "MOVES update Index: [%d] \n", ulFileIndex++);
1160                                 int skip_flag = 0;
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);
1173                                                 break;
1174                                         }
1175                                         if (memcmp(target_file.sha1, target_sha1, SHA_DIGEST_SIZE) == 0) {
1176                                                 LOGL(LOG_SSENGINE, "Patch already applied\n");
1177                                                 skip_flag = 1;
1178                                                 if (target_file.data)
1179                                                         SS_Free(target_file.data);
1180                                         } else {
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);
1186                                                 break;
1187                                         }
1188                                 } else {
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);
1192                                         break;
1193                                 }
1194
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);
1200                                                 break;
1201                                         } else {
1202                                                 // Verification
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);
1210                                                                 break;
1211                                                         }
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);
1216                                                         } else {
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);
1222                                                                 break;
1223                                                         }
1224                                                 }
1225                                         }
1226                                 }
1227                                 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
1228                                 pFsNode = pFsNode->nextnode;
1229                                 ulFileIndex++;
1230                         }
1231                         LOGL(LOG_SSENGINE, "MOVES : Total index = [%d]\n",
1232                              ulFileIndex - 1);
1233                         LOGL(LOG_SSENGINE, "MOVES mode end\n");
1234                 }
1235                 break;
1236         case DELETES:
1237                 {
1238                         LOGL(LOG_SSENGINE, "DELETES mode start\n");
1239
1240                         int ulFiletype = 0;
1241                         while (pFsNode) {
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);
1247                                         else
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);
1252                                                 break;
1253                                         }
1254                                         ulFileIndex++;
1255                                 }
1256                                 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
1257                                 pFsNode = pFsNode->nextnode;
1258                         }
1259                         LOGL(LOG_SSENGINE, "DELETES : Total index = [%d]\n",
1260                              ulFileIndex - 1);
1261                         LOGL(LOG_SSENGINE, "DELETES mode end\n");
1262                 }
1263                 break;
1264         case DELETE_END:
1265                 {
1266                         LOGL(LOG_SSENGINE, "DELETE_END mode start\n");
1267
1268                         int ulFiletype = 0;
1269                         while (pFsNode) {
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);
1275                                         else
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);
1280                                                 break;
1281                                         }
1282                                         ulFileIndex++;
1283                                 }
1284                                 pFsNode = pFsNode->nextnode;
1285                         }
1286                         LOGL(LOG_SSENGINE, "DELETE_END : Total index = [%d]\n",
1287                              ulFileIndex - 1);
1288                         LOGL(LOG_SSENGINE, "DELETE_END mode end\n");
1289                 }
1290                 break;
1291
1292         case NEWFILES:
1293                 {
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;
1301                                 }
1302
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);
1305                                 } else {
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;
1309                                 }
1310
1311                                 SS_DeleteFile(ua_dataSS->tar_data->new_files_info.extracted_name);
1312                         } else {
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);
1314                         }
1315                         LOGL(LOG_SSENGINE, "NEWFILES mode end\n");
1316                 }
1317                 break;
1318         case SYMDIFFS:
1319                 {
1320                         LOGL(LOG_SSENGINE, "SYMDIFFS mode start\n");
1321                         while (pFsNode) {
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);
1330                                         }
1331                                 } else {
1332                                         LOGE("Unlink Failed, result = [%d], index = [%d]\n", ulResult, ulFileIndex);
1333                                         SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
1334                                         break;
1335                                 }
1336                                 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
1337                                 pFsNode = pFsNode->nextnode;
1338                                 ulFileIndex++;
1339                         }
1340                         LOGL(LOG_SSENGINE, "SYMDIFFS : Total index = [%d]\n",
1341                              ulFileIndex - 1);
1342                         LOGL(LOG_SSENGINE, "SYMDIFFS mode end\n");
1343                 }
1344                 break;
1345         case SYMNEWFILES:
1346                 {
1347                         LOGL(LOG_SSENGINE, "SYMNEWFILES mode start\n");
1348
1349                         fs_params *head_node;
1350                         int retry_count = 0, do_retry = 0;
1351
1352  SYMLINK_CREATE:
1353                         head_node = pFsNode;
1354                         while (head_node) {
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);
1363                                         break;
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;
1368                                         continue;
1369                                 }
1370                                 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
1371                                 head_node = head_node->nextnode;
1372                                 ulFileIndex++;
1373                         }
1374                         LOGL(LOG_SSENGINE, "SYMNEWFILES : Total index = [%d]\n",
1375                              ulFileIndex - 1);
1376                         if (do_retry && (retry_count < 4)) {
1377                                 retry_count++;
1378                                 ulFileIndex = 0;
1379                                 do_retry = 0;
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);
1384                                 break;
1385                         }
1386                         LOGL(LOG_SSENGINE, "SYMNEWFILES mode end\n");
1387                 }
1388                 break;
1389         case HARDDIFFS:
1390                 {
1391                         LOGL(LOG_SSENGINE, "HARDDIFFS mode start\n");
1392                         while (pFsNode) {
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);
1401                                         }
1402                                 } else {
1403                                         LOGE("Removing old hardlink Failed, result = [%d], index = [%d]\n", ulResult, ulFileIndex);
1404                                         SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
1405                                         break;
1406                                 }
1407                                 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
1408                                 pFsNode = pFsNode->nextnode;
1409                                 ulFileIndex++;
1410                         }
1411                         LOGL(LOG_SSENGINE, "HARDDIFFS : Total index = [%d]\n",
1412                              ulFileIndex - 1);
1413                         LOGL(LOG_SSENGINE, "HARDDIFFS mode end\n");
1414                 }
1415                 break;
1416         case HARDNEWFILES:
1417                 {
1418                         LOGL(LOG_SSENGINE, "HARDNEWFILES mode start\n");
1419             fs_params *head_node = pFsNode;
1420                         while (head_node) {
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);
1428                                         break;
1429                                 }
1430                                 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
1431                                 head_node = head_node->nextnode;
1432                                 ulFileIndex++;
1433                         }
1434                         LOGL(LOG_SSENGINE, "HARDNEWFILES : Total index = [%d]\n",
1435                              ulFileIndex - 1);
1436                         LOGL(LOG_SSENGINE, "HARDNEWFILES mode end\n");
1437
1438         }
1439                 break;
1440         default:
1441                 break;
1442         }
1443         return ulResult;
1444 }
1445
1446 /*!
1447  *********************************************************************************
1448  *                                       SS_FSUpdatemain
1449  *********************************************************************************
1450  *
1451  * @brief
1452  *      This is the API exposed from the engine to update FS.
1453  *
1454  *
1455  *      @param
1456  *
1457  *      @return                         returns S_SS_SUCCESS
1458  *                                              E_SS_FAILURE in case of error
1459  *
1460  *********************************************************************************
1461  */
1462
1463 int SS_FSUpdatemain(ua_dataSS_t * ua_dataSS)
1464 {
1465         int ulResult = S_SS_SUCCESS;
1466
1467         fs_list *head_ptr_node = NULL;
1468         char new_patch_path[SS_MAX_FILE_PATH] = {0};
1469
1470         if (!ua_dataSS)
1471                 return E_SS_BAD_PARAMS; // Set error ??
1472         head_ptr_node = headptr_list;
1473
1474         SS_GetPartition_LocDetails(ua_dataSS);
1475
1476         LOGL(LOG_SSENGINE, "FS Update Entry\n");
1477
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");
1485
1486                 } else {
1487                         LOGL(LOG_SSENGINE, "SS_FSUpdateFile - DELETES fail!!\n");
1488                         goto cleanup;
1489                 }
1490         }
1491
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");
1499
1500                 } else {
1501                         LOGL(LOG_SSENGINE, "SS_FSUpdateFile - DIFFS fail!!\n");
1502                         goto cleanup;
1503                 }
1504         }
1505
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");
1513
1514                         } else {
1515                                 LOGL(LOG_SSENGINE, "SS_FSUpdateFile - MOVES fail!!\n");
1516                                 goto cleanup;
1517                         }
1518         }
1519
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");
1527
1528                         } else {
1529                                 LOGL(LOG_SSENGINE, "SS_FSUpdateFile - DELETE_END fail!!\n");
1530                                 goto cleanup;
1531                         }
1532         }
1533
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);
1538                 ulResult =
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");
1543                 } else {
1544                         LOGL(LOG_SSENGINE, "SS_FSUpdateFile - NEWFILES fail!!\n");
1545                         goto cleanup;
1546                 }
1547         }
1548
1549         if (head_ptr_node->sym_difref == NULL) {
1550                 LOGL(LOG_SSENGINE, "No SYMDIFF header\n");
1551         } else if (ulResult == S_SS_SUCCESS) {
1552                 ulResult =
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");
1557
1558                 } else {
1559                         LOGL(LOG_SSENGINE, "SS_FSUpdateFile - SYMDIFFS fail!!\n");
1560                         goto cleanup;
1561                 }
1562         }
1563
1564         if (head_ptr_node->sym_newref == NULL) {
1565                 LOGL(LOG_SSENGINE, "No SYMNEW header\n");
1566         } else if (ulResult == S_SS_SUCCESS) {
1567                 ulResult =
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");
1572
1573                 } else {
1574                         LOGL(LOG_SSENGINE, "SS_FSUpdateFile - SYMNEWFILES fail!!\n");
1575                         goto cleanup;
1576                 }
1577         }
1578
1579         if (head_ptr_node->hard_newref == NULL) {
1580                 LOGL(LOG_SSENGINE, "No HARDNEW header\n");
1581         } else if (ulResult == S_SS_SUCCESS) {
1582                 ulResult =
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");
1587
1588                 } else {
1589                         LOGL(LOG_SSENGINE, "SS_FSUpdateFile - HARDNEWFILES fail!!\n");
1590                         goto cleanup;
1591                 }
1592         }
1593
1594         if (head_ptr_node->hard_difref == NULL) {
1595                 LOGL(LOG_SSENGINE, "No HARDDIFF header\n");
1596         } else if (ulResult == S_SS_SUCCESS) {
1597                 ulResult =
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");
1602
1603                 } else {
1604                         LOGL(LOG_SSENGINE, "SS_FSUpdateFile - HARDDIFFs fail!!\n");
1605                         goto cleanup;
1606                 }
1607         }
1608
1609 cleanup:
1610         if (ulResult == S_SS_SUCCESS)
1611                 ulResult = SS_FSSetAttributes(ua_dataSS);
1612
1613         sync();
1614         sleep(1);
1615         SS_FSClearNodes();
1616
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");
1620                 return ulResult;
1621         }
1622
1623         LOGL(LOG_SSENGINE, "FS update complete - fail!\n");
1624         return SS_GetUpgradeState();
1625 }
1626
1627 /*!
1628  *********************************************************************************
1629  *                                       SS_FSUpdatemain
1630  *********************************************************************************
1631  *
1632  * @brief
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
1635  *
1636  *
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))
1640  *
1641  *      @return                         returns S_SS_SUCCESS
1642  *                                              E_SS_FAILURE in case of error
1643  *
1644  *********************************************************************************
1645  */
1646 size_t SS_FSAvailiableFreeSpace(char *block_name)
1647 {
1648
1649         struct mntent *ent;
1650         FILE *aFile;
1651         struct statfs sb;
1652         aFile = setmntent("/proc/mounts", "r");
1653         if (aFile == NULL) {
1654                 LOGE("setmntent error\n");
1655                 return E_SS_FAILURE;
1656         }
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);
1661                 }
1662         }
1663         endmntent(aFile);
1664         return ((long long)sb.f_bsize * (long long)sb.f_bavail >= (long long)SIZE_4GB) ? SIZE_4GB : sb.f_bsize * sb.f_bavail ;
1665 }
1666
1667 int SS_FSVerifyPartition(ua_dataSS_t * ua_dataSS)
1668 {
1669         int ulResult = S_SS_SUCCESS;
1670         if (!ua_dataSS) {
1671                 LOGE("Wrong Param for fs verification\n");
1672                 SS_SetUpgradeState(E_SS_BAD_PARAMS);
1673                 return E_SS_FAILURE;
1674         }
1675
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);
1681
1682         if (!headptr_list) {
1683                 LOGE("FS Verification Failed\n");
1684                 SS_FSClearNodes();
1685                 ulResult = E_SS_FAILURE;
1686         }
1687
1688         if (ulResult == S_SS_SUCCESS)
1689                 return ulResult;
1690         else
1691                 return SS_GetUpgradeState();
1692 }
1693
1694 int SS_PatchSourceClear(char *patch_path)
1695 {
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);
1701         }
1702         return ret;
1703 }
1704
1705 long SS_GetUPIVersion(unsigned char *ver_str)
1706 {
1707         if (ver_str) {
1708                 strncpy((char *)ver_str, SS_TOTA_VERSION, MAX_PATH);
1709                 return S_SS_SUCCESS;//wgid: 2456
1710         } else
1711                 return E_SS_FAILURE;
1712 }
1713
1714 struct BrotliFile {
1715         BrotliDecoderState *state;
1716         int fd;
1717         size_t available_in;
1718         size_t available_out;
1719         size_t total_size;
1720         const uint8_t *compressed_pos;
1721         unsigned char buff_in[T_BLOCKSIZE];
1722 };
1723
1724 struct BrotliFile *brotli_file = NULL;
1725
1726 int brotli_open(const char *path, __attribute__((unused)) int oflat, ...)
1727 {
1728         assert(path);
1729         if (brotli_file != NULL) {
1730                 LOGE("Cannot open another brotli file.");
1731                 return -1;
1732         }
1733         brotli_file = (struct BrotliFile*)malloc(sizeof(struct BrotliFile));
1734         if (brotli_file == NULL) {
1735                 LOGE("Memory allocation error: %m (%d)", errno);
1736                 return -1;
1737         }
1738         brotli_file->fd = open(path, O_RDONLY);
1739         if (brotli_file->fd == -1) {
1740                 free(brotli_file);
1741                 brotli_file = NULL;
1742                 LOGE("Failed to open compressed file %s: %m (%d)", path, errno);
1743                 return -1;
1744         }
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);
1749         return 0;
1750 }
1751
1752 ssize_t brotli_read(__attribute__((unused)) int fd, void *buff, size_t len)
1753 {
1754         assert(buff);
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,
1762                                                            &available_out,
1763                                                            &out_pos,
1764                                                            &brotli_file->total_size);
1765                 switch (result) {
1766                         case BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT:
1767                                 {
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);
1774                                         }
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;
1779                                         if (r_read < 0) {
1780                                                 LOGE("Error reading compressed file: %m (%d)", errno);
1781                                                 return -1;
1782                                         }
1783
1784                                         brotli_file->available_in += r_read;
1785                                         break;
1786                         }
1787                         case BROTLI_DECODER_RESULT_ERROR:
1788                                 {
1789                                         BrotliDecoderErrorCode code = BrotliDecoderGetErrorCode(brotli_file->state);
1790                                         const char *err_str = BrotliDecoderErrorString(code);
1791                                         LOGE("Brotli decoder error: %d %s", code, err_str);
1792                                         return -1;
1793                         }
1794                 }
1795         }
1796         return len - available_out;
1797 }
1798
1799 int brotli_close(__attribute__((unused)) int fd)
1800 {
1801         if (brotli_file != NULL) {
1802                 if (brotli_file->fd > 0)
1803                         close(brotli_file->fd);
1804                 BrotliDecoderDestroyInstance(brotli_file->state);
1805                 free(brotli_file);
1806                 brotli_file = NULL;
1807         }
1808
1809         return 0;
1810 }
1811
1812 ssize_t brotli_write(__attribute__((unused)) int fd,
1813                      __attribute__((unused)) const void *buff,
1814                      __attribute__((unused)) size_t len)
1815 {
1816         return ENOTSUP;
1817 }
1818
1819 int decompress_tar_brotli(const char *path)
1820 {
1821         TAR *tar = NULL;
1822         tartype_t type = {
1823                 .openfunc = brotli_open,
1824                 .closefunc = brotli_close,
1825                 .readfunc = brotli_read,
1826                 .writefunc = brotli_write
1827         };
1828
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;
1832         }
1833         if (tar_extract_all(tar, ".") == -1) {
1834                 LOGL(LOG_SSENGINE, "Tar %s extract error: %m (%d)", path, errno);
1835                 return E_SS_FAILURE;
1836         }
1837         if (tar_close(tar) == -1) {
1838                 LOGL(LOG_SSENGINE, "Tar %s close error: %m (%d)", path, errno);
1839         }
1840
1841         return S_SS_SUCCESS;
1842 }