merge tizen 2.4 & add test bin 18/61518/3
authorjongmyeongko <jongmyeong.ko@samsung.com>
Tue, 8 Mar 2016 10:50:05 +0000 (19:50 +0900)
committerjongmyeongko <jongmyeong.ko@samsung.com>
Tue, 8 Mar 2016 10:58:01 +0000 (19:58 +0900)
TODO : smack labeling, consider user private app, test all functions

Change-Id: I36f60296cd02fb631c22906724ec8f374689f529
Signed-off-by: jongmyeongko <jongmyeong.ko@samsung.com>
22 files changed:
CMakeLists.txt
app2sd.manifest.in [moved from packaging/app2sd.manifest with 100% similarity]
app2sd.pc.in
doc/images/SLP_app2ext_PG_image01.png [deleted file]
doc/images/app2ext_diag.png [changed mode: 0755->0644]
doc/images/app2ext_install_diag.png [changed mode: 0755->0644]
doc/images/app2ext_uninstall_diag.png [changed mode: 0755->0644]
inc/SLP_app2ext_PG.h [changed mode: 0755->0644]
inc/app2ext_interface.h [changed mode: 0755->0644]
packaging/app2sd.changes [deleted file]
packaging/app2sd.spec [changed mode: 0755->0644]
plugin/app2sd/CMakeLists.txt [changed mode: 0755->0644]
plugin/app2sd/inc/SLP_app2sd_PG.h [changed mode: 0755->0644]
plugin/app2sd/inc/app2sd_interface.h [changed mode: 0755->0644]
plugin/app2sd/inc/app2sd_internals.h [changed mode: 0755->0644]
plugin/app2sd/src/app2sd_interface.c [changed mode: 0755->0644]
plugin/app2sd/src/app2sd_internals.c [changed mode: 0755->0644]
plugin/app2sd/src/app2sd_internals_registry.c [changed mode: 0755->0644]
plugin/app2sd/src/app2sd_internals_utils.c [changed mode: 0755->0644]
src/app2ext_interface.c [changed mode: 0755->0644]
test/CMakeLists.txt [new file with mode: 0644]
test/src/test_app2ext.c [new file with mode: 0644]

index cff815f..a3bd604 100644 (file)
@@ -46,9 +46,13 @@ TARGET_LINK_LIBRARIES(${APP2EXT} ${libpkgs_LDFLAGS})
 SET(CMAKE_INSTALL_PREFIX "/usr")
 SET(PREFIX ${CMAKE_INSTALL_PREFIX})
 
+CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/app2sd.manifest.in ${CMAKE_BINARY_DIR}/app2sd.manifest @ONLY)
+
 CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/app2sd.pc.in ${CMAKE_BINARY_DIR}/app2sd.pc @ONLY)
 
 INSTALL(TARGETS ${APP2EXT} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
 INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/app2sd.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
 INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/inc/app2ext_interface.h DESTINATION include)
 
+ADD_SUBDIRECTORY(test)
+
similarity index 100%
rename from packaging/app2sd.manifest
rename to app2sd.manifest.in
index d2e6ce8..5e3edbc 100644 (file)
@@ -7,6 +7,6 @@ includedir=@INCLUDE_INSTALL_DIR@
 Name: app2sd
 Description: The app2sd Library
 Version: 1.1.0
-Requires: vconf dlog
+Requires: vconf dlog libtzplatform-config
 Cflags: -I${includedir}
 Libs: -L${libdir} -lapp2sd -lapp2ext
