merge 2.4 & fix errors for delta generation feature 96/51896/1
authorjongmyeongko <jongmyeong.ko@samsung.com>
Tue, 17 Nov 2015 02:17:02 +0000 (11:17 +0900)
committerjongmyeongko <jongmyeong.ko@samsung.com>
Tue, 17 Nov 2015 05:59:32 +0000 (14:59 +0900)
Change-Id: I55636b07fcaa4d00408f2415dbdd01244ed0c0ac
Signed-off-by: jongmyeongko <jongmyeong.ko@samsung.com>
12 files changed:
CMakeLists.txt
data/pkgmgr-create-delta.sh.in [new file with mode: 0644]
data/pkgmgr-unzip-tpk.sh.in [new file with mode: 0644]
data/usage_guide_for_create_delta_package.txt [new file with mode: 0644]
packaging/pkgmgr-tool.spec
src/delta.c [new file with mode: 0644]
src/delta.h [new file with mode: 0644]
src/pkg_clearcache.c
src/pkg_cmd.c
src/pkg_getsize.c
src/pkg_info.c
src/pkg_initdb.c

index 18b6ccf92796336c53d9d6fc3b7f758ce3d8a834..2f902ad7332fe19b6ace70fe408e766da7455d33 100644 (file)
@@ -42,7 +42,7 @@ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIE")
 SET(CMAKE_C_FLAGS_DEBUG "-O0 -g -fPIE")
 SET(CMAKE_C_FLAGS_RELEASE "-O2 -fPIE")
 
-ADD_EXECUTABLE(pkgcmd src/pkg_cmd.c)
+ADD_EXECUTABLE(pkgcmd src/pkg_cmd.c src/delta.c)
 TARGET_LINK_LIBRARIES(pkgcmd pkgmgr-client ${pkgs_test_LDFLAGS})
 INSTALL(TARGETS pkgcmd DESTINATION bin)
 
