2 * upgrade-apply-deltafs
4 * Copyright (c) 2017 - 2022 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the License);
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
26 #include <sys/types.h>
27 #include <sys/reboot.h>
37 #include <hal/device/hal-board.h>
41 #include "fota_util.h"
42 #include "engine/SS_Common.h"
43 #include "engine/SS_UPI.h"
44 #include "engine/fota_common.h"
45 #include "engine/fota_tar.h"
46 #include "engine/ua_types.h"
49 #define SYSTEM_LOG_DIR "/opt/var/log"
50 #define TEMP_FOLDER "/tmp" // TODO
52 //char ua_slot_mode = 0;
53 int dm_verity_status = DM_VERITY_DISABLED;
55 // TODO: Consider changing all to PATH_MAX
56 static char fota_result[MAX_FILE_PATH];
57 static char fota_cause[MAX_FILE_PATH];
58 static char delta_folder[MAX_FOLDER_PATH];
59 static char delta_path[MAX_FILE_PATH];
60 static char log_folder[MAX_FOLDER_PATH];
61 static char result_folder[MAX_FOLDER_PATH];
62 static char temp_folder[MAX_FOLDER_PATH];
63 static char log_path[MAX_FILE_PATH];
64 static char mnt_point[MAX_FILE_PATH];
66 static ua_part_info_t s_part_info;
68 static ua_update_cfg_t s_update_cfg;
70 static ua_update_data_t s_update_data;
72 static tar_info s_tar_data;
74 static text_file_info s_text_files_info[NO_OF_TEXT_FILES];
76 static file_7z_info s_new_files_info;
78 typedef struct temp_opt{
84 static ua_delta_info_t s_delta_info;
86 unsigned int __log_level__ =
87 (LOG_DEBUG | LOG_FLASH | LOG_FILE | LOG_FUNCS | LOG_GUI | LOG_ENGINE | LOG_INFO);
88 FILE *__log_out_file__;
90 static void save_result(int result);
91 static void save_cause(int cause);
93 #define TMP_DIR "/tmp/upgrade"
94 #define PROGRESS_FILE TMP_DIR "/ro_progress"
96 #define HAL_PROGRESS_MIN 40
97 #define HAL_PROGRESS_MAX 80
99 void print_usage(const char *msg)
104 printf("print_usage: upgrade-apply-deltafs --archive delta_path --dest directory --archive-file label.img/\n"
105 "delta_path: filepath of delta (allowed file extensions: .tar, .tar.gz, .tgz)\n"
106 "directory: directory where partition to be upgraded is mounted\n"
107 "label.img: name of the directory inside of delta that is to be used during upgrade\n"
111 void print_error_code(int err)
113 char msg[]="upgrade-apply-deltafs error:";
115 case UPI_CONFIG_ERROR:
116 printf("%s config error.\n", msg);
118 case UPI_DELTA_PATH_ERROR:
119 printf("%s delta path error.\n", msg);
121 case UPI_DELTA_PATH_LENGTH_ERROR:
122 printf("%s delta path length error.\n", msg);
124 case UPI_VERSION_ERROR:
125 printf("%s version error.\n", msg);
127 case UPI_VERIFY_ERROR:
128 printf("%s verify error.\n", msg);
130 case UPI_UPDATE_ERROR:
131 printf("%s update error.\n", msg);
133 case UPI_INVALID_PARAM_ERROR:
134 printf("%s invalid parameter error.\n", msg);
136 case UPI_DELTACOUNT_ERROR:
137 printf("%s delta count error.\n", msg);
139 case UPI_PARTINFO_ERROR:
140 printf("%s partition information error.\n", msg);
143 printf("upgrade-apply-deltafs unable to determine error code: %d\n", err);
147 void fota_gui_update_progress(int percent)
154 ret = stat(TMP_DIR, &s);
156 // TMP_DIR exists but it is not directory
157 if (!S_ISDIR(s.st_mode))
160 goto update_progress;
161 } else if (errno == ENOENT) // TMP_DIR not exists
164 LOG("stat failed : %m\n");
169 ret = remove(TMP_DIR);
171 LOG("remove failed : %m\n");
176 ret = mkdir(TMP_DIR, 0755);
178 LOG("mkdir failed : %m\n");
183 fd = creat(PROGRESS_FILE, 0644);
185 LOG("creat failed : %m\n");
189 ret = dprintf(fd, "%d\n", percent);
190 if (close(fd) != 0) {
191 LOG("close failed : %m\n");
195 LOG("write failed (%d) : %m\n", ret);
199 LOG("Succeed to write\n");
202 static void set_upgrade_progress(int percent)
204 int relative_precent = HAL_PROGRESS_MIN + ((HAL_PROGRESS_MAX - HAL_PROGRESS_MIN) * percent)/100;
207 if (hal_device_board_set_upgrade_status(relative_precent) < 0) {
208 LOG("set_upgrade_status failed: %d\n", relative_precent);
213 LOG("set_upgrade_status success: %d\n", relative_precent);
216 /*-----------------------------------------------------------------------------
218 ----------------------------------------------------------------------------*/
219 // TODO - remove this mechanism, only makes log less readable
220 void fota_gui_progress(void * pbUserData, unsigned long uPercent)
224 ua_dataSS_t *ua_data = (ua_dataSS_t *)pbUserData;
225 ua_update_data_t *ua_update_data = ua_data->update_data;
227 LOGL(LOG_FUNCS|LOG_GUI, "%s: ++ uPercent(%lu%%), config->weight=%lu\n", __func__,
228 uPercent, (long unsigned int)ua_update_data->weight);
231 percent = ua_update_data->weight_offset + ua_update_data->weight;
233 percent = ua_update_data->weight_offset + (ua_update_data->weight * uPercent / 100);
235 set_upgrade_progress(percent);
237 * re-arrange progress percentage between scout & update
239 * 0 ~ 100 -> from ~ to
241 switch (ua_data->ua_operation) {
246 case UI_OP_SCOUT_UPDATE:
249 to = (dm_verity_status == DM_VERITY_ENABLED) ? 80 : 100;
257 percent = from + ((to - from) * percent / 100);
259 fota_gui_update_progress(percent); /* update progress bar and text */
261 LOGL(LOG_FUNCS|LOG_GUI, "-- uPercent=%lu, Print Percent(%d%%)\n", uPercent, percent);
264 /*-----------------------------------------------------------------------------
266 ----------------------------------------------------------------------------*/
267 int verify_Delta_FS()
270 ua_dataSS_t ua_dataSS;
271 ua_part_info_t *ua_part_info = &s_part_info;
272 ua_update_cfg_t *ua_update_cfg = &s_update_cfg;
273 ua_update_data_t *ua_update_data = &s_update_data;
274 ua_delta_info_t *ua_delta_info = &s_delta_info;
275 tar_info *ua_tar_data = &s_tar_data;
276 ua_dataSS.parti_info = ua_part_info;
277 ua_dataSS.update_cfg = ua_update_cfg;
278 ua_dataSS.update_data = ua_update_data;
279 ua_dataSS.update_delta = ua_delta_info;
280 ua_dataSS.ua_operation = UI_OP_SCOUT;
281 ua_dataSS.tar_data = ua_tar_data;
282 ua_dataSS.ui_progress = fota_gui_progress;
284 if (ua_update_data->ua_delta_path != NULL) {
285 LOG("Verifying %s \n", ua_dataSS.parti_info->ua_parti_name);
286 ret = SS_FSVerifyPartition(&ua_dataSS);
292 /*-----------------------------------------------------------------------------
294 ----------------------------------------------------------------------------*/
295 int update_Delta_FS(unsigned long ui32Operation)
298 ua_dataSS_t ua_dataSS;
299 ua_part_info_t *ua_part_info = &s_part_info;
300 ua_update_cfg_t *ua_update_cfg = &s_update_cfg;
301 ua_update_data_t *ua_update_data = &s_update_data;
302 ua_delta_info_t *ua_delta_info = &s_delta_info;
303 tar_info *ua_tar_data = &s_tar_data;
304 ua_dataSS.parti_info = ua_part_info;
305 ua_dataSS.update_cfg = ua_update_cfg;
306 ua_dataSS.update_data = ua_update_data;
307 ua_dataSS.update_delta = ua_delta_info;
308 ua_dataSS.ua_operation = ui32Operation;
309 ua_dataSS.tar_data = ua_tar_data;
310 ua_dataSS.ui_progress = fota_gui_progress;
312 if (ua_update_data->ua_delta_path != NULL)
313 ret = SS_FSUpdatemain(&ua_dataSS);
318 /*-----------------------------------------------------------------------------
320 ----------------------------------------------------------------------------*/
321 /* set data weight using data size minimum:1 total: 100 */
323 static void set_data_weight(unsigned int total_data_size)
325 LOG("%s entered, total_data_size=%u\n", __func__, total_data_size);
326 s_update_data.weight = 100;
327 LOG("%s leaved\n", __func__);
330 /*-----------------------------------------------------------------------------
331 set_data_weight_offset
332 ----------------------------------------------------------------------------*/
334 static void set_data_weight_offset(void)
336 LOG("%s entered\n", __func__);
337 s_update_data.weight_offset = 0; // not sure what it does, keep it like this for now
338 LOG("s_update_data.weight_offset=%u\n", s_update_data.weight_offset);
339 LOG("%s leaved\n", __func__);
342 /*-----------------------------------------------------------------------------
344 ----------------------------------------------------------------------------*/
346 static void get_time_stamp(void)
351 gettimeofday(&tv, NULL);
352 sec = (int) tv.tv_sec;
353 msec = (int) (tv.tv_usec / 1000);
354 snprintf(ts, sizeof(ts), "%06d.%03d", sec % 100000, msec);
357 /*-----------------------------------------------------------------------------
358 remove_cfg_file_files
359 ----------------------------------------------------------------------------*/
360 void remove_extracted_files(void)
362 for (int i = 0; i < NO_OF_TEXT_FILES; i++)
364 if (s_tar_data.text_files_info[i].size > 0) {
365 if (unlink(s_tar_data.text_files_info[i].extracted_name) < 0) {
366 LOGE("unlink error!\n");
372 /*-----------------------------------------------------------------------------
374 ----------------------------------------------------------------------------*/
379 unsigned long ui32Operation = UI_OP_SCOUT;
380 char * org_dir = getcwd(NULL, 0);
382 if ((ret = chdir(mnt_point)) < 0) {
386 if (tar_get_cfg_data(&s_tar_data) < 0) {
387 LOGE("Delta read error!\n");
388 ret = UPI_DELTACOUNT_ERROR;
391 if (s_tar_data.text_files_info[PATCHLIST_FILE].size <= 0) {
392 LOGE("Patchlist file not present in delta -> aborting!\n");
393 ret = UPI_DELTACOUNT_ERROR;
397 s_update_data.data_size = s_tar_data.uncompressed_folder_size;
398 LOGL(LOG_DEBUG, "s_update_data.data_size=%lu, ua_delta_path=%s, "
399 "ua_subject_name=%s\n",
400 (long unsigned int)s_update_data.data_size,
401 s_update_data.ua_delta_path,
402 s_part_info.ua_subject_name);
404 if (s_update_data.data_size <= 0) {
405 ret = UPI_DELTACOUNT_ERROR;
411 LOG(" set weight to draw progressive bar.....\n");
412 set_data_weight(s_update_data.data_size);
413 set_data_weight_offset();
415 LOG("s_part_info.ua_parti_name = %s ua_delta_path = %s ua_subject_name=%s\n",
416 s_part_info.ua_parti_name,
417 s_update_data.ua_delta_path,
418 s_part_info.ua_subject_name);
420 if (s_update_data.data_size > 0) {
422 LOG("[%s] Verify %s ..............................................................\n", ts,
423 s_part_info.ua_parti_name);
425 ret = verify_Delta_FS();
426 LOG("return form verify : %d\n", ret);
429 ret = UPI_VERIFY_ERROR;
430 LOG("%s verify fail\n", s_part_info.ua_parti_name);
436 LOG("[%s] Verify End ..............................................................\n", ts);
439 ui32Operation = UI_OP_SCOUT_UPDATE;
442 if (s_update_data.data_size > 0) {
444 LOG("[%s] Update %s ..............................................................\n", ts,
445 s_part_info.ua_parti_name);
447 ret = update_Delta_FS(ui32Operation);
448 LOG("return form update : %d\n", ret);
451 ret = UPI_UPDATE_ERROR;
452 LOG("%s update fail\n", s_part_info.ua_parti_name);
457 if ((ret = chdir(org_dir)) < 0) {
463 LOG("[%s] Update End ..............................................................\n", ts);
469 remove_extracted_files();
474 /*-----------------------------------------------------------------------------
476 ----------------------------------------------------------------------------*/
479 snprintf(log_path, sizeof(log_path), "%s", LOG_FILE_PATH);
481 __log_out_file__ = fopen(log_path, "w");
482 if (__log_out_file__ == NULL) {
483 perror("file open error\n");
488 LOG("===== log start [%s] =====\n", ts);
491 /*-----------------------------------------------------------------------------
493 ----------------------------------------------------------------------------*/
494 void log_deinit(void)
497 LOG("===== log end [%s] =====\n", ts);
499 if (__log_out_file__) {
500 fclose(__log_out_file__);
501 __log_out_file__ = NULL;
507 /*-----------------------------------------------------------------------------
509 ----------------------------------------------------------------------------*/
510 static void print_error_cause(int error)
513 case E_SS_FSBADDELTA:
514 LOG("Corrupted firmware update package, did not store correctly. Detected, for example, by mismatched CRCs between actual and expected.\n");
516 case E_SS_BAD_PARAMS:
517 LOG("Wrong Firmware Update Package delivered to device based on current device characteristics\n");
519 case E_SS_MALLOC_ERROR:
520 LOG("The update fails because there isn't sufficient memory to update the device.\n");
522 case E_SS_FSSRCBACKUPFAILED:
523 case E_SS_WRITE_ERROR:
524 case E_SS_FSFAILEDTOBACKUPPATCHINFO:
525 case E_SS_FSBADATTRIBUTES:
526 LOG("The update failed because writing data to the device was unsuccessful.\n");
528 case E_SS_FSSRCCURRUPTED:
529 case E_SS_FSSHA_MISMATCH:
530 case E_SS_FSFAILEDTOPARSEDELTACNT:
531 case E_SS_FSFAILEDTOOPENPATCHINFO:
532 case E_SS_FSFAILEDTOPARSEDELTAINFO:
533 LOG("The update failed because data was corrupted during update of device.\n");
536 LOG("another error\n");
542 <Corrupted Firmware Update Package>
543 Corrupted firmware update package, did not store correctly. Detected, for example, by mismatched CRCs between actual and expected.
544 E_RB_PKG_CORRUPTED(0x8000000D)
545 E_RB_PKG_NOT_AUTHORIZED(0x8000000E): not used
547 <Firmware Update Package-Device Mismatch>
548 Wrong Firmware Update Package delivered to device based on current device characteristics
549 E_RB_BAD_PARAMS(0x800000002)
550 E_RB_WRONG_UPI_VER(0x80000011):not used
551 E_RB_WRONG_UPI_UPDATE(0x80000012): not used
552 E_RB_UPDATE_SECTOR_SIG(0x80000013): not used
554 <Failed Firmware Update Package Validation>
555 Failure to positively validate digital signature of firmware update package
556 E_RB_NON_DP_FORMAT_NOT_SUPPORTED(0x8001001A)
557 E_RB_INVALID_DP_HEADER(0x80010025)
558 E_RB_INVALID_DP_WRONG_SIGNATURE(0x80010026)
559 E_RB_INVALID_DP(0x80010027)
561 <Firmware Update Package Not Acceptable>
562 Firmware Update Package is Not Acceptable
563 E_RB_PKG_TOO_SHORT(0x8000000B) not used
564 E_RB_PKG_TOO_LONG(0x8000000C) not used
565 E_RB_PKG_NOT_AUTHORIZED(0x8000000F)
567 <Firmware update fails due to device out of memory>
568 The update fails because there isn\A1\AFt sufficient memory to update the device.
569 E_RB_NOT_ENOUGH_RAM(0x8000001E)
572 /*-----------------------------------------------------------------------------
574 ----------------------------------------------------------------------------*/
575 void save_cause(int cause)
577 char return_char[20];
580 LOG("%s entered, 0x%x\n", __func__, cause);
582 print_error_cause(cause);
584 if ((result_fp = fopen(fota_cause, "w")) == NULL) {
585 LOG("cause file open fail\n");
589 snprintf(return_char, sizeof(return_char), "%x", cause);
590 fwrite(return_char, strlen(return_char), 1, result_fp);
593 LOG("%s leaved!\n", __func__);
596 /*-----------------------------------------------------------------------------
598 ----------------------------------------------------------------------------*/
599 void save_result(int result)
601 char return_char[20];
604 LOG("%s entered, result=0x%x\n", __func__, result);
606 if ((result_fp = fopen(fota_result, "w")) == NULL) {
607 LOG("result file open fail\n");
611 snprintf(return_char, sizeof(return_char), "%x", result);
612 fwrite(return_char, strlen(return_char), 1, result_fp);
615 LOG("%s leaved!\n", __func__);
620 /*-----------------------------------------------------------------------------
621 check_dm_verity_status
622 ----------------------------------------------------------------------------*/
623 int check_dm_verity_status(void)
627 ret = access("/usr/bin/verityctl", F_OK);
629 if (errno == ENOENT) {
630 LOG("dm-verity status : disabled\n");
631 dm_verity_status = DM_VERITY_DISABLED;
634 LOG("access failed with errno: %d\n", errno);
639 LOG("dm-verity status : enabled\n");
640 dm_verity_status = DM_VERITY_ENABLED;
644 /*-----------------------------------------------------------------------------
646 ----------------------------------------------------------------------------*/
647 int set_delta_folder(void)
649 char *pos = strrchr(delta_path, '/');
651 snprintf(delta_folder, MAX_FOLDER_PATH, ".", delta_path); // if no "/" in delta path, assume current directory as delta folder
654 if ((pos - delta_path + 1) == strlen(delta_path)) {
655 print_usage("Invalid delta path");
658 snprintf(delta_folder, (pos - delta_path) + 1, "%s", delta_path);
661 /*-----------------------------------------------------------------------------
663 ----------------------------------------------------------------------------*/
664 void set_tar_info(TAR *tar)
666 s_tar_data.subject_name = strdup(s_part_info.ua_subject_name);
667 s_tar_data.tar = tar;
668 s_tar_data.subject_offset = 0;
669 s_tar_data.uncompressed_folder_size = 0;
671 s_new_files_info.offset = 0;
672 snprintf(s_new_files_info.item_name, MAX_FILE_PATH, "%s%s", s_tar_data.subject_name, SS_NEW_COMPRESSED_FILE);
673 snprintf(s_new_files_info.extracted_name, MAX_FILE_PATH, "%s/%s", s_update_data.ua_delta_folder, SS_NEW_COMPRESSED_FILE);
675 s_text_files_info[PATCHLIST_FILE].size = 0;
676 s_text_files_info[ATTR_FILE].size = 0;
678 snprintf(s_text_files_info[PATCHLIST_FILE].item_name, MAX_FILE_PATH, "%s%s%s", s_tar_data.subject_name, s_part_info.ua_parti_name, SS_PATCHLISTFORMAT);
679 snprintf(s_text_files_info[PATCHLIST_FILE].extracted_name, MAX_FILE_PATH, "%s/%s%s", s_update_data.ua_delta_folder, s_part_info.ua_parti_name, SS_PATCHLISTFORMAT);
681 snprintf(s_text_files_info[ATTR_FILE].item_name, MAX_FILE_PATH, "%s%s%s", s_tar_data.subject_name, s_part_info.ua_parti_name, SS_PATCH_ATTR_FORMAT);
682 snprintf(s_text_files_info[ATTR_FILE].extracted_name, MAX_FILE_PATH, "%s/%s%s", s_update_data.ua_delta_folder, s_part_info.ua_parti_name, SS_PATCH_ATTR_FORMAT);
684 s_tar_data.text_files_info[PATCHLIST_FILE] = s_text_files_info[PATCHLIST_FILE];
685 s_tar_data.text_files_info[ATTR_FILE] = s_text_files_info[ATTR_FILE];
686 s_tar_data.new_files_info = s_new_files_info;
688 /*-----------------------------------------------------------------------------
690 ----------------------------------------------------------------------------*/
691 int arg_parse(int argc, char ** argv, temp_opt *my_opt)
694 print_usage("Invalid parameter count");
697 char * archive = NULL;
698 char * archive_file = NULL;
700 const struct option long_options[] = {
701 {"archive", required_argument, NULL, 0 },
702 {"dest", required_argument, NULL, 1 },
703 {"archive-file", required_argument, NULL, 2 },
707 int option = getopt_long(argc, argv, "", long_options, NULL);
712 if (archive != NULL) {
713 print_usage("Parameters repeated");
720 print_usage("Parameters repeated");
726 if (archive_file != NULL) {
727 print_usage("Parameters repeated");
730 archive_file = optarg;
733 print_usage("Invalid parameters");
737 if (archive_file == NULL || dest == NULL || archive == NULL) {
738 print_usage("Wrong parameters");
741 (*my_opt).archive = archive;
742 (*my_opt).dest = dest;
743 (*my_opt).archive_file = archive_file;
748 /*-----------------------------------------------------------------------------
750 ----------------------------------------------------------------------------*/
751 int main(int argc, char **argv)
753 char ver_str[MAX_PATH];
761 if (arg_parse(argc, argv, &my_opt) < 0) {
762 ret = UPI_INVALID_PARAM_ERROR;
766 #if defined(FEATURE_SUPPORT_CAPABILITY)
767 SS_set_feature_support_capability(1);
770 snprintf(delta_path, sizeof(delta_folder)-1, "%s", my_opt.archive);
771 if (set_delta_folder() < 0) {
772 ret = UPI_INVALID_PARAM_ERROR;
775 s_update_data.ua_delta_folder = strdup(delta_folder);
776 s_update_data.ua_delta_path = strdup(delta_path);
777 snprintf(mnt_point, sizeof(mnt_point)-1, "%s", my_opt.dest);
778 snprintf(temp_folder, sizeof(temp_folder)-1, "%s", TEMP_FOLDER);
779 snprintf(log_folder, sizeof(log_folder)-1, "%s", SYSTEM_LOG_DIR);
780 snprintf(fota_result, sizeof(fota_result), "%s/%s", result_folder, "result");
783 if (check_dm_verity_status() < 0) { // to be removed
784 LOG("check_dm_verity_status fail\n");
785 ret = UPI_CONFIG_ERROR;
789 dot_pos = strchr(my_opt.archive_file, '.');
790 len = (dot_pos - my_opt.archive_file);
791 s_part_info.ua_parti_name = (char*)malloc(sizeof(char) * (len + 1));
792 strncpy(s_part_info.ua_parti_name, my_opt.archive_file, len);
793 s_part_info.ua_parti_name[len] = '\0';
795 s_part_info.ua_subject_name = my_opt.archive_file;
796 s_update_cfg.source_img_size = 0; // TODO lets see if 0 works
798 if (tar_get_tartype(s_update_data.ua_delta_path, &type) < 0) {
799 ret = UPI_CONFIG_ERROR;
803 if (tar_init_with_type(&tar, s_update_data.ua_delta_path, type) < 0) {
804 ret = UPI_CONFIG_ERROR;
812 LOG("<<<<<<<<<<< log_init >>>>>>>>>>>>\n");
814 /* UPI version check */
815 if (S_SS_SUCCESS == SS_GetUPIVersion((unsigned char*)ver_str)) {
816 LOG("<<<<<<<<< TOTA Update Agent %s >>>>>>>>>>>>\n", ver_str);
818 LOG("[SS_GetUPIVersion fail] \n");
819 ret = UPI_VERSION_ERROR;
822 /* Main Update Routine : Scout & Update */
824 LOG("[update_all ret=%d]\n", ret);
827 LOG("Result=%d\n", ret);
830 print_error_code(ret);
832 /* Before initialize fota path */
833 case UPI_INVALID_PARAM_ERROR:
834 case UPI_DELTA_PATH_ERROR:
835 case UPI_CONFIG_ERROR:
836 case UPI_PARTINFO_ERROR:
837 case UPI_DELTA_PATH_LENGTH_ERROR:
841 /* After initialize fota path */
842 case UPI_VERSION_ERROR:
843 case UPI_DELTACOUNT_ERROR:
844 case UPI_VERIFY_ERROR:
845 case UPI_UPDATE_ERROR:
848 tar_close(s_tar_data.tar);
853 /* Preserve log file for debugging */
855 tar_close(s_tar_data.tar);
859 LOG("!!! Not expected ret (= %d)\n", ret);
862 if(s_part_info.ua_parti_name) free(s_part_info.ua_parti_name);
863 if(s_part_info.ua_subject_name) free(s_part_info.ua_subject_name);