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)
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/)
--- /dev/null
+#!/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
--- /dev/null
+#!/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
--- /dev/null
+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.
+
+
+
+
%{_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}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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_ */
/*
- * 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>,
-
/*
- * 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>,
#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)
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'},
{"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'},
KILLAPP_REQ,
LIST_REQ,
SHOW_REQ,
- HELP_REQ
+ HELP_REQ,
+ CREATE_DELTA
};
typedef enum pm_tool_request_e req_type;
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];
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");
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
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");
long starttime;
long endtime;
struct timeval tv;
+ bool is_root_cmd = false;
if (argc == 1)
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);
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),
}
}
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;
}
/*
- * 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>,
/*
- * 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>,
/*
- * 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>,