@@ -77,3 +77,7 @@ INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/data/mime.tpk.xml DESTINATION /usr/sha
 
 CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/data/pkgmgr.patch.sh.in pkgmgr.patch.sh @ONLY)
 INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/pkgmgr.patch.sh DESTINATION ${SYSCONF_INSTALL_DIR}/opt/upgrade/)
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/data/pkgmgr-unzip-tpk.sh.in pkgmgr-unzip-tpk.sh @ONLY)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/pkgmgr-unzip-tpk.sh DESTINATION ${SYSCONF_INSTALL_DIR}/package-manager/)
+CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/data/pkgmgr-create-delta.sh.in pkgmgr-create-delta.sh @ONLY)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/pkgmgr-create-delta.sh DESTINATION ${SYSCONF_INSTALL_DIR}/package-manager/)
diff --git a/data/pkgmgr-create-delta.sh.in b/data/pkgmgr-create-delta.sh.in
new file mode 100644 (file)
index 0000000..747ddc0
--- /dev/null
@@ -0,0 +1,270 @@
+#!/bin/bash
+usage()
+{
+    cat <<EOF
+usage:
+    $1
+       -a|--old_tpk=<old_tpk>
+       -b|--new_tpk=<new_tpk>
+       -p|--delta_tpk=<delta_tpk>
+       [-o|--option=<option>]
+       [-h|--help]
+Mandatory args:
+ -a|--old_tpk          full/absolute delta_tpk of old_tpk
+ -b|--new_tpk          full/absolute delta_tpk of new_tpk
+ -p|--delta_tpk                delta_tpk for delta dir
+Optional args:
+ -h,--help                     print this help
+EOF
+  return 0
+}
+
+options=$(getopt -o hp:a:b:p: -l help,old_tpk:,new_tpk:,delta_tpk: -- "$@")
+if [ $? -ne 0 ]; then
+    usage $(basename $0)
+    exit 1
+fi
+eval set -- "$options"
+
+while true
+do
+    case "$1" in
+        -h|--help)             usage $0 && exit 0;;
+        -a|--old_tpk)  old_tpk=$2; shift 2;;
+        -b|--new_tpk)  new_tpk=$2; shift 2;;
+        -p|--delta_tpk)        delta_tpk=$2; shift 2;;
+        --)             shift 1; break ;;
+        *)              break ;;
+    esac
+done
+
+if [ -z "$old_tpk" ]; then
+    echo "'old_tpk' parameter is required"
+    exit 1
+fi
+
+if [ -z "$new_tpk" ]; then
+    echo "'new_tpk' parameter is required"
+    exit 1
+fi
+
+temp_delta_repo="/opt/usr/temp_delta/"
+outpath="_FILES"
+temp_delta_dir="tmp"
+XDELTA="xdelta3"
+diff_file="/opt/usr/temp_delta/difffile.txt"
+
+cleanup()
+{
+       `rm -rf $temp_delta_repo`
+}
+
+which()
+{
+       local aflag sflag ES a opt
+
+       OPTIND=1
+       while builtin getopts as opt ; do
+               case "$opt" in
+               a)      aflag=-a ;;
+               s)      sflag=1 ;;
+               ?)      echo "which: usage: which [-as] command [command ...]" >&2
+                       exit 2 ;;
+               esac
+       done
+
+       (( $OPTIND > 1 )) && shift $(( $OPTIND - 1 ))
+
+       # without command arguments, exit with status 1
+       ES=1
+
+       # exit status is 0 if all commands are found, 1 if any are not found
+       for command; do
+               # if $command is a function, make sure we add -a so type
+               # will look in $PATH after finding the function
+               a=$aflag
+               case "$(builtin type -t $command)" in
+               "function")     a=-a;;
+               esac
+
+               if [ -n "$sflag" ]; then
+                       builtin type -p $a $command >/dev/null 2>&1
+               else
+                       builtin type -p $a $command
+               fi
+               ES=$?
+       done
+
+       return $ES
+}
+
+old_tpk_unzip_path=$temp_delta_repo`basename $old_tpk`$outpath
+new_tpk_unzip_path=$temp_delta_repo`basename $new_tpk`$outpath
+sample_delta=$temp_delta_repo$temp_delta_dir
+
+while read line
+       do
+               if [[ "$line" =~ "differ" ]]; then
+                       if ! which $XDELTA; then
+                               echo "FAIL: $XDELTA is not installed!" >&2
+                               cleanup
+                               exit 1
+                       else
+                               break
+                       fi
+               fi
+done < $diff_file
+
+#create new delta directory
+if ! mkdir $sample_delta; then
+    echo "FAIL: mkdir !" >&2
+    cleanup
+    exit 1
+fi
+
+#create separate temporary xmls for <modified>, <added>, <removed> which will be merged to one delta_info.xml
+`touch $sample_delta/modified.xml`
+`echo "<modify-files>" >> $sample_delta/modified.xml`
+
+`touch $sample_delta/added.xml`
+`echo "<add-files>" >> $sample_delta/added.xml`
+
+`touch $sample_delta/removed.xml`
+`echo "<remove-files>" >> $sample_delta/removed.xml`
+
+`touch $sample_delta/delta_info.xml`
+`echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" >> $sample_delta/delta_info.xml`
+`echo "<delta xmlns=\"http://tizen.org/ns/delta\">" >> $sample_delta/delta_info.xml`
+
+while read line
+       do
+       if [[ "$line" =~ "differ" ]]; then
+               count=0
+               for word in $line
+                       do
+                       count=$((count+1));
+                       #echo $word
+                       if [ $count -eq 2 ]; then
+                               file1=$word;
+                               #echo "file1 delta_tpk "$file1
+                       elif [ $count -eq 4 ]; then
+                               file2=$word;
+                               #echo "file2 delta_tpk "$file2
+                       fi
+                       done
+                       parent_path=${file1##*$old_tpk_unzip_path}
+                       filepath=`basename $parent_path`
+                       dirpath=`dirname $parent_path`
+                       #echo "dirpath "$dirpath
+                       #echo "filepath "$filepath
+                       if [[ "$line" =~ "tizen-manifest.xml"  || "$line" =~ "signature1.xml" || "$line" =~ "author-signature.xml" ]] ; then
+                               if ! mkdir -p $sample_delta$dirpath; then
+                                       echo "FAIL: mkdir failed !" >&2
+                                       cleanup
+                                       exit 1
+                               fi
+                               if ! cp -r $new_tpk_unzip_path/$dirpath/$filepath $sample_delta/$dirpath/$filepath; then
+                                       echo "FAIL: cp failed !" >&2
+                                       cleanup
+                                       exit 1
+                               fi
+                       else
+                               if ! mkdir -p $sample_delta$dirpath; then
+                                       echo "FAIL: mkdir failed!" >&2
+                                       cleanup
+                                       exit 1
+                               fi
+                               if ! xdelta3 -e -s $file1 $file2 $sample_delta$dirpath/$filepath; then
+                                       echo "FAIL: xdelta3 failed!" >&2
+                                       cleanup
+                                       exit 1
+                               fi
+                       fi
+
+                       dirpath=${dirpath:1:${#dirpath}}
+                       if [ ${#dirpath} -gt 1 ];then
+                               dirpath="$dirpath/"
+                       fi
+                       if [[ "$line" =~ "tizen-manifest.xml"  || "$line" =~ "signature1.xml" || "$line" =~ "author-signature.xml" ]] ; then
+                               `echo "<file name=\"$dirpath$filepath\" />" >> $sample_delta/added.xml`
+                       else
+                               `echo "<file name=\"$dirpath$filepath\" />" >> $sample_delta/modified.xml`
+                       fi
+
+       elif [[ "$line" =~ "$old_tpk_unzip_path" ]]; then
+               parent_path=${line##*$old_tpk_unzip_path}
+               #echo "removed " $parent_path
+               string_to_replace_with="/"
+               result_string="${parent_path/: /$string_to_replace_with}"
+               #echo $result_string
+               dirpath=`dirname $result_string`
+               filepath=`basename $result_string`
+               #echo "dirpath "$dirpath
+               #echo "filepath "$filepath
+
+               dirpath=${dirpath:1:${#dirpath}}
+               if [ ${#dirpath} -gt 1 ];then
+                       dirpath="$dirpath/"
+               fi
+               `echo "<file name=\"$dirpath$filepath\" />" >> $sample_delta/removed.xml`
+       elif [[ "$line" =~ "$new_tpk_unzip_path" ]]; then
+               parent_path=${line##*$new_tpk_unzip_path}
+               #echo "added " $parent_path
+               string_to_replace_with="/"
+               result_string="${parent_path/: /$string_to_replace_with}"
+               #echo $result_string
+               dirpath=`dirname $result_string`
+               filepath=`basename $result_string`
+               #echo "dirpath "$dirpath
+               #echo "filepath "$filepath
+               if ! mkdir -p $sample_delta$dirpath; then
+                       echo "FAIL: mkdir failed!" >&2
+                       cleanup
+                       exit 1
+               fi
+               if ! cp -r $new_tpk_unzip_path/$dirpath/$filepath $sample_delta/$dirpath/$filepath; then
+                       echo "FAIL: cp failed!" >&2
+                       cleanup
+                       exit 1
+               fi
+               dirpath=${dirpath:1:${#dirpath}}
+               if [ ${#dirpath} -gt 1 ];then
+                       dirpath="$dirpath/"
+               fi
+               `echo "<file name=\"$dirpath$filepath\" />" >> $sample_delta/added.xml`
+
+       fi
+       #echo -e "$line\n";
+done < $diff_file
+
+#close tags
+`echo "</modify-files>" >> $sample_delta/modified.xml`
+`echo "</remove-files>" >> $sample_delta/removed.xml`
+`echo "</add-files>" >> $sample_delta/added.xml`
+
+#merge
+if ! cat $sample_delta/modified.xml $sample_delta/removed.xml $sample_delta/added.xml >> $sample_delta/delta_info.xml; then
+       echo "FAIL: merge failed" >&2
+       cleanup
+       exit 1
+fi
+#close tag metadata.xml
+`echo "</delta>" >> $sample_delta/delta_info.xml`
+#remove temporary xmls
+`rm $sample_delta/modified.xml $sample_delta/removed.xml $sample_delta/added.xml `
+`chmod -R +x $sample_delta`
+cd $sample_delta
+dirpath=`dirname $delta_tpk`
+#echo $dirpath
+filepath=`basename $delta_tpk`
+#echo $filepath
+`echo zip -r $filepath.zip *`
+if ! mv $filepath.zip $dirpath/$filepath.delta; then
+       echo "FAIL: mv failed" >&2
+       cleanup
+       exit 1
+fi
+`chmod -R +x $dirpath/$filepath.delta`
+cd ..
+
+cleanup
diff --git a/data/pkgmgr-unzip-tpk.sh.in b/data/pkgmgr-unzip-tpk.sh.in
new file mode 100644 (file)
index 0000000..464205a
--- /dev/null
@@ -0,0 +1,78 @@
+#!/bin/bash
+usage()
+{
+    cat <<EOF
+usage:
+    $1
+       -a|--old_tpk=<old_tpk>
+       -b|--new_tpk=<new_tpk>
+       -p|--delta_tpk=<delta_tpk>
+               [-o|--option=<option>]
+               [-h|--help]
+Mandatory args:
+ -a|--old_tpk         full/absolute delta_tpk of old_tpk
+ -b|--new_tpk         full/absolute delta_tpk of new_tpk
+ -p|--delta_tpk                        delta_tpk for delta dir
+Optional args:
+  -h,--help         print this help
+EOF
+    return 0
+}
+
+options=$(getopt -o hp:a:b:p: -l help,old_tpk:,new_tpk:,delta_tpk: -- "$@")
+if [ $? -ne 0 ]; then
+    usage $(basename $0)
+    exit 1
+fi
+eval set -- "$options"
+
+while true
+do
+    case "$1" in
+        -h|--help)     usage $0 && exit 0;;
+        -a|--old_tpk)  old_tpk=$2; shift 2;;
+        -b|--new_tpk)  new_tpk=$2; shift 2;;
+        -p|--delta_tpk)        delta_tpk=$2; shift 2;;
+        --)             shift 1; break ;;
+        *)              break ;;
+    esac
+done
+
+if [ -z "$old_tpk" ]; then
+    echo "'old_tpk' parameter is required"
+    exit 1
+fi
+
+if [ -z "$new_tpk" ]; then
+    echo "'new_tpk' parameter is required"
+    exit 1
+fi
+
+temp_delta_repo="/opt/usr/temp_delta/"
+outpath="_FILES"
+
+cleanup()
+{
+       `rm -rf $temp_delta_repo`
+}
+
+cleanup
+
+if ! mkdir -p $temp_delta_repo; then
+       echo "FAIL: mkdir failed !" >&2
+       exit 1
+fi
+
+old_tpk_unzip_path=$temp_delta_repo`basename $old_tpk`$outpath
+new_tpk_unzip_path=$temp_delta_repo`basename $new_tpk`$outpath
+
+#unzip to .tpk_FILES
+if ! unzip -q $old_tpk -d $old_tpk_unzip_path; then
+       echo "FAIL: unzip $old_tpk failed!" >&2
+       exit 1
+fi
+if ! unzip -q $new_tpk -d $new_tpk_unzip_path; then
+       echo "FAIL: unzip $new_tpk failed!" >&2
+       cleanup
+       exit 1
+fi
diff --git a/data/usage_guide_for_create_delta_package.txt b/data/usage_guide_for_create_delta_package.txt
new file mode 100644 (file)
index 0000000..3caac61
--- /dev/null
@@ -0,0 +1,31 @@
+About the tool
+
+#This tool creates delta package manually.
+#unzips the tpk files whose delta has to be created
+#compares the directory tpk1 with tpk2.
+#the differences are stored in a file /tmp/difffile.txt (removed after use)
+#The difffile.txt file contains information about the files modified,removed,added.
+#The difffile.txt is parsed and used to create delta package.
+#a delta_info.xml is constructed, which shows list of files(with path) that were added, modified or removed.
+
+USAGE
+pkgcmd -X <old version> -Y <new version> -Z [output file]
+
+  old version-->is the tpk for old version
+  new version-->is the tpk for new version
+  output file-->the ouput delta package
+
+Note:
+#first two parameters are compulsory.
+#If no output file path is passed it is taken as /tmp/delta_pkg.dtpk
+
+PRECAUTIONARY INFORMATION
+#need to have root permission for some of the instructions.
+#xdelta3 needs to be installed on the device.
+
+OUTPUT
+#The output is a delta package in form of a .dtpk (zipped) file.
+
+
+
+
index 43d239400b91ded97080ecd814a4369525a175f0..a869486183df571fbd792ed40def0043f0ac7bfb 100644 (file)
@@ -70,4 +70,6 @@ chsmack -a '*' %{TZ_SYS_RW_PACKAGES}
 %{_bindir}/pkginfo
 %{_datadir}/mime/packages/mime.wac.xml
 %{_datadir}/mime/packages/mime.tpk.xml
+%attr(0700,root,root) /etc/package-manager/pkgmgr-unzip-tpk.sh
+%attr(0700,root,root) /etc/package-manager/pkgmgr-create-delta.sh
 /usr/share/license/%{name}
diff --git a/src/delta.c b/src/delta.c
new file mode 100644 (file)
index 0000000..dba2a27
--- /dev/null
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Vivek Kumar <vivek.kumar2@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <dirent.h>
+#include <glib.h>
+#include <glib-object.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/wait.h>
+#include "delta.h"
+
+static GList * __list_directory(const char * dir_name, const char * tpk_path, GList * list);
+static int __compare_files(char * path1, char * path2);
+static void __print_to_file(char* msg);
+static void __free_g_list(GList * list);
+
+static void __free_g_list(GList * list)
+{
+       GList * iter = NULL;
+       for (iter = list; iter != NULL; iter = iter->next)
+       {
+               if (iter->data)
+                       free(iter->data);
+       }
+       g_list_free(list);
+       return;
+}
+
+static GList * __list_directory (const char * dir_name, const char * tpk_path, GList * list)
+{
+        DIR *dir = NULL;
+        struct dirent entry, *result;
+        int flag = 0;
+        char path[PATH_MAX] = {0, };
+        char rel_path_old_tpk_file[PATH_MAX] = {0, };
+        char *file_path = NULL;
+        char buf[BUF_SIZE] = {0};
+
+        dir = opendir(dir_name);
+        if (!dir)
+        {
+                if (strerror_r(errno, buf, sizeof(buf)) == 0) {
+                        printf ("Cannot open directory '%s': %s\n", dir_name, buf);
+                }
+                exit (EXIT_FAILURE);
+        }
+        while (1)
+        {
+                const char * d_name = NULL;
+                int ret = 0;
+                ret = readdir_r(dir, &entry, &result); /* "Readdir" gets subsequent entries from "d". */
+                if (ret != 0 || result == NULL)/* There are no more entries in this directory, so break out of the while loop. */
+                {
+                        flag++;
+                        break;
+                }
+                d_name = entry.d_name;
+                if (!(entry.d_type & DT_DIR))
+                {
+                        snprintf(rel_path_old_tpk_file, PATH_MAX, "%s/%s", dir_name, d_name);
+                        strncpy(path, rel_path_old_tpk_file+strlen(tpk_path), strlen(rel_path_old_tpk_file));
+                        file_path = strndup(path, sizeof(path));
+                        list = g_list_append(list, file_path);
+                        memset(path, 0, PATH_MAX);
+                        memset(rel_path_old_tpk_file, 0, PATH_MAX);
+
+                }
+
+                if (entry.d_type & DT_DIR)                      /* Check that the directory is not "d" or d's parent. */
+                {
+                        if (strcmp(d_name, "..") != 0 && strcmp (d_name, ".") != 0)
+                        {
+                                int path_length;
+                                path_length = snprintf (path, PATH_MAX, "%s/%s", dir_name, d_name);
+                                if (path_length >= PATH_MAX)
+                                {
+                                        printf("Path length has got too long.\n");
+                                        exit(EXIT_FAILURE);
+                                }
+                                list = __list_directory (path, tpk_path, list);
+                                memset(path, 0, PATH_MAX);/* Recursively call "list_dir" with the new path. */
+                        }
+                }
+        }
+        if(flag == 1)
+        {
+                snprintf (rel_path_old_tpk_file, PATH_MAX, "%s/", dir_name);
+                strncpy(path, rel_path_old_tpk_file+strlen(tpk_path), strlen(rel_path_old_tpk_file));
+                file_path = strndup(path, sizeof(path));
+                list = g_list_prepend(list, file_path);
+                memset(path, 0, PATH_MAX);
+                memset(rel_path_old_tpk_file, 0, PATH_MAX);
+        }
+        if (closedir(dir))
+        {
+                if (strerror_r(errno, buf, sizeof(buf)) == 0) {
+                        printf("Could not close '%s': %s\n", dir_name, buf);
+                }
+                exit(EXIT_FAILURE);
+        }
+        return list;
+}
+
+static char * __create_md5Hash(char * file_name)
+{
+       FILE *inFile = fopen (file_name, "rb");
+       unsigned char data[1024] = {0, };
+       int bytes = 0;
+
+       GChecksum *checksum = NULL;
+       char *checksum_val = NULL;
+       char *return_val = NULL;
+
+       if (inFile == NULL) {
+               printf("%s can't be opened.\n", file_name);
+               return 0;
+       }
+
+       checksum = g_checksum_new(G_CHECKSUM_MD5);
+       if (checksum == NULL) {
+               printf("failed to create a new GChecksum\n");
+               fclose(inFile);
+               return 0;
+       }
+
+       while ((bytes = fread(data, 1, 1024, inFile)) != 0) {
+               g_checksum_update(checksum, (const guchar *)data, bytes);
+       }
+
+       checksum_val = (char *)g_checksum_get_string(checksum);
+       if (checksum_val) {
+               return_val = strdup(checksum_val);
+       }
+
+       g_checksum_free(checksum);
+       fclose(inFile);
+
+       return return_val;
+}
+
+static int __compare_files(char * old_file, char * new_file)
+{
+       char *md5_old_file = NULL;
+       char *md5_new_file = NULL;
+       md5_old_file = __create_md5Hash(old_file);
+       if(md5_old_file == NULL)
+       {
+               printf("md5checksum failed for %s.\n", old_file );
+               exit(EXIT_FAILURE);
+       }
+       md5_new_file = __create_md5Hash(new_file);
+       if(md5_new_file == NULL)
+       {
+                printf("md5checksum failed for %s.\n", new_file );
+                exit(EXIT_FAILURE);
+       }
+       if(strcmp(md5_old_file, md5_new_file) == 0)
+       {
+               free(md5_old_file);
+               free(md5_new_file);
+               return 0;
+       }
+       else
+       {
+               free(md5_old_file);
+               free(md5_new_file);
+               return 1;
+       }
+}
+
+static void __print_to_file(char* msg)
+{
+        FILE *fp;
+        fp = fopen(DIFF_FILE, "a");
+        if (fp == NULL)
+        {
+                printf("Cannot open %s for writing ", DIFF_FILE);
+                exit(1);
+        }
+        fprintf(fp, "%s \n", msg);
+        memset(msg, 0, MAX_MESSAGE_LEN);
+        fclose(fp);
+}
+
+void __create_diff_file(char * old_tpk_path, char * new_tpk_path)
+{
+        char rel_path_old_tpk_file[PATH_MAX] = {0, }, rel_path_new_tpk_file[PATH_MAX] = {0, };
+        GList *list_dir_old_tpk = NULL, *list_dir_new_tpk = NULL, *iterator_old_tpk = NULL, *iterator_new_tpk = NULL, *next_iterator_old_tpk = NULL, *next_iterator_new_tpk = NULL;
+        int ret = -1;
+
+        list_dir_old_tpk = __list_directory (old_tpk_path, old_tpk_path, list_dir_old_tpk);
+        list_dir_new_tpk = __list_directory (new_tpk_path, new_tpk_path, list_dir_new_tpk);
+        if(list_dir_old_tpk == NULL)
+        {
+                printf("Could Not read %s\n", old_tpk_path);
+                return;
+        }
+
+        if(list_dir_new_tpk == NULL)
+        {
+                printf("Could Not read %s\n", new_tpk_path);
+                return;
+        }
+
+        iterator_old_tpk = list_dir_old_tpk;
+        iterator_new_tpk = list_dir_new_tpk;
+
+       while(iterator_old_tpk != NULL)
+       {
+               next_iterator_old_tpk = iterator_old_tpk->next;
+
+               iterator_new_tpk = list_dir_new_tpk;
+               while(iterator_new_tpk != NULL)
+                {
+                       next_iterator_new_tpk = iterator_new_tpk->next;
+
+                        if(strcmp((char *)iterator_old_tpk->data, (char *)iterator_new_tpk->data) == 0)
+                        {
+                                snprintf(rel_path_old_tpk_file, PATH_MAX,"%s%s", old_tpk_path,(char *)iterator_old_tpk->data);
+                                snprintf(rel_path_new_tpk_file, PATH_MAX,"%s%s", new_tpk_path,(char *)iterator_new_tpk->data);
+                                ret = 0;
+                                if(rel_path_new_tpk_file[strlen(rel_path_new_tpk_file) - 1] != '/')
+                                {
+                                        ret = __compare_files(rel_path_old_tpk_file, rel_path_new_tpk_file);
+                                        if (ret == 1)
+                                        {
+                                                snprintf(message, MAX_MESSAGE_LEN, "Files %s and %s differ", rel_path_old_tpk_file, rel_path_new_tpk_file);
+                                                __print_to_file(message);
+                                        }
+                                }
+                                list_dir_new_tpk = g_list_delete_link(list_dir_new_tpk, iterator_new_tpk);
+                                list_dir_old_tpk = g_list_delete_link(list_dir_old_tpk, iterator_old_tpk);
+                                iterator_new_tpk = next_iterator_new_tpk;
+                                iterator_old_tpk = next_iterator_old_tpk;
+                                break;
+                        }
+                        iterator_new_tpk = next_iterator_new_tpk;
+                }
+                iterator_old_tpk = next_iterator_old_tpk;
+        }
+
+       //find if new file or new directory
+       iterator_old_tpk = list_dir_old_tpk;
+       while(iterator_old_tpk != NULL)
+       {
+               iterator_new_tpk = iterator_old_tpk->next;
+               while(iterator_new_tpk != NULL)
+               {
+                       next_iterator_new_tpk = iterator_new_tpk->next;
+                       if (strstr(iterator_new_tpk->data, iterator_old_tpk->data) != NULL)
+                               list_dir_new_tpk = g_list_delete_link(list_dir_new_tpk, iterator_new_tpk);
+                       iterator_new_tpk = next_iterator_new_tpk;
+               }
+               iterator_old_tpk = iterator_old_tpk->next;
+       }
+
+       iterator_old_tpk = list_dir_new_tpk;
+       while(iterator_old_tpk != NULL)
+       {
+               iterator_new_tpk = iterator_old_tpk->next;
+               while(iterator_new_tpk != NULL)
+               {
+                       next_iterator_new_tpk = iterator_new_tpk->next;
+                       if (strstr(iterator_new_tpk->data, iterator_old_tpk->data) != NULL)
+                               list_dir_new_tpk = g_list_delete_link(list_dir_new_tpk, iterator_new_tpk);
+                       iterator_new_tpk = next_iterator_new_tpk;
+               }
+               iterator_old_tpk = iterator_old_tpk->next;
+       }
+
+       iterator_old_tpk = list_dir_old_tpk;
+       while(iterator_old_tpk != NULL)
+       {
+               snprintf(message, MAX_MESSAGE_LEN, "Only in %s%s", old_tpk_path, (char *)iterator_old_tpk->data);
+               __print_to_file(message);
+               iterator_old_tpk = iterator_old_tpk->next;
+       }
+       iterator_new_tpk = list_dir_new_tpk;
+       while(iterator_new_tpk != NULL)
+       {
+               snprintf(message, MAX_MESSAGE_LEN, "Only in %s%s", new_tpk_path, (char *)iterator_new_tpk->data);
+               __print_to_file(message);
+               iterator_new_tpk = iterator_new_tpk->next;
+       }
+
+       /*to free GSList*/
+       __free_g_list(list_dir_old_tpk);
+       __free_g_list(list_dir_new_tpk);
+}
+
+int __xsystem(const char *argv[])
+{
+     int status = 0;
+     pid_t pid;
+     pid = fork();
+     switch (pid) {
+     case -1:
+             perror("fork failed");
+             return -1;
+     case 0:
+             /* child */
+             if (execvp(argv[0], (char *const *)argv) < 0) {
+                                char buf[BUF_SIZE] = {0};
+                                if (strerror_r(errno, buf, sizeof(buf)) == 0) {
+                                        fprintf(stderr, "execvp failed %d....%s\n", errno, buf);    /*Don't use d_msg_app2sd */
+                                }
+             }
+             _exit(-1);
+     default:
+             /* parent */
+             break;
+     }
+     if (waitpid(pid, &status, 0) == -1) {
+             perror("waitpid failed");
+             return -1;
+     }
+     if (WIFSIGNALED(status)) {
+             perror("signal");
+             return -1;
+     }
+     if (!WIFEXITED(status)) {
+             /* shouldn't happen */
+             perror("should not happen");
+             return -1;
+     }
+     return WEXITSTATUS(status);
+}
diff --git a/src/delta.h b/src/delta.h
new file mode 100644 (file)
index 0000000..699a937
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Vivek Kumar <vivek.kumar2@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef DELTA_H_
+#define DELTA_H_
+
+#define DIFF_FILE                      "/opt/usr/temp_delta/difffile.txt"
+#define TEMP_DELTA_REPO                "/opt/usr/temp_delta/"
+#define UNZIPFILE                      "_FILES"
+#define MAX_MESSAGE_LEN 1024
+#define BUF_SIZE 1024
+char message[MAX_MESSAGE_LEN];
+
+void __create_diff_file(char * old_tpk_path, char * new_tpk_path);
+int __xsystem(const char *argv[]);
+
+#endif /* DELTA_H_ */
index 9a20dd939f5a620585c7ca18cf3fde0a0b2d84df..4cdfb3c8f1e8dee80de5f682d6f5716265b0d53a 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * slp-pkgmgr
- *
  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
  *
  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>,
index 45621e8ba1c04f65964f7398f6970068efa86804..e94ca952dc58069f78f0b1248587e4b103ad6688 100644 (file)
@@ -1,7 +1,4 @@
-
 /*
- * slp-pkgmgr
- *
  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
  *
  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>,
@@ -45,6 +42,7 @@
 
 #include <package-manager.h>
 #include <package-manager-types.h>
+#include "delta.h"
 
 #define PKG_TOOL_VERSION       "0.1"
 #define APP_INSTALLATION_PATH_RW       tzplatform_getenv(TZ_USER_APP)
@@ -62,7 +60,7 @@ static int __return_cb(uid_t target_uid, int req_id, const char *pkg_type,
 static int __convert_to_absolute_path(char *path);
 
 /* Supported options */
-const char *short_options = "iurmcgCkaADL:lsd:p:t:n:T:S:e:M:Gqh";
+const char *short_options = "iurmcgCkaADL:lsd:p:t:n:T:S:e:M:X:Y:Z:Gqh";
 const struct option long_options[] = {
        {"install", 0, NULL, 'i'},
        {"uninstall", 0, NULL, 'u'},
@@ -80,6 +78,9 @@ const struct option long_options[] = {
        {"show", 0, NULL, 's'},
        {"descriptor", 1, NULL, 'd'},
        {"package-path", 1, NULL, 'p'},
+       {"old_pkg", 1, NULL, 'X'},
+       {"new_pkg", 1, NULL, 'Y'},
+       {"delta_pkg", 1, NULL, 'Z'},
        {"package-type", 1, NULL, 't'},
        {"package-name", 1, NULL, 'n'},
        {"move-type", 1, NULL, 'T'},
@@ -108,7 +109,8 @@ enum pm_tool_request_e {
        KILLAPP_REQ,
        LIST_REQ,
        SHOW_REQ,
-       HELP_REQ
+       HELP_REQ,
+       CREATE_DELTA
 };
 typedef enum pm_tool_request_e req_type;
 
@@ -118,6 +120,12 @@ struct pm_tool_args_t {
        char pkg_type[PKG_TYPE_STRING_LEN_MAX];
        char pkgid[PKG_NAME_STRING_LEN_MAX];
        char des_path[PATH_MAX];
+       char pkg_old[PATH_MAX];
+       char pkg_new[PATH_MAX];
+       char delta_pkg[PATH_MAX];
+       char resolved_path_pkg_old[PATH_MAX];
+       char resolved_path_pkg_new[PATH_MAX];
+       char resolved_path_delta_pkg[PATH_MAX];
        char label[PKG_NAME_STRING_LEN_MAX];
        char tep_path[PATH_MAX];
        char tep_move[PKG_NAME_STRING_LEN_MAX];
@@ -404,6 +412,7 @@ static void __print_usage()
        printf("pkgcmd -g -T <getsize type> -n <pkgid> \n");
        printf("pkgcmd -C -n <pkgid> \n");
        printf("pkgcmd -k -n <pkgid> \n");
+       printf("pkgcmd -X <old_pkg> -Y <new_pkg> -Z <delta_pkg> \n");
 
        printf("Example:\n");
        printf("pkgcmd -u -n com.samsung.calculator\n");
@@ -491,6 +500,9 @@ static int __process_request(uid_t uid)
        pkgmgr_client *pc = NULL;
        char buf[1024] = {'\0'};
        int pid = -1;
+       char pkg_old[PATH_MAX] = {0, };
+       char pkg_new[PATH_MAX] = {0, };
+
 #if !GLIB_CHECK_VERSION(2,35,0)
        g_type_init();
 #endif
@@ -534,7 +546,50 @@ static int __process_request(uid_t uid)
                g_main_loop_run(main_loop);
                ret = data.result;
                break;
+       case CREATE_DELTA:
+               printf("CREATE_DELTA\n");
+               if (data.pkg_old[0] == '\0' || data.pkg_new[0] == '\0' ) {
+                       printf("tpk pkg missing\n");
+                       break;
+               }
+               if(data.delta_pkg[0] == '\0') {
+                       snprintf(data.resolved_path_delta_pkg, PATH_MAX, "/tmp/delta_pkg");
+                       printf("output file will be /tmp/delta_pkg.delta\n");
+               }
+               const char *unzip_argv[] = {"sh", "/etc/package-manager/pkgmgr-unzip-tpk.sh", "-a", data.resolved_path_pkg_old, "-b", data.resolved_path_pkg_new, "-p", data.resolved_path_delta_pkg, NULL};
+               ret = __xsystem(unzip_argv);
+               if (ret != 0) {
+                       printf("unzip is fail .\n");
+                       return ret;
+               }
+               printf("unzip is success .\n");
+               char *ptr_old_tpk = NULL;
+               ptr_old_tpk = strrchr(data.resolved_path_pkg_old, '/');
+               if (!ptr_old_tpk) {
+                       printf("not able to extract tpk name.\n");
+                       break;
+               }
+               ptr_old_tpk++;
+               char *ptr_new_tpk = NULL;
+               ptr_new_tpk = strrchr(data.resolved_path_pkg_new, '/');
+               if (!ptr_new_tpk) {
+                       printf("not able to extract tpk name.\n");
+                       break;
+               }
+               ptr_new_tpk++;
 
+               snprintf(pkg_old, PATH_MAX,"%s%s%s", TEMP_DELTA_REPO, ptr_old_tpk, UNZIPFILE);
+               snprintf(pkg_new, PATH_MAX,"%s%s%s", TEMP_DELTA_REPO, ptr_new_tpk, UNZIPFILE);
+               __create_diff_file(pkg_old, pkg_new);
+
+               const char *delta_argv[] = {"sh", "/etc/package-manager/pkgmgr-create-delta.sh", "-a", data.resolved_path_pkg_old, "-b", data.resolved_path_pkg_new, "-p", data.resolved_path_delta_pkg, NULL};
+               ret = __xsystem(delta_argv);
+               if (ret != 0) {
+                       printf("create delta script fail .\n");
+                       return ret;
+               }
+               printf("create delta script success .\n");
+               break;
        case UNINSTALL_REQ:
                if (data.pkgid[0] == '\0') {
                        printf("Please provide the arguments.\n");
@@ -899,6 +954,7 @@ int main(int argc, char *argv[])
        long starttime;
        long endtime;
        struct timeval tv;
+       bool is_root_cmd = false;
 
 
        if (argc == 1)
@@ -911,6 +967,12 @@ int main(int argc, char *argv[])
        memset(data.des_path, '\0', PATH_MAX);
        memset(data.pkg_path, '\0', PATH_MAX);
        memset(data.pkgid, '\0', PKG_NAME_STRING_LEN_MAX);
+       memset(data.pkg_old, '\0', PATH_MAX);
+       memset(data.pkg_new, '\0', PATH_MAX);
+       memset(data.delta_pkg, '\0', PATH_MAX);
+       memset(data.resolved_path_pkg_old, '\0', PATH_MAX);
+       memset(data.resolved_path_pkg_new, '\0', PATH_MAX);
+       memset(data.resolved_path_delta_pkg, '\0', PATH_MAX);
        memset(data.pkg_type, '\0', PKG_TYPE_STRING_LEN_MAX);
        memset(data.label, '\0', PKG_TYPE_STRING_LEN_MAX);
        memset(data.tep_path, '\0', PATH_MAX);
@@ -1008,6 +1070,32 @@ int main(int argc, char *argv[])
                        printf("path is %s\n", data.pkg_path);
                        break;
 
+               case 'X': /*old_tpk*/
+                       data.request = CREATE_DELTA;
+                       is_root_cmd = true;
+                       if (optarg) {
+                               strncpy(data.pkg_old, optarg, PATH_MAX - 1);
+                       }
+                       realpath(data.pkg_old, data.resolved_path_pkg_old);
+                       printf("pkg_old abs path is %s\n", data.resolved_path_pkg_old);
+                       break;
+
+               case 'Y': /*new_tpk*/
+                       if (optarg) {
+                               strncpy(data.pkg_new, optarg, PATH_MAX - 1);
+                       }
+                       realpath(data.pkg_new, data.resolved_path_pkg_new);
+                       printf("pkg_new abs path is %s\n", data.resolved_path_pkg_new);
+                       break;
+
+               case 'Z': /*delta_tpk*/
+                       if (optarg) {
+                               strncpy(data.delta_pkg, optarg, PATH_MAX - 1);
+                       }
+                       printf("delta_pkg is %s\n", data.delta_pkg);
+                       realpath(data.delta_pkg, data.resolved_path_delta_pkg);
+                       printf("delta_pkg abs path is %s\n",data.resolved_path_delta_pkg);
+                       break;
                case 'd':       /* descriptor path */
                        if (optarg)
                                snprintf(data.des_path, sizeof(data.des_path),
@@ -1068,7 +1156,7 @@ int main(int argc, char *argv[])
                }
        }
        uid_t uid = getuid();
-       if(uid == OWNER_ROOT) {
+       if(!is_root_cmd && uid == OWNER_ROOT) {
                printf("Current User is Root! : Only regular users are allowed\n");
                return -1;
        }
index 3f096af52ab636e095d7eaf27bd2440983f44af8..0dace91129bcdc2d9be1f1c8f7deeb9c0de06dc4 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * slp-pkgmgr
- *
  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
  *
  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>,
index 3964e324452dd04b80830fbf223def85e9cb9444..f6cbaa951844bf335574ddb73cfa22937f1cd205 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * slp-pkgmgr
- *
  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
  *
  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>,
index 91e32e9d45bfa5f2dccd8a0d2360307c1b3b4f2a..771a7d17fe472d2b820455ae463b7c89fccd1c30 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * slp-pkgmgr
- *
  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
  *
  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>,