--- /dev/null
+/*
+
+Copyright © 2022 Samsung Electronics Co., Ltd.. All rights reserved.
+
+Permission is hereby granted, without written agreement and without license or royalty fees, to use, copy, modify, and distribute
+this software and its documentation for any purpose, provided that the above copyright notice and the following two paragraphs appear
+in all copies of this software.
+
+IN NO EVENT SHALL SAMSUNG ELECTRONICS CO., LTD. BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF SAMSUNG ELECTRONICS CO., LTD. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+SAMSUNG ELECTRONICS CO., LTD. SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND SAMSUNG ELECTRONICS CO., LTD. HAS NO OBLIGATION TO PROVIDE
+MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+
+*/
+
+
+
+#include <stdio.h>
+#include <getopt.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <system_info.h>
+
+#include "delta-verifier.h"
+
+static void print_usage(const char* msg)
+{
+ if (msg)
+ printf("%s\n", msg);
+
+ printf("\n\tprint_usage: --update_info_path filepath\n"
+ "\t\tfilepath -> filepath to update_info.ini file extracted from delta\n");
+}
+
+static int get_update_info_path(int argc, char** argv, char** dest)
+{
+ *dest = NULL;
+ if (argc != 3) {
+ print_usage("Invalid parameter count");
+ return -1;
+ }
+ const struct option long_options[] = {
+ {"update_info_path", required_argument, NULL, 0},
+ {0}
+ };
+ while (1) {
+ int option = getopt_long(argc, argv, "", long_options, NULL);
+ if (option < 0)
+ break;
+ switch (option) {
+ case 0:
+ if (*dest != NULL) {
+ print_usage("Parameters repeated");
+ free(*dest);
+ return -1;
+ }
+ *dest = strdup(optarg);
+ if (*dest == NULL) {
+ ERR_ERRNO("strdup()");
+ return -1;
+ }
+ break;
+ default:
+ print_usage("Invalid parameters");
+ if (*dest)
+ free(*dest);
+ return -1;
+ }
+ }
+ if (*dest == NULL) {
+ print_usage("Wrong parameters");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int write_variable_data_with_format(FILE* write_file, const char* var_name, char* var_value)
+{
+ char tmp[MAX_STRING];
+ snprintf(tmp, MAX_STRING, "%s=%s\n", var_name, var_value);
+ if (fwrite(tmp, 1, strlen(tmp), write_file) != strlen(tmp)) {
+ ERR("fwrite() not successful");
+ return -1;
+ }
+ return 0;
+}
+
+static int write_info_from_api(FILE* write_file)
+{
+ const char* var_names[NO_OF_API_VARIABLES] = {
+ "model_name",
+ "manufacturer",
+ "device_type"
+ };
+
+ for (int i = 0; i < NO_OF_API_VARIABLES; i++) {
+ char* info;
+ char tmp_name[MAX_STRING];
+ snprintf(tmp_name , MAX_STRING, "%s/%s", API_SYSTRM_PREFIX, var_names[i]);
+ if (system_info_get_platform_string(tmp_name, &info) < 0) {
+ ERR("system_info_get_platform_string() fail.");
+ return -1;
+ }
+
+ if (write_variable_data_with_format(write_file, var_names[i], info)) {
+ free(info);
+ return -1;
+ }
+
+ free(info);
+ }
+ return 0;
+}
+
+static size_t get_file_size(FILE* file)
+{
+ fseek(file, 0, SEEK_END);
+ size_t size = ftell(file);
+ fseek(file, 0 , SEEK_SET);
+
+ return size;
+}
+
+static int write_info_from_file(FILE* read_file, FILE* write_file)
+{
+ const char* var_names[NO_OF_CONFIG_VARIABLES] = {
+ "RELEASE_NAME",
+ "ARCH",
+ "DATE"
+ };
+
+ char full_var_names[NO_OF_CONFIG_VARIABLES][MAX_STRING];
+ for (int i = 0; i < NO_OF_CONFIG_VARIABLES; i++) {
+ snprintf(full_var_names[i], MAX_STRING, "%s%s", TIZEN_BUILD_PREFIX, var_names[i]);
+ }
+
+ size_t read_size = get_file_size(read_file);
+ char* read_buf = (char*)malloc(read_size);
+ if (read_buf == NULL) {
+ ERR_ERRNO("malloc()");
+ return -1;
+ }
+
+ if (fread(read_buf, 1, read_size, read_file) != read_size) {
+ ERR("fread() not successful");
+ free(read_buf);
+ return -1;
+ }
+
+ const char* separators = " =\n\"";
+ char* read_word = strtok(read_buf, separators);
+ int loop_iter = 0;
+ int processed = 0;
+
+ while(read_word != NULL) {
+ if (processed == NO_OF_CONFIG_VARIABLES)
+ break;
+
+ loop_iter++;
+ if (loop_iter % 2 == 1) {
+ for (int i = 0; i < NO_OF_API_VARIABLES; i++) {
+ if (strcmp(full_var_names[i], read_word) == 0)
+ {
+ processed++;
+ loop_iter++;
+ read_word = strtok(NULL, separators);
+
+ char lowercase_name[MAX_STRING];
+ strcpy(lowercase_name, full_var_names[i]);
+ for (int j = 0; j < strlen(lowercase_name); j++)
+ lowercase_name[j] = tolower(lowercase_name[j]);
+
+ char to_write[MAX_STRING];
+ if (snprintf(to_write, MAX_STRING, "%s=%s\n", lowercase_name, read_word) < 0) {
+ ERR_ERRNO("snprintf()");
+ return -1;
+ }
+
+ if (fwrite(to_write, 1, strlen(to_write), write_file) != strlen(to_write)) {
+ free(read_buf);
+ return -1;
+ }
+ break;
+ }
+ }
+ }
+ read_word = strtok(NULL, separators);
+ }
+
+ free(read_buf);
+ return 0;
+}
+
+int compare_info_files(FILE* update_info_file, FILE* device_info_file)
+{
+ size_t update_info_size, device_info_size;
+ update_info_size = get_file_size(update_info_file);
+ device_info_size = get_file_size(device_info_file);
+
+ if (device_info_size != update_info_size)
+ return 1;
+
+ int ret = 0;
+ char* device_read_buf = NULL;
+ char* update_read_buf = NULL;
+
+ update_read_buf = (char*)malloc(update_info_size + 1);
+ if (update_read_buf == NULL) {
+ ERR_ERRNO("malloc()");
+ ret = -1;
+ goto cleanup;
+ }
+
+ device_read_buf = (char*)malloc(device_info_size + 1);
+ if (device_read_buf == NULL) {
+ ERR_ERRNO("malloc()");
+ ret = -1;
+ goto cleanup;
+ }
+
+ if (fread(update_read_buf, 1, update_info_size, update_info_file) != update_info_size) {
+ ERR("fread() not successful");
+ ret = -1;
+ goto cleanup;
+ }
+ update_read_buf[update_info_size] = '\0';
+
+ if (fread(device_read_buf, 1, device_info_size, device_info_file) != device_info_size) {
+ ERR("fread() not successful");
+ ret = -1;
+ goto cleanup;
+ }
+ device_read_buf[device_info_size] = '\0';
+
+ if (strcmp(update_read_buf, device_read_buf) != 0) {
+ ret = 1;
+ }
+
+cleanup:
+ if (update_read_buf)
+ free(update_read_buf);
+ if (device_read_buf)
+ free(device_read_buf);
+ return ret;
+}
+
+int verify_delta_device_compatability(char* update_info_file_path)
+{
+ int ret = 0;
+ FILE* update_original = NULL, * tizen_build_conf = NULL, * device_info = NULL;
+
+ if ((update_original = fopen(update_info_file_path, "r")) == NULL) {
+ ERR_ERRNO("fopen()");
+ ret = -1;
+ goto cleanup;
+ }
+
+ if ((device_info = fopen(DEVICE_INFO_PATH, "r")) == NULL) {
+ if ((device_info = fopen(DEVICE_INFO_PATH, "w+")) == NULL) {
+ ERR_ERRNO("fopen()");
+ ret = -1;
+ goto cleanup;
+ }
+
+ if ((tizen_build_conf = fopen(TIZEN_BUILD_CONFIG_PATH, "r")) == NULL) {
+ ERR_ERRNO("fopen()");
+ ret = -1;
+ goto cleanup;
+ }
+
+ if (write_info_from_api(device_info) < 0) {
+ ERR("write_info_from_api()");
+ ret = -1;
+ goto cleanup;
+ }
+
+ if (write_info_from_file(tizen_build_conf, device_info) < 0) {
+ ERR("write_info_from_api()");
+ ret = -1;
+ goto cleanup;
+ }
+ }
+
+ int comparison_result;
+ if ((comparison_result = compare_info_files(update_original, device_info)) < 0) {
+ ERR("compare_info_file()");
+ ret = -1;
+ goto cleanup;
+ } else if (comparison_result == 0) {
+ // delete device info only if successful
+ fclose(device_info);
+ device_info = NULL;
+ unlink(DEVICE_INFO_PATH);
+ ret = 0;
+ } else {
+ ret = 1;
+ }
+
+cleanup:
+ if (update_original != NULL)
+ fclose(update_original);
+
+ if (tizen_build_conf != NULL)
+ fclose(tizen_build_conf);
+
+ if (device_info != NULL)
+ fclose(device_info);
+
+ return ret;
+}
+
+int main(int argc, char** argv)
+{
+ char* update_info_path;
+ if (get_update_info_path(argc, argv, &update_info_path) < 0) {
+ ERR("Parameter verification failed.");
+ return -1;
+ }
+
+ int ret = verify_delta_device_compatability(update_info_path);
+
+ free(update_info_path);
+
+ if (ret < 0)
+ ERR("Delta verification failed due to an unexpected error.");
+ else if (ret == 0)
+ printf("Delta is compatible with this device\n");
+ else
+ printf("Delta is not compatible with this device\n");
+
+ return ret;
+}
\ No newline at end of file
--- /dev/null
+/*
+
+Copyright © 2022 Samsung Electronics Co., Ltd.. All rights reserved.
+
+Permission is hereby granted, without written agreement and without license or royalty fees, to use, copy, modify, and distribute
+this software and its documentation for any purpose, provided that the above copyright notice and the following two paragraphs appear
+in all copies of this software.
+
+IN NO EVENT SHALL SAMSUNG ELECTRONICS CO., LTD. BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF SAMSUNG ELECTRONICS CO., LTD. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+SAMSUNG ELECTRONICS CO., LTD. SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND SAMSUNG ELECTRONICS CO., LTD. HAS NO OBLIGATION TO PROVIDE
+MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+
+*/
+
+
+
+#pragma once
+
+#ifdef DEBUG
+#define ERR_ERRNO(source) (perror(source),\
+ fprintf(stderr,"%s:%d\n",__FILE__,__LINE__))
+#define ERR(source) fprintf(stderr,"[%s:%d] %s\n",__FILE__,__LINE__, source)
+#else
+#define ERR_ERRNO(source) do {} while(0)
+#define ERR(source) do {} while(0)
+#endif
+
+#define TIZEN_BUILD_CONFIG_PATH "/etc/tizen-build.conf"
+#define TMP_DIR "/tmp/"
+#define DEVICE_INFO_PATH TMP_DIR "device-info.ini"
+
+#define API_TIZEN_PREFIX "http://tizen.org"
+#define API_SYSTRM_PREFIX API_TIZEN_PREFIX "/system"
+#define TIZEN_BUILD_PREFIX "TZ_BUILD_"
+
+#define NO_OF_API_VARIABLES 3
+#define NO_OF_CONFIG_VARIABLES 3
+#define MAX_STRING 100
\ No newline at end of file