9eca8a80a0052c24c89e4e08f33dfdc5722f75be
[platform/core/system/libtota.git] / ss_engine / SS_UPI.c
1 /*
2  * libtota
3  *
4  * Copyright (c) 2017 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 <sys/stat.h>
32 #include <unistd.h>
33 #include <sys/statfs.h>
34 #include <mntent.h>
35 #include "ua_types.h"
36 #include "SS_Common.h"
37 #include "fota_common.h"
38 #include "SS_UPI.h"
39 #include "SS_PatchDelta.h"
40 #include "SS_Engine_Errors.h"
41 #include "SS_FSUpdate.h"
42
43 int gtotalFSCnt = 0;
44 int FS_UpgradeState = E_SS_FAILURE;
45 int gvalid_session = 0;          //used as fail-safe in case device is turmed off or battery removed during update
46 fs_list *fs_headptr_main = NULL;
47 fs_list *headptr_list[UA_PARTI_MAX];
48 tar_Data_t *tar_cfg_data = NULL;
49
50 #ifdef MEM_PROFILING
51 /*
52         Description:
53                 Create script file , set it executable, execute script in child process
54                 Only works if valid delta.tar is present for upgrade
55         Summary:
56                 If MEM_PROFILING is activated,
57                 we can see the result of memory profiling after delta upgrade
58                 in file defined by macro - SS_MEMORY_PROFILING_SCRIPT
59 */
60 int mem_profiling_start = 0;
61 int SS_Do_Memory_Profiling()
62 {
63         int ret = -1;
64         pid_t pid;
65         char memory_usage_script[1024] = "#!/bin/bash\nlog_file=$1\npid=$2\nmaxmem=0\nwhile [[ -d \"/proc/${pid}\" ]]; do\n\
66                                           mem=`cat /proc/${pid}/smaps | grep Pss | grep -v Swap|awk '{print $2}'|awk '{s+=$1} END {print s}'`\n\
67                                           if [[ ${mem} -gt ${maxmem} ]]; then\nmaxmem=${mem}\n\
68                                                   echo -e \"Memory usage till now is: ${maxmem} KB.\" >> $log_file\n    fi\n    sleep 0.01\ndone\n\
69                                                           echo -e \"Max was : ${maxmem} KB.\" >> $log_file\n";
70         char cmd[1024] = { 0, };
71
72         //Open a file and write the script contents in it
73         FILE *fp = fopen(SS_MEMORY_PROFILING_SCRIPT, "w+");
74         fwrite(memory_usage_script, strlen(memory_usage_script), 1, fp);
75         fclose(fp);
76         //make the file executable        -        Octal 495 is 757 decimal
77         if (chmod(SS_MEMORY_PROFILING_SCRIPT, 495) < 0) {
78                 LOGE("Error in chmod(%s, 495) - %d (%s)\n", SS_MEMORY_PROFILING_SCRIPT, errno, strerror(errno));
79                 return E_SS_FAILURE;
80         }
81         //calling mem_use.sh
82         //Usage : <location of script> <location of log file to be created> <pid of the calling process>
83         pid = getpid();
84         snprintf(cmd, sizeof(cmd) - 1, "%s %s %d", SS_MEMORY_PROFILING_SCRIPT, SS_MEMORY_USAGE_LOG, pid);
85         ret = _system_cmd_nowait(cmd);
86         sleep(1);
87         LOG("ret for memory profiling cmd is %d\n", ret);
88         if (ret == 0) {
89                 mem_profiling_start = 1;
90                 return S_SS_SUCCESS;
91         } else {
92                 LOGE("Could not start Memory Profiling\n");
93                 return E_SS_FAILURE;
94         }
95 }
96 #endif
97
98 #ifdef TIME_PROFILING
99 static char ts1[256];
100 static double ts2;
101 double fast_tar_get_item_size_time = 0.0;
102 double SS_LoadFile_time = 0.0;
103 double SS_FSBuildNodes_time = 0.0;
104
105 static void get_time_stamp1(void)
106 {
107         struct timeval tv;
108         int sec, msec;
109
110         gettimeofday(&tv, NULL);
111         sec = (int)tv.tv_sec;
112         msec = (int)(tv.tv_usec / 1000);
113         snprintf(ts1, 256, "%06d.%03d", sec % 100000, msec);
114 }
115
116 static double get_time_stamp2(void)
117 {
118         struct timeval tv;
119
120         gettimeofday(&tv, NULL);
121         ts2 = (double)tv.tv_sec + (double)(tv.tv_usec / 1000000.0);
122         return ts2;
123 }
124 #endif
125
126 //Check SS function if available
127 int file_exist(char *filename)
128 {
129         struct stat buf;
130         int ret = 0;
131
132         ret = lstat(filename, &buf);
133         if (ret < 0)
134                 ret = stat(filename, &buf);
135         return (ret >= 0) ? (1) : (0);
136 }
137
138 long SS_GetUPIVersion(unsigned char *ver_str)
139 {
140         if (ver_str) {
141                 strncpy((char *)ver_str, SS_TOTA_VERSION, MAX_PATH);
142 #ifdef MEM_PROFILING
143                 if (!mem_profiling_start)
144                         if (!(S_SS_SUCCESS == SS_Do_Memory_Profiling()))
145                                 LOGE("Unable to start Memory_Profiling");
146 #endif
147                 return S_SS_SUCCESS;//wgid: 2456
148         } else
149                 return E_SS_FAILURE;
150 }
151
152 int SS_CalculateFileSha(char *filename, int filesize, FileInfo * file)
153 {
154
155         FILE *fp = NULL;
156         int ulResult = S_SS_SUCCESS;
157         int chunk = 20*1024*1024;
158         char buf[256];
159
160         fp = fopen(filename, "rb");
161         if (fp == NULL) {
162                 strerror_r(errno, buf, sizeof(buf));
163                 LOGE("failed to open \"%s\": %s\n", filename, buf);
164                 ulResult = E_SS_FAILURE;
165                 goto Cleanup;
166         }
167
168         file->data = SS_Malloc(chunk);
169         if (!file->data) {
170                 strerror_r(errno, buf, sizeof(buf));
171                 LOGE("failed to allocate memory for \"%s\": %s\n", filename, buf);
172                 ulResult = E_SS_FAILURE;
173                 goto Cleanup;
174         }
175
176         ssize_t bytes_read = 0;
177         sha1_ctx_t sha_ctx;
178         sha1_init(&sha_ctx);
179
180         while (filesize > 0) {
181                 if (filesize < chunk) {
182                         bytes_read = fread(file->data, 1, filesize, fp);
183                         if (bytes_read != filesize) {
184                                 LOGE("short read of \"%s\" (%ld bytes of %ld)\n", filename, (long)bytes_read, (long)file->size);
185                                 ulResult = E_SS_FAILURE;
186                                 goto Cleanup;
187                         }
188                         sha1_update(&sha_ctx, file->data, filesize);
189                         break;
190                 } else {
191                         bytes_read = fread(file->data, 1, chunk, fp);
192                         if (bytes_read != chunk) {
193                                 LOGE("short read of \"%s\" (%ld bytes of %ld)\n", filename, (long)bytes_read, (long)file->size);
194                                 ulResult = E_SS_FAILURE;
195                                 goto Cleanup;
196                         }
197                         sha1_update(&sha_ctx, file->data, chunk);
198                         filesize -= chunk;
199                 }
200         }
201
202         sha1_final(&sha_ctx, (uint32_t *) &file->sha1);
203
204 Cleanup:
205         if (fp)
206                 fclose(fp);
207         if (file->data)
208                 SS_Free(file->data);
209         return ulResult;
210 }
211
212 int SS_verify_DELTA_image(char *filename)
213 {
214
215         FileInfo file;
216         FILE *fp = NULL;
217         char line[SS_TOKEN_MAXLINE_LEN] = { '\0' };
218         char * delta_size = NULL;
219         char *signature = NULL;
220         char * sha1trg = NULL;
221         char *saveptr;
222         uint8_t target_sha1[SHA_DIGEST_SIZE] = { 0, };
223         char cmd[512] = { 0, };
224         char buf[256];
225         int udelta_size = 0;
226         int ulResult = S_SS_SUCCESS;
227
228         if (stat(filename, &file.st) != 0) {
229                 strerror_r(errno, buf, sizeof(buf));
230                 LOGE("failed to stat \"%s\": %s\n", filename, buf);
231                 return -1;
232         }
233
234         snprintf(cmd, sizeof(cmd) - 1, "grep -o -P '%s' --binary-files=text system/%s > %s",
235                                 SS_IMAGE_MAGIC_KEY, filename, SS_IMAGE_MAGIC_KEY_VAL);
236
237         ulResult = _system_cmd_wait(cmd);
238         if (ulResult != S_SS_SUCCESS) {
239                 LOGE("Grep extraction for [%s] failed, code [%d]\n", cmd, ulResult);
240                 ulResult = E_SS_FAILURE;
241                 goto Cleanup;
242         }
243
244         fp = fopen(SS_IMAGE_MAGIC_KEY_VAL, "r");
245         if (!fp) {
246                 LOGE("Grep extraction for [%s] failed, code [%d]\n", cmd, ulResult);
247                 ulResult = E_SS_FAILURE;
248                 goto Cleanup;
249         }
250
251         if (fgets(line, SS_TOKEN_MAXLINE_LEN, fp) == NULL) {
252                 ulResult = E_SS_FAILURE;
253                 goto Cleanup;
254         }
255         fclose(fp);
256         fp = NULL;
257
258         signature = strtok_r(line, SS_TOEKN_COLON, &saveptr);
259         delta_size = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
260         sha1trg = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
261
262         if (signature && sha1trg && delta_size) {
263                 udelta_size = atoi(delta_size);
264         if (udelta_size < 0)
265                                 LOGE("Invalid udelta_size %d (%s)\n", udelta_size, delta_size);
266                 LOGL(LOG_SSENGINE, "delta_size %d sha1trg %s\n", udelta_size, sha1trg);
267         } else {
268                 LOGE("Could not parse signature [%s]\n", line);
269                 ulResult = E_SS_FAILURE;
270                 goto Cleanup;
271         }
272
273         if (ParseSha1(sha1trg, target_sha1) != 0) {
274                 LOGE("failed to parse tgt-sha1 \"%s\"\n", sha1trg);
275                 ulResult = E_SS_FAILURE;
276                 goto Cleanup;
277         }
278
279         ulResult = SS_CalculateFileSha(filename, udelta_size, &file);
280         if (ulResult != S_SS_SUCCESS)
281                 goto Cleanup;
282
283         if (memcmp(file.sha1, target_sha1, SHA_DIGEST_SIZE) != 0) {
284                 LOGE("SHA mismatch -[%s] actual [%x] target [%x]\n", filename, file.sha1, target_sha1);
285                 SS_SetUpgradeState(E_SS_FSBADDELTA);
286                 ulResult = E_SS_FAILURE;
287                 goto Cleanup;
288         } else {
289                 LOGL(LOG_SSENGINE, "DELTA verified %s \n", sha1trg);
290         }
291
292 Cleanup:
293         if (fp)
294                 fclose(fp);
295         if (file_exist(SS_IMAGE_MAGIC_KEY_VAL))
296                 SS_DeleteFile(SS_IMAGE_MAGIC_KEY_VAL);
297         return ulResult;
298 }
299
300
301 int SS_GetProgressResolution(int ultotalFSCnt)
302 {
303         if (ultotalFSCnt < DISPLAYRESOLUTION_SIZE)
304                 return 1;
305         else
306                 return (ultotalFSCnt / DISPLAYRESOLUTION_SIZE);
307 }
308
309 void SS_SetUpgradeState(int Val)
310 {
311         LOGE("FAILED to upgrade Cause:[0x%x]\n", Val);
312         FS_UpgradeState = Val;
313         return;
314 }
315
316 int SS_GetUpgradeState()
317 {
318         return FS_UpgradeState;
319 }
320
321 int SS_Get_last_update_del_type(void)
322 {
323         int fd;
324         unsigned char buf[256];
325         char *ptr = NULL;
326         int status = -1;
327         int del_type = 0;
328         int result = 0;
329
330         if (file_exist(SS_UPDATE_STATUR_PATH) == 0) {
331                 LOG("No exist file!!\n");
332                 return 0;
333         }
334
335         fd = open(SS_UPDATE_STATUR_PATH, O_RDWR, S_IRWXU);
336         if (fd == -1) {
337                 LOG("Could not open status file!!\n");
338                 return 0;
339         }
340
341         result = SS_ReadFile(fd, 0, buf, sizeof(buf));
342         if (result != 0) {
343                 LOG("SS_ReadFile failed!!\n");
344                 return 0;
345         }
346
347         ptr = strtok((char *)buf, " ");
348
349         if (ptr != NULL) {
350                 status = atoi(ptr);
351                 ptr = strtok(NULL, " ");
352         }
353
354         if (ptr != NULL) {
355                 del_type = atoi(ptr);
356         }
357
358         result = SS_CloseFile(fd);
359         if (result != 0)
360                 LOG("SS_CloseFile failed!!\n");
361
362         LOG("del_type:[%d] (status: [%d])\n", del_type, status);
363
364         return del_type;
365 }
366
367 int SS_Get_last_update_status(void)
368 {
369         int fd;
370         unsigned char buf[256];
371         char *ptr = NULL;
372         int status = -1;
373         int del_type = 0;
374         int result = 0;
375
376         if (file_exist(SS_UPDATE_STATUR_PATH) == 0) {
377                 LOG("No exist file!!\n");
378                 return 0;
379         }
380
381         fd = open(SS_UPDATE_STATUR_PATH, O_RDWR, S_IRWXU);
382         if (fd == -1) {
383                 LOG("Could not open status file!!\n");
384                 return 0;
385         }
386
387         result = SS_ReadFile(fd, 0, buf, sizeof(buf));
388         if (result != 0) {
389                 LOG("SS_ReadFile failed!!\n");
390                 return 0;
391         }
392
393         LOG("buf:[%s]\n", buf);
394
395         ptr = strtok((char *)buf, " ");
396
397         if (ptr != NULL) {
398                 status = atoi(ptr);
399                 ptr = strtok(NULL, " ");
400         }
401
402         if (ptr != NULL) {
403                 del_type = atoi(ptr);
404         }
405
406         result = SS_CloseFile(fd);
407         if (result != 0)
408                 LOG("SS_CloseFile failed!!\n");
409
410         LOG("status:[%d] (del_type: [%d])\n", status, del_type);
411
412         return status;
413 }
414
415
416 void SS_Set_last_update_status(int status, int del_type)
417 {
418         int fd;
419         int result = 0;
420         char num_str[16];
421         LOG("status:[%d], del_type:[%d]\n", status, del_type);
422
423         fd = open(SS_UPDATE_STATUR_PATH, O_RDWR | O_CREAT, S_IRWXU);
424         if (fd == -1) {
425                 LOG("Could not open status file!!\n");
426                 return;
427         }
428
429         sprintf(num_str, "%d %d", status, del_type);
430         result = SS_WriteFile(fd, 0, (unsigned char *)num_str, strlen(num_str));
431         if (result != 0)
432                 LOG("SS_WriteFile failed!!\n");
433
434         result = SS_CloseFile(fd);
435         if (result != 0)
436                 LOG("SS_CloseFile failed!!\n");
437
438         sync();
439
440 }
441
442 int SS_rename(const char *old_file_name, const char *new_file_name)
443 {
444         if (link(old_file_name, new_file_name) < 0) {
445                 if (errno == EEXIST) {
446                         if (unlink(new_file_name) < 0 || link(old_file_name, new_file_name) < 0)
447                                 return -1;
448                 } else
449                         return -1;
450         }
451         if (unlink(old_file_name) < 0) {
452                 if (unlink(new_file_name) == 0)
453                         return -1;
454         }
455         return 0;
456 }
457
458 int SS_rename1(const char *old_file_name, const char *new_file_name)
459 {
460
461         int result = E_SS_FAILURE;
462         char *temp_name = NULL;
463         temp_name = (char *)SS_Malloc(strlen(new_file_name) + 10);
464         if (temp_name == NULL)
465                 return E_SS_FAILURE;
466         snprintf(temp_name, strlen(new_file_name) + 10, "%s.temp", new_file_name);
467         result = rename(new_file_name, temp_name);
468         if (result != 0)
469                 goto Cleanup;
470         result = rename(old_file_name, new_file_name);
471         if (result != 0)
472                 goto Cleanup;
473         result = unlink(temp_name);
474  Cleanup:
475         if (temp_name)
476                 SS_Free(temp_name);
477         return result;
478 }
479
480 /*!
481  *********************************************************************************
482  *                                       SS_FSVerifyNode
483  *********************************************************************************
484  *
485  * @brief
486  *      This is to verify nodes being added to global control structure for diff and delete cases.
487  *      gvalid_session global is used to check if nodes are already verified.
488  *
489  *
490  *      @param
491  *
492  *      @return                         returns S_SS_SUCCESS and
493  *                                              returns E_SS_FAILURE in case any error occurs
494  *
495  *********************************************************************************
496  */
497 int SS_FSVerifyNode(const char *path, const char *patchname, const char *sha1src, int type,
498                                         char *patchpath_name, int *data_size, int *data_offset)
499 {
500         char patch[MAX_FILE_PATH] = { 0 };
501         FileInfo source_file;
502         uint8_t source_sha1[SHA_DIGEST_SIZE];
503
504         if (gvalid_session) {
505                 if ((type == DIFFS || type == DELETES || type == MOVES) && !file_exist((char *)path)) {
506                         LOGE("failed to verifyNodes [does not exist], Path : [%s] Type[%d]\n", path, type);
507                         SS_SetUpgradeState(E_SS_FSBADNODES);
508                         return E_SS_FAILURE;
509                 }
510                 snprintf(patch, MAX_FILE_PATH, "%s%s%s", patchpath_name, "/", patchname);
511                 if ((type == DIFFS/*||type == NEWFILES */)) {   // allowing size 0 also for folders
512                         if (tar_get_item_size_from_struct(&tar_cfg_data, patchname, data_size, data_offset)
513                                         != S_SS_SUCCESS) {
514                                 LOGE("failed to get item size from struct, Patch : [%s]\n", patchname);
515                                 SS_SetUpgradeState(E_SS_FSBADNODES);
516                                 return E_SS_FAILURE;
517                         }
518                         if (*data_size < 0) {
519                                 LOGE("failed to verifyNodes [delta absent], Patch : [%s] Type[%d]\n", patch, type);
520                                 SS_SetUpgradeState(E_SS_FSBADNODES);
521                                 return E_SS_FAILURE;
522                         }
523                 }
524                 //For other types (NEWs, SYMs, Folders), SHA check not required
525                 if ((type == DIFFS || type == MOVES/* ||type == DELETES */) &&
526                                 (strcmp(sha1src, SS_NULLENTRY) != 0)) {
527                         if (ParseSha1(sha1src, source_sha1) != 0) {
528                                 LOGE("Failed to parse Src-sha1 \"%s\"\n", sha1src);
529                                 return E_SS_FAILURE;
530                         }
531                         if (SS_LoadFile(path, &source_file) == 0) {
532                                 if (memcmp(source_file.sha1, source_sha1, SHA_DIGEST_SIZE) != 0) {
533                                         SS_Free(source_file.data);
534                                         LOGE("SS_FSVerifyNode - SHA mismatch with SRC  - PATH [%s]\n", path);
535                                         SS_SetUpgradeState(E_SS_FSSRCCURRUPTED);        // Define other error
536                                         return E_SS_FAILURE;
537                                 }
538                         }
539                         SS_Free(source_file.data);
540                 }
541         } else {
542                 LOGL(LOG_SSENGINE, "FS partition Already verified - Filling only size and offset \n");
543                 snprintf(patch, MAX_FILE_PATH, "%s%s%s", patchpath_name, "/", patchname);
544                 if ((type == DIFFS/* ||type == NEWFILES */)) {   // allowing size 0 also for folders
545                         if (tar_get_item_size_from_struct(&tar_cfg_data, patchname, data_size, data_offset)
546                                         != S_SS_SUCCESS) {
547                                 LOGE("failed to get item size from struct, Patch : [%s] \n", patchname);
548                                 SS_SetUpgradeState(E_SS_FSBADNODES);
549                                 return E_SS_FAILURE;
550                         }
551                         if (*data_size < 0) {
552                                 LOGE("failed to verifyNodes [delta absent], Patch : [%s] Type[%d]\n", patch, type);
553                                 SS_SetUpgradeState(E_SS_FSBADNODES);
554                                 return E_SS_FAILURE;
555                         }
556                 }
557         }
558         return S_SS_SUCCESS;
559 }
560
561 /*!
562  *********************************************************************************
563  *                                       SS_AppendNode
564  *********************************************************************************
565  *
566  * @brief
567  *      This is to append node to the global control structure for delta files.
568  *
569  *
570  *      @param
571  *
572  *      @return                         returns S_SS_SUCCESS and
573  *                                              returns E_SS_FAILURE in case any error occurs
574  *
575  *********************************************************************************
576  */
577 int SS_AppendNode(const char *ubDeltaPath, fs_params ** headparam, fs_params ** tailparam, const char *old_path,
578                                   const char *new_path, const char *patchname, const char *sha1src, const char *sha1trg, int type,
579                                   char *patchpath_name)
580 {
581         fs_params *newnode = NULL;
582         int data_size = 0;
583         int data_offset = 0;
584
585         if (!ubDeltaPath || !old_path || !new_path || !patchname || !sha1src || !sha1trg || !patchpath_name) {
586                 LOGE("Bad Nodes, NULL params passed for Appending Nodes \n");
587                 SS_SetUpgradeState(E_SS_FSINVALIDNODEPARAMS);
588                 return E_SS_FAILURE;
589         }
590         if ((E_SS_FAILURE ==
591                  SS_FSVerifyNode(old_path, patchname, sha1src, type, patchpath_name, &data_size, &data_offset))) {
592                 LOGE("Bad Nodes, Failed to pass verification - [Delta Path - %s][OldPath - %s] [NewPath - %s] \n", ubDeltaPath,
593                          old_path, new_path);
594                 return E_SS_FAILURE;
595         }
596         newnode = (fs_params *) SS_Malloc(sizeof(fs_params));
597         if (!newnode)
598                 return E_SS_FAILURE;
599         strncpy(newnode->file_old_path, old_path, SS_MAX_NAMELENSUPPORTED);//wgid: 29483
600         strncpy(newnode->file_new_path, new_path, SS_MAX_NAMELENSUPPORTED);//wgid: 29482
601         strncpy(newnode->patch_name, patchname, SS_MAX_NAMELENSUPPORTED);//wgid: 28033
602         strncpy(newnode->sha1src, sha1src, sizeof(newnode->sha1src) -1);//wgid: 25282
603         strncpy(newnode->sha1trg, sha1trg, sizeof(newnode->sha1trg) - 1);//wgid: 25283
604         newnode->type = type;
605         newnode->data_size = data_size;
606         newnode->data_offset = data_offset;
607         newnode->nextnode = NULL;
608
609         //LOG("%s %s %d %s %s \n",newnode->file_path,newnode->patch_name,newnode->type, newnode->sha1src, newnode->sha1trg);
610
611         if (*headparam == NULL) {
612                 *headparam = newnode;
613                 *tailparam = newnode;
614         } else {
615                 (*tailparam)->nextnode = newnode;
616                 (*tailparam) = (*tailparam)->nextnode;
617         }
618         return S_SS_SUCCESS;
619
620 }
621
622 void SS_UpdateUIProgress(ua_dataSS_t * ua_dataSS, int ulTotalFsCnt, int ulDone)
623 {
624         static int ss_count = 1;
625         int res_val = SS_GetProgressResolution(ulTotalFsCnt);
626         if (!ua_dataSS) {
627                 LOGE("Error ua_dataSS\n");
628                 return;
629         }
630 //LOG("\nvalues are ss_count[%d] total_file_cnt[%d]",ss_count,ulTotalFsCnt);
631         if (ulDone == 1) {
632                 if (ua_dataSS->ui_progress)
633                         ua_dataSS->ui_progress(ua_dataSS, 100);
634                 ss_count = 1;
635         } else if (ss_count < ulTotalFsCnt) {
636                 if (ss_count % res_val == 0) { //Max 50 times display
637                         double data = (double)ss_count / (double)ulTotalFsCnt;
638                         if (ua_dataSS->ui_progress)
639                                 ua_dataSS->ui_progress(ua_dataSS, data * 100);
640                 }
641                 ss_count++;
642         } else {
643                 if (ua_dataSS->ui_progress)
644                         ua_dataSS->ui_progress(ua_dataSS, 100);
645                 ss_count = 1;
646         }
647
648 }
649
650 /*!
651  *********************************************************************************
652  *                                       SS_FSClearNodes
653  *********************************************************************************
654  *
655  * @brief
656  *      This is to clear the global control structure for delta files.
657  *
658  *
659  *      @param
660  *
661  *      @return
662  *
663  *********************************************************************************
664  */
665 void SS_FSClearNodes(int idx)
666 {
667         fs_params *local_temp = NULL;
668         fs_params *local_next = NULL;
669         LOGL(LOG_SSENGINE, "Free Nodes idx=%d \n", idx);
670         if (headptr_list[idx]) {
671                 if (headptr_list[idx]->del_ref) {
672                         local_temp = headptr_list[idx]->del_ref;
673                         while (local_temp) {
674                                 local_next = local_temp->nextnode;
675                                 SS_Free(local_temp);
676                                 local_temp = local_next;
677                         }
678                 }
679                 if (headptr_list[idx]->dif_ref) {
680                         local_temp = headptr_list[idx]->dif_ref;
681                         while (local_temp) {
682                                 local_next = local_temp->nextnode;
683                                 SS_Free(local_temp);
684                                 local_temp = local_next;
685                         }
686                 }
687                 if (headptr_list[idx]->move_ref) {
688                         local_temp = headptr_list[idx]->move_ref;
689                         while (local_temp) {
690                                 local_next = local_temp->nextnode;
691                                 SS_Free(local_temp);
692                                 local_temp = local_next;
693                         }
694                 }
695                 if (headptr_list[idx]->new_ref) {
696                         local_temp = headptr_list[idx]->new_ref;
697                         while (local_temp) {
698                                 local_next = local_temp->nextnode;
699                                 SS_Free(local_temp);
700                                 local_temp = local_next;
701                         }
702                 }
703                 if (headptr_list[idx]->sym_difref) {
704                         local_temp = headptr_list[idx]->sym_difref;
705                         while (local_temp) {
706                                 local_next = local_temp->nextnode;
707                                 SS_Free(local_temp);
708                                 local_temp = local_next;
709                         }
710                 }
711                 if (headptr_list[idx]->sym_newref) {
712                         local_temp = headptr_list[idx]->sym_newref;
713                         while (local_temp) {
714                                 local_next = local_temp->nextnode;
715                                 SS_Free(local_temp);
716                                 local_temp = local_next;
717                         }
718                 }
719                 SS_Free(headptr_list[idx]);
720                 headptr_list[idx] = NULL;
721         }
722 }
723
724 /*!
725  *********************************************************************************
726  *                                       SS_FSGetDeltaCount
727  *********************************************************************************
728  *
729  * @brief
730  *      This is to get the delta count for diffs , deletes etc.
731  *
732  *
733  *      @param
734  *
735  *      @return                         returns structure with delta count info
736  *                                              NULL in case of error
737  *
738  *********************************************************************************
739  */
740
741 struct details *SS_FSGetDeltaCount(char *ubDeltaPath, char *ubDeltaInfoFile)
742 {
743         int size = 0, bckupsize = 0, ret = 1;
744         char *token = NULL;
745         char *FileData = NULL;
746         int data_size = -1;
747         char *line = NULL;
748         char *saveptr;
749         char buf[256];
750         struct details *refer_copy = NULL;
751         FILE *filename_bkup = NULL;
752
753         if (!(ubDeltaPath && ubDeltaInfoFile)) {
754                 LOGE("failed to Parse DELTA count information: \n");
755                 SS_SetUpgradeState(E_SS_BAD_PARAMS);
756                 return NULL;
757         }
758         refer_copy = (struct details *)SS_Malloc(sizeof(struct details));
759
760         if (refer_copy == NULL) {
761                 LOGE("failed to allocate memory\n");
762                 return NULL;
763         }
764
765         LOGL(LOG_SSENGINE, "Delta File Info =%s\n", ubDeltaInfoFile);
766
767         size = tar_get_item_size(ubDeltaPath, ubDeltaInfoFile);
768         if (size < 0) {
769                 LOGE("failed to Access DELTA info file DPath:[%s] File: [%s]\n", ubDeltaPath, ubDeltaInfoFile);
770                 SS_SetUpgradeState(E_SS_FSBADDELTA);
771                 ret = 0;
772                 goto cleanup;
773         }
774
775         FileData = SS_Malloc(size + 1);
776         if (FileData == NULL) {
777                 LOGE("Failed to Allocate Memory\n");
778                 SS_SetUpgradeState(E_SS_MALLOC_ERROR);
779                 ret = 0;
780                 goto cleanup;
781         }
782
783         memset(FileData, 0, size + 1);
784         data_size = tar_get_cfg_data(ubDeltaPath, ubDeltaInfoFile, FileData, size);
785         if (data_size <= 0) {      // == 0 is NOT okay??
786                 LOGE("Failed to read cfg data from Delta\n");
787                 SS_SetUpgradeState(E_SS_FSBADDELTA);
788                 ret = 0;
789                 goto cleanup;
790         }
791         filename_bkup = fopen(SS_PATCHLIST_BKUPLOC, "wb+");
792         if (filename_bkup == NULL) {
793                 strerror_r(errno, buf, sizeof(buf));
794                 LOGE("Failed to create BACKUP file Error:[%s]\n", buf);
795                 SS_SetUpgradeState(E_SS_FSFAILEDTOBACKUPPATCHINFO);
796                 ret = 0;
797                 goto cleanup;
798         }
799
800         bckupsize = fwrite(FileData, 1, data_size, filename_bkup);  //RECHECK SIZE 1
801         if (bckupsize <= 0) {
802                 SS_SetUpgradeState(E_SS_FSFAILEDTOBACKUPPATCHINFO);
803                 ret = 0;
804                 goto cleanup;
805         }
806         LOGL(LOG_SSENGINE, " Size [%d] DataSize [%d] BakUpSize [%d]\n", size, data_size, bckupsize);
807
808         line = strstr(FileData, SS_FSCOUNT_MAGIC_KEY);
809         if (line) {
810                 LOGL(LOG_SSENGINE, "SS_FSGetDeltaCount() last line %s \n", line);
811
812                 token = strtok_r(&line[SS_FSCOUNT_MAGIG_KEYLEN], SS_TOKEN_SPACE, &saveptr);
813                 if (token)
814                         refer_copy->diffs = atoi(token);
815                 else {
816                         SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT);
817                         ret = 0;
818                         goto cleanup;
819                 }
820                 token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr);
821                 if (token)
822                         refer_copy->moves = atoi(token);
823                 else {
824                         SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT);
825                         ret = 0;
826                         goto cleanup;
827                 }
828
829                 token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr);
830                 if (token)
831                         refer_copy->news = atoi(token);
832                 else {
833                         SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT);
834                         ret = 0;
835                         goto cleanup;
836                 }
837
838                 token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr);
839                 if (token)
840                         refer_copy->deletes = atoi(token);
841                 else {
842                         SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT);
843                         ret = 0;
844                         goto cleanup;
845                 }
846
847                 token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr);
848                 if (token)
849                         refer_copy->symdiffs = atoi(token);
850                 else {
851                         SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT);
852                         ret = 0;
853                         goto cleanup;
854                 }
855
856                 token = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr);
857                 if (token)
858                         refer_copy->symnews = atoi(token);
859                 else {
860                         SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT);
861                         ret = 0;
862                         goto cleanup;
863                 }
864
865                 gtotalFSCnt =
866                         refer_copy->diffs + refer_copy->moves + refer_copy->news + refer_copy->deletes + refer_copy->symdiffs +
867                         refer_copy->symnews;
868                 LOG("SS_FSGetDeltaCount() total no of file %d\n", gtotalFSCnt);
869
870         } else {
871                 SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTACNT);
872                 LOG("SS_FSGetDeltaCount() Failed to read last line\n");
873         }
874         if (gtotalFSCnt < 0) {
875                 ret = 0;
876                 goto cleanup;
877         }
878
879  cleanup:
880         if (ret) {
881                 SS_Free(FileData);
882                 if (filename_bkup)
883                         fclose(filename_bkup);
884                 return refer_copy;
885         } else {
886                 SS_Free(FileData);
887                 SS_Free(refer_copy);
888                 if (filename_bkup)
889                         fclose(filename_bkup);
890                 return NULL;
891         }
892
893 }
894
895 /*!
896  *********************************************************************************
897  *                                       SS_FSBuildNodes
898  *********************************************************************************
899  *
900  * @brief
901  *      This is used to build the gobal control structure for diffs, deletes etc.
902  *      For all the entries in config file (which has info) the information is parsed to the global control struct
903  *
904  *
905  *      @param
906  *
907  *      @return                         returns fs_list structure filled with details of all the files to be diff-ed ,deleted etc.
908  *                                              NULL in case of error
909  *
910  *********************************************************************************
911  */
912 fs_list *SS_FSBuildNodes(ua_dataSS_t * ua_dataSS)
913 {
914         FILE *fp = NULL;
915         char line[SS_TOKEN_MAXLINE_LEN] = { '\0' };
916         char string_na[] = "NA";
917         char *patch_name = NULL;
918         char *source_name = NULL;
919         char *target_name = NULL;
920         char *sha1src = NULL;
921         char *sha1trg = NULL;
922         char *change_type = NULL;
923         char *file_type = NULL;
924         char *saveptr;
925         uint32_t ulPatchCount = 0, del_type = DELETES;
926         fs_params *fs_diffhead = NULL;
927         fs_params *fs_difftail = NULL;
928         fs_params *fs_movehead = NULL;
929         fs_params *fs_movetail = NULL;
930         fs_params *fs_newhead = NULL;
931         fs_params *fs_delhead = NULL;
932         fs_params *fs_deltail = NULL;
933         fs_params *fs_symlinkdiffhead = NULL;
934         fs_params *fs_symlinkdifftail = NULL;
935         fs_params *fs_symlinknewhead = NULL;
936         fs_params *fs_symlinknewtail = NULL;
937
938         struct details *local = NULL;
939         fs_list *fs_head_node = NULL;
940         int i = 0, retval = 0;
941         if (!ua_dataSS) {
942                 LOGE("Bad structure ua_dataSS\n");
943                 SS_SetUpgradeState(E_SS_BAD_PARAMS);
944                 return NULL;
945         }
946         LOGL(LOG_SSENGINE, " Build Nodes Entry \n");
947         if (tar_cfg_data == NULL)
948                 tar_cfg_data = tar_build_cfg_table(ua_dataSS->update_data->ua_delta_path);
949         if (!tar_cfg_data) {
950                 LOGE(" tar_build_cfg_table  Failed \n");
951                 SS_SetUpgradeState(E_SS_BAD_PARAMS);
952                 return NULL;
953         }
954         local = SS_FSGetDeltaCount(ua_dataSS->update_data->ua_delta_path, ua_dataSS->update_delta->ua_patch_info);
955         if (local == NULL) {
956                 LOGE(" Build Nodes Failed \n");
957                 if (tar_cfg_data)
958                         tar_free_cfg_table(&tar_cfg_data);
959                 SS_SetUpgradeState(E_SS_BAD_PARAMS);
960                 return NULL;
961         }
962
963         fp = fopen(SS_PATCHLIST_BKUPLOC, "r");
964         if (!fp) {
965                 SS_SetUpgradeState(E_SS_FSFAILEDTOOPENPATCHINFO);
966                 if (tar_cfg_data)
967                         tar_free_cfg_table(&tar_cfg_data);
968                 SS_Free(local);
969                 return NULL;
970         }
971
972         ulPatchCount = local->diffs + local->deletes + local->news + local->moves + local->symdiffs + local->symnews;
973         LOG("Total FS count [%d].\n", ulPatchCount);
974 /*
975 ************************************************************************
976 Parsing logic implemented for patchlist
977 ************************************************************************
978 Sample entries in patchlist as below :
979 <CHANGE-TYPE>:<FILE-TYPE>:<OTHER-DETAILS...>
980 ************************************************************************
981 DIFF:REG:system/bin/vi:system/bin/vi:2f2f3dc6d3ee06af0080ac7975f22941660f2480:78b2d44af32d854c70f1cb7431a60c2682a320cc:diff1_vi.delta
982 DIFF:TPK:system/usr/packages/removable/com.samsung.calculator.tpk:system/usr/packages/removable/com.samsung.calculator.tpk:
983                                  96fc1bcde30d501ba65ef0038e05da46d255a7b3:fa1d5d9daa4097ac302b69244297f508577c3a01:diff1598_com.samsung.calculator.tpk.delta/
984 MOVE:REG:system/etc/smack/accesses.d/heremaps-engine-devel:system/usr/apps/com.samsung.contacts/res/temp:da39a3ee5e6b4b0d3255bfef95601890afd80709
985 DEL:REG:system/usr/ug/res/images/ug-phone/contacts/favorites_icon_remove.PNG:38ad8be378506d19b1c769d46be262cf100f6c59
986 DEL:SYM:system/usr/apps/com.samsung.message-lite/lib/libmsg-common.so
987 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:
988                                         libplugin-na-mobex.so.0.3.57
989 SYM:NEW:system/lib/firmware/vbc_eq:/opt/system/vbc_eq
990 ***********************************************************************
991 */
992         if (local && ((local->diffs) > 0 || (local->moves > 0))) {
993                 LOGL(LOG_SSENGINE, "%ss [%d] %ss [%d]\n", SS_STRING_DIFF, local->diffs, SS_STRING_MOVE, local->moves);
994                 for (i = 0; i < (local->diffs + local->moves); i++) {
995                         if (fgets(line, SS_TOKEN_MAXLINE_LEN, fp) == NULL) {
996                                 SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO);
997                                 break;
998                         }
999                         //LOGL(LOG_SSENGINE, "DIFF LINE:[%d] [%s] \n",i+1,line);
1000
1001                         change_type = strtok_r(line, SS_TOEKN_COLON, &saveptr);
1002                         file_type = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
1003
1004                         if (change_type && strcmp(change_type, SS_STRING_MOVE) == 0) {   // && strcmp(file_type,"TPK") == 0){
1005                                 source_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
1006                                 target_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
1007                                 sha1src = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr);
1008                                 //LOGL(LOG_SSENGINE, "%s Index [%d]\n", SS_STRING_MOVE, i);
1009
1010                                 if (!source_name || !target_name || !sha1src) {
1011                                         SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO);
1012                                         //LOGE("Failed to extract Patch Info Type:DELETES \n");
1013                                         LOGE("Failed to parse DIFFS - LINE:[%d] [%s] \n", i + 1, line);
1014                                         goto CleanUp;
1015                                 }
1016                                 retval =
1017                                         SS_AppendNode(ua_dataSS->update_data->ua_delta_path, &fs_movehead, &fs_movetail, source_name,
1018                                                                   target_name, string_na, sha1src, string_na, MOVES,
1019                                                                   ua_dataSS->update_delta->ua_patch_path);
1020                                 if (retval == E_SS_FAILURE)      // ONLY test purpose, should enable this
1021                                         goto CleanUp;
1022                                 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
1023                         } else if (change_type && strcmp(change_type, SS_STRING_DIFF) == 0) {     // && strcmp(file_type,"TPK") == 0){
1024                                 source_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
1025                                 target_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
1026                                 sha1src = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
1027                                 sha1trg = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
1028                                 patch_name = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr);
1029                                 //LOGL(LOG_SSENGINE, "%s Index [%d]\n", SS_STRING_DIFF, i);
1030
1031                                 if (patch_name && (strlen(patch_name) <= SS_MAX_NAMELENSUPPORTED)) {
1032                                         retval =
1033                                                 SS_AppendNode(ua_dataSS->update_data->ua_delta_path, &fs_diffhead, &fs_difftail,
1034                                                                           source_name, target_name, patch_name, sha1src, sha1trg, DIFFS,
1035                                                                           ua_dataSS->update_delta->ua_patch_path);
1036                                         if (retval == E_SS_FAILURE) // ONLY test purpose, should enable this
1037                                                 goto CleanUp;
1038                                 } else {
1039                                         SS_SetUpgradeState(E_SS_FILENAMELENERROR);
1040                                         LOGE("File Name length Limitation Error File:[%s]\n", patch_name);
1041                                         goto CleanUp;
1042                                 }
1043                                 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
1044                         } else {
1045                                 SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO);
1046                                 LOGE("Patch Name format Error File\n");
1047                                 goto CleanUp;
1048                         }
1049                 }
1050         }
1051         if (local && (local->news) > 0) {   //check if new files archive is present in the delta
1052                 char new_patch_path[MAX_FILE_PATH] = { 0, };
1053                 snprintf(new_patch_path, MAX_FILE_PATH, "%s%s", ua_dataSS->parti_info->ua_subject_name, SS_COMPRESSED_FILE);
1054                 if (tar_get_item_size(ua_dataSS->update_data->ua_delta_path, new_patch_path) <= 0) {
1055                         SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO);
1056                         LOGE("New files not present in Patch\n");
1057                         goto CleanUp;
1058                 }
1059         }
1060         if (local && (local->deletes) > 0) {            //this is to group to delete list
1061                 LOGL(LOG_SSENGINE, "%ss [%d]\n", SS_STRING_DEL, local->deletes);
1062                 for (i = 0; i < (local->deletes); i++) {
1063                         if (fgets(line, SS_TOKEN_MAXLINE_LEN, fp) == NULL) {
1064                                 SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO);
1065                                 break;
1066                         }
1067
1068                         change_type = strtok_r(line, SS_TOEKN_COLON, &saveptr);
1069                         file_type = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
1070
1071                         if (file_type && strcmp(file_type, SS_STRING_REG) == 0) {
1072                                 source_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
1073                                 sha1src = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr);
1074                                 del_type = DELETES;
1075                         } else if (file_type && strcmp(file_type, SS_STRING_SYM) == 0) {
1076                                 source_name = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr);
1077                                 sha1src = string_na;
1078                                 del_type = DELETES;
1079                         } else if (file_type && strcmp(file_type, SS_STRING_END) == 0) {
1080                                 source_name = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr);
1081                                 sha1src = string_na;
1082                                 del_type = DELETE_END;
1083                         } else {
1084                                 LOGE("Failed to parse DELETES - LINE:[%d] [%s] \n", i + 1, line);
1085                                 goto CleanUp;
1086                         }
1087
1088                         if (!source_name || !sha1src) {
1089                                 SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO);
1090                                 //LOGE("Failed to extract Patch Info Type:DELETES \n");
1091                                 LOGE("Failed to parse DELETES - LINE:[%d] [%s] \n", i + 1, line);
1092                                 goto CleanUp;
1093                         }
1094                         //LOGL(LOG_SSENGINE, "%s Index [%d]\n", SS_STRING_DEL, i);
1095                         retval =
1096                                 SS_AppendNode(ua_dataSS->update_data->ua_delta_path, &fs_delhead, &fs_deltail, source_name,
1097                                                           string_na, string_na, sha1src, string_na, del_type,
1098                                                           ua_dataSS->update_delta->ua_patch_path);
1099                         if (retval == E_SS_FAILURE) // ONLY test purpose, should enable this
1100                                 goto CleanUp;
1101                         SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
1102
1103                 }
1104         }                                                  //For symlink files
1105
1106         if (local && (local->symdiffs) > 0) {
1107                 LOGL(LOG_SSENGINE, "%s %ss [%d]\n", SS_STRING_SYM, SS_STRING_DIFF, local->symdiffs);
1108                 for (i = 0; i < (local->symdiffs); i++) {          //get the count from below function
1109                         if (fgets(line, SS_TOKEN_MAXLINE_LEN, fp) == NULL) {
1110                                 SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO);
1111                                 break;
1112                         }
1113                         //LOGL(LOG_SSENGINE, "SYMDIFF LINE:[%d] [%s] \n",i+1,line);
1114
1115                         change_type = strtok_r(line, SS_TOEKN_COLON, &saveptr);
1116                         file_type = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
1117
1118                         if ((change_type && file_type) &&
1119                                         strcmp(change_type, SS_STRING_SYM) == 0 && strcmp(file_type, SS_STRING_DIFF) == 0) {    // && strcmp(file_type,"TPK") == 0){
1120                                 source_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
1121                                 target_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
1122                                 patch_name = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr);
1123                                 //LOGL(LOG_SSENGINE, "%s %s Index [%d]\n", SS_STRING_SYM, SS_STRING_DIFF, i);
1124
1125                                 if (!source_name || !target_name || !patch_name) {
1126                                         SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO);
1127                                         //LOGE("Failed to extract Patch Info Type:DELETES \n");
1128                                         LOGE("Failed to parse SymDiffs - LINE:[%d] [%s] \n", i + 1, line);
1129                                         goto CleanUp;
1130                                 }
1131                                 retval =
1132                                         SS_AppendNode(ua_dataSS->update_data->ua_delta_path, &fs_symlinkdiffhead, &fs_symlinkdifftail,
1133                                                                   source_name, target_name, patch_name, string_na, string_na, SYMDIFFS,
1134                                                                   ua_dataSS->update_delta->ua_patch_path);
1135                                 if (retval == E_SS_FAILURE)      // ONLY test purpose, should enable this
1136                                         goto CleanUp;
1137                                 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
1138                         }
1139                 }
1140         }
1141         if (local && (local->symnews) > 0) {
1142                 LOGL(LOG_SSENGINE, "%s %ss [%d]n", SS_STRING_SYM, SS_STRING_NEW, local->symnews);
1143                 for (i = 0; i < (local->symnews); i++) {
1144                         if (fgets(line, SS_TOKEN_MAXLINE_LEN, fp) == NULL) {
1145                                 SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO);
1146                                 break;
1147                         }
1148                         //LOGL(LOG_SSENGINE, "SYMNEWS LINE:[%d] [%s] \n",i+1,line);
1149
1150                         change_type = strtok_r(line, SS_TOEKN_COLON, &saveptr);
1151                         file_type = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
1152
1153                         if ((change_type && file_type) &&
1154                                         (strcmp(change_type, SS_STRING_SYM) == 0 && strcmp(file_type, SS_STRING_NEW) == 0)) {
1155                                 source_name = strtok_r(NULL, SS_TOEKN_COLON, &saveptr);
1156                                 patch_name = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr);
1157                                 //LOGL(LOG_SSENGINE, "%s %s Index [%d]\n", SS_STRING_SYM, SS_STRING_NEW, i);
1158
1159                                 if (!source_name || !patch_name) {
1160                                         SS_SetUpgradeState(E_SS_FSFAILEDTOPARSEDELTAINFO);
1161                                         //LOGE("Failed to extract Patch Info Type:DELETES \n");
1162                                         LOGE("Failed to parse SymNews - LINE:[%d] [%s] \n", i + 1, line);
1163                                         goto CleanUp;
1164                                 }
1165                                 retval =
1166                                         SS_AppendNode(ua_dataSS->update_data->ua_delta_path, &fs_symlinknewhead, &fs_symlinknewtail,
1167                                                                   source_name, string_na, patch_name, string_na, string_na, SYMNEWFILES,
1168                                                                   ua_dataSS->update_delta->ua_patch_path);
1169                                 if (retval == E_SS_FAILURE)      // ONLY test purpose, should enable this
1170                                         goto CleanUp;
1171                                 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
1172                         }
1173                 }
1174         }
1175
1176         fs_head_node = (fs_list *) SS_Malloc(sizeof(fs_list));
1177         if (!fs_head_node) {
1178                 SS_SetUpgradeState(E_SS_MALLOC_ERROR);
1179                 goto CleanUp;
1180         }
1181         fs_head_node->dif_ref = fs_diffhead;
1182         fs_head_node->move_ref = fs_movehead;
1183         fs_head_node->new_ref = fs_newhead;
1184         fs_head_node->del_ref = fs_delhead;
1185         fs_head_node->sym_difref = fs_symlinkdiffhead;
1186         fs_head_node->sym_newref = fs_symlinknewhead;
1187         fs_head_node->ulPatchCount = ulPatchCount;
1188
1189         SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 1);
1190
1191  CleanUp:
1192         fclose(fp);
1193         SS_Free(local);
1194         unlink(SS_PATCHLIST_BKUPLOC);
1195         if (retval == E_SS_FAILURE)
1196                 if (tar_cfg_data)
1197                         tar_free_cfg_table(&tar_cfg_data);
1198         return fs_head_node;
1199 }
1200
1201 void SS_GetPartition_LocDetails(ua_dataSS_t * ua_dataSS)
1202 {
1203         LOGL(LOG_SSENGINE, "PART NAME: [%s] \n", ua_dataSS->parti_info->ua_parti_name);
1204         snprintf(ua_dataSS->update_delta->ua_patch_path, MAX_FILE_PATH, "%s", ua_dataSS->parti_info->ua_subject_name);
1205         snprintf(ua_dataSS->update_delta->ua_patch_info, MAX_FILE_PATH, "%s%s%s", ua_dataSS->parti_info->ua_subject_name,
1206                          ua_dataSS->parti_info->ua_parti_name, SS_PATCHLISTFORMAT);
1207         snprintf(ua_dataSS->update_delta->ua_attrib_path, MAX_FILE_PATH, "%s%s%s", ua_dataSS->parti_info->ua_subject_name,
1208                          ua_dataSS->parti_info->ua_parti_name, SS_PATCH_ATTR_FORMAT);
1209         LOGL(LOG_SSENGINE, "PatchPath[%s] PatchInfo [%s] Attributes [%s]\n", ua_dataSS->update_delta->ua_patch_path,
1210                  ua_dataSS->update_delta->ua_patch_info, ua_dataSS->update_delta->ua_attrib_path);
1211
1212         return;
1213 }
1214
1215 //Support functions//Change Struct format details (Can include total file count also???)/*!
1216 /*
1217 ******************************************************************************** *
1218 SS_FSSetAttributes
1219         *********************************************************************************
1220         * *@brief
1221         * This is used to set the file attributes at the end of application of patches in FS
1222         *
1223         * *@param
1224         *
1225         *@return returns S_SS_SUCCESS
1226         * E_SS_FAILURE in case of error
1227         *
1228         *********************************************************************************
1229  */
1230 int SS_FSSetAttributes(ua_dataSS_t * ua_dataSS)
1231 {
1232         char *pline = NULL;
1233         char *psaveptr = NULL;
1234         char *pfilePath = NULL;
1235         char *pfiletype = NULL;
1236         char *attributSize = NULL;
1237         char *pattribs = NULL;
1238         int ulAttribSize = 0;
1239         int result = S_SS_SUCCESS;
1240         int fail_cnt = 0;
1241
1242         if (!(ua_dataSS && ua_dataSS->update_delta && ua_dataSS->update_data->ua_delta_path)) {
1243                 LOGE("Bad params for SS_FSSetAttributes\n");
1244                 SS_SetUpgradeState(E_SS_BAD_PARAMS);
1245                 return E_SS_FAILURE;
1246         }
1247         LOGL(LOG_SSENGINE, "ATTRIB PATH: [%s] \n", ua_dataSS->update_delta->ua_attrib_path);
1248
1249         int item_size = tar_get_item_size(ua_dataSS->update_data->ua_delta_path, ua_dataSS->update_delta->ua_attrib_path);
1250
1251         if (item_size <= 0) {
1252                 LOGL(LOG_SSENGINE, "No Attributes to SET\n");
1253                 return S_SS_SUCCESS;    // Delta with ONLY deletes
1254         }
1255         char *item_data = SS_Malloc(item_size + 1);
1256         if (item_data == NULL) {
1257                 LOGE("SS_Malloc failed!! - item_data\n");
1258                 SS_SetUpgradeState(E_SS_MALLOC_ERROR);
1259                 return E_SS_FAILURE;
1260         }
1261         int read_data =
1262                 tar_get_cfg_data(ua_dataSS->update_data->ua_delta_path, ua_dataSS->update_delta->ua_attrib_path, item_data,
1263                                                  item_size);
1264         if (read_data <= 0) {
1265                 LOGE("read_data failed!!\n");
1266                 SS_SetUpgradeState(E_SS_FSBADDELTA);
1267                 if (item_data != NULL)
1268                         SS_Free(item_data);
1269                 return E_SS_FAILURE;
1270         }
1271         pline = strtok_r(item_data, "\n", &psaveptr);
1272         if (pline == NULL) {
1273                 LOGL(LOG_SSENGINE, "No Attributes to SET as no lines in file\n");
1274                 if (item_data != NULL)
1275                         SS_Free(item_data);
1276                 return E_SS_FAILURE;
1277         }
1278
1279         while (pline) {
1280                 char *saveptr_pline;
1281                 pfilePath = strtok_r(pline, "\"", &saveptr_pline);
1282
1283                 if (pfilePath && strcmp(pfilePath, SS_FWSLASH) == 0) {
1284                         LOGE("\n skip root: it is RO");
1285                         pline = strtok_r(NULL, SS_TOKEN_NEWLINE, &psaveptr);
1286                         continue;
1287                 }
1288
1289                 pfiletype = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr_pline);
1290                 attributSize = strtok_r(NULL, SS_TOKEN_SPACE, &saveptr_pline);
1291                 pattribs = strtok_r(NULL, SS_TOKEN_NEWLINE, &saveptr_pline);
1292                 LOG("\nSS_FSSetAttributes [%s][%s][%s]", pfiletype, attributSize, pattribs);
1293                 if (pattribs && pfilePath && pfiletype) {
1294                         ulAttribSize = strlen(pattribs);
1295                         //LOG("\nSS_SetFileAttributes [%s][%s][%d][%s]",pfilePath,pfiletype,ulAttribSize, pattribs );
1296                         //LOG("SS_SetFileAttributes [%s]\n", pfilePath);
1297
1298                         result = SS_SetFileAttributes(pfilePath, ulAttribSize, (const unsigned char *)pattribs);
1299                         if (result != S_SS_SUCCESS) {
1300                                 LOGE("\n Failed to set Attributes %s", pfilePath);
1301                                 SS_SetUpgradeState(E_SS_FSBADATTRIBUTES);
1302                                 if (item_data)
1303                                         SS_Free(item_data);
1304                                 fail_cnt++;
1305                         }
1306                 } else {
1307                         LOGE("\n Failed to Parse Attributes - LINE %s", pline);
1308                         SS_SetUpgradeState(E_SS_FSBADATTRIBUTES);
1309                         if (item_data)
1310                                 SS_Free(item_data);
1311                         fail_cnt++;
1312                 }
1313                 pline = strtok_r(NULL, SS_TOKEN_NEWLINE, &psaveptr);
1314         }
1315
1316         SS_Free(item_data);
1317
1318         if (fail_cnt > 0)
1319                 result = E_SS_FAILURE;
1320         else
1321                 result = S_SS_SUCCESS;
1322
1323         return result;
1324 }
1325
1326 /*!
1327  *********************************************************************************
1328  *                                       SS_FSUpdateFile
1329  *********************************************************************************
1330  *
1331  * @brief
1332  *      This is used to update individual files on case basis
1333  *
1334  *
1335  *      @param
1336  *
1337  *      @return                         returns S_SS_SUCCESS
1338  *                                              E_SS_FAILURE in case of error
1339  *
1340  *********************************************************************************
1341  */
1342 int SS_FSUpdateFile(int ubFileType, ua_dataSS_t * ua_dataSS, int ulPatchCount, fs_params * pFsNode,
1343                                         const char *patch_path)
1344 {
1345         int ulFileIndex = 1;
1346         char ubPatch[SS_MAX_FILE_PATH] = {
1347                 0
1348         };
1349         int ulReadCnt = 0;
1350         int ulResult = S_SS_SUCCESS;
1351
1352         if (!patch_path) {
1353                 LOGE("Bad patch_path name\n");
1354                 return E_SS_FAILURE;
1355         }
1356         switch (ubFileType) {
1357         case DIFFS:
1358                 {
1359                         tar_open(ua_dataSS->update_data->ua_delta_path);
1360 #ifdef TIME_PROFILING
1361                         get_time_stamp1();  //total time capturing
1362                         t1 = atoi(ts1);
1363 #endif
1364                         while (pFsNode) {
1365                                 LOGL(LOG_SSENGINE, "DIFFS update Index: [%d] \n", ulFileIndex++);
1366                                 snprintf(ubPatch, SS_MAX_FILE_PATH, "%s%s", patch_path, pFsNode->patch_name);
1367                                 //LOGL(LOG_SSENGINE, "DIFF list --- [File Name %s]\n [Patch Name %s]",pFsNode->file_path, ubPatch);
1368                                 if (pFsNode->data_size > 0) {
1369                                         ulReadCnt =
1370                                                 fast_tar_extract_file(ua_dataSS->update_data->ua_delta_path, ubPatch, SS_PATCHFILE_SOURCE,
1371                                                                                           pFsNode->data_size, pFsNode->data_offset);
1372                                         if (ulReadCnt < 0) {
1373                                                 ulResult = E_SS_FAILURE;
1374                                                 tar_close();
1375                                                 SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
1376                                                 LOGE("Delta Read Failed\n");
1377                                                 break;
1378                                         }
1379                                         //LOGL(LOG_SSENGINE,"Updating [Item - %s]and size is[%d] Read Count[%d]\n",ubPatch, pFsNode->data_size, ulReadCnt);
1380
1381                                         if (ulReadCnt > 0)
1382                                                 ulResult =
1383                                                         SS_UpdateDeltaFS(pFsNode->file_old_path, pFsNode->file_new_path, pFsNode->sha1src,
1384                                                                                          pFsNode->sha1trg, pFsNode->data_size);
1385                                         if (ulResult != S_SS_SUCCESS) {
1386                                                 LOGE("FS update Failed Result : [%d], [Item - %s]and size is[%d] Read Count[%d]\n", ulResult,
1387                                                          ubPatch, pFsNode->data_size, ulReadCnt);
1388                                                 tar_close();
1389                                                 SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
1390                                                 break;
1391                                         }
1392                                         SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
1393                                         pFsNode = pFsNode->nextnode;
1394                                 }
1395                                 else {
1396                                         ulResult = E_SS_FAILURE;
1397                                         tar_close();
1398                                         LOGE("size is invalid\n");
1399                                         SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
1400                                         break;
1401                                 }
1402                         }
1403 #ifdef TIME_PROFILING
1404                         get_time_stamp1();  //total time capturing
1405                         t2 = atoi(ts1);
1406                         LOG("Shirsh time for DIFFS - [%d] \n", (t2 - t1));
1407 #endif
1408                         tar_close();
1409                 }
1410                 break;
1411         case MOVES:
1412                 {
1413 #ifdef TIME_PROFILING
1414                         get_time_stamp1();  //total time capturing
1415                         t1 = atoi(ts1);
1416 #endif
1417                         while (pFsNode) {
1418                                 LOGL(LOG_SSENGINE, "MOVES update Index: [%d] \n", ulFileIndex++);
1419                                 ulResult = SS_MoveFile(pFsNode->file_old_path, pFsNode->file_new_path);
1420                                 if (ulResult != S_SS_SUCCESS) {
1421                                         LOGE("Move Failed for [%s] to [%s]\n", pFsNode->file_old_path, pFsNode->file_new_path);
1422                                         SS_SetUpgradeState(ulResult);
1423                                         break;
1424                                 }
1425                                 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
1426                                 pFsNode = pFsNode->nextnode;
1427                         }
1428 #ifdef TIME_PROFILING
1429                         get_time_stamp1();  //total time capturing
1430                         t2 = atoi(ts1);
1431                         LOG("Shirsh time for DELETES - [%d] \n", (t2 - t1));
1432 #endif
1433                 }
1434                 break;
1435         case DELETES:
1436                 {
1437                         int ulFiletype = 0;
1438 #ifdef TIME_PROFILING
1439                         get_time_stamp1();  //total time capturing
1440                         t1 = atoi(ts1);
1441 #endif
1442                         while (pFsNode) {
1443                                 if (pFsNode->type == DELETES) {
1444                                         LOGL(LOG_SSENGINE, "DELETES update Index: [%d] \n", ulFileIndex++);
1445                                         SS_GetFileType(pFsNode->file_old_path, (enumFileType *) & ulFiletype);
1446                                         if (ulFiletype == 2)            //FT_FOLDER
1447                                                 ulResult = SS_DeleteFolder(pFsNode->file_old_path);
1448                                         else
1449                                                 ulResult = SS_DeleteFile(pFsNode->file_old_path);
1450                                         if (ulResult != S_SS_SUCCESS) {
1451                                                 LOGE("Delete Failed\n");
1452                                                 SS_SetUpgradeState(ulResult);
1453                                                 break;
1454                                         }
1455                                 }
1456                                 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
1457                                 pFsNode = pFsNode->nextnode;
1458                         }
1459 #ifdef TIME_PROFILING
1460                         get_time_stamp1();  //total time capturing
1461                         t2 = atoi(ts1);
1462                         LOG("Shirsh time for DELETES - [%d] \n", (t2 - t1));
1463 #endif
1464                 }
1465                 break;
1466         case DELETE_END:
1467                 {
1468                         int ulFiletype = 0;
1469 #ifdef TIME_PROFILING
1470                         get_time_stamp1();  //total time capturing
1471                         t1 = atoi(ts1);
1472 #endif
1473                         while (pFsNode) {
1474                                 if (pFsNode->type == DELETE_END) {
1475                                         LOGL(LOG_SSENGINE, "DELETE_END update Index: [%d] \n", ulFileIndex++);
1476                                         SS_GetFileType(pFsNode->file_old_path, (enumFileType *) & ulFiletype);
1477                                         if (ulFiletype == 2)            //FT_FOLDER
1478                                                 ulResult = SS_DeleteFolder(pFsNode->file_old_path);
1479                                         else
1480                                                 ulResult = SS_DeleteFile(pFsNode->file_old_path);
1481                                         if (ulResult != S_SS_SUCCESS) {
1482                                                 LOGE("Delete Failed\n");
1483                                                 SS_SetUpgradeState(ulResult);
1484                                                 break;
1485                                         }
1486                                 }
1487                                 pFsNode = pFsNode->nextnode;
1488                         }
1489 #ifdef TIME_PROFILING
1490                         get_time_stamp1();  //total time capturing
1491                         t2 = atoi(ts1);
1492                         LOG("Shirsh time for DELETE_END - [%d] \n", (t2 - t1));
1493 #endif
1494                 }
1495                 break;
1496
1497         case NEWFILES:
1498                 {
1499 #ifdef TIME_PROFILING
1500                         get_time_stamp1();  //total time capturing
1501                         t1 = atoi(ts1);
1502 #endif
1503                         LOGL(LOG_SSENGINE, "Starting New file upgrade for   [%s]\n", patch_path);
1504                         if (tar_extract_file(ua_dataSS->update_data->ua_delta_path, (char *)patch_path, SS_NEW_COMPRESSED_FILE) >=
1505                                 0)
1506                                 if (_7zdecompress(SS_NEW_COMPRESSED_FILE) == 0)
1507                                         LOGL(LOG_SSENGINE, "7zip extracted  successfully %s\n", ua_dataSS->parti_info->ua_parti_name);
1508                                 else
1509                                         LOGL(LOG_SSENGINE, "7zip extraction error for %s\n", ua_dataSS->parti_info->ua_parti_name);
1510                         else
1511                                 LOGL(LOG_SSENGINE, "tar extraction error for %s\n", ua_dataSS->parti_info->ua_parti_name);
1512                         SS_DeleteFile(SS_NEW_COMPRESSED_FILE);
1513 #ifdef TIME_PROFILING
1514                         get_time_stamp1();  //total time capturing
1515                         t2 = atoi(ts1);
1516                         LOG("Shirsh time for NEWFILES - [%d] \n", (t2 - t1));
1517 #endif
1518                 }
1519                 break;
1520         case SYMDIFFS:
1521                 {
1522 #ifdef TIME_PROFILING
1523                         get_time_stamp1();  //total time capturing
1524                         t1 = atoi(ts1);
1525 #endif
1526                         while (pFsNode) {
1527                                 LOGL(LOG_SSENGINE, "SYMDIFFS update Index: [%d] \n", ulFileIndex++);
1528                                 //LOG("Sym Diff file paths: [Linkname - %s] [reference file name- %s][]\n", pFsNode->file_path,pFsNode->patch_name);
1529                                 ulResult = SS_Unlink(pFsNode->file_old_path);
1530                                 if (ulResult == S_SS_SUCCESS)
1531                                         ulResult = SS_Link(NULL, pFsNode->file_new_path, pFsNode->patch_name);
1532                                 else {
1533                                         LOGE("Unlink Failed\n");
1534                                         SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
1535                                         break;
1536                                 }
1537                                 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
1538                                 pFsNode = pFsNode->nextnode;
1539                         }
1540 #ifdef TIME_PROFILING
1541                         get_time_stamp1();  //total time capturing
1542                         t2 = atoi(ts1);
1543                         LOG("Shirsh time for SYMDIFFS - [%d] \n", (t2 - t1));
1544 #endif
1545                 }
1546                 break;
1547         case SYMNEWFILES:
1548                 {
1549                         fs_params *head_node;
1550                         int retry_count = 0, do_retry = 0;
1551 #ifdef TIME_PROFILING
1552                         get_time_stamp1();  //total time capturing
1553                         t1 = atoi(ts1);
1554 #endif
1555  SYMLINK_CREATE:
1556                         head_node = pFsNode;
1557                         while (head_node) {
1558                                 LOGL(LOG_SSENGINE, "SYMNEWS update Index: [%d] \n", ulFileIndex++);
1559                                 snprintf(ubPatch, SS_MAX_FILE_PATH, "%s%s%s", patch_path, "/", head_node->patch_name);
1560                                 LOGL(LOG_SSENGINE, "Sym New file paths: [Linkname - %s] [reference file name- %s][]\n",
1561                                          head_node->file_old_path, head_node->patch_name);
1562                                 ulResult = SS_Link(NULL, head_node->file_old_path, head_node->patch_name);
1563                                 if (ulResult == E_SS_FAILURE) {
1564                                         LOGE("Link Failed\n");
1565                                         SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
1566                                         break;
1567                                 } else if (ulResult == ENOENT) {  //to handle cases where new symlink points to a new symlink yet to be created
1568                                         do_retry = 1;      //we will retry the failed symlinks with error 2 (no file or dir) again after this cycle
1569                                         //SS_UpdateUIProgress(ua_dataSS,ulPatchCount);
1570                                         head_node = head_node->nextnode;
1571                                         continue;
1572                                 }
1573                                 SS_UpdateUIProgress(ua_dataSS, ulPatchCount, 0);
1574                                 head_node = head_node->nextnode;
1575                         }
1576                         if (do_retry && (retry_count < 4)) {
1577                                 retry_count++;
1578                                 ulFileIndex = 0;
1579                                 do_retry = 0;
1580                                 goto SYMLINK_CREATE;
1581                         } else if (do_retry && (retry_count >= 4)) {  //retry to be done maximum 4 times
1582                                 LOGE("Link Failed after %d retrys\n", retry_count);
1583                                 //SS_SetUpgradeState(E_SS_FSUPDATEFAILED);
1584                                 break;
1585                         }
1586 #ifdef TIME_PROFILING
1587                         get_time_stamp1();  //total time capturing
1588                         t2 = atoi(ts1);
1589                         LOG("Shirsh time for SYMNEWS - [%d] \n", (t2 - t1));
1590 #endif
1591                 }
1592                 break;
1593         default:
1594                 break;
1595         }
1596         return ulResult;
1597 }
1598
1599 #ifdef MEM_PROFILING
1600 extern int max_mem;
1601 extern int cur_mem;
1602 #endif
1603 /*!
1604  *********************************************************************************
1605  *                                       SS_FSUpdatemain
1606  *********************************************************************************
1607  *
1608  * @brief
1609  *      This is the API exposed from the engine to update FS.
1610  *
1611  *
1612  *      @param
1613  *
1614  *      @return                         returns S_SS_SUCCESS
1615  *                                              E_SS_FAILURE in case of error
1616  *
1617  *********************************************************************************
1618  */
1619
1620 int SS_FSUpdatemain(ua_dataSS_t * ua_dataSS, int part_idx)
1621 {
1622         int ulResult = S_SS_SUCCESS;
1623         int del_type = 0;
1624         fs_list *head_ptr_node = NULL;
1625         char new_patch_path[SS_MAX_FILE_PATH] = {
1626                 0
1627         };
1628
1629         if (!ua_dataSS)
1630                 return E_SS_BAD_PARAMS; // Set error ??
1631         head_ptr_node = headptr_list[part_idx];
1632
1633         if (!head_ptr_node) {      //in case of power failure, try rebilding nodes again
1634                 SS_FSVerifyPartition(ua_dataSS, part_idx);
1635                 head_ptr_node = headptr_list[part_idx];
1636         }
1637
1638         if (!head_ptr_node)
1639                 return E_SS_FSBADNODES;
1640
1641         SS_GetPartition_LocDetails(ua_dataSS);
1642
1643         LOGL(LOG_SSENGINE, "FS Update Entry PartIndex: [%d]\n", part_idx);
1644
1645         del_type = SS_Get_last_update_del_type();
1646         LOGL(LOG_SSENGINE, "del_type: [%d]\n", del_type);
1647
1648         if (head_ptr_node->del_ref == NULL) {
1649                 LOGL(LOG_SSENGINE, "No DEL header\n");
1650         } else if (ulResult == S_SS_SUCCESS) {
1651                 if (del_type < DELETES) {
1652                         ulResult = SS_FSUpdateFile(DELETES, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->del_ref,
1653                                         ua_dataSS->update_delta->ua_patch_path);
1654                         if (ulResult == S_SS_SUCCESS) {
1655                                 LOGL(LOG_SSENGINE, "SS_FSUpdateFile - DELETES success!!\n");
1656                                 SS_Set_last_update_status(part_idx, DELETES);
1657                         }
1658                 } else {
1659                         LOGL(LOG_SSENGINE, "SS_FSUpdateFile - DELETES already applied!!\n");
1660                 }
1661         }
1662
1663         if (head_ptr_node->dif_ref == NULL) {
1664                 LOGL(LOG_SSENGINE, "No DIFF header\n");
1665         } else if (ulResult == S_SS_SUCCESS) {
1666                 ulResult =
1667                         SS_FSUpdateFile(DIFFS, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->dif_ref,
1668                                                         ua_dataSS->update_delta->ua_patch_path);
1669                 if (ulResult == S_SS_SUCCESS) {
1670                         LOGL(LOG_SSENGINE, "SS_FSUpdateFile - DIFFS success!!\n");
1671                 }
1672         }
1673
1674         if (head_ptr_node->move_ref == NULL) {
1675                 LOGL(LOG_SSENGINE, "No MOVE header\n");
1676         } else if (ulResult == S_SS_SUCCESS) {
1677                 if (del_type < MOVES) {
1678                 ulResult =
1679                         SS_FSUpdateFile(MOVES, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->move_ref,
1680                                                         ua_dataSS->update_delta->ua_patch_path);
1681                         if (ulResult == S_SS_SUCCESS) {
1682                                 LOGL(LOG_SSENGINE, "SS_FSUpdateFile - MOVES success!!\n");
1683                                 SS_Set_last_update_status(part_idx, MOVES);
1684                         }
1685                 } else {
1686                         LOGL(LOG_SSENGINE, "SS_FSUpdateFile - MOVES already applied!!\n");
1687                 }
1688         }
1689
1690         if (head_ptr_node->del_ref == NULL) {
1691                 LOGL(LOG_SSENGINE, "No DEL header\n");
1692         } else if (ulResult == S_SS_SUCCESS) {
1693                 if (del_type < DELETE_END) {
1694                         ulResult = SS_FSUpdateFile(DELETE_END, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->del_ref,
1695                                         ua_dataSS->update_delta->ua_patch_path);
1696                         if (ulResult == S_SS_SUCCESS) {
1697                                 LOGL(LOG_SSENGINE, "SS_FSUpdateFile - DELETE_END success!!\n");
1698                                 SS_Set_last_update_status(part_idx, DELETE_END);
1699                         }
1700                 } else {
1701                         LOGL(LOG_SSENGINE, "SS_FSUpdateFile - DELETE_END already applied!!\n");
1702                 }
1703         }
1704
1705          if (ulResult == S_SS_SUCCESS) {
1706                  //new file extraction start
1707                 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
1708                 LOGL(LOG_SSENGINE, "File path created to extract new files : [%s]\n", new_patch_path);
1709                 ulResult =
1710                         SS_FSUpdateFile(NEWFILES, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->new_ref, new_patch_path);
1711                 //new file extraction end
1712                 if (ulResult == S_SS_SUCCESS) {
1713                         LOGL(LOG_SSENGINE, "SS_FSUpdateFile - NEWFILES success!!\n");
1714                 }
1715         }
1716
1717         if (head_ptr_node->sym_difref == NULL) {
1718                 LOGL(LOG_SSENGINE, "No SYMDIFF header\n");
1719         } else if (ulResult == S_SS_SUCCESS) {
1720                 ulResult =
1721                         SS_FSUpdateFile(SYMDIFFS, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->sym_difref,
1722                                                         ua_dataSS->update_delta->ua_patch_path);
1723                 if (ulResult == S_SS_SUCCESS) {
1724                         LOGL(LOG_SSENGINE, "SS_FSUpdateFile - SYMDIFFS success!!\n");
1725                 }
1726         }
1727
1728         if (head_ptr_node->sym_newref == NULL) {
1729                 LOGL(LOG_SSENGINE, "No SYMNEW header\n");
1730         } else if (ulResult == S_SS_SUCCESS) {
1731                 ulResult =
1732                         SS_FSUpdateFile(SYMNEWFILES, ua_dataSS, head_ptr_node->ulPatchCount, head_ptr_node->sym_newref,
1733                                                         ua_dataSS->update_delta->ua_patch_path);
1734                 if (ulResult == S_SS_SUCCESS) {
1735                         LOGL(LOG_SSENGINE, "SS_FSUpdateFile - SYMNEWFILES success!!\n");
1736                 }
1737         }
1738
1739
1740         if (ulResult == S_SS_SUCCESS) {
1741                 ulResult = SS_FSSetAttributes(ua_dataSS);
1742         } else {
1743                 SS_FSSetAttributes(ua_dataSS);  // To prevent boot failures by smack.
1744         }
1745
1746         sync();
1747         sleep(1);
1748         SS_FSClearNodes(part_idx);
1749
1750         if (ulResult == S_SS_SUCCESS) {
1751                 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
1752                 SS_Set_last_update_status(part_idx, DEL_TYPE_MAX);
1753         }
1754
1755         LOGL(LOG_SSENGINE, "FS update Complete PartIndex: [%d]\n", part_idx);
1756 #ifdef  MEM_PROFILING
1757         LOGL(LOG_SSENGINE, "Stats are : Cur Max : [%d] Global Max : [%d]\n", cur_mem, max_mem);
1758 #endif
1759         if (ulResult == S_SS_SUCCESS)
1760                 return ulResult;
1761         else
1762                 return SS_GetUpgradeState();
1763 }
1764
1765 /*!
1766  *********************************************************************************
1767  *                                       SS_FSUpdatemain
1768  *********************************************************************************
1769  *
1770  * @brief
1771  *      This is the API exposed from the engine to update FS.
1772  *      FS entry function for updating FS partition. Should be invoked only after verification of the partition
1773  *
1774  *
1775  *      @param                          Requires common data structure having all details & Partition Index.
1776  *                                              (Used for getting right NODES information that built during verification)
1777  *                                              (Configuration, Delta info, Partition Info, UI link , Kind of operation.(Verify or Updates))
1778  *
1779  *      @return                         returns S_SS_SUCCESS
1780  *                                              E_SS_FAILURE in case of error
1781  *
1782  *********************************************************************************
1783  */
1784 size_t SS_FSAvailiableFreeSpace(char *block_name)
1785 {
1786
1787         struct mntent *ent;
1788         FILE *aFile;
1789         struct statfs sb;
1790         aFile = setmntent("/proc/mounts", "r");
1791         if (aFile == NULL) {
1792                 LOGE("setmntent error");
1793                 return E_SS_FAILURE;
1794         }
1795         while (NULL != (ent = getmntent(aFile))) {
1796                 if (strcmp(ent->mnt_fsname, block_name) == 0) {
1797                         if (statfs(ent->mnt_dir, &sb) == 0)
1798                                 LOGL(LOG_SSENGINE, "Total free space = %d, blocks free = %d\n", sb.f_bsize * sb.f_bavail, sb.f_bfree);
1799                 }
1800         }
1801         endmntent(aFile);
1802         return sb.f_bsize * sb.f_bavail;
1803 }
1804
1805 int SS_FSVerifyPartition(ua_dataSS_t * ua_dataSS, int part_idx)
1806 {
1807         int ulResult = S_SS_SUCCESS;
1808         size_t free_space = 0;
1809         if (!ua_dataSS) {
1810                 LOGE("Wrong Param for fs verification\n");
1811                 SS_SetUpgradeState(E_SS_BAD_PARAMS);
1812                 return E_SS_FAILURE;
1813         }
1814
1815         LOGL(LOG_SSENGINE, "FS max free mem reqired : [%d]\n", ua_dataSS->update_cfg->soure_img_size);
1816         free_space = SS_FSAvailiableFreeSpace(ua_dataSS->parti_info->ua_blk_name);
1817         if (free_space != E_SS_FAILURE) {
1818                 //Source img size is max single file size for a file system under upgrade, which is updated in CFG file by UPG
1819                 if ((free_space) < (ua_dataSS->update_cfg->soure_img_size + ua_dataSS->update_cfg->soure_img_size / 10)) {
1820                         LOGE("Not enough free space [%d] for max size [%d]\n", free_space,
1821                                  (ua_dataSS->update_cfg->soure_img_size + ua_dataSS->update_cfg->soure_img_size / 10));
1822                         //SS_SetUpgradeState(E_SS_FSMEMORYERROR);
1823                         //return E_SS_FAILURE;
1824                 } else
1825                         LOGL(LOG_SSENGINE, "Enough space for Partition [%s]\n", ua_dataSS->parti_info->ua_parti_name);
1826         }
1827
1828         SS_GetAvailableFreeSpace(SS_COMMON_WORKSPACE, &free_space);
1829         //Checking for 2 times the file size free space , as delta can be worst case size of file.
1830         if ((free_space) < (2 * ua_dataSS->update_cfg->soure_img_size)) {
1831                 LOGE("Not enough free space [%d] for max size [%d]\n", free_space, (2 * ua_dataSS->update_cfg->soure_img_size));
1832                 SS_SetUpgradeState(E_SS_FSMEMORYERROR);
1833                 return E_SS_FAILURE;
1834         }
1835 #ifdef MEM_PROFILING
1836         if (!mem_profiling_start)
1837                 if (!(S_SS_SUCCESS == SS_Do_Memory_Profiling()))
1838                         return E_SS_FAILURE;
1839 #endif
1840         SS_GetPartition_LocDetails(ua_dataSS);
1841         LOGL(LOG_SSENGINE, "FS Verification Start PartIndex:[%d]\n", part_idx);
1842         if (ua_dataSS->ua_operation == UI_OP_SCOUT)
1843                 gvalid_session = 1;  // (shd b true if called during verification)
1844         headptr_list[part_idx] = SS_FSBuildNodes(ua_dataSS);
1845 #ifdef TIME_PROFILING
1846         LOGL(LOG_SSENGINE, "fast_tar_get_item_size_time :[%lf]\n", fast_tar_get_item_size_time);
1847         LOGL(LOG_SSENGINE, "SS_LoadFile_time :[%lf]\n", SS_LoadFile_time);
1848         LOGL(LOG_SSENGINE, "SS_FSBuildNodes_time :[%lf]\n", SS_FSBuildNodes_time);
1849 #endif
1850         if (!headptr_list[part_idx]) {
1851                 LOGE("FS Verification Failed PartIndex: [%d]\n", part_idx);
1852                 SS_FSClearNodes(part_idx);
1853                 ulResult = E_SS_FAILURE;
1854         }
1855
1856         if (ulResult == S_SS_SUCCESS)
1857                 return ulResult;
1858         else
1859                 return SS_GetUpgradeState();
1860 }
1861
1862 //Should check if space is available????
1863 int SS_BackupSource(const char *source_filename)
1864 {
1865         int ret = E_SS_FAILURE;
1866
1867         if (source_filename) {
1868                 ret = (int)SS_CopyFile(source_filename, SS_BACKUP_SOURCE);
1869                 if (ret != S_SS_SUCCESS) {
1870                         LOGE("failed to back up source file  Error [%d]\n", ret);
1871                         SS_SetUpgradeState(E_SS_FSSRCBACKUPFAILED);
1872                 }
1873         }
1874         return ret;
1875 }
1876
1877 int SS_BackupSourceClear(void)
1878 {
1879         int ret = E_SS_FAILURE;
1880         ret = (int)SS_DeleteFile(SS_BACKUP_SOURCE);
1881         if (ret != S_SS_SUCCESS) {
1882                 LOGE("failed to delete BACKUP file\n");
1883                 SS_SetUpgradeState(E_SS_FSSRCBACKUPFAILED);
1884         }
1885         return ret;
1886 }
1887
1888 int SS_PatchSourceClear(void)
1889 {
1890         int ret = E_SS_FAILURE;
1891         ret = (int)SS_DeleteFile(SS_PATCHFILE_SOURCE);
1892         if (ret != S_SS_SUCCESS) {
1893                 LOGE("failed to delete PATCHFILE file\n");
1894                 SS_SetUpgradeState(E_SS_PATCHFILE_DEL_ERROR);
1895         }
1896         return ret;
1897 }
1898 int SS_IMGVerifyFullImage(ua_dataSS_t * ua_dataSS)
1899 {
1900         int read_cnt = 0, patch_size = 0;
1901         FileInfo source_file;
1902         uint8_t target_sha1[SHA_DIGEST_SIZE];
1903         int ulResult = S_SS_SUCCESS;
1904
1905         if (!(ua_dataSS && ua_dataSS->update_cfg && ua_dataSS->parti_info &&
1906                                 ua_dataSS->parti_info->ua_blk_name &&
1907                                 !(ua_dataSS->update_cfg->skip_verify == 1))) {
1908                 LOGE("Bad structure or members\n");
1909                 SS_SetUpgradeState(E_SS_BAD_PARAMS);
1910                 return E_SS_FAILURE;
1911         }
1912
1913         LOGL(LOG_SSENGINE, "FULL IMG Verification Entry BlkName:[%s]\n", ua_dataSS->parti_info->ua_blk_name);
1914
1915         if (ua_dataSS->update_data && ua_dataSS->parti_info && ua_dataSS->update_data->ua_delta_path
1916                 && ua_dataSS->parti_info->ua_subject_name) {
1917                 patch_size = tar_get_item_size(ua_dataSS->update_data->ua_delta_path, ua_dataSS->parti_info->ua_subject_name);
1918         } else {
1919                 LOGE("Bad structure members in ua_dataSS\n");
1920                 SS_SetUpgradeState(E_SS_BAD_PARAMS);
1921                 ulResult = E_SS_FAILURE;
1922                 goto Cleanup;
1923         }
1924
1925         if (ua_dataSS->update_cfg && ua_dataSS->update_cfg->soure_img_size && ua_dataSS->update_cfg->target_sha1) {
1926                 LOGL(LOG_SSENGINE, "\nParams -image size [%d] sha1 [%s]\n",
1927                          ua_dataSS->update_cfg->soure_img_size, ua_dataSS->update_cfg->target_sha1);
1928         } else {
1929                 LOGE("Bad structure member update_cfg in ua_dataSS\n");
1930                 SS_SetUpgradeState(E_SS_BAD_PARAMS);
1931                 ulResult = E_SS_FAILURE;
1932                 goto Cleanup;
1933         }
1934
1935         if (ParseSha1(ua_dataSS->update_cfg->target_sha1, target_sha1) != 0) {
1936                 LOGE("failed to parse tgt-sha1 \"%s\"\n", ua_dataSS->update_cfg->target_sha1);
1937                 SS_SetUpgradeState(E_SS_IMGBADDELTA);
1938                 ulResult = E_SS_FAILURE;
1939                 goto Cleanup;
1940         }
1941
1942         if ((patch_size) > 0)
1943                 read_cnt = tar_extract_file(ua_dataSS->update_data->ua_delta_path,
1944                                 ua_dataSS->parti_info->ua_subject_name, SS_PATCHFILE_SOURCE);
1945
1946         if (read_cnt <= 0) {
1947                 LOGL(LOG_SSENGINE, "Failed to read delta\n");
1948                 SS_SetUpgradeState(E_SS_IMGBADDELTA);
1949                 ulResult = E_SS_FAILURE;
1950                 goto Cleanup;
1951         }
1952         if (SS_LoadFile(SS_PATCHFILE_SOURCE, &source_file) == 0) {
1953                 if (memcmp(source_file.sha1, target_sha1, SHA_DIGEST_SIZE) == 0) {
1954                         LOGL(LOG_SSENGINE, "Patch Can be applied\n");
1955                         SS_Free(source_file.data);
1956                         ulResult = S_SS_SUCCESS;
1957                 } else{
1958                         LOGL(LOG_SSENGINE, "Patch Cannot be applied\n");
1959                         SS_Free(source_file.data);
1960                         SS_SetUpgradeState(E_SS_IMGBADDELTA);
1961                         ulResult = E_SS_FAILURE;
1962                         goto Cleanup;
1963                 }
1964         } else {
1965                 LOGL(LOG_SSENGINE, "Failed to LoadFile\n");
1966                 SS_SetUpgradeState(E_SS_IMGBADDELTA);
1967                 ulResult = E_SS_FAILURE;
1968         }
1969
1970 Cleanup:
1971         if (file_exist(SS_PATCHFILE_SOURCE))
1972                 SS_DeleteFile(SS_PATCHFILE_SOURCE);
1973         return ulResult;
1974 }
1975
1976 int SS_IMGVerfiyPartition(ua_dataSS_t * ua_dataSS)
1977 {
1978         FileInfo source_file;
1979         int ulResult = S_SS_SUCCESS;
1980         uint8_t source_sha1[SHA_DIGEST_SIZE];
1981         uint8_t target_sha1[SHA_DIGEST_SIZE];
1982         size_t free_space = 0;
1983
1984         if (!(ua_dataSS && ua_dataSS->update_cfg && ua_dataSS->parti_info && ua_dataSS->parti_info->ua_blk_name)) {
1985                 LOGE("Bad structure or members\n");
1986                 SS_SetUpgradeState(E_SS_BAD_PARAMS);
1987                 return E_SS_FAILURE;
1988         }
1989
1990         //We verify twice the image size for BACKUP source, not on Partition. As Patch will be created on RAM
1991         SS_GetAvailableFreeSpace(SS_COMMON_WORKSPACE, &free_space);
1992         if ((free_space) < (2 * ua_dataSS->update_cfg->target_img_size)) {
1993                 LOGE("Not enough free space [%d] for twice max size [%d]\n", free_space,
1994                          (2 * ua_dataSS->update_cfg->target_img_size));
1995                 SS_SetUpgradeState(E_SS_FSMEMORYERROR);
1996                 return E_SS_FAILURE;
1997         }
1998
1999         if (ParseSha1(ua_dataSS->update_cfg->soure_sha1, source_sha1) != 0) {
2000                 LOGE("failed to parse Src-sha1 \"%s\"\n", ua_dataSS->update_cfg->soure_sha1);
2001                 SS_SetUpgradeState(E_SS_SHAPRASE_FAILED);
2002                 return E_SS_FAILURE;
2003         }
2004         // corner case, Parsing sha can fail if update.cfg is wrong/manually edited
2005         if (ParseSha1(ua_dataSS->update_cfg->target_sha1, target_sha1) != 0) {
2006                 LOGE("failed to parse Target-sha1 \"%s\"\n", ua_dataSS->update_cfg->target_sha1);
2007                 SS_SetUpgradeState(E_SS_SHAPRASE_FAILED);
2008                 return E_SS_FAILURE;
2009         }
2010
2011         source_file.size = ua_dataSS->update_cfg->soure_img_size;
2012         source_file.data = NULL;
2013         if (SS_LoadPartition(ua_dataSS->parti_info->ua_blk_name, &source_file) == 0) {
2014                 if (memcmp(source_file.sha1, source_sha1, SHA_DIGEST_SIZE) == 0) {
2015                         LOGL(LOG_SSENGINE, "SS_IMGVerfiyPartition - SHA matches with source [%s] \n",
2016                                  ua_dataSS->parti_info->ua_blk_name);
2017                 } else {                          // Need not compare with Target sha as once upgraded, it should NOT verify same partition again.
2018                         SS_SetUpgradeState(E_SS_IMGSRCCURRUPTED);
2019                         ulResult = E_SS_FAILURE;
2020                 }
2021         }
2022         SS_Free(source_file.data);
2023         if (ulResult == S_SS_SUCCESS) {
2024                 if (ua_dataSS->ui_progress)
2025                         ua_dataSS->ui_progress(ua_dataSS, 100);
2026                 return ulResult;
2027         } else
2028                 return SS_GetUpgradeState();
2029 }
2030
2031 /*!
2032  *********************************************************************************
2033  *                                       SS_IMGUpdatemain
2034  *********************************************************************************
2035  *
2036  * @brief
2037  *      This is the API exposed from the engine to update Images(FULL and DELTA images)
2038  *
2039  *
2040  *      @param
2041  *
2042  *      @return                         returns S_SS_SUCCESS
2043  *                                              E_SS_FAILURE in case of error
2044  *
2045  *********************************************************************************
2046  */
2047
2048 int SS_IMGUpdatemain(ua_dataSS_t * ua_dataSS, int update_type)  //SS_FSUpdatePartition
2049 {
2050         int read_cnt = 0, patch_size;
2051         int ulResult = S_SS_SUCCESS;
2052
2053         //sprintf(Blk_name, "%s%s%s","EMMC",":", ua_dataSS->parti_info->ua_blk_name);
2054         //LOGL(LOG_SSENGINE, "IMG Upgrade Entry BlkName:[%s]\n",Blk_name);
2055         if (!ua_dataSS) {
2056                 LOGE("Bad structure ua_dataSS\n");
2057                 SS_SetUpgradeState(E_SS_BAD_PARAMS);
2058                 return E_SS_FAILURE;
2059         }
2060         LOGL(LOG_SSENGINE, "IMG Upgrade Entry BlkName:[%s]\n", ua_dataSS->parti_info->ua_blk_name);
2061
2062         if (ua_dataSS->update_data && ua_dataSS->parti_info && ua_dataSS->update_data->ua_delta_path
2063                 && ua_dataSS->parti_info->ua_subject_name)
2064                 patch_size = tar_get_item_size(ua_dataSS->update_data->ua_delta_path, ua_dataSS->parti_info->ua_subject_name);
2065         else {
2066                 LOGE("Bad structure members in ua_dataSS\n");
2067                 SS_SetUpgradeState(E_SS_BAD_PARAMS);
2068                 return E_SS_FAILURE;
2069         }
2070         if (ua_dataSS->update_cfg && ua_dataSS->update_cfg->soure_img_size && ua_dataSS->update_cfg->target_sha1)
2071                 LOGL(LOG_SSENGINE, "\n SS_IMGUpdatemain Params -source size [%d] sha1 [%s]",
2072                          ua_dataSS->update_cfg->soure_img_size, ua_dataSS->update_cfg->target_sha1);
2073         else {
2074                 LOGE("Bad structure member update_cfg in ua_dataSS\n");
2075                 SS_SetUpgradeState(E_SS_BAD_PARAMS);
2076                 return E_SS_FAILURE;
2077         }
2078
2079         if ((patch_size) > 0)
2080                 read_cnt =
2081                         tar_extract_file(ua_dataSS->update_data->ua_delta_path, ua_dataSS->parti_info->ua_subject_name,
2082                                                          SS_PATCHFILE_SOURCE);
2083
2084         if (read_cnt <= 0) {
2085                 ulResult = E_SS_FAILURE;
2086                 SS_SetUpgradeState(E_SS_IMGBADDELTA);
2087                 return E_SS_FAILURE;    //ulResult;
2088         }
2089         if (ua_dataSS->ui_progress)
2090                 ua_dataSS->ui_progress(ua_dataSS, 40);
2091
2092         if (update_type == FULL_IMG && ua_dataSS->update_data->ua_temp_path)
2093                 ulResult = SS_MoveFile(SS_PATCHFILE_SOURCE, ua_dataSS->update_data->ua_temp_path);
2094         else if ((ua_dataSS->update_cfg->update_type == DELTA_IMG && ua_dataSS->write_data_to_blkdev)
2095                                         || ua_dataSS->update_cfg->update_type == EXTRA) {
2096
2097                 FILE *fp = NULL;
2098                 char buf[14] = { 0, };  //to store zImage-delta magic keyword
2099                 ssize_t bytes_read;
2100                 fp = fopen(SS_PATCHFILE_SOURCE, "r");
2101                 bytes_read = fread(buf, 1, 13, fp);             //error check not required as any delta corruption will be caught in SS_UpdateDeltaIMG
2102                 if (bytes_read != 13)
2103                         LOGL(LOG_SSENGINE, "short read of \"%s\" (%ld bytes of %ld)\n", SS_PATCHFILE_SOURCE, (long)bytes_read, (long)13);
2104                 fclose(fp);
2105
2106                 if (strcmp(buf, SS_KERNEL_MAGIC) == 0)
2107                         ulResult = SS_UpdateDeltaKernel(ua_dataSS, ua_dataSS->write_data_to_blkdev);
2108                 else
2109                         ulResult = SS_UpdateDeltaIMG(ua_dataSS, ua_dataSS->write_data_to_blkdev);
2110         } else {
2111                 LOGE("Update type is INVALID - Exit \n");
2112                 ulResult = E_SS_FAILURE;
2113                 SS_SetUpgradeState(E_SS_BAD_PARAMS);
2114                 return E_SS_FAILURE;
2115         }
2116
2117         if (ulResult == S_SS_SUCCESS) {
2118                 if (ua_dataSS->ui_progress)
2119                         ua_dataSS->ui_progress(ua_dataSS, 100);
2120                 return ulResult;
2121         } else
2122                 return SS_GetUpgradeState();
2123 }