diff --git a/doc/images/SLP_app2ext_PG_image01.png b/doc/images/SLP_app2ext_PG_image01.png
deleted file mode 100755 (executable)
index e69de29..0000000
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
index 00429a0..543ac67
@@ -68,9 +68,12 @@ extern "C" {
 #endif
 
 #define APP2EXT_SUCCESS 0
-#define MMC_PATH tzplatform_mkpath(TZ_SYS_STORAGE, "sdcard")
-#define APP2SD_PATH tzplatform_mkpath(TZ_SYS_STORAGE, "sdcard/app2sd/")
-#define APP_INSTALLATION_PATH tzplatform_mkpath(TZ_USER_APP, "")
+#define MMC_PATH tzplatform_mkpath(TZ_SYS_MEDIA, "sdcard")
+#define APP2SD_PATH tzplatform_mkpath(TZ_SYS_MEDIA, "sdcard/app2sd/")
+/* user app */
+#define APP_INSTALLATION_USER_PATH tzplatform_mkpath(TZ_USER_APP, "/")
+/* gloabl app */
+#define APP_INSTALLATION_PATH tzplatform_mkpath(TZ_SYS_RW_APP, "/")
 
 /**
  * Enum for application installation location
@@ -277,6 +280,15 @@ typedef int (*app2ext_enable)(const char *appname);
 typedef int (*app2ext_disable)(const char *appname);
 
 /**
+ * @brief :This function type is for a function that is implemented by plugin
+ * and called after application uninstallation.
+ *
+ * @param[in]  pkgid           application package name which is to be uninstalled
+ * @return     0 if success,  error code(>0) if fail
+ */
+typedef int (*app2ext_force_clean)(const char *pkgid);
+
+/**
  * This structure defines the app2ext interfaces. Plugins have to implement these functions
  */
 typedef struct app2ext_interface_t{
@@ -287,6 +299,7 @@ typedef struct app2ext_interface_t{
        app2ext_pre_uninstall           pre_uninstall;
        app2ext_post_uninstall          post_uninstall;
        app2ext_move                    move;
+       app2ext_force_clean             force_clean;
        app2ext_enable                  enable;
        app2ext_disable                 disable;
 } app2ext_interface;
@@ -470,6 +483,23 @@ if (ret < 0) {
  */
 API int app2ext_disable_external_dir(void);
 
+/**
+ * @brief : This API clean the directory and symbolic link which are made by app2ext
+ * @return     error < 0  if pkg enable fail ,
+ @code
+ #include <app2ext_interface.h>
+int ret = -1;
+
+ret = app2ext_force_clean_pkg("docomo6002");
+if (ret < 0) {
+       printf("\n force_clean fail  ");
+} else {
+       printf("\n force_clean success");
+}
+ @endcode
+ */
+API int app2ext_force_clean_pkg(const char *pkgid);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/packaging/app2sd.changes b/packaging/app2sd.changes
deleted file mode 100644 (file)
index 3e2a4c7..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-* Mon Sep 16 2013 Anas Nashif <anas.nashif@intel.com> accepted/tizen/20130912.093813@9ace0b4
-- package libapp2sd.so only in -devel
-
-* Thu Jul 11 2013 Rusty Lynch <rusty.lynch@intel.com> accepted/tizen/20130710.221534@cf263b1
-- Remove left over app2sd.manifest.in
-
old mode 100755 (executable)
new mode 100644 (file)
index ceec704..40bcdbc
@@ -1,40 +1,50 @@
 Name:       app2sd
 Summary:    Application installation on external memory
-Version:    0.5.27
-Release:    0
+Version:    0.5.42
+Release:    1
 Group:      Application Framework/Package Management
 License:    Apache-2.0
 Source0:    %{name}-%{version}.tar.gz
-Source1001:     app2sd.manifest
 
-BuildRequires:  cmake
-BuildRequires:  pkgconfig(db-util)
-BuildRequires:  pkgconfig(dlog)
 BuildRequires:  pkgconfig(libssl)
+BuildRequires:  pkgconfig(vconf)
+BuildRequires:  pkgconfig(dlog)
 BuildRequires:  pkgconfig(openssl)
+BuildRequires:  pkgconfig(db-util)
 BuildRequires:  pkgconfig(pkgmgr-info)
-BuildRequires:  pkgconfig(vconf)
+BuildRequires:  pkgconfig(libprivilege-control)
 BuildRequires:  pkgconfig(libtzplatform-config)
+BuildRequires:  cmake
 
 %description
 Tizen application installation on external memory
 
 %package devel
-Summary:        Application install on external memory (devel)
-Requires:       app2sd = %{version}-%{release}
+Summary:    Application install on external memory (devel)
+Group:      Development/Libraries
+Requires:   app2sd = %{version}-%{release}
 
 %description devel
 Tizen application installation on external memory (devel)
 
+%package test
+Summary:    Application install on external memory (test)
+Group:      Development/Libraries
+Requires:   app2sd = %{version}-%{release}
+
+%description test
+Tizen application installation on external memory (test)
+
 %prep
 %setup -q
-cp %{SOURCE1001} .
 
 %build
 %cmake .
-make %{?_smp_mflags}
+
+make %{?jobs:-j%jobs}
 
 %install
+rm -rf %{buildroot}
 %make_install
 
 mkdir -p %{buildroot}/usr/share/license
@@ -45,19 +55,21 @@ cp LICENSE %{buildroot}/usr/share/license/%{name}
 %postun -p /sbin/ldconfig
 
 %files
-%manifest %{name}.manifest
+%manifest app2sd.manifest
 %defattr(-,root,root,-)
 %{_libdir}/libapp2ext.so.*
 %{_libdir}/libapp2sd.so*
 /usr/share/license/%{name}
 
+
 %files devel
-%manifest %{name}.manifest
 %defattr(-,root,root,-)
 %{_includedir}/app2ext_interface.h
 %{_libdir}/pkgconfig/app2sd.pc
 %{_libdir}/libapp2sd.so
 %{_libdir}/libapp2ext.so
 
-
+%files test
+%defattr(-,root,root,-)
+%{_bindir}/test_app2ext
 
old mode 100755 (executable)
new mode 100644 (file)
index 05e885a..d417cf3
@@ -3,18 +3,19 @@ PROJECT(app2sd C)
 
 ### Required packages
 INCLUDE(FindPkgConfig)
-pkg_check_modules(pkgs REQUIRED libssl dlog openssl db-util pkgmgr-info vconf libtzplatform-config)
+pkg_check_modules(pkgs REQUIRED libssl dlog openssl db-util pkgmgr-info vconf libprivilege-control libtzplatform-config)
 
 FOREACH(flag ${pkgs_CFLAGS})
        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
 ENDFOREACH(flag)
 
-pkg_check_modules(libpkgs REQUIRED libssl dlog openssl db-util pkgmgr-info vconf)
+pkg_check_modules(libpkgs REQUIRED libssl dlog openssl db-util pkgmgr-info vconf libprivilege-control)
 
 FOREACH(flag ${libpkgs_CFLAGS})
        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
 ENDFOREACH(flag)
 
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
 
 ### Local include directories
@@ -33,7 +34,7 @@ ADD_LIBRARY(${APP2SD} SHARED ${libapp2sd_SOURCES})
 SET_TARGET_PROPERTIES(${APP2SD} PROPERTIES SOVERSION ${VERSION_MAJOR})
 SET_TARGET_PROPERTIES(${APP2SD} PROPERTIES VERSION ${VERSION})
 SET_TARGET_PROPERTIES(${APP2SD} PROPERTIES COMPILE_FLAGS "${libapp2sd_CFLAGS}")
-TARGET_LINK_LIBRARIES(${APP2SD} ${libpkgs_LDFLAGS})
+TARGET_LINK_LIBRARIES(${APP2SD} ${libpkgs_LDFLAGS} "-lm")
 
 SET(CMAKE_INSTALL_PREFIX "/usr")
 SET(PREFIX ${CMAKE_INSTALL_PREFIX})
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
index b2e1a91..d958a01
@@ -28,8 +28,8 @@
 #define _GNU_SOURCE
 #endif
 
-#ifndef _BSD_SOURCE
-#define _BSD_SOURCE
+#ifndef _DEFAULT_SOURCE
+#define _DEFAULT_SOURCE
 #endif
 
 /*Include Headers*/
@@ -47,6 +47,7 @@
 #include <errno.h>
 #include <sys/mount.h>
 #include <app2sd_interface.h>
+#include <math.h>
 
 #define DIR_PERMS (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
 
@@ -58,6 +59,7 @@
 #define DEV_MAJOR              7
 
 #define FS_TYPE                "ext4"
+#define INTERNAL_STORAGE_PATH "/opt/usr"
 
 typedef enum mount_type_t {
        MOUNT_TYPE_RD = 0,
@@ -104,6 +106,9 @@ int _app2sd_move_app(const char *pkgid, app2ext_move_type move_cmd, GList* dir_l
 /*utility to delete the directory*/
 int _app2sd_delete_directory(char *dirname);
 
+/*utility to delete symbolic link*/
+void _app2sd_delete_symlink(const char *dirname);
+
 /*utility to calculate the size of a directory in MB*/
 unsigned long long _app2sd_calculate_dir_size(char *dirname);
 
@@ -153,6 +158,9 @@ int _app2sd_unmount_app_content(const char *pkgid);
 /*This function removes the loopbck encryption setup for the app*/
 int _app2sd_remove_loopback_encryption_setup(const char *pkgid);
 
+/*This function removes all of loopbck encryption setup for the app*/
+int _app2sd_remove_all_loopback_encryption_setups(const char *pkgid);
+
 /*This function updates loopback device size*/
 int _app2sd_update_loopback_device_size(const char *pkgid,
        int size, GList* dir_list);
@@ -180,8 +188,7 @@ int _app2sd_remove_password_from_db(const char *pkgid);
 int _app2sd_set_password_in_db(const char *pkgid,
                                      const char *passwd);
 
-/* This functions setup path for smack */
-int _app2sd_setup_path(const char *pkgid, const char *dirpath,
-                                               int apppathtype, const char *groupid);
+/* This functions make result file */
+void _app2sd_make_result_info_file(char *pkgid, int size);
 
 #endif
old mode 100755 (executable)
new mode 100644 (file)
index 0a3db32..6f4c878
 #include <pkgmgr-info.h>
 #include <vconf.h>
 
-/* For multi-user support */
-#include <tzplatform_config.h>
-
 #define MAX_BUF_LEN    1024
-#define APP2SD_TMP_PATH tzplatform_mkpath(TZ_USER_APP, "tmp")
 
 int app2sd_pre_app_install(const char *pkgid, GList* dir_list,
                                int size)
@@ -43,33 +39,42 @@ int app2sd_pre_app_install(const char *pkgid, GList* dir_list,
        char *device_node = NULL;
        char *devi = NULL;
        char *result = NULL;
+       int reqd_disk_size = size + ceil(size*0.2);
 
-       /*Validate the function parameter recieved */
+       /* debug path */
+       app2ext_print("MMC_PATH = (%s)\n", MMC_PATH);
+       app2ext_print("APP2SD_PATH = (%s)\n", APP2SD_PATH);
+       app2ext_print("APP_INSTALLATION_PATH = (%s)\n", APP_INSTALLATION_PATH);
+       app2ext_print("APP_INSTALLATION_USER_PATH = (%s)\n", APP_INSTALLATION_USER_PATH);
+
+       /* Validate the function parameter recieved */
        if (pkgid == NULL || dir_list == NULL || size <= 0) {
                app2ext_print("App2Sd Error : Invalid function arguments\n");
                return APP2EXT_ERROR_INVALID_ARGUMENTS;
        }
-       /*Check whether MMC is present or not */
+       /* Check whether MMC is present or not */
        ret = _app2sd_check_mmc_status();
        if (ret) {
                app2ext_print("App2Sd Error : MMC not preset OR Not ready %d\n",
                        ret);
                return APP2EXT_ERROR_MMC_STATUS;
        }
-       /*Find available free memory in the MMC card */
+       /* Find available free memory in the MMC card */
        ret = _app2sd_get_available_free_memory(MMC_PATH,
                                                &free_mmc_mem);
        if (ret) {
                app2ext_print("App2Sd Error : Unable to get available free memory in MMC %d\n", ret);
                return APP2EXT_ERROR_MMC_STATUS;
        }
-       /*If avaialalbe free memory in MMC is less than required size + 5MB , return error */
-       if ((size + PKG_BUF_SIZE + MEM_BUF_SIZE) > free_mmc_mem) {
+       app2ext_print("Size details for application installation:size=%dMB, reqd_disk_size=%dMB, free_mmc_size=%dMB\n",
+                        size, reqd_disk_size, free_mmc_mem);
+       /* If avaialalbe free memory in MMC is less than required size + 5MB , return error */
+       if ((reqd_disk_size + PKG_BUF_SIZE + MEM_BUF_SIZE) > free_mmc_mem) {
                app2ext_print("Insufficient memory in MMC for application installation %d\n", ret);
                return APP2EXT_ERROR_MMC_INSUFFICIENT_MEMORY;
        }
-       /*Create a loopback device */
-       ret = _app2sd_create_loopback_device(pkgid, (size+PKG_BUF_SIZE));
+       /* Create a loopback device */
+       ret = _app2sd_create_loopback_device(pkgid, (reqd_disk_size+PKG_BUF_SIZE));
        if (ret) {
                app2ext_print("App2Sd Error : Package already present\n");
                char buf_dir[FILENAME_MAX] = { 0, };
@@ -82,14 +87,14 @@ int app2sd_pre_app_install(const char *pkgid, GList* dir_list,
                                 buf_dir);
                }
        }
-       /*Perform Loopback encryption setup */
+       /* Perform Loopback encryption setup */
        device_node = _app2sd_do_loopback_encryption_setup(pkgid);
        if (!device_node) {
                app2ext_print("App2Sd Error : Loopback encryption setup failed\n");
                _app2sd_delete_loopback_device(pkgid);
                return APP2EXT_ERROR_DO_LOSETUP;
        }
-       /*Check whether loopback device is associated with device node or not */
+       /* Check whether loopback device is associated with device node or not */
        devi = _app2sd_find_associated_device_node(pkgid);
        if (devi == NULL) {
                app2ext_print("App2Sd Error : finding associated device node failed\n");
@@ -97,7 +102,7 @@ int app2sd_pre_app_install(const char *pkgid, GList* dir_list,
                goto FINISH_OFF;
        }
 
-       /*Format the loopback file system */
+       /* Format the loopback file system */
        ret = _app2sd_create_file_system(device_node);
        if (ret) {
                app2ext_print("App2Sd Error : creating FS failed failed\n");
@@ -105,7 +110,7 @@ int app2sd_pre_app_install(const char *pkgid, GList* dir_list,
                goto FINISH_OFF;
        }
 
-       /*Mount the loopback encrypted pseudo device on application installation path as with Read Write permission */
+       /* Mount the loopback encrypted pseudo device on application installation path as with Read Write permission */
        ret =_app2sd_mount_app_content(pkgid, device_node, MOUNT_TYPE_RW,
                                        dir_list, APP2SD_PRE_INSTALL);
        if (ret) {
@@ -114,7 +119,7 @@ int app2sd_pre_app_install(const char *pkgid, GList* dir_list,
                goto FINISH_OFF;
        }
 
-       /*Success */
+       /* Success */
        ret = APP2EXT_SUCCESS;
        goto END;
 
@@ -426,7 +431,7 @@ int app2sd_pre_app_uninstall(const char *pkgid)
 END:
        if (ret != APP2EXT_SUCCESS)
                app2ext_print("App2Sd Error : app2sd has [%d]error, but return success for uninstallation\n", ret);
-       return APP2EXT_SUCCESS;
+       return ret;
 }
 
 /*
@@ -502,7 +507,7 @@ int app2sd_post_app_uninstall(const char *pkgid)
 END:
        if (ret != APP2EXT_SUCCESS)
                app2ext_print("App2Sd Error : app2sd has [%d]error, but return success for uninstallation\n", ret);
-       return APP2EXT_SUCCESS;
+       return ret;
 }
 
 int app2sd_move_installed_app(const char *pkgid, GList* dir_list,
@@ -539,7 +544,7 @@ int app2sd_move_installed_app(const char *pkgid, GList* dir_list,
                        pkgmgrinfo_pkginfo_destroy_pkginfo(info_handle);
                        goto END;
        } else {
-               app2ext_print("App2Sd info : STORAGE Move[%d] is success\n", storage);
+               app2ext_print("App2Sd info : pkgid[%s] move to STORAGE[%d]\n", pkgid, storage);
        }
        pkgmgrinfo_pkginfo_destroy_pkginfo(info_handle);
 
@@ -549,7 +554,7 @@ int app2sd_move_installed_app(const char *pkgid, GList* dir_list,
                goto END;
        }
 
-       /*If move is completed, then update installed storage to pkgmgr_parser db*/
+       /* If move is completed, then update installed storage to pkgmgr_parser db */
        if (move_type == APP2EXT_MOVE_TO_EXT) {
                pkgmgrinfo_ret = pkgmgrinfo_pkginfo_set_installed_storage(pkgid, INSTALL_EXTERNAL);
                if (pkgmgrinfo_ret < 0) {
@@ -576,6 +581,7 @@ int app2sd_pre_app_upgrade(const char *pkgid, GList* dir_list,
        char *device_node = NULL;
        unsigned long long curr_size = 0;
        FILE *fp = NULL;
+       int reqd_disk_size = size + ceil(size*0.2);
 
        /*Validate function arguments*/
        if (pkgid == NULL || dir_list == NULL || size<=0) {
@@ -603,15 +609,15 @@ int app2sd_pre_app_upgrade(const char *pkgid, GList* dir_list,
        fclose(fp);
        /*Get installed app size*/
        curr_size = _app2sd_calculate_file_size(app_path);
-       curr_size = (curr_size/1024)/1024;
+       curr_size = (curr_size)/(1024 * 1024);
 
        if (curr_size==0) {
                app2ext_print
                    ("App2SD Error: App Entry is not present in SD Card\n");
                return APP2EXT_ERROR_LOOPBACK_DEVICE_UNAVAILABLE;
        }
-       if (curr_size<size) {
-               ret = _app2sd_update_loopback_device_size(pkgid, size, dir_list);
+       if ((int)curr_size < reqd_disk_size) {
+               ret = _app2sd_update_loopback_device_size(pkgid, reqd_disk_size, dir_list);
                if(APP2EXT_SUCCESS !=ret) {
                        app2ext_print
                            ("App2SD Error: _app2sd_update_loopback_device_size() failed\n");
@@ -632,7 +638,7 @@ int app2sd_pre_app_upgrade(const char *pkgid, GList* dir_list,
                /*Do  mounting */
                ret =
                    _app2sd_mount_app_content(pkgid, device_node,
-                                       MOUNT_TYPE_RW, NULL,
+                                       MOUNT_TYPE_RW, dir_list,
                                        APP2SD_PRE_UPGRADE);
                if (ret) {
                        app2ext_print("App2Sd Error : Re-mount failed\n");
@@ -790,6 +796,57 @@ int app2sd_force_cleanup(const char *pkgid){
 }
 #endif
 
+int app2sd_force_clean(const char *pkgid)
+{
+       char buf_dir[FILENAME_MAX] = { 0, };
+       int ret = APP2EXT_SUCCESS;
+
+       /*Validate the function parameter recieved */
+       if (pkgid == NULL) {
+               app2ext_print("Invalid func parameters\n");
+               return APP2EXT_ERROR_INVALID_ARGUMENTS;
+       }
+       app2ext_print("star force_clean [%s]", pkgid);
+
+       sync(); //2
+       /*Unmount the loopback encrypted pseudo device from the application installation path */
+       ret = _app2sd_unmount_app_content(pkgid);
+       if (ret) {
+               app2ext_print("Unable to unmount the app content %d\n", ret);
+       }
+
+       /*Detach the loopback encryption setup for the application */
+       ret = _app2sd_remove_all_loopback_encryption_setups(pkgid);
+       if (ret) {
+               app2ext_print("Unable to Detach the loopback encryption setup for the application");
+       }
+
+       /*Delete the loopback device from the SD card */
+       ret = _app2sd_delete_loopback_device(pkgid);
+       if (ret) {
+               app2ext_print("Unable to Detach the loopback encryption setup for the application");
+       }
+
+       /*Delete symlink*/
+       memset((void *)&buf_dir, '\0', FILENAME_MAX);
+       snprintf(buf_dir, FILENAME_MAX, "%s%s", APP_INSTALLATION_PATH, pkgid);
+
+       _app2sd_delete_symlink(buf_dir);
+
+       /*remove passwrd from DB*/
+       ret = _app2sd_initialize_db();
+       if (ret) {
+               app2ext_print("\n app2sd db initialize failed");
+       }
+       ret = _app2sd_remove_password_from_db(pkgid);
+       if (ret) {
+               app2ext_print("cannot remove password from db \n");
+       }
+
+       app2ext_print("finish force_clean");
+       return 0;
+}
+
 /* This is the plug-in load function. The plugin has to bind its functions to function pointers of handle
        @param[in/out]          st_interface    Specifies the storage interface.
 */
@@ -804,6 +861,7 @@ app2ext_on_load(app2ext_interface *st_interface)
        st_interface->pre_upgrade= app2sd_pre_app_upgrade;
        st_interface->post_upgrade= app2sd_post_app_upgrade;
        st_interface->move= app2sd_move_installed_app;
+       st_interface->force_clean= app2sd_force_clean;
        st_interface->enable= app2sd_on_demand_setup_init;
        st_interface->disable= app2sd_on_demand_setup_exit;
 }
old mode 100755 (executable)
new mode 100644 (file)
index 22fd099..cf474d2
 #include <app2sd_internals.h>
 #include <app2sd_interface.h>
 
+#include <sys/xattr.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <unistd.h>
 #include <stdlib.h>
+#include <string.h>
 #include <dirent.h>
 #include <sys/stat.h>
 #include <stdio.h>
 #include <fcntl.h>
 #include <time.h>
 #include <dlog.h>
+#include <privilege-control.h>
+#include <sys/statvfs.h>
+
+extern int app2sd_force_clean(const char *pkgid);
 
 /*
 ########### Internal APIs ##################
  */
-enum path_type {
-       PATH_PRIVATE,
-       PATH_GROUP_RW,
-       PATH_PUBLIC_RO,
-       PATH_SETTINGS_RW,
-       PATH_NPRUNTIME,
-       PATH_ANY_LABEL
-};
+static int _app2sd_setup_path(const char *pkgid, const char *dirpath,
+               int apppathtype, const char *groupid)
+{
+       int ret = 0;
+
+       if (groupid == NULL) {
+               ret = perm_app_setup_path(pkgid, dirpath, apppathtype);
+               app2ext_print( "[smack] app_setup_path(), result = [%d]", ret);
+       } else {
+               ret = perm_app_setup_path(pkgid, dirpath, apppathtype, groupid);
+               app2ext_print( "[smack] app_setup_path(), result = [%d]", ret);
+       }
+
+       return ret;
+}
 
+/*
 static int _app2sd_apply_app_smack(const char *pkgid, GList* dir_list, const char *groupid)
 {
        int ret = APP2EXT_SUCCESS;
@@ -63,7 +77,7 @@ static int _app2sd_apply_app_smack(const char *pkgid, GList* dir_list, const cha
                if (dir_detail && dir_detail->name
                        && dir_detail->type == APP2EXT_DIR_RO) {
                        snprintf(path, FILENAME_MAX, "%s%s/%s",APP_INSTALLATION_PATH, pkgid, dir_detail->name);
-                       ret = _app2sd_setup_path(pkgid, path, PATH_ANY_LABEL, groupid);
+                       ret = _app2sd_setup_path(pkgid, path, PERM_APP_PATH_ANY_LABEL, groupid);
                        if (ret) {
                                app2ext_print ("App2Sd Error : unable to smack %s\n", path);
                                return APP2EXT_ERROR_MOVE;
@@ -74,7 +88,9 @@ static int _app2sd_apply_app_smack(const char *pkgid, GList* dir_list, const cha
 
        return APP2EXT_SUCCESS;
 }
+*/
 
+/*
 static int _app2sd_apply_mmc_smack(const char *pkgid, GList* dir_list, const char *groupid)
 {
        int ret = APP2EXT_SUCCESS;
@@ -89,7 +105,7 @@ static int _app2sd_apply_mmc_smack(const char *pkgid, GList* dir_list, const cha
                        && dir_detail->type == APP2EXT_DIR_RO) {
                        snprintf(path, FILENAME_MAX, "%s%s/.mmc/%s",APP_INSTALLATION_PATH, pkgid, dir_detail->name);
 
-                       ret = _app2sd_setup_path(pkgid, path, PATH_ANY_LABEL, groupid);
+                       ret = _app2sd_setup_path(pkgid, path, PERM_APP_PATH_ANY_LABEL, groupid);
                        if (ret) {
                                app2ext_print ("App2Sd Error : unable to smack %s\n", path);
                                return APP2EXT_ERROR_MOVE;
@@ -100,6 +116,7 @@ static int _app2sd_apply_mmc_smack(const char *pkgid, GList* dir_list, const cha
 
        return APP2EXT_SUCCESS;
 }
+*/
 
 char *_app2sd_find_associated_device_node(const char *pkgid)
 {
@@ -111,22 +128,23 @@ char *_app2sd_find_associated_device_node(const char *pkgid)
        char *devnode = NULL;
        snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
                 pkgid);
+       app2ext_print("sdcard app_path = (%s)\n", app_path);
        result = (char *)_app2sd_find_associated_device(app_path);
        if (result == NULL) {
-               app2ext_print
-                   ("App2SD Error! Unable to find the associated File\n");
+               app2ext_print("App2SD info! there is no the associated File with [%s]\n", pkgid);
                return NULL;
        }
-       /*process the string*/
+       /* process the string*/
+       app2ext_print("result = (%s)\n", result);
        snprintf(dev, FILENAME_MAX-1, "%s", result);
        if (strstr(dev, "/dev") == NULL) {
-               app2ext_print
-                   ("App2SD Error! Unable to find the associated File\n");
+               app2ext_print("App2SD Error! Unable to find the associated File\n");
 
                free(result);
                return NULL;
        } else {
-               ret_result = strtok(dev, delims);
+               char *saveptr = NULL;
+               ret_result = strtok_r(dev, delims, &saveptr);
                if (ret_result)
                        devnode = strdup(ret_result);
        }
@@ -144,7 +162,7 @@ char *_app2sd_create_loopdevice_node(void)
        FILE *fp = NULL;
 
        result = (char *)_app2sd_find_free_device();
-       /*validate the result */
+       /* validate the result */
        if (result == NULL || strstr(result, "/dev") == NULL) {
                app2ext_print("No device found, creating device node...\n");
 
@@ -237,7 +255,7 @@ char *_app2sd_do_loopback_encryption_setup(const char *pkgid)
                }
        }
 
-       /*Get Free device node*/
+       /* Get Free device node*/
        device_node = _app2sd_create_loopdevice_node();
        if (NULL == device_node) {
                free(passwd);
@@ -300,7 +318,7 @@ char *_app2sd_do_loopback_duplicate_encryption_setup(const char *pkgid, const ch
                }
 
        }
-       /*Get Free device node*/
+       /* Get Free device node*/
        device_node = _app2sd_create_loopdevice_node();
        if (NULL == device_node) {
                free(passwd);
@@ -358,6 +376,37 @@ int _app2sd_remove_loopback_encryption_setup(const char *pkgid)
        return ret;
 }
 
+int _app2sd_remove_all_loopback_encryption_setups(const char *pkgid)
+{
+       int ret = APP2EXT_SUCCESS;
+       char *result = NULL;
+       char *dev_node = NULL;
+       while(1) {
+               if ((dev_node = _app2sd_find_associated_device_node(pkgid)) == NULL) {
+                       app2ext_print("finish to find the association\n");
+                       ret = APP2EXT_SUCCESS;
+                       break;
+               }
+
+               app2ext_print("find node ::  %s \n", dev_node);
+
+               result = (char *)_app2sd_detach_loop_device(dev_node);
+               if (result == NULL) {
+                       app2ext_print("App2sd Error: Error in detaching\n");
+                       ret = APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE;
+                       break;
+               } else {
+                       free(result);
+                       result = NULL;
+               }
+               if (dev_node) {
+                       free(dev_node);
+                       dev_node = NULL;
+               }
+       }
+       return ret;
+}
+
 int _app2sd_create_loopback_device(const char *pkgid, int size)
 {
        int ret = APP2EXT_SUCCESS;
@@ -429,27 +478,31 @@ int _app2sd_create_file_system(const char *device_path)
 {
        int ret = APP2EXT_SUCCESS;
        FILE *fp = NULL;
-       if (NULL == device_path) {
+       char err_buf[1024] = {0,};
+
+       if (device_path == NULL) {
                app2ext_print("App2Sd Error: invalid param [NULL]\n");
                return APP2EXT_ERROR_INVALID_ARGUMENTS;
        }
 
-       /*Format the filesystem [create a filesystem]*/
+       /* Format the filesystem [create a filesystem]*/
        const char *argv[] = { "/sbin/mkfs.ext4", device_path, NULL };
        fp = fopen(device_path, "r+");
        if (fp == NULL) {
+               strerror_r(errno, err_buf, sizeof(err_buf));
                app2ext_print
                    ("App2sd Error: Unable to access %s [System errono is %d.....%s]\n",
-                    device_path, errno, strerror(errno));
+                    device_path, errno, err_buf);
                return APP2EXT_ERROR_ACCESS_FILE;
        } else {
                fclose(fp);
        }
        ret = _xsystem(argv);
        if (ret) {
+               strerror_r(errno, err_buf, sizeof(err_buf));
                app2ext_print
                    ("App2Sd Error : creating file system failed [System error is %s\n",
-                    strerror(errno));
+                    err_buf);
                return APP2EXT_ERROR_CREATE_FS;
        }
        return ret;
@@ -490,11 +543,20 @@ static int _app2sd_create_dir_with_link(const char *pkgid,
                }
        }
 
-       ret = _app2sd_setup_path(pkgid, app_dir_path, PATH_ANY_LABEL, pkgid);
+       /* TODO */
+       /*
+       ret = _app2sd_setup_path(pkgid, app_dir_path, PERM_APP_PATH_ANY_LABEL, pkgid);
+       if (ret) {
+               app2ext_print ("App2Sd Error : unable to smack %s\n", app_dir_path);
+               return APP2EXT_ERROR_MOVE;
+       }
+
+       ret = _app2sd_setup_path(pkgid, app_dir_mmc_path, PERM_APP_PATH_ANY_LABEL, pkgid);
        if (ret) {
                app2ext_print ("App2Sd Error : unable to smack %s\n", app_dir_mmc_path);
                return APP2EXT_ERROR_MOVE;
        }
+       */
 
        return ret;
 }
@@ -538,6 +600,11 @@ int _app2sd_mount_app_content(const char *pkgid, const char *dev,
        mode_t mode = DIR_PERMS;
        char app_dir_path[FILENAME_MAX] = { 0, };
        char app_dir_mmc_path[FILENAME_MAX] = { 0, };
+       struct timespec time = {
+               .tv_sec = 0,
+               .tv_nsec = 1000 * 1000 * 200
+       };
+
        if (NULL == pkgid || NULL == dev) {
                app2ext_print("App2Sd Error : Input param is NULL %s %s \n",
                             pkgid, dev);
@@ -564,7 +631,7 @@ int _app2sd_mount_app_content(const char *pkgid, const char *dev,
                }
        }
 
-       usleep(200 * 1000);     /* 200ms sleep*/
+       nanosleep(&time, NULL); /* 200ms sleep */
        app2ext_print ("App2Sd info : give a delay for mount\n");
 
        switch (mount_type) {
@@ -572,7 +639,7 @@ int _app2sd_mount_app_content(const char *pkgid, const char *dev,
                {
                        if ((ret =
                             mount(dev, app_dir_mmc_path, FS_TYPE,
-                                  MS_MGC_VAL | MS_RDONLY, NULL)) < 0) {
+                                  MS_MGC_VAL | MS_RDONLY | MS_NOSUID, NULL)) < 0) {
                                app2ext_print
                                    ("App2Sd Error : Read Only Mount failed [System Erro no is %d], dev is %s path is %s\n",
                                     errno, dev, app_dir_mmc_path);
@@ -583,7 +650,7 @@ int _app2sd_mount_app_content(const char *pkgid, const char *dev,
        case MOUNT_TYPE_RW:
                {
                        if ((ret =
-                            mount(dev, app_dir_mmc_path, FS_TYPE, MS_MGC_VAL,
+                            mount(dev, app_dir_mmc_path, FS_TYPE, MS_MGC_VAL | MS_NOSUID,
                                   NULL)) < 0) {
                                app2ext_print
                                    ("App2Sd Error : Read Write Mount failed [System Erro no is %d]\n",
@@ -596,7 +663,7 @@ int _app2sd_mount_app_content(const char *pkgid, const char *dev,
                {
                        if ((ret =
                             mount(dev, app_dir_mmc_path, FS_TYPE,
-                                  MS_MGC_VAL | MS_NOEXEC, NULL)) < 0) {
+                                  MS_MGC_VAL | MS_NOEXEC | MS_NOSUID, NULL)) < 0) {
                                app2ext_print
                                    ("App2Sd Error : RWX Mount failed [System Erro no is %d]\n",
                                     errno);
@@ -608,7 +675,7 @@ int _app2sd_mount_app_content(const char *pkgid, const char *dev,
                {
                        if ((ret =
                             mount(dev, app_dir_mmc_path, FS_TYPE,
-                                  MS_MGC_VAL | MS_RDONLY | MS_REMOUNT,
+                                  MS_MGC_VAL | MS_RDONLY | MS_REMOUNT | MS_NOSUID,
                                   NULL)) < 0) {
                                app2ext_print
                                    ("App2Sd Error : RWX Mount failed [System Erro no is %d]\n",
@@ -621,7 +688,7 @@ int _app2sd_mount_app_content(const char *pkgid, const char *dev,
                {
                        if ((ret =
                             mount(dev, app_dir_mmc_path, FS_TYPE,
-                                  MS_MGC_VAL | MS_REMOUNT, NULL)) < 0) {
+                                  MS_MGC_VAL | MS_REMOUNT | MS_NOSUID, NULL)) < 0) {
                                app2ext_print
                                    ("App2Sd Error : RWX Mount failed [System Erro no is %d]\n",
                                     errno);
@@ -636,7 +703,7 @@ int _app2sd_mount_app_content(const char *pkgid, const char *dev,
                        break;
                }
        }
-       if (cmd == APP2SD_PRE_INSTALL || cmd == APP2SD_MOVE_APP_TO_MMC) {
+       if (cmd == APP2SD_PRE_INSTALL || cmd == APP2SD_MOVE_APP_TO_MMC || cmd == APP2SD_PRE_UPGRADE) {
                ret = _app2sd_create_directory_entry(pkgid, dir_list);
        }
        return ret;
@@ -646,9 +713,12 @@ int _app2sd_unmount_app_content(const char *pkgid)
 {
        int ret = APP2EXT_SUCCESS;
        char app_dir_mmc_path[FILENAME_MAX] = { 0, };
+
        snprintf(app_dir_mmc_path, FILENAME_MAX, "%s%s/.mmc", APP_INSTALLATION_PATH, pkgid);
        if ((ret = umount(app_dir_mmc_path)) < 0) {
-               app2ext_print("Unable to umount the dir %s\n", strerror(errno));
+               char err_buf[1024] = {0,};
+               strerror_r(errno, err_buf, sizeof(err_buf));
+               app2ext_print("Unable to umount the dir %s\n", err_buf);
        }
        return ret;
 }
@@ -658,21 +728,20 @@ static int _app2sd_move_to_archive(const char *src_path, const char *arch_path)
        int ret = APP2EXT_SUCCESS;
 
        ret = _app2sd_copy_dir(src_path, arch_path);
-       if (ret) {
-               if (ret != APP2EXT_ERROR_ACCESS_FILE) {
-                       app2ext_print
-                           ("App2Sd Error : unable to copy from %s to %s .....err is %s\n",
-                            src_path, arch_path, strerror(errno));
-                       return APP2EXT_ERROR_MOVE;
-               }
+       if (ret && ret != APP2EXT_ERROR_ACCESS_FILE) {
+               char err_buf[1024] = {0,};
+               strerror_r(errno, err_buf, sizeof(err_buf));
+               app2ext_print("App2Sd Error : unable to copy from %s to %s .....err is %s\n",
+                               src_path, arch_path, err_buf);
+               return APP2EXT_ERROR_MOVE;
        }
+
        ret = _app2sd_delete_directory((char *)src_path);
-       if (ret) {
-               if (ret != APP2EXT_ERROR_ACCESS_FILE) {
-                       app2ext_print("App2Sd Error : unable to delete %s \n", src_path);
-                       return APP2EXT_ERROR_DELETE_DIRECTORY;
-               }
+       if (ret && ret != APP2EXT_ERROR_ACCESS_FILE) {
+               app2ext_print("App2Sd Error : unable to delete %s \n", src_path);
+               return APP2EXT_ERROR_DELETE_DIRECTORY;
        }
+
        return ret;
 }
 
@@ -686,6 +755,7 @@ int _app2sd_move_app_to_external(const char *pkgid, GList* dir_list)
        char mmc_path[FILENAME_MAX] = { 0, };
        unsigned long long total_size = 0;
        int reqd_size = 0;
+       int reqd_disk_size = 0;
        char *device_node = NULL;
        char *devi = NULL;
        mode_t mode = DIR_PERMS;
@@ -694,7 +764,7 @@ int _app2sd_move_app_to_external(const char *pkgid, GList* dir_list)
        GList *list = NULL;
        app2ext_dir_details* dir_detail = NULL;
 
-       /*Check whether MMC is present or not */
+       /* Check whether MMC is present or not */
        ret = _app2sd_check_mmc_status();
        if (ret) {
                app2ext_print
@@ -706,14 +776,14 @@ int _app2sd_move_app_to_external(const char *pkgid, GList* dir_list)
        snprintf(mmc_path, FILENAME_MAX,
                 "%s%s", APP2SD_PATH, pkgid);
 
-       /*check whether application is in external memory or not */
+       /* check whether application is in external memory or not */
        fp = fopen(mmc_path, "r+");
        if (fp != NULL) {
                app2ext_print
                    ("Already %s entry is present in the SD Card, delete entry and go on without return\n",
                     pkgid);
                fclose(fp);
-//             return APP2EXT_ERROR_ALREADY_FILE_PRESENT;
+               app2sd_force_clean(pkgid);
        }
 
        snprintf(app_mmc_path, FILENAME_MAX,
@@ -727,7 +797,6 @@ int _app2sd_move_app_to_external(const char *pkgid, GList* dir_list)
                        app2ext_print
                            ("App2sd Error: Unable to create directory for archiving, error no is %d\n",
                             errno);
-//                     return APP2EXT_ERROR_CREATE_DIRECTORY;
                }
        }
 
@@ -749,9 +818,10 @@ int _app2sd_move_app_to_external(const char *pkgid, GList* dir_list)
                list = g_list_next(list);
        }
 
-       reqd_size = ((total_size / 1024) / 1024) + 2;
+       reqd_size = ((total_size)/( 1024 * 1024)) + 2;
+       reqd_disk_size = reqd_size + ceil(reqd_size * 0.2);
 
-       /*Find avialable free memory in the MMC card */
+       /* Find avialable free memory in the MMC card */
        ret =
            _app2sd_get_available_free_memory
            (MMC_PATH, &free_mmc_mem);
@@ -761,22 +831,21 @@ int _app2sd_move_app_to_external(const char *pkgid, GList* dir_list)
                     ret);
                return APP2EXT_ERROR_MMC_STATUS;
        }
-       /*If avaialalbe free memory in MMC is less than required size + 5MB , return error */
-       if (reqd_size > free_mmc_mem) {
+       /* If avaialalbe free memory in MMC is less than required size + 5MB , return error */
+       if (reqd_disk_size > free_mmc_mem) {
                app2ext_print
                    ("App2Sd Error : Insufficient memory in MMC for application installation %d\n",
                     ret);
                return APP2EXT_ERROR_MMC_INSUFFICIENT_MEMORY;
        }
-       /*Create a loopback device */
+       /* Create a loopback device */
        ret =
-           _app2sd_create_loopback_device(pkgid, (reqd_size+PKG_BUF_SIZE));
+           _app2sd_create_loopback_device(pkgid, (reqd_disk_size+PKG_BUF_SIZE));
        if (ret) {
                app2ext_print
                    ("App2Sd Error : loopback node creation failed\n");
-//             return APP2EXT_ERROR_CREATE_DEVICE;
        }
-       /*Perform Loopback encryption setup */
+       /* Perform Loopback encryption setup */
        device_node =
            _app2sd_do_loopback_encryption_setup(pkgid);
        if (!device_node) {
@@ -785,7 +854,7 @@ int _app2sd_move_app_to_external(const char *pkgid, GList* dir_list)
                     device_node);
                return APP2EXT_ERROR_DO_LOSETUP;
        }
-       /*Check whether loopback device is associated with device node or not */
+       /* Check whether loopback device is associated with device node or not */
        devi = _app2sd_find_associated_device_node(pkgid);
        if (devi == NULL) {
                app2ext_print
@@ -795,7 +864,7 @@ int _app2sd_move_app_to_external(const char *pkgid, GList* dir_list)
                free(devi);
                devi = NULL;
        }
-       /*Format the loopback file system */
+       /* Format the loopback file system */
        ret = _app2sd_create_file_system(device_node);
        if (ret) {
                app2ext_print
@@ -826,7 +895,6 @@ int _app2sd_move_app_to_external(const char *pkgid, GList* dir_list)
                                            ("App2Sd Error : unable to copy from %s to %s \n",
                                             path,
                                             app_archive_path);
-//                                     return APP2EXT_ERROR_MOVE;
                                }
                        }
                }
@@ -834,7 +902,7 @@ int _app2sd_move_app_to_external(const char *pkgid, GList* dir_list)
        }
        /********Archiving code ends***********/
 
-       /*mount the loopback encrypted pseudo device on application installation path as with Read Write permission */
+       /* mount the loopback encrypted pseudo device on application installation path as with Read Write permission */
        ret =
            _app2sd_mount_app_content(pkgid, device_node,
                                      MOUNT_TYPE_RW, dir_list,
@@ -860,17 +928,12 @@ int _app2sd_move_app_to_external(const char *pkgid, GList* dir_list)
                             app_mmc_path);
                        if (ret) {
                                if (ret == APP2EXT_ERROR_ACCESS_FILE) {
-                                       app2ext_print
-                                           ("App2Sd Error : unable to access %s\n",
-                                            path);
+                                       app2ext_print("App2Sd Error : unable to access %s\n", path);
                                } else {
-                                       app2ext_print
-                                           ("App2Sd Error : unable to copy from %s to %s .....err is %s\n",
-                                            path,
-                                            app_mmc_path,
-                                            strerror
-                                            (errno));
-//                                     return APP2EXT_ERROR_MOVE;
+                                       char err_buf[1024] = {0,};
+                                       strerror_r(errno, err_buf, sizeof(err_buf));
+                                       app2ext_print("App2Sd Error : unable to copy from %s to %s .....err is %s\n",
+                                                       path, app_mmc_path, err_buf);
                                }
                        }
                        ret =
@@ -898,17 +961,19 @@ int _app2sd_move_app_to_external(const char *pkgid, GList* dir_list)
                app2ext_print
                    ("App2Sd Error : unable to delete %s \n",
                     app_archive_path);
-//             return APP2EXT_ERROR_DELETE_DIRECTORY;
        }
 
+       /* TODO */
+       /*
        ret = _app2sd_apply_mmc_smack(pkgid, dir_list, pkgid);
+       */
        if (ret) {
                app2ext_print("App2Sd Error : unable to apply app smack\n");
                return APP2EXT_ERROR_MOVE;
        }
 
-       /*Restore archive ends */
-       /*Re-mount the loopback encrypted pseudo device on application installation path as with Read Only permission */
+       /* Restore archive ends */
+       /* Re-mount the loopback encrypted pseudo device on application installation path as with Read Only permission */
        ret = _app2sd_unmount_app_content(pkgid);
        if (ret) {
                return APP2EXT_ERROR_REMOUNT;
@@ -937,6 +1002,11 @@ int _app2sd_move_app_to_internal(const char *pkgid, GList* dir_list)
        FILE *fp = NULL;
        GList *list = NULL;
        app2ext_dir_details* dir_detail = NULL;
+       int reqd_size = 0;
+       int free_internal_mem = 0;
+       struct statvfs buf = {0,};
+       unsigned long long temp = 0;
+       char err_buf[1024] = {0,};
 
        snprintf(app_mmc_path, FILENAME_MAX,
                 "%s%s/.mmc", APP_INSTALLATION_PATH,  pkgid);
@@ -947,7 +1017,7 @@ int _app2sd_move_app_to_internal(const char *pkgid, GList* dir_list)
        snprintf(mmc_path, FILENAME_MAX,
                 "%s%s", APP2SD_PATH, pkgid);
 
-       /*Check whether MMC is present or not */
+       /* Check whether MMC is present or not */
        ret = _app2sd_check_mmc_status();
        if (ret) {
                app2ext_print
@@ -956,7 +1026,7 @@ int _app2sd_move_app_to_internal(const char *pkgid, GList* dir_list)
                return APP2EXT_ERROR_MMC_STATUS;
        }
 
-       /*check whether application is in external memory or not */
+       /* check whether application is in external memory or not */
        fp = fopen(mmc_path, "r+");
        if (fp == NULL) {
                app2ext_print
@@ -968,11 +1038,54 @@ int _app2sd_move_app_to_internal(const char *pkgid, GList* dir_list)
                fp = NULL;
        }
 
-       /*Get the associated device node for SD card applicationer */
+       memset((void *)&buf, '\0', sizeof(struct statvfs));
+       ret = statvfs(INTERNAL_STORAGE_PATH, &buf);
+       if (0 == ret){
+               temp = (buf.f_bsize * buf.f_bavail)/(1024*1024);
+               free_internal_mem = (int)temp;
+       }else{
+               app2ext_print("App2SD Error: Unable to get internal storage size\n");
+               return APP2EXT_ERROR_MMC_INSUFFICIENT_MEMORY; /* TODO: new error no for internal? */
+       }
+
+       /* check app entry is there in sd card or not. */
+       snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
+                pkgid);
+       app2ext_print("App2Sd Log : Checking path %s\n", app_path);
+       fp = fopen(app_path, "r+");
+       if (fp == NULL) {
+               app2ext_print
+                   ("App2SD Error: App Entry is not present in SD Card\n");
+               return APP2EXT_ERROR_INVALID_PACKAGE;
+       }
+       fclose(fp);
+       /* Get installed app size*/
+       temp = _app2sd_calculate_file_size(app_path);
+       reqd_size = (int)((temp)/(1024 * 1024));
+       app2ext_print("App2Sd Log : Reqd size is %d\n", reqd_size);
+
+       if (reqd_size == 0) {
+               app2ext_print
+                   ("App2SD Error: App Entry is not present in SD Card\n");
+               return APP2EXT_ERROR_LOOPBACK_DEVICE_UNAVAILABLE;
+       }
+
+       app2ext_print("Reqd Size: %d MB, free internal mem %d MB\n", reqd_size, free_internal_mem);
+       /* If avaialalbe free memory in internal storage is less than required size, return error */
+       if (reqd_size > free_internal_mem) {
+               app2ext_print
+                   ("App2Sd Error : Insufficient memory in internal storage for application installation %d\n",
+                    ret);
+               return APP2EXT_ERROR_MMC_INSUFFICIENT_MEMORY; /* TODO: new error no for internal? */
+       }
+       /* Get the associated device node for SD card applicationer */
+       snprintf(app_path, FILENAME_MAX, "%s%s/", APP_INSTALLATION_PATH,
+                pkgid);
+
        device_node =
            _app2sd_find_associated_device_node(pkgid);
        if (NULL == device_node) {
-               /*Do loopback setup */
+               /* Do loopback setup */
                device_node =
                    _app2sd_do_loopback_encryption_setup
                    (pkgid);
@@ -981,7 +1094,7 @@ int _app2sd_move_app_to_internal(const char *pkgid, GList* dir_list)
                            ("App2Sd Error : loopback encryption setup failed\n");
                        return APP2EXT_ERROR_DO_LOSETUP;
                }
-               /*Do  mounting */
+               /* Do mounting */
                ret =
                    _app2sd_mount_app_content(pkgid,
                                              device_node,
@@ -994,7 +1107,7 @@ int _app2sd_move_app_to_internal(const char *pkgid, GList* dir_list)
                        return APP2EXT_ERROR_MOUNT_PATH;
                }
        } else {
-               /*Do  re-mounting */
+               /* Do re-mounting */
                ret =
                    _app2sd_mount_app_content(pkgid,
                                              device_node,
@@ -1012,7 +1125,6 @@ int _app2sd_move_app_to_internal(const char *pkgid, GList* dir_list)
                app2ext_print
                    ("App2Sd Error : unable to create directory%s\n",
                     app_archive_path);
-//             return APP2EXT_ERROR_CREATE_DIRECTORY;
        }
 
 
@@ -1021,7 +1133,7 @@ int _app2sd_move_app_to_internal(const char *pkgid, GList* dir_list)
                dir_detail = (app2ext_dir_details *)list->data;
                if (dir_detail && dir_detail->name
                        && dir_detail->type == APP2EXT_DIR_RO) {
-                               /*Archiving code */
+                               /* Archiving code */
                                memset((void *)&path, '\0',
                                       FILENAME_MAX);
                                snprintf(path, FILENAME_MAX,
@@ -1034,21 +1146,15 @@ int _app2sd_move_app_to_internal(const char *pkgid, GList* dir_list)
                                     app_archive_path);
                                if (ret) {
                                        if (ret == APP2EXT_ERROR_ACCESS_FILE) {
-                                               app2ext_print
-                                                   ("App2Sd Error : unable to access %s\n",
-                                                    path);
+                                               app2ext_print("App2Sd Error : unable to access %s\n", path);
                                        } else {
-                                               app2ext_print
-                                                   ("App2Sd Error : unable to copy from %s to %s .....err is %s\n",
-                                                    path,
-                                                    app_archive_path,
-                                                    strerror
-                                                    (errno));
-//                                             return APP2EXT_ERROR_MOVE;
+                                               strerror_r(errno, err_buf, sizeof(err_buf));
+                                               app2ext_print("App2Sd Error : unable to copy from %s to %s .....err is %s\n",
+                                                               path, app_archive_path, err_buf);
                                        }
                                }
 
-                               /*Delete the symbolic link files [bin, lib, res]*/
+                               /* Delete the symbolic link files [bin, lib, res]*/
                                memset((void *)&path, '\0',
                                       FILENAME_MAX);
                                snprintf(path, FILENAME_MAX,
@@ -1058,46 +1164,34 @@ int _app2sd_move_app_to_internal(const char *pkgid, GList* dir_list)
                                ret = unlink(path);
                                if (ret) {
                                        if (errno == ENOENT) {
-                                               app2ext_print
-                                                   ("App2Sd Error : Directory %s does not exist\n",
-                                                    path);
+                                               app2ext_print("App2Sd Error : Directory %s does not exist\n", path);
                                        } else {
-                                               app2ext_print
-                                                   ("App2Sd Error : unable to remove the symbolic link file %s, it is already unlinked!!!\n",
-                                                    path);
-//                                             return APP2EXT_ERROR_DELETE_LINK_FILE;
+                                               app2ext_print("App2Sd Error : unable to remove the symbolic link file %s,"
+                                                               " it is already unlinked!!!\n", path);
                                        }
                                }
 
-                               /*Copy content to destination */
+                               /* Copy content to destination */
                                memset((void *)&path, '\0',
                                       FILENAME_MAX);
                                snprintf(path, FILENAME_MAX,
-                                        "%s%s/.archive/%s", APP_INSTALLATION_PATH,
-                                        pkgid,
-                                        dir_detail->name);
-                               ret =
-                                   _app2sd_copy_dir
-                                   (path, app_path);
+                                       "%s%s/.archive/%s", APP_INSTALLATION_PATH,
+                                        pkgid, dir_detail->name);
+                               ret = _app2sd_copy_dir(path, app_path);
                                if (ret) {
                                        if (ret == APP2EXT_ERROR_ACCESS_FILE) {
-                                               app2ext_print
-                                                   ("App2Sd Error : unable to access %s\n",
-                                                    path);
+                                               app2ext_print("App2Sd Error : unable to access %s\n", path);
                                        } else {
-                                               app2ext_print
-                                                   ("App2Sd Error : unable to copy from %s to %s .....err is %s\n",
-                                                    path,
-                                                    app_path,
-                                                    strerror
-                                                    (errno));
-//                                             return APP2EXT_ERROR_MOVE;
+                                               strerror_r(errno, err_buf, sizeof(err_buf));
+                                               app2ext_print("App2Sd Error : unable to copy from %s to %s .....err is %s\n",
+                                                               path, app_path, err_buf);
                                        }
                                }
                }
                list = g_list_next(list);
        }
 
+       app2ext_print("App2Sd info : Copying file completed\n");
        ret = _app2sd_unmount_app_content(pkgid);
        if (ret) {
                app2ext_print
@@ -1125,17 +1219,18 @@ int _app2sd_move_app_to_internal(const char *pkgid, GList* dir_list)
                app2ext_print
                    ("App2Sd Error : unable to delete %s \n",
                     app_mmc_path);
-//             return APP2EXT_ERROR_DELETE_DIRECTORY;
        }
        ret = _app2sd_delete_directory(app_archive_path);
        if (ret) {
                app2ext_print
                    ("App2Sd Error : unable to delete %s \n",
                     app_archive_path);
-//             return APP2EXT_ERROR_DELETE_DIRECTORY;
        }
 
+       /* TODO */
+       /*
        ret = _app2sd_apply_app_smack(pkgid, dir_list, pkgid);
+       */
        if (ret) {
                app2ext_print("App2Sd Error : unable to apply app smack\n");
                return APP2EXT_ERROR_MOVE;
@@ -1148,7 +1243,7 @@ int _app2sd_move_app(const char *pkgid, app2ext_move_type move_cmd, GList* dir_l
 {
        int ret = APP2EXT_SUCCESS;
 
-       /*Check whether MMC is present or not */
+       /* Check whether MMC is present or not */
        ret = _app2sd_check_mmc_status();
        if (ret) {
                app2ext_print
@@ -1242,7 +1337,7 @@ int _app2sd_duplicate_device(const char *pkgid, GList* dir_list, char *dev_node,
        int err_res = 0;
        char *result = NULL;
 
-       /*Create a new loopback device */
+       /* Create a new loopback device */
        snprintf(temp_pkgid, FILENAME_MAX,
                 "%s.new", pkgid);
        ret = _app2sd_create_loopback_device(temp_pkgid, (size+PKG_BUF_SIZE));
@@ -1251,7 +1346,7 @@ int _app2sd_duplicate_device(const char *pkgid, GList* dir_list, char *dev_node,
                return ret;
        }
        app2ext_print("App2Sd  : _app2sd_create_loopback_device SUCCESS\n");
-       /*Perform Loopback encryption setup */
+       /* Perform Loopback encryption setup */
        dev_node = _app2sd_do_loopback_duplicate_encryption_setup(pkgid, temp_pkgid);
        if (!dev_node) {
                app2ext_print("App2Sd Error : losetup failed, device node is %s\n", dev_node);
@@ -1260,7 +1355,7 @@ int _app2sd_duplicate_device(const char *pkgid, GList* dir_list, char *dev_node,
                return APP2EXT_ERROR_DO_LOSETUP;
        }
        app2ext_print("App2Sd  : _app2sd_do_loopback_duplicate_encryption_setup SUCCESS\n");
-       /*Check whether loopback device is associated with device node or not */
+       /* Check whether loopback device is associated with device node or not */
        devi = _app2sd_find_associated_device_node(temp_pkgid);
        if (devi == NULL) {
                app2ext_print("App2Sd Error : finding associated device node failed\n");
@@ -1268,7 +1363,7 @@ int _app2sd_duplicate_device(const char *pkgid, GList* dir_list, char *dev_node,
                goto FINISH_OFF;
        }
        app2ext_print("App2Sd  : _app2sd_find_associated_device_node SUCCESS\n");
-       /*Format the loopback file system */
+       /* Format the loopback file system */
        ret = _app2sd_create_file_system(dev_node);
        if (ret) {
                app2ext_print("App2Sd Error : creating FS failed failed\n");
@@ -1276,7 +1371,7 @@ int _app2sd_duplicate_device(const char *pkgid, GList* dir_list, char *dev_node,
                goto FINISH_OFF;
        }
        app2ext_print("App2Sd  : _app2sd_create_file_system SUCCESS\n");
-       /*Do  mounting for new dev*/
+       /* Do mounting for new dev*/
        ret =
            _app2sd_mount_app_content(temp_pkgid, dev_node, MOUNT_TYPE_RW,
                                dir_list, APP2SD_PRE_UPGRADE);
@@ -1332,14 +1427,14 @@ int _app2sd_update_loopback_device_size(const char *pkgid,
        }
 
        app2ext_print("App2Sd  : _app2sd_mount_app_content SUCCESS\n");
-       /*check app entry is there in sd card or not. */
+       /* check app entry is there in sd card or not. */
        snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
                 pkgid);
 
-       /*Get the associated device node for SD card applicatione */
+       /* Get the associated device node for SD card applicatione */
        old_device_node = _app2sd_find_associated_device_node(pkgid);
        if (NULL == old_device_node) {
-               /*Do loopback setup */
+               /* Do loopback setup */
                old_device_node = _app2sd_do_loopback_encryption_setup(pkgid);
                if (old_device_node == NULL) {
                        app2ext_print
@@ -1347,7 +1442,7 @@ int _app2sd_update_loopback_device_size(const char *pkgid,
                        err_res = APP2EXT_ERROR_DO_LOSETUP;
                        goto FINISH_OFF;
                }
-               /*Do  mounting */
+               /* Do mounting */
                ret =
                    _app2sd_mount_app_content(pkgid, old_device_node,
                                              MOUNT_TYPE_RW, dir_list,
@@ -1355,10 +1450,9 @@ int _app2sd_update_loopback_device_size(const char *pkgid,
                if (ret) {
                        app2ext_print("App2Sd Error : Re-mount failed\n");
                        err_res = APP2EXT_ERROR_MOUNT_PATH;
-//                     goto FINISH_OFF;
                }
        } else {
-               /*Do  re-mounting */
+               /* Do re-mounting */
                ret =
                    _app2sd_mount_app_content(pkgid, old_device_node,
                                              MOUNT_TYPE_RW_REMOUNT, dir_list,
@@ -1366,7 +1460,6 @@ int _app2sd_update_loopback_device_size(const char *pkgid,
                if (ret) {
                        app2ext_print("App2Sd Error : Re-mount failed\n");
                        err_res = APP2EXT_ERROR_MOUNT_PATH;
-//                     goto FINISH_OFF;
                }
        }
 
@@ -1379,7 +1472,6 @@ int _app2sd_update_loopback_device_size(const char *pkgid,
        if (ret) {
                app2ext_print("App2Sd Error : copy ro content  failed\n");
                err_res = ret;
-//             goto FINISH_OFF;
        }
 
        ret = _app2sd_unmount_app_content(pkgid);
@@ -1387,13 +1479,11 @@ int _app2sd_update_loopback_device_size(const char *pkgid,
                app2ext_print
                    ("App2SD Error: Unable to unmount the SD application\n");
                err_res = APP2EXT_ERROR_UNMOUNT;
-//             goto FINISH_OFF;
        }
        ret = _app2sd_remove_loopback_encryption_setup(pkgid);
        if (ret) {
                app2ext_print("App2SD Error: Unable to remove loopback setup\n");
                err_res = APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
-//             goto FINISH_OFF;
        }
        ret = _app2sd_unmount_app_content(temp_pkgid);
        if (ret) {
old mode 100755 (executable)
new mode 100644 (file)
index 991c5aa..4446237
@@ -111,18 +111,19 @@ int _app2sd_initialize_db()
 int _app2sd_set_password_in_db(const char *pkgid,
                                      const char *passwd)
 {
-       char query[MAX_QUERY_LEN] = { 0, };
        char *error_message = NULL;
 
-       sqlite3_snprintf(MAX_QUERY_LEN, query, "insert into app2sd(pkgid,password)\
-                       values ('%s','%s')", pkgid, passwd);
+       char *query = sqlite3_mprintf("insert into app2sd(pkgid,password) values (%Q, %Q)", pkgid, passwd);
 
        if (SQLITE_OK != sqlite3_exec(app2sd_db, query, NULL, NULL,
                                      &error_message)) {
                app2ext_print("Don't execute query = %s, error message = %s\n",
                             query, error_message);
+
+               sqlite3_free(query);
                return APP2EXT_ERROR_SQLITE_REGISTRY;
        }
+       sqlite3_free(query);
        app2ext_print("\n sqlite insertion done ");
        return APP2EXT_SUCCESS;
 }
@@ -136,20 +137,20 @@ int _app2sd_set_password_in_db(const char *pkgid,
  */
 int _app2sd_remove_password_from_db(const char *pkgid)
 {
-       char query[MAX_QUERY_LEN] = { 0 };
        char *error_message = NULL;
 
-       sqlite3_snprintf(MAX_QUERY_LEN, query,
-                "delete from app2sd where pkgid LIKE '%s'", pkgid);
+       char *query = sqlite3_mprintf("delete from app2sd where pkgid LIKE %Q", pkgid);
        app2ext_print("\n deletion querys is %s ", query);
 
        if (SQLITE_OK != sqlite3_exec(app2sd_db, query, NULL,
                                      NULL, &error_message)) {
                app2ext_print("Don't execute query = %s, error message = %s\n",
                             query, error_message);
+               sqlite3_free(query);
                return APP2EXT_ERROR_SQLITE_REGISTRY;
        }
 
+       sqlite3_free(query);
        app2ext_print("\n app2sd password deletion done ");
        return APP2EXT_SUCCESS;
 
old mode 100755 (executable)
new mode 100644 (file)
index c63e810..8eeafe0
@@ -28,6 +28,7 @@
 #include <sys/wait.h>
 #include <unistd.h>
 #include <stdlib.h>
+#include <string.h>
 #include <sys/types.h>
 #include <dirent.h>
 #include <sys/stat.h>
 #include <dlog.h>
 #include <sys/statvfs.h>
 #include <errno.h>
-#include <dlfcn.h>
 
 #define        PASSWD_LEN              8
 #define        ASCII_PASSWD_CHAR       93
-#define LIB_PRIVILEGE_CONTROL          "libprivilege-control.so.0"
 
 /*
 ########### Internal APIs ##################
@@ -51,6 +50,8 @@ int _xsystem(const char *argv[])
 {
        int status = 0;
        pid_t pid;
+       char err_buf[1024] = {0,};
+
        pid = fork();
        switch (pid) {
        case -1:
@@ -58,7 +59,10 @@ int _xsystem(const char *argv[])
                return -1;
        case 0:
                /* child */
-               execvp(argv[0], (char *const *)argv);
+               strerror_r(errno, err_buf, sizeof(err_buf));
+               if (execvp(argv[0], (char *const *)argv) < 0) {
+                       fprintf(stderr, "execvp failed %d....%s\n", errno, err_buf);    /*Don't use d_msg_app2sd */
+               }
                _exit(-1);
        default:
                /* parent */
@@ -118,6 +122,7 @@ int _app2sd_get_available_free_memory(const char *sd_path, int *free_mem)
 {
        struct statvfs buf;
        int ret = 0;
+       unsigned long long temp = 0;
        if (sd_path == NULL || free_mem == NULL) {
                app2ext_print("App2Sd Error : Invalid input parameter\n");
                return -1;
@@ -125,54 +130,56 @@ int _app2sd_get_available_free_memory(const char *sd_path, int *free_mem)
        memset((void *)&buf, '\0', sizeof(struct statvfs));
        ret = statvfs(sd_path, &buf);
        if (ret) {
-               app2ext_print
-                   ("App2SD Error: Unable to get SD Card memory information\n");
+               app2ext_print("App2SD Error: Unable to get SD Card memory information\n");
                return APP2EXT_ERROR_MMC_INFORMATION;
        }
-       *free_mem = ((buf.f_bfree * buf.f_bsize) / 1024) / 1024;
+       temp = (unsigned long long)buf.f_bsize*buf.f_bavail;
+       *free_mem = (int)(temp/(1024*1024));
        return 0;
 }
 
 int _app2sd_delete_directory(char *dirname)
 {
        DIR *dp = NULL;
-       struct dirent *ep = NULL;
+       struct dirent ep;
+       struct dirent *er = NULL;
        char abs_filename[FILENAME_MAX] = { 0, };
        int ret = 0;
+
        dp = opendir(dirname);
        if (dp != NULL) {
-               while ((ep = readdir(dp)) != NULL) {
+               while (readdir_r(dp, &ep, &er) == 0 && er != NULL) {
                        struct stat stFileInfo;
 
                        snprintf(abs_filename, FILENAME_MAX, "%s/%s", dirname,
-                               ep->d_name);
+                               ep.d_name);
 
                        if (lstat(abs_filename, &stFileInfo) < 0) {
                                perror(abs_filename);
-                               closedir(dp);
+                               (void)closedir(dp);
                                return -1;
                        }
 
                        if (S_ISDIR(stFileInfo.st_mode)) {
-                               if (strcmp(ep->d_name, ".")
-                                   && strcmp(ep->d_name, "..")) {
+                               if (strcmp(ep.d_name, ".")
+                                   && strcmp(ep.d_name, "..")) {
                                        ret = _app2sd_delete_directory(abs_filename);
-                                       if (ret < 0) {
-                                               closedir(dp);
+                                       if (ret <0) {
+                                               (void)closedir(dp);
                                                return -1;
                                        }
                                }
                        } else {
                                ret = remove(abs_filename);
-                               if (ret < 0) {
-                                       closedir(dp);
+                               if (ret <0) {
+                                       (void)closedir(dp);
                                        return -1;
                                }
                        }
                }
                (void)closedir(dp);
                ret = remove(dirname);
-               if (ret < 0)
+               if (ret <0)
                        return -1;
        } else {
                app2ext_print("Couldn't open the directory[%s]\n", dirname);
@@ -180,6 +187,58 @@ int _app2sd_delete_directory(char *dirname)
        return 0;
 }
 
+void _app2sd_delete_symlink(const char *dirname)
+{
+       int ret = 0;
+       DIR *dp = NULL;
+       struct dirent ep;
+       struct dirent *er = NULL;
+       char abs_filename[FILENAME_MAX] = { 0, };
+
+       app2ext_print("star clean_symlink [%s]", dirname);
+
+       dp = opendir(dirname);
+       if (dp != NULL) {
+               while (readdir_r(dp, &ep, &er) == 0 && er != NULL) {
+                       char mmc_path[PATH_MAX] = {0};
+
+                       if (!strcmp(ep.d_name, ".") || !strcmp(ep.d_name, ".."))
+                               continue;
+
+                       /*get realpath find symlink to ".mmc" and unlink it*/
+                       snprintf(abs_filename, FILENAME_MAX, "%s/%s", dirname, ep.d_name);
+                       char *path = realpath(abs_filename, mmc_path);
+                       if(!path){
+                               app2ext_print("realpath failed\n");
+                       }
+
+                       if (strstr(mmc_path,".mmc")) {
+                               app2ext_print("force unlink [%s]", abs_filename);
+                               if (unlink(abs_filename)) {
+                                       if (errno == ENOENT) {
+                                               app2ext_print("Unable to access file %s\n", abs_filename);
+                                       } else {
+                                               app2ext_print("Unable to delete %s\n", abs_filename);
+                                       }
+                               }
+                       }
+
+               }
+               (void)closedir(dp);
+
+               /*delete ".mmc" folder*/
+               snprintf(abs_filename, FILENAME_MAX, "%s/.mmc", dirname);
+               ret = remove(abs_filename);
+               if (ret == -1) {
+                       return;
+               }
+       } else {
+               app2ext_print("Couldn't open the directory[%s]\n", dirname);
+       }
+
+       app2ext_print("finish clean_symlink");
+}
+
 int _app2sd_copy_dir(const char *src, const char *dest)
 {
        int ret = APP2EXT_SUCCESS;
@@ -208,15 +267,17 @@ unsigned long long _app2sd_calculate_dir_size(char *dirname)
 {
        static unsigned long long total = 0;
        DIR *dp = NULL;
-       struct dirent *ep = NULL;
+       struct dirent ep;
+       struct dirent *er = NULL;
        char abs_filename[FILENAME_MAX] = { 0, };;
+
        dp = opendir(dirname);
        if (dp != NULL) {
-               while ((ep = readdir(dp)) != NULL) {
+               while (readdir_r(dp, &ep, &er) == 0 && er != NULL) {
                        struct stat stFileInfo;
 
                        snprintf(abs_filename, FILENAME_MAX, "%s/%s", dirname,
-                                ep->d_name);
+                                ep.d_name);
 
                        if (stat(abs_filename, &stFileInfo) < 0)
                                perror(abs_filename);
@@ -224,8 +285,8 @@ unsigned long long _app2sd_calculate_dir_size(char *dirname)
                                total += stFileInfo.st_size;
 
                                if (S_ISDIR(stFileInfo.st_mode)) {
-                                       if (strcmp(ep->d_name, ".")
-                                           && strcmp(ep->d_name, "..")) {
+                                       if (strcmp(ep.d_name, ".")
+                                           && strcmp(ep.d_name, "..")) {
                                                _app2sd_calculate_dir_size
                                                    (abs_filename);
                                        }
@@ -264,6 +325,8 @@ char *_app2sd_encrypt_device(const char *device, const char *pkgid,
        char buf[FILENAME_MAX] = { 0, };
        char *ret_result = NULL;
        int result = 0;
+       char err_buf[1024] = {0,};
+
        if (pipe(my_pipe) < 0) {
                fprintf(stderr, "Unable to create pipe\n");
                return NULL;
@@ -279,24 +342,29 @@ char *_app2sd_encrypt_device(const char *device, const char *pkgid,
                close(2);
                result = dup(my_pipe[1]);
                if (result < 0) {
-                       fprintf(stderr, "dup failed %d....%s\n", errno, strerror(errno));
+                       strerror_r(errno, err_buf, sizeof(err_buf));
+                       fprintf(stderr, "dup failed %d....%s\n", errno, err_buf);
                        _exit(-1);
                }
                result = dup(my_pipe[1]);
                if (result < 0) {
-                       fprintf(stderr, "dup failed %d....%s\n", errno, strerror(errno));
+                       strerror_r(errno, err_buf, sizeof(err_buf));
+                       fprintf(stderr, "dup failed %d....%s\n", errno, err_buf);
                        _exit(-1);
                }
                if (execvp(argv[0], (char *const *)argv) < 0) {
-                       fprintf(stderr, "execvp failed %d....%s\n", errno, strerror(errno));    /*Don't use d_msg_app2sd */
+                       strerror_r(errno, err_buf, sizeof(err_buf));
+                       fprintf(stderr, "execvp failed %d....%s\n", errno, err_buf);    /*Don't use d_msg_app2sd */
                }
                _exit(-1);
        default:
                /* parent */
                close(my_pipe[1]);
                result = read(my_pipe[0], buf, FILENAME_MAX);
-               if (result < 0)
-                       fprintf(stderr, "read failed %d....%s\n", errno, strerror(errno));
+               if (result < 0) {
+                       strerror_r(errno, err_buf, sizeof(err_buf));
+                       fprintf(stderr, "read failed %d....%s\n", errno, err_buf);
+               }
                break;
        }
 
@@ -319,6 +387,8 @@ char *_app2sd_detach_loop_device(const char *device)
        char buf[FILENAME_MAX] = { 0, };
        char *ret_result = NULL;
        int result = 0;
+       char err_buf[1024] = {0,};
+
        if (pipe(my_pipe) < 0) {
                fprintf(stderr, "Unable to create pipe\n");
                return NULL;
@@ -334,12 +404,14 @@ char *_app2sd_detach_loop_device(const char *device)
                close(2);
                result = dup(my_pipe[1]);
                if (result < 0) {
-                       fprintf(stderr, "dup failed %d....%s\n", errno, strerror(errno));
+                       strerror_r(errno, err_buf, sizeof(err_buf));
+                       fprintf(stderr, "dup failed %d....%s\n", errno, err_buf);
                        _exit(-1);
                }
                result = dup(my_pipe[1]);
                if (result < 0) {
-                       fprintf(stderr, "dup failed %d....%s\n", errno, strerror(errno));
+                       strerror_r(errno, err_buf, sizeof(err_buf));
+                       fprintf(stderr, "dup failed %d....%s\n", errno, err_buf);
                        _exit(-1);
                }
                if (execvp(argv[0], (char *const *)argv) < 0) {
@@ -350,8 +422,10 @@ char *_app2sd_detach_loop_device(const char *device)
                /* parent */
                close(my_pipe[1]);
                result = read(my_pipe[0], buf, FILENAME_MAX);
-               if (result < 0)
-                       fprintf(stderr, "read failed %d....%s\n", errno, strerror(errno));
+               if (result < 0) {
+                       strerror_r(errno, err_buf, sizeof(err_buf));
+                       fprintf(stderr, "read failed %d....%s\n", errno, err_buf);
+               }
                break;
        }
 
@@ -366,7 +440,7 @@ char *_app2sd_detach_loop_device(const char *device)
        return ret_result;
 }
 
-/*Note: Don't use any printf statement inside this function*/
+/* Note: Don't use any printf statement inside this function*/
 char *_app2sd_find_associated_device(const char *mmc_app_path)
 {
        const char *argv[] = { "/sbin/losetup", "-j", mmc_app_path, NULL };
@@ -375,6 +449,8 @@ char *_app2sd_find_associated_device(const char *mmc_app_path)
        char buf[FILENAME_MAX] = { 0, };
        char *ret_result = NULL;
        int result = 0;
+       char err_buf[1024] = {0,};
+
        if (pipe(my_pipe) < 0) {
                fprintf(stderr, "Unable to create pipe\n");
                return NULL;
@@ -390,24 +466,28 @@ char *_app2sd_find_associated_device(const char *mmc_app_path)
                close(2);
                result = dup(my_pipe[1]);
                if (result < 0) {
-                       fprintf(stderr, "dup failed %d....%s\n", errno, strerror(errno));
+                       strerror_r(errno, err_buf, sizeof(err_buf));
+                       fprintf(stderr, "dup failed %d....%s\n", errno, err_buf);
                        _exit(-1);
                }
                result = dup(my_pipe[1]);
                if (result < 0) {
-                       fprintf(stderr, "dup failed %d....%s\n", errno, strerror(errno));
+                       strerror_r(errno, err_buf, sizeof(err_buf));
+                       fprintf(stderr, "dup failed %d....%s\n", errno, err_buf);
                        _exit(-1);
                }
                if (execvp(argv[0], (char *const *)argv) < 0) {
-                       fprintf(stderr, "execvp failed\n");     /*Don't use d_msg_app2sd */
+                       fprintf(stderr, "execvp failed\n");     /* Don't use d_msg_app2sd */
                }
                _exit(-1);
        default:
                /* parent */
                close(my_pipe[1]);
                result = read(my_pipe[0], buf, FILENAME_MAX);
-               if (result < 0)
-                       fprintf(stderr, "read failed %d....%s\n", errno, strerror(errno));
+               if (result < 0) {
+                       strerror_r(errno, err_buf, sizeof(err_buf));
+                       fprintf(stderr, "read failed %d....%s\n", errno, err_buf);
+               }
                break;
        }
 
@@ -428,9 +508,11 @@ char *_app2sd_find_free_device(void)
        const char *argv[] = { "/sbin/losetup", "-f", NULL };
        pid_t pid;
        int my_pipe[2] = { 0, };
-       char buf[FILENAME_MAX+1] = { 0, };
+       char buf[FILENAME_MAX + 1] = { 0, };
        char *ret_result = NULL;
        int result = 0;
+       char err_buf[1024] = {0,};
+
        if (pipe(my_pipe) < 0) {
                fprintf(stderr, "Unable to create pipe\n");
                return NULL;
@@ -446,12 +528,14 @@ char *_app2sd_find_free_device(void)
                close(2);
                result = dup(my_pipe[1]);
                if (result < 0) {
-                       fprintf(stderr, "dup failed %d....%s\n", errno, strerror(errno));
+                       strerror_r(errno, err_buf, sizeof(err_buf));
+                       fprintf(stderr, "dup failed %d....%s\n", errno, err_buf);
                        _exit(-1);
                }
                result = dup(my_pipe[1]);
                if (result < 0) {
-                       fprintf(stderr, "dup failed %d....%s\n", errno, strerror(errno));
+                       strerror_r(errno, err_buf, sizeof(err_buf));
+                       fprintf(stderr, "dup failed %d....%s\n", errno, err_buf);
                        _exit(-1);
                }
                if (execvp(argv[0], (char *const *)argv) < 0) {
@@ -462,8 +546,10 @@ char *_app2sd_find_free_device(void)
                /* parent */
                close(my_pipe[1]);
                result = read(my_pipe[0], buf, FILENAME_MAX);
-               if (result < 0)
-                       fprintf(stderr, "read failed %d....%s\n", errno, strerror(errno));
+               if (result < 0) {
+                       strerror_r(errno, err_buf, sizeof(err_buf));
+                       fprintf(stderr, "read failed %d....%s\n", errno, err_buf);
+               }
                break;
        }
 
@@ -492,6 +578,7 @@ char *_app2sd_generate_password(const char *pkgid)
        int i = 0;
        int appname_len = strlen(pkgid);
        int j = appname_len;
+       unsigned int seed;
 
        /* Length of the password */
        ret_result = (char*)malloc(PASSWD_LEN+1);
@@ -502,8 +589,9 @@ char *_app2sd_generate_password(const char *pkgid)
        memset((void *)ret_result, '\0', PASSWD_LEN+1);
 
        while(i < PASSWD_LEN) {
-               char_1 = (rand()+pkgid[j--])%ASCII_PASSWD_CHAR;
-               char_2 = rand()%ASCII_PASSWD_CHAR;
+               seed = time(NULL);
+               char_1 = (rand_r(&seed)+pkgid[j--])%ASCII_PASSWD_CHAR;
+               char_2 = rand_r(&seed)%ASCII_PASSWD_CHAR;
                passwd[i] = set[char_1];
                passwd[i+1] = set[(pkgid[j--])*2];
                if (i<PASSWD_LEN-3)
@@ -515,47 +603,3 @@ char *_app2sd_generate_password(const char *pkgid)
        memcpy(ret_result, passwd, PASSWD_LEN+1);
        return ret_result;
 }
-
-/*@_app2sd_setup_path
-* change smack label given groupid
-* return: On success, it will return the password, else NULL.
-*/
-int _app2sd_setup_path(const char *pkgid, const char *dirpath,
-                                               int apppathtype, const char *groupid)
-{
-       int ret = 0;
-       void *handle = NULL;
-       char *errmsg = NULL;
-       int (*perm_app_setup_path)(const char*, const char*, int, ...) = NULL;
-
-       if (pkgid == NULL || dirpath == NULL)
-               return -1;
-
-       handle = dlopen(LIB_PRIVILEGE_CONTROL, RTLD_LAZY | RTLD_GLOBAL);
-       if (!handle) {
-               app2ext_print( "setup path: dlopen() failed. [%s]", dlerror());
-               return -1;
-       }
-
-       perm_app_setup_path = dlsym(handle, "perm_app_setup_path");
-       errmsg = dlerror();
-       if ((errmsg != NULL) || (perm_app_setup_path == NULL)) {
-               app2ext_print( "setup path: dlsym() failed. [%s]", errmsg);
-               dlclose(handle);
-               return -1;
-       }
-
-       if (groupid == NULL) {
-               app2ext_print( "[smack] perm_app_setup_path(%s, %s, %d)", pkgid, dirpath, apppathtype);
-               ret = perm_app_setup_path(pkgid, dirpath, apppathtype);
-               app2ext_print( "[smack] perm_app_setup_path(), result = [%d]", ret);
-       } else {
-               app2ext_print( "[smack] perm_app_setup_path(%s, %s, %d, %s)", pkgid, dirpath, apppathtype, groupid);
-               ret = perm_app_setup_path(pkgid, dirpath, apppathtype, groupid);
-               app2ext_print( "[smack] perm_app_setup_path(), result = [%d]", ret);
-       }
-
-       dlclose(handle);
-       return ret;
-}
-
old mode 100755 (executable)
new mode 100644 (file)
index e075417..f01262d
@@ -120,6 +120,13 @@ int app2ext_get_app_location(const char *appname)
        snprintf(app_mmc_internal_path, FILENAME_MAX,
        "%s%s/.mmc", APP_INSTALLATION_PATH, appname);
 
+       app2ext_print("MMC_PATH = (%s)\n", MMC_PATH);
+       app2ext_print("APP2SD_PATH = (%s)\n", APP2SD_PATH);
+       app2ext_print("APP_INSTALLATION_PATH = (%s)\n", APP_INSTALLATION_PATH);
+       app2ext_print("APP_INSTALLATION_USER_PATH = (%s)\n", APP_INSTALLATION_USER_PATH);
+       app2ext_print("app_dir_path = (%s)\n", app_dir_path);
+       app2ext_print("app_mmc_path = (%s)\n", app_mmc_path);
+       app2ext_print("app_mmc_internal_path = (%s)\n", app_mmc_internal_path);
 
        /*check whether application is in external memory or not */
        fp = fopen(app_mmc_path, "r");
@@ -132,6 +139,7 @@ int app2ext_get_app_location(const char *appname)
        /*check whether application is in internal or not */
        fp = fopen(app_dir_path, "r");
        if (fp == NULL) {
+               app2ext_print("app_dir_path open failed, package not installed\n");
                return APP2EXT_NOT_INSTALLED;
        } else {
                fclose(fp);
@@ -139,9 +147,11 @@ int app2ext_get_app_location(const char *appname)
                        but SD card is not present*/
                fp = fopen(app_mmc_internal_path, "r");
                if (fp == NULL) {
+                       app2ext_print("internal mem\n");
                        return APP2EXT_INTERNAL_MEM;
                } else {
                        fclose(fp);
+                       app2ext_print("app_mmc_internal_path exists, error mmc status\n");
                        return APP2EXT_ERROR_MMC_STATUS;
                }
        }
@@ -173,6 +183,7 @@ int app2ext_enable_external_pkg(const char *pkgid)
 
                app2_handle->interface.enable(pkgid);
                app2ext_deinit(app2_handle);
+               app2ext_print("App2Ext enable_external_pkg [%s]\n", pkgid);
        }
        return 0;
 }
@@ -203,6 +214,7 @@ int app2ext_disable_external_pkg(const char *pkgid)
 
                app2_handle->interface.disable(pkgid);
                app2ext_deinit(app2_handle);
+               app2ext_print("App2Ext disable_external_pkg [%s]\n", pkgid);
        }
        return 0;
 }
@@ -212,7 +224,7 @@ int app2ext_enable_external_dir(void)
        int ret = 0;
        DIR *dir = NULL;
        char buf[FILENAME_MAX] = { 0, };
-       struct dirent entry, *result;
+       struct dirent entry, *result = NULL;
 
        dir = opendir(APP2SD_PATH);
        if (!dir) {
@@ -236,7 +248,7 @@ int app2ext_disable_external_dir(void)
        int ret = 0;
        DIR *dir = NULL;
        char buf[FILENAME_MAX] = { 0, };
-       struct dirent entry, *result;
+       struct dirent entry, *result = NULL;
 
        dir = opendir(APP2SD_PATH);
        if (!dir) {
@@ -254,3 +266,36 @@ int app2ext_disable_external_dir(void)
        closedir(dir);
        return 0;
 }
+
+int app2ext_force_clean_pkg(const char *pkgid)
+{
+       /*Validate the function parameter received */
+       if (pkgid == NULL) {
+               app2ext_print("invalid func parameters\n");
+               return 0;
+       }
+
+       FILE *fp = NULL;
+       app2ext_handle *app2_handle = NULL;
+       char app_mmc_path[FILENAME_MAX] = { 0, };
+       snprintf(app_mmc_path, FILENAME_MAX, "%s%s/.mmc", APP_INSTALLATION_PATH, pkgid);
+
+       fp = fopen(app_mmc_path, "r");
+       if (fp == NULL) {
+               return 0;
+       } else {
+               fclose(fp);
+       }
+
+       app2_handle = app2ext_init(APP2EXT_SD_CARD);
+       if (app2_handle == NULL) {
+               app2ext_print("app2_handle : app2ext init failed\n");
+               return 0;
+       }
+
+       app2_handle->interface.force_clean(pkgid);
+       app2ext_deinit(app2_handle);
+       app2ext_print("App2Ext force_clean_pkg [%s]\n", pkgid);
+       return 0;
+}
+
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
new file mode 100644 (file)
index 0000000..8d68e7a
--- /dev/null
@@ -0,0 +1,34 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(test_app2ext C)
+
+SET(SOURCE_DIR ${CMAKE_SOURCE_DIR})
+
+SET(SRCS
+       ${SOURCE_DIR}/test/src/test_app2ext.c
+)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED dlog)
+
+FOREACH(flag ${pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+pkg_check_modules(libpkgs REQUIRED dlog)
+
+FOREACH(flag ${libpkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+### Local include directories
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/inc)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIE ${EXTRA_CFLAGS}")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g -Wall -Wextra -fPIE")
+SET(CMAKE_C_FLAGS_RELEASE "-O3 -fPIE")
+
+ADD_EXECUTABLE(test_app2ext ${SRCS})
+TARGET_LINK_LIBRARIES(test_app2ext app2ext -ldl ${pkgs_LDFLAGS} "-pie")
+
+INSTALL(TARGETS test_app2ext DESTINATION /usr/bin COMPONENT Runtime)
+
diff --git a/test/src/test_app2ext.c b/test/src/test_app2ext.c
new file mode 100644 (file)
index 0000000..12304c4
--- /dev/null
@@ -0,0 +1,505 @@
+/*
+ * test_app2ext
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <app2ext_interface.h>
+
+#define SUCCESS 0
+#define FAIL 1
+#define CMD_LEN 256
+
+app2ext_handle *handle = NULL;
+
+#define PKGNAME_INSTALL "org.example.basicuiapplication"
+#define PKGNAME_UPGRADE "org.example.basicuiapplication"
+
+char pkg_ro_content_rpm[3][5] = { "bin", "res", "lib" };
+
+char error_list[45][100] = {
+       "SUCCESS",
+       "APP2EXT_ERROR_UNKNOW",
+       "APP2EXT_ERROR_INVALID_ARGUMENTS",
+       "APP2EXT_ERROR_MOVE",
+       "APP2EXT_ERROR_PRE_UNINSTALL",
+       "APP2EXT_ERROR_MMC_STATUS",
+       "APP2EXT_ERROR_DB_INITIALIZE",
+       "APP2EXT_ERROR_SQLITE_REGISTRY",
+       "APP2EXT_ERROR_PASSWD_GENERATION",
+       "APP2EXT_ERROR_MMC_INFORMATION",
+       "APP2EXT_ERROR_MMC_INSUFFICIENT_MEMORY",
+       "APP2EXT_ERROR_DELETE_DIRECTORY",
+       "APP2EXT_ERROR_CREATE_SYMLINK",
+       "APP2EXT_ERROR_CREATE_DIRECTORY",
+       "APP2EXT_ERROR_DELETE_LINK_FILE",
+       "APP2EXT_ERROR_PKG_EXISTS",
+       "APP2EXT_ERROR_ACCESS_FILE",
+       "APP2EXT_ERROR_OPEN_DIR",
+       "APP2EXT_ERROR_ALREADY_FILE_PRESENT",
+       "APP2EXT_ERROR_FILE_ABSENT",
+       "APP2EXT_ERROR_STRCMP_FAILED",
+       "APP2EXT_ERROR_INVALID_PACKAGE",
+       "APP2EXT_ERROR_CREATE_DIR_ENTRY",
+       "APP2EXT_ERROR_PASSWORD_GENERATION",
+       "APP2EXT_ERROR_COPY_DIRECTORY",
+       "APP2EXT_ERROR_INVALID_CASE",
+       "APP2EXT_ERROR_SYMLINK_ALREADY_EXISTS",
+       "APP2EXT_ERROR_APPEND_HASH_TO_FILE",
+       "APP2EXT_ERROR_CREATE_DEVICE",
+       "APP2EXT_ERROR_DO_LOSETUP",
+       "APP2EXT_ERROR_CREATE_FS",
+       "APP2EXT_ERROR_MOUNT_PATH",
+       "APP2EXT_ERROR_CLEANUP",
+       "APP2EXT_ERROR_MOUNT",
+       "APP2EXT_ERROR_REMOUNT",
+       "APP2EXT_ERROR_PIPE_CREATION",
+       "APP2EXT_ERROR_LOOPBACK_DEVICE_UNAVAILABLE",
+       "APP2EXT_ERROR_VCONF_REGISTRY",
+       "APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_NODE",
+       "APP2EXT_ERROR_UNMOUNT",
+       "APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE",
+       "APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE",
+       "APP2EXT_ERROR_ALREADY_MOUNTED",
+       "APP2EXT_ERROR_PLUGIN_INIT_FAILED",
+       "APP2EXT_ERROR_PLUGIN_DEINIT_FAILED"
+};
+
+static int __get_integer_input_data(void);
+
+static char *__get_string_input_data(void);
+
+static int __get_integer_input_data(void)
+{
+       char input_str[32] = { 0, };
+       int data = 0;
+
+       if (fgets(input_str, 32, stdin) == NULL) {
+               printf("Input buffer overflow....\n");
+               return -1;
+       }
+
+       if (sscanf(input_str, "%4d", &data) != 1) {
+               printf("Input only integer option....\n");
+               return -1;
+       }
+
+       return data;
+}
+
+static void Usage(void)
+{
+       printf("\n*********************************************\n");
+       printf("\n Test Suite Usage \n");
+       printf("\n Test_id      test_case\n");
+       printf("\n   1          TC_app_install (Pre-install,Install, Post-install, OnDemand init, App Launch, OnDemand Exit)\n");
+       printf("\n   2          TC_app_uninstall (Pre-uninstall, Uninstall, Post-uninstall)\n");
+       printf("\n   3          TC_app_upgrade (Pre-upgrade, Upgrade, Post-Upgrade)\n");
+       printf("\n   4          TC_app_move\n");
+       printf("\n   5          TC_app_get_location\n");
+       printf("\n   6          Exit\n");
+}
+
+GList * populate_dir_details()
+{
+       GList *dir_list = NULL;
+       GList *list = NULL;
+       app2ext_dir_details* dir_detail = NULL;
+       int i;
+
+
+       for (i=0; i<3; i++) {
+               dir_detail = (app2ext_dir_details*) calloc(1, sizeof(app2ext_dir_details));
+               if (dir_detail == NULL) {
+                       printf("\nMemory allocation failed\n");
+                       goto FINISH_OFF;
+               }
+               dir_detail->name = (char*) calloc(1, sizeof(char)*(strlen(pkg_ro_content_rpm[i])+2));
+               if (dir_detail->name == NULL) {
+                       printf("\nMemory allocation failed\n");
+                       free(dir_detail);
+                       goto FINISH_OFF;
+               }
+               snprintf(dir_detail->name, (strlen(pkg_ro_content_rpm[i])+1), "%s", pkg_ro_content_rpm[i]);
+               dir_detail->type = APP2EXT_DIR_RO;
+               dir_list = g_list_append(dir_list, dir_detail);
+       }
+       if (dir_list) {
+               list = g_list_first(dir_list);
+               while (list) {
+                       dir_detail = (app2ext_dir_details *)list->data;
+                       list = g_list_next(list);
+               }
+       }
+       return dir_list;
+FINISH_OFF:
+       if (dir_list) {
+               list = g_list_first(dir_list);
+               while (list) {
+                       dir_detail = (app2ext_dir_details *)list->data;
+                       if (dir_detail && dir_detail->name) {
+                               free(dir_detail->name);
+                       }
+                       list = g_list_next(list);
+               }
+               g_list_free(dir_list);
+       }
+       return NULL;
+}
+
+void clear_dir_list(GList* dir_list)
+{
+       GList *list = NULL;
+       app2ext_dir_details* dir_detail = NULL;
+       if (dir_list) {
+               list = g_list_first(dir_list);
+               while (list) {
+                       dir_detail = (app2ext_dir_details *)list->data;
+                       if (dir_detail && dir_detail->name) {
+                               free(dir_detail->name);
+                       }
+                       list = g_list_next(list);
+               }
+               g_list_free(dir_list);
+       }
+}
+
+int TC_app_install()
+{
+       printf("TC_app_install %s \n", PKGNAME_INSTALL);
+       GList *dir_list = NULL;
+       int ret = -1;
+
+       //char cmd_install[CMD_LEN+1];
+       //snprintf(cmd_install, CMD_LEN,"tpk-backend -y %s", PKGNAME_INSTALL);
+
+       dir_list = populate_dir_details();
+       if (dir_list == NULL) {
+               printf("\nError in populating the directory list\n");
+               return -1;
+       }
+       ret = handle->interface.pre_install(PKGNAME_INSTALL, dir_list, 20);
+       if (ret) {
+               printf("\n TC : pre app install API fail. Reason %s", error_list[ret]);
+               clear_dir_list(dir_list);
+               return -1;
+       }
+
+       /*
+       printf("\n cmd_install is %s ", cmd_install);
+       ret = system(cmd_install);
+       if (ret) {
+
+               printf("\n TC :  tpk-backend  install command  fail %d ", ret);
+               ret = handle->interface.post_install(PKGNAME_INSTALL, 1);
+               if (ret) {
+                       printf("\n TC : post app install API fail Reason %s", error_list[ret]);
+               }
+               clear_dir_list(dir_list);
+               return -1;
+       }
+       */
+
+       ret = handle->interface.post_install(PKGNAME_INSTALL, 2);
+       if (ret) {
+               printf("\n TC : post app install API fail Reason %s", error_list[ret]);
+               clear_dir_list(dir_list);
+               return -1;
+       }
+
+       ret = handle->interface.enable(PKGNAME_INSTALL);
+       if (ret) {
+               printf("\n TC : app enable API fail Reason %s", error_list[ret]);
+               clear_dir_list(dir_list);
+               return -1;
+       }
+
+       /*
+       printf("\nLaunching application after install");
+       ret = aul_open_app(PKGNAME_INSTALL);
+
+       if (ret < 0)
+               printf("\n launch fail");
+       else
+               printf("\n application launched");
+
+       sleep(5);
+
+       ret = system("killall -9 basicuiapplication");
+       if (ret < 0)
+               printf("\n app exit fail");
+       else
+               printf("\n application exited");
+
+       sleep(5);
+       */
+
+       ret = handle->interface.disable(PKGNAME_INSTALL);
+       if (ret < 0 || ret > 44) {
+               printf("Unknown error\n");
+       } else {
+               printf("Returned Result: %s\n", error_list[ret]);
+       }
+       clear_dir_list(dir_list);
+       return ret;
+}
+
+int TC_app_uninstall()
+{
+       printf("TC_app_uninstall  %s \n", PKGNAME_INSTALL);
+       int ret = -1;
+       //char cmd_uninstall[CMD_LEN+1];
+       //snprintf(cmd_uninstall, CMD_LEN, "tpk-backend -y %s", PKGNAME_INSTALL);
+
+       ret = handle->interface.pre_uninstall(PKGNAME_INSTALL);
+       if (ret) {
+               printf("\n TC : pre app uninstall API fail. Reason %s", error_list[ret]);
+               return -1;
+       }
+
+       /*
+       printf("\n cmd_uninstall is %s ", cmd_uninstall);
+       ret = system(cmd_uninstall);
+       if (ret) {
+               printf("\n TC :  rpm  uninstall command  fail Reason %s", error_list[ret]);
+               return -1;
+       }
+       */
+
+       ret = handle->interface.post_uninstall(PKGNAME_INSTALL);
+       if (ret) {
+               printf("\n TC : post app uninstall API fail Reason %s", error_list[ret]);
+               return -1;
+       }
+
+       return ret;
+}
+
+int TC_app_upgrade()
+{
+       printf("TC_app_uninstall  %s \n", PKGNAME_INSTALL);
+       int ret = -1;
+       //char cmd_uninstall[CMD_LEN+1];
+       //snprintf(cmd_uninstall, CMD_LEN, "rpm -U %s", PKGNAME_UPGRADE);
+
+       GList *dir_list = populate_dir_details();
+       if (dir_list == NULL) {
+               printf("\nError in populating the directory list\n");
+               return -1;
+       }
+
+       ret = handle->interface.pre_upgrade(PKGNAME_INSTALL, dir_list, 40);
+       if (ret) {
+               printf("\n TC : pre app upgrade API fail. Reason %s", error_list[ret]);
+               clear_dir_list(dir_list);
+               return -1;
+       }
+
+       /*
+       printf("\n cmd_uninstall is %s ", cmd_uninstall);
+       ret = system(cmd_uninstall);
+       if (ret) {
+               printf("\n TC :  rpm  upgrade command  fail Reason %s", error_list[ret]);
+               ret = handle->interface.post_upgrade(PKGNAME_INSTALL_RPM, 1);
+               if (ret) {
+                       printf("\n TC : post app upgrade API fail Reason %s", error_list[ret]);
+               }
+               clear_dir_list(dir_list);
+               return -1;
+       }
+       */
+
+       ret = handle->interface.post_upgrade(PKGNAME_INSTALL, 2);
+       if (ret) {
+               printf("\n TC : post app upgrade API fail Reason %s", error_list[ret]);
+               clear_dir_list(dir_list);
+               return -1;
+       }
+       clear_dir_list(dir_list);
+       return ret;
+}
+
+int TC_app_move()
+{
+       printf("TC_app_move  %s \n", PKGNAME_INSTALL);
+       int ret = -1;
+       int ret_check = -1;
+       GList *dir_list = populate_dir_details();
+       if (dir_list == NULL) {
+               printf("\nError in populating the directory list\n");
+               return -1;
+       }
+
+       ret = app2ext_get_app_location(PKGNAME_INSTALL);
+       printf("return value = (%d)", ret);
+       if (ret == APP2EXT_SD_CARD) {
+               printf("\n app %s is in sd card ", PKGNAME_INSTALL);
+               printf("\n app  %s  will be moved to internal memory ",
+                      PKGNAME_INSTALL);
+               ret = handle->interface.move(PKGNAME_INSTALL, dir_list, APP2EXT_MOVE_TO_PHONE);
+               if (ret) {
+                       printf("\n  TC: move API failed Reason %s", error_list[ret]);
+                       clear_dir_list(dir_list);
+                       return -1;
+               }
+               ret = app2ext_get_app_location(PKGNAME_INSTALL);
+               if (ret_check == APP2EXT_INTERNAL_MEM)
+                       printf("\n app %s is moved to internal memory ",
+                              PKGNAME_INSTALL);
+       } else if (ret == APP2EXT_INTERNAL_MEM) {
+               printf("\n app %s  is  in internal memory ", PKGNAME_INSTALL);
+               printf("\n app %s will be moved to sd card", PKGNAME_INSTALL);
+
+               ret = handle->interface.move(PKGNAME_INSTALL, dir_list, APP2EXT_MOVE_TO_EXT);
+               if (ret) {
+                       printf("\n  TC: move API failed Reason %s", error_list[ret]);
+                       clear_dir_list(dir_list);
+                       return -1;
+               }
+               ret = app2ext_get_app_location(PKGNAME_INSTALL);
+               if (ret_check == APP2EXT_SD_CARD)
+                       printf("\n app %s is moved to sd card ",
+                              PKGNAME_INSTALL);
+       }  else {
+               ret = APP2EXT_ERROR_INVALID_PACKAGE;
+               printf("\n errorReason %s", error_list[ret]);
+               clear_dir_list(dir_list);
+               return ret;
+       }
+       clear_dir_list(dir_list);
+       return ret;
+}
+
+void TC_app_get_location()
+{
+       printf("TC_app_get_location  %s \n", PKGNAME_INSTALL);
+       int ret = -1;
+
+       ret = app2ext_get_app_location(PKGNAME_INSTALL);
+       if (ret == APP2EXT_SD_CARD) {
+               printf("\n app %s is in sd card ", PKGNAME_INSTALL);
+       } else if (ret == APP2EXT_INTERNAL_MEM) {
+               printf("\n app %s  is  in internal memory ", PKGNAME_INSTALL);
+       } else {
+               printf("\napp %s is not installed", PKGNAME_INSTALL);
+       }
+}
+
+void TC_enable_external_dir()
+{
+       printf("TC_enable_external_dir\n");
+       int ret = -1;
+
+       ret = app2ext_enable_external_dir();
+       if (ret == 0) {
+               printf("\n app2ext_enable_external_dir() success");
+       } else {
+               printf("\n app2ext_enable_external_dir() failed");
+       }
+}
+
+void TC_disable_external_dir()
+{
+       printf("TC_disable_external_dir\n");
+       int ret = -1;
+
+       ret = app2ext_disable_external_dir();
+       if (ret == 0) {
+               printf("\n app2ext_disable_external_dir() success");
+       } else {
+               printf("\n app2ext_disable_external_dir() failed");
+       }
+}
+
+int main(int argc, char **argv)
+{
+       printf("\nEnter plug-in type: 1. App2SD 2. App2mUSB 3.App2CLOUD\n");
+       int plugin = __get_integer_input_data();
+       int ret = 0;
+       if (plugin !=1) {
+               printf("Plug-in type currently not supported");
+               return -1;
+       }
+       handle = app2ext_init(APP2EXT_SD_CARD);
+       if (handle == NULL) {
+               ret = APP2EXT_ERROR_PLUGIN_INIT_FAILED;
+               printf("app2ext_init. Reason:%s\n", error_list[ret]);
+               return -1;
+       }
+       do {
+               Usage();
+               printf("Enter Option for testing\n");
+               int option = __get_integer_input_data();
+               switch (option) {
+               case 1:
+                       {
+                               TC_app_install();
+                               break;
+                       }
+               case 2:
+                       {
+                               TC_app_uninstall();
+                               break;
+                       }
+               case 3:
+                       {
+                               TC_app_upgrade();
+                               break;
+                       }
+               case 4:
+                       {
+                               TC_app_move();
+                               break;
+                       }
+               case 5:
+                       {
+                               TC_app_get_location();
+                               break;
+                       }
+               case 6:
+                       {
+                               TC_enable_external_dir();
+                               break;
+                       }
+               case 7:
+                       {
+                               TC_disable_external_dir();
+                               break;
+                       }
+               case 8: {
+                               app2ext_deinit(handle);
+                               return 0;
+                       }
+               default:
+                       {
+                               printf("\nInvalid test id\n");
+                               break;
+                       }
+               }
+       } while(1);
+       app2ext_deinit(handle);
+       return 0;
+}