Tizen 2.1 base
authorJinkun Jang <jinkun.jang@samsung.com>
Tue, 12 Mar 2013 16:46:27 +0000 (01:46 +0900)
committerJinkun Jang <jinkun.jang@samsung.com>
Tue, 12 Mar 2013 16:46:27 +0000 (01:46 +0900)
28 files changed:
AUTHORS [new file with mode: 0755]
CMakeLists.txt [new file with mode: 0755]
app2sd.manifest [new file with mode: 0755]
app2sd.pc.in [new file with mode: 0755]
debian/app2sd-dev.install.in [new file with mode: 0644]
debian/app2sd.install.in [new file with mode: 0644]
debian/changelog [new file with mode: 0755]
debian/compat [new file with mode: 0755]
debian/control [new file with mode: 0755]
debian/copyright [new file with mode: 0755]
debian/dirs [new file with mode: 0755]
debian/rules [new file with mode: 0755]
doc/images/SLP_app2ext_PG_image01.png [new file with mode: 0755]
doc/images/app2ext_diag.png [new file with mode: 0755]
doc/images/app2ext_install_diag.png [new file with mode: 0755]
doc/images/app2ext_uninstall_diag.png [new file with mode: 0755]
inc/SLP_app2ext_PG.h [new file with mode: 0755]
inc/app2ext_interface.h [new file with mode: 0755]
packaging/app2sd.spec [new file with mode: 0755]
plugin/app2sd/CMakeLists.txt [new file with mode: 0755]
plugin/app2sd/inc/SLP_app2sd_PG.h [new file with mode: 0755]
plugin/app2sd/inc/app2sd_interface.h [new file with mode: 0755]
plugin/app2sd/inc/app2sd_internals.h [new file with mode: 0755]
plugin/app2sd/src/app2sd_interface.c [new file with mode: 0755]
plugin/app2sd/src/app2sd_internals.c [new file with mode: 0755]
plugin/app2sd/src/app2sd_internals_registry.c [new file with mode: 0755]
plugin/app2sd/src/app2sd_internals_utils.c [new file with mode: 0755]
src/app2ext_interface.c [new file with mode: 0755]

diff --git a/AUTHORS b/AUTHORS
new file mode 100755 (executable)
index 0000000..ead8dbd
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1 @@
+Garima Shrivastava<garima.s@samsung.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..ed20cfa
--- /dev/null
@@ -0,0 +1,53 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+#SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
+PROJECT(app2ext C)
+
+SET(VERSION_MAJOR 0)
+SET(VERSION "${VERSION_MAJOR}.4.2")
+
+#Add your submodule directory name
+ADD_SUBDIRECTORY(plugin/app2sd)
+### Required packages
+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)
+
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+### Local include directories
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/inc ${CMAKE_SOURCE_DIR}/src)
+
+## build app2ext library
+SET(app2ext_dir "${CMAKE_SOURCE_DIR}")
+SET(app2ext_inc_dir "${app2ext_dir}/inc")
+SET(app2ext_src_dir "${app2ext_dir}/src")
+SET(APP2EXT "app2ext")
+SET(libapp2ext_SOURCES ${app2ext_src_dir}/app2ext_interface.c)
+SET(libapp2ext_LDFLAGS " -L/usr/lib -module -avoid-version -ldl ")
+SET(libapp2ext_CFLAGS  " ${CFLAGS} -fPIC -I${app2ext_inc_dir} ")
+
+ADD_LIBRARY(${APP2EXT} SHARED ${libapp2ext_SOURCES})
+SET_TARGET_PROPERTIES(${APP2EXT} PROPERTIES SOVERSION ${VERSION_MAJOR})
+SET_TARGET_PROPERTIES(${APP2EXT} PROPERTIES VERSION ${VERSION})
+SET_TARGET_PROPERTIES(${APP2EXT} PROPERTIES COMPILE_FLAGS "${libapp2ext_CFLAGS}")
+TARGET_LINK_LIBRARIES(${APP2EXT} ${libpkgs_LDFLAGS})
+
+SET(CMAKE_INSTALL_PREFIX "/usr")
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+
+
+CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/app2sd.pc.in ${CMAKE_BINARY_DIR}/app2sd.pc @ONLY)
+
+INSTALL(TARGETS ${APP2EXT} DESTINATION lib COMPONENT RuntimeLibraries)
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/app2sd.pc DESTINATION lib/pkgconfig)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/inc/app2ext_interface.h DESTINATION include)
+
diff --git a/app2sd.manifest b/app2sd.manifest
new file mode 100755 (executable)
index 0000000..ec5cd53
--- /dev/null
@@ -0,0 +1,15 @@
+<manifest>
+       <define>
+               <domain name="app2sd"/>
+       </define>
+       <request>
+               <domain name="app2sd"/>
+       </request>
+       <assign>
+               <filesystem path="/usr/lib/libapp2ext.so.0" label="_"/>
+               <filesystem path="/usr/lib/libapp2ext.so.0.4.2" label="_"/>
+               <filesystem path="/usr/lib/libapp2sd.so" label="_"/>
+               <filesystem path="/usr/lib/libapp2sd.so.0" label="_"/>
+               <filesystem path="/usr/lib/libapp2sd.so.0.4.2" label="_"/>
+       </assign>
+</manifest>
diff --git a/app2sd.pc.in b/app2sd.pc.in
new file mode 100755 (executable)
index 0000000..bc90238
--- /dev/null
@@ -0,0 +1,12 @@
+# Package information for app2sd
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: app2sd
+Description: The app2sd Library
+Version: 1.1.0
+Requires: vconf dlog
+Cflags: -I${includedir}
+Libs: -L${libdir} -lapp2sd -lapp2ext
diff --git a/debian/app2sd-dev.install.in b/debian/app2sd-dev.install.in
new file mode 100644 (file)
index 0000000..258b9f0
--- /dev/null
@@ -0,0 +1,2 @@
+@PREFIX@/include/app2sd_interface.h
+@PREFIX@/lib/pkgconfig/*.pc
diff --git a/debian/app2sd.install.in b/debian/app2sd.install.in
new file mode 100644 (file)
index 0000000..bf766f0
--- /dev/null
@@ -0,0 +1 @@
+@PREFIX@/lib/*.so*
diff --git a/debian/changelog b/debian/changelog
new file mode 100755 (executable)
index 0000000..0d77b89
--- /dev/null
@@ -0,0 +1,8 @@
+app2sd (0.2.1) unstable; urgency=low
+
+  * Initial release
+  * Git: slp/pkgs/a/app2sd
+  * Tag: app2sd_0.2.1
+
+ -- Jaeho Lee <jaeho81.lee@samsung.com>  Thu, 24 May 2012 12:04:51 +0530
+
diff --git a/debian/compat b/debian/compat
new file mode 100755 (executable)
index 0000000..7ed6ff8
--- /dev/null
@@ -0,0 +1 @@
+5
diff --git a/debian/control b/debian/control
new file mode 100755 (executable)
index 0000000..7bf93c6
--- /dev/null
@@ -0,0 +1,27 @@
+Source: app2sd
+Section: devel
+Priority: extra
+Maintainer: Garima Shrivastava <garima.s@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
+Build-Depends: debhelper (>= 5),libssl-dev, libslp-setting-dev, libslp-db-util-dev
+Standards-Version: 3.7.2
+
+Package: app2sd
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: <App2sd is a utility for enabling installation of applications to sd card and also to move to and from sd card.>
+
+Package: app2sd-dev
+Architecture: any
+Depends: app2sd (= ${Source-Version})
+Description: App2sd dev package
+
+Package: app2sd-doc
+Architecture: all
+Description: <App2sd is a utility for enabling installation of applications to sd card and also to move to and from sd card.>
+
+Package: app2sd-dbg
+Section: debug
+Architecture: any
+Depends: app2sd (= ${Source-Version})
+Description: App2sd dbg package
+
diff --git a/debian/copyright b/debian/copyright
new file mode 100755 (executable)
index 0000000..37b94ac
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2012 - 2013 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.
+ *
+ */
diff --git a/debian/dirs b/debian/dirs
new file mode 100755 (executable)
index 0000000..ca882bb
--- /dev/null
@@ -0,0 +1,2 @@
+usr/bin
+usr/sbin
diff --git a/debian/rules b/debian/rules
new file mode 100755 (executable)
index 0000000..f902937
--- /dev/null
@@ -0,0 +1,126 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+
+# These are used for cross-compiling and for saving the configure script
+# from having to guess our platform (since we know it already)
+DEB_BUILD_GNU_TYPE  ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
+DEB_HOST_GNU_TYPE   ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
+DEB_HOST_ARCH       ?= $(shell dpkg-architecture -qDEB_HOST_ARCH)
+DEB_HOST_ARCH_OS    ?= $(shell dpkg-architecture -qDEB_HOST_GNU_OS)
+
+CFLAGS ?= -Wall -g
+LDFLAGS ?=
+PREFIX ?= /usr
+DATADIR ?= /opt
+
+ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
+       CFLAGS += -O0
+else
+       CFLAGS += -O2
+endif
+
+# architecture is not arm
+ifneq (, $(findstring arm, $(DEB_HOST_ARCH)))
+       # do something here
+else
+       # do something here for arm
+endif
+
+CFLAGS += -fvisibility=hidden -fPIC
+LDFLAGS += -Wl,--rpath=$(PREFIX)/lib -Wl,--as-needed
+
+CMAKE_TMP_DIR = $(CURDIR)/cmake_tmp
+
+config.status:
+
+configure: configure-stamp
+
+configure-stamp:
+       dh_testdir
+       mkdir -p $(CMAKE_TMP_DIR);
+       export LD_LIBRARY_PATH=$(LD_LIBRARY_PATH):$(CMAKE_TMP_DIR) && cd $(CMAKE_TMP_DIR); CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" LDFLAGS="$(LDFLAGS)" cmake .. -DCMAKE_INSTALL_PREFIX=$(PREFIX)
+       touch configure-stamp
+
+build: build-stamp
+
+build-stamp: configure-stamp
+       dh_testdir
+       # Add here commands to compile the package.
+       cd $(CMAKE_TMP_DIR) && $(MAKE) all
+
+       for f in `find $(CURDIR)/debian/ -name "*.in"`; do \
+               cat $$f > $${f%.in}; \
+               sed -i -e "s#@PREFIX@#$(PREFIX)#g" $${f%.in}; \
+               sed -i -e "s#@DATADIR@#$(DATADIR)#g" $${f%.in}; \
+       done
+
+       touch $@
+
+clean:
+       dh_testdir
+       dh_testroot
+       rm -f *-stamp
+
+       rm -rf $(CMAKE_TMP_DIR)
+
+       for f in `find $(CURDIR)/debian/ -name "*.in"`; do \
+               rm -f $${f%.in}; \
+       done
+
+       dh_clean
+
+install: build
+       dh_testdir
+       dh_testroot
+       dh_clean -k
+       dh_installdirs
+
+       # Add here commands to install the package into debian/ncurses.
+       cd $(CMAKE_TMP_DIR) && $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+       dh_testdir
+       dh_testroot
+       dh_installchangelogs
+#      dh_installdocs
+       dh_installexamples
+       dh_install --list-missing --sourcedir=debian/tmp
+#      dh_installmenu
+#      dh_installdebconf
+#      dh_installlogrotate
+#      dh_installemacsen
+#      dh_installpam
+#      dh_installmime
+#      dh_python
+#      dh_installinit
+#      dh_installcron
+#      dh_installinfo
+       dh_installman
+       dh_link
+       dh_strip --dbg-package=app2sd-dbg
+       dh_compress
+       dh_fixperms
+#      dh_perl
+       dh_makeshlibs
+       dh_installdeb
+       dh_shlibdeps
+       dh_gencontrol
+       dh_md5sums
+       dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install
diff --git a/doc/images/SLP_app2ext_PG_image01.png b/doc/images/SLP_app2ext_PG_image01.png
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/doc/images/app2ext_diag.png b/doc/images/app2ext_diag.png
new file mode 100755 (executable)
index 0000000..137eaf3
Binary files /dev/null and b/doc/images/app2ext_diag.png differ
diff --git a/doc/images/app2ext_install_diag.png b/doc/images/app2ext_install_diag.png
new file mode 100755 (executable)
index 0000000..6fd73ee
Binary files /dev/null and b/doc/images/app2ext_install_diag.png differ
diff --git a/doc/images/app2ext_uninstall_diag.png b/doc/images/app2ext_uninstall_diag.png
new file mode 100755 (executable)
index 0000000..2e61c71
Binary files /dev/null and b/doc/images/app2ext_uninstall_diag.png differ
diff --git a/inc/SLP_app2ext_PG.h b/inc/SLP_app2ext_PG.h
new file mode 100755 (executable)
index 0000000..48c0b8a
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * app2ext
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jyotsna Dhumale <jyotsna.a@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ *
+ * @ingroup SLP_PG
+ * @defgroup app2ext_PG App2Ext
+ * @{
+
+<h1 class="pg">Introduction</h1>
+App2Ext is a feature that enables package installers to install applications on external storage like SD card, Micro USB flash drive or Cloud.
+It also provides option to move installed applications from external memory to internal memory and vice versa.
+
+<h1 class="pg">App2Ext process view</h1>
+\image html app2ext_diag.png "Picture 1. App2Ext Process View Diagram"
+\image rtf app2ext_diag.png "Picture 1. App2Ext Process View Diagram"
+
+<h1 class="pg">Installation to SD Card</h1>
+Package installer should call the App2Ext's Init API to initialize SD plug-in. Once the plug-in initialization is done App2Ext returns a storage handle to the Package installer. Package installer should then call the pre-install setup API with respect to the storage handle which will be mapped to app2sd's pre-install API. The App2Ext Pre-install API performs the setup required for the installation based on the external storage type.
+After pre-install setup is done Package installer can proceed with the installation of the application. When package installation is completed by the package installer, post-install setup API should be called. This API removes the setup created for installation during pre-install API.
+
+Refer to Picture 2. for flow diagram.
+
+<h1 class="pg">Installation Setup Flow for App2SD plug-in</h1>
+\image html app2ext_install_diag.png "Picture 2. Installation on SD card Flow Diagram"
+\image rtf app2ext_install_diag.png "Picture 2. Installation on SD card Flow Diagram"
+
+<h1 class="pg">Un-installation from SD Card</h1>
+Package installer should call the App2Ext's Init API to initialize SD plug-in. Once the plug-in initialization is done App2Ext returns a storage handle to the Package installer. Package installer should then call the pre-uninstall setup API with respect to the storage handle which will be mapped to app2sd's pre-uninstall API. Pre-uninstall API performs the setup required for the package un-installation based on the external storage type.
+After pre-uninstall setup is done Package installer can proceed with un-installation of the package. When package un-installation is completed by the package installer, post-uninstall setup API should be called. This API removes the setup created for un-installation during pre-uninstall API.
+
+Refer to Picture 3. for flow diagram.
+
+<h1 class="pg">Un-installation Setup Flow for App2SD plug-in</h1>
+\image html app2ext_uninstall_diag.png "Picture 3. Un-installation from SD card Flow Diagram"
+\image rtf app2ext_uninstall_diag.png "Picture 3. Un-installation from SD card Flow Diagram"
+
+
+<h1 class="pg">API list and description</h1>
+<ul>
+       <li>app2ext_init() : Initialize plug-in based on storage type </li>
+       <li>app2ext_deinit() : De-initialize plug-in</li>
+       <li>app2ext_get_app_location() : Returns application current location</li>
+</ul>
+
+ * @}
+ */
diff --git a/inc/app2ext_interface.h b/inc/app2ext_interface.h
new file mode 100755 (executable)
index 0000000..fc11918
--- /dev/null
@@ -0,0 +1,402 @@
+/*
+ * app2ext
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jyotsna Dhumale <jyotsna.a@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __APP2EXT_INTERFACE_H__
+#define __APP2EXT_INTERFACE_H__
+
+/**
+ * @file app2ext_interface.h
+ * @version 0.5
+ * @brief    This file declares API of app2ext library
+ */
+/**
+ * @addtogroup APPLICATION_FRAMEWORK
+ * @{
+ *
+ * @defgroup app2ext
+ * @version    0.5
+ *
+ * @section    Header to use them:
+ * @code
+ * #include <app2ext_interface.h>
+ * @endcode
+ *
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#include <dlog/dlog.h>
+#include <glib.h>
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "APP2EXT"
+
+#ifdef _DEBUG_MODE_
+#define app2ext_print(fmt, arg...) LOGD(fmt,##arg)
+#else
+#define app2ext_print(FMT, ARG...) SLOGD(FMT,##ARG);
+#endif
+
+#define APP2EXT_SUCCESS 0
+#define MMC_PATH "/opt/storage/sdcard"
+#define APP2SD_PATH MMC_PATH"/app2sd/"
+#define APP_INSTALLATION_PATH "/opt/usr/apps/"
+
+/**
+ * Enum for application installation location
+ */
+typedef enum app2ext_install_location_t {
+       APP2EXT_INTERNAL_MEM = 0,
+       APP2EXT_SD_CARD,
+       APP2EXT_MICRO_USB,
+       APP2EXT_CLOUD,
+       APP2EXT_NOT_INSTALLED
+} app2ext_install_location;
+
+/**
+ * Enum for installation/upgrade status[success/failure]
+ */
+typedef enum app2ext_status_t {
+       APP2EXT_STATUS_FAILED = 1,
+       APP2EXT_STATUS_SUCCESS
+} app2ext_status;
+
+/**
+ * Enum for directory type
+ */
+typedef enum app2ext_dir_type_t {
+       APP2EXT_DIR_RO,
+       APP2EXT_DIR_RW,
+} app2ext_dir_type;
+
+/**
+ * Enum for move command
+ * @see app2sd_move_installed_app()
+ */
+typedef enum app2ext_move_type_t {
+       APP2EXT_MOVE_TO_EXT = 1,
+       APP2EXT_MOVE_TO_PHONE
+} app2ext_move_type;
+
+/**
+ * Enum for error codes
+ */
+typedef enum app2ext_error_t {
+       APP2EXT_ERROR_INVALID_ARGUMENTS = 2,
+       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
+} app2ext_error;
+
+/**
+ * @brief :This function type is for a function that is implemented by plugin
+ * and called before application is to be installed.
+ *
+ * @param[in]  appname         application package name which is to be installed
+ * @param[in]  dir_list        directory structure of the application
+ *                              This should be polulated by the package manager
+ *                              before calling pre_install and should be freed after
+ *                              pre_install returns.
+ *                              Each node of dir_list is of type app2ext_dir_details
+ *                              which has members Name(dirname) and Type (RO/RW)
+ *                              For eg for rpm the dir_list should be populated with
+ *                              nodes like : (lib, APP2EXT_DIR_RO), (res, APP2EXT_DIR_RO),
+                                (bin, APP2EXT_DIR_RO), (data, APP2EXT_DIR_RW)
+ * @param[in]  size            Size of the application
+ * @return     0 if success,  error code(>0) if fail
+ */
+typedef int (*app2ext_pre_install)(const char *appname, GList* dir_list, int size);
+
+/**
+ * @brief :This function type is for a function that is implemented by plugin
+ * and called after application installation.
+ *
+ * @param[in]  appname         application package name which is to be installed
+ * @param[in]  install_status  Installation status (Success/Failure)
+ *                             [ Enum :APP2EXT_STATUS_SUCCESS,
+ *                                     APP2EXT_STATUS_FAILED]
+ * @return     0 if success,  error code(>0) if fail
+ */
+typedef int (*app2ext_post_install)(const char *appname, app2ext_status install_status);
+
+/**
+ * @brief :This function type is for a function that is implemented by plugin
+ * and called before application upgrade.
+ *
+ * @param[in]  appname         application package name which is to be upgraded
+ * @param[in]  dir_list        directory structure of the application
+ *                              This should be polulated by the package manager
+ *                              before calling pre_upgrade and should be freed after
+ *                              pre_upgrade returns.
+ *                              Each node of dir_list is of type app2ext_dir_details
+ *                              which has members Name(dirname) and Type (RO/RW)
+ *                              For eg for rpm the dir_list should be populated with
+ *                              nodes like : (lib, APP2EXT_DIR_RO), (res, APP2EXT_DIR_RO),
+                                (bin, APP2EXT_DIR_RO), (data, APP2EXT_DIR_RW)
+ * @param[in]  size            Size of the application
+ * @return     0 if success,  error code(>0) if fail
+ */
+typedef int (*app2ext_pre_upgrade)(const char *appname, GList* dir_list, int size);
+
+/**
+ * @brief :This function type is for a function that is implemented by plugin
+ * and called before application upgradation.
+ *
+ * @param[in]  appname         application package name which is to be upgraded
+ * @param[in]  upgrade_status  Upgrade status (Success/Failure)
+ *                             [ Enum :APP2EXT_STATUS_SUCCESS,
+ *                                     APP2EXT_STATUS_FAILED]
+ * @return     0 if success,  error code(>0) if fail
+ */
+typedef int (*app2ext_post_upgrade)(const char *appname, app2ext_status upgrade_status);
+
+/**
+ * @brief :This function type is for a function that is implemented by plugin
+ * and called before application uninstallation.
+ *
+ * @param[in]  appname         application package name which is to be uninstalled
+ * @return     0 if success,  error code(>0) if fail
+ */
+typedef int (*app2ext_pre_uninstall)(const char *appname);
+
+/**
+ * @brief :This function type is for a function that is implemented by plugin
+ * and called after application uninstallation.
+ *
+ * @param[in]  appname         application package name which is to be uninstalled
+ * @return     0 if success,  error code(>0) if fail
+ */
+typedef int (*app2ext_post_uninstall)(const char *appname);
+
+/**
+ * @brief :This function type is for a function that is implemented by plugin
+ * and called when application is to be moved from extrenal memory
+ *to internal memory or vice versa.
+ *
+ * @param[in]  appname         application package name which is to be moved
+ * @param[in]  dir_list        directory structure of the application
+ *                              This should be polulated by the package manager
+ *                              before calling move and should be freed after
+ *                              move returns.
+ *                              Each node of dir_list is of type app2ext_dir_details
+ *                              which has members Name(dirname) and Type (RO/RW)
+ *                              For eg for rpm the dir_list should be populated with
+ *                              nodes like : (lib, APP2EXT_DIR_RO), (res, APP2EXT_DIR_RO),
+                                (bin, APP2EXT_DIR_RO), (data, APP2EXT_DIR_RW)
+ * @param[in]  move_type       move type
+ *                             [Enum: APP2EXT_MOVE_TO_EXT, APP2EXT_MOVE_TO_PHONE]
+ * @return     0 if success,  error code(>0) if fail
+ */
+typedef int (*app2ext_move)(const char *appname, GList* dir_list, app2ext_move_type move_type);
+
+/**
+ * @brief :This function type is for a function that is implemented by plugin
+ * and called to enable application before application launch.
+ *
+ * @param[in]  appname         application package name which is to be enabled
+ * @return     0 if success,  error code(>0) if fail
+ */
+typedef int (*app2ext_enable)(const char *appname);
+
+/**
+ * @brief :This function type is for a function that is implemented by plugin
+ * and called to disable application before application exit.
+ *
+ * @param[in]  appname         application package name which is to be disabled
+ * @return     0 if success,  error code(>0) if fail
+ */
+typedef int (*app2ext_disable)(const char *appname);
+
+/**
+ * This structure defines the app2ext interfaces. Plugins have to implement these functions
+ */
+typedef struct app2ext_interface_t{
+       app2ext_pre_install             pre_install;
+       app2ext_post_install            post_install;
+       app2ext_pre_upgrade             pre_upgrade;
+       app2ext_post_upgrade            post_upgrade;
+       app2ext_pre_uninstall           pre_uninstall;
+       app2ext_post_uninstall          post_uninstall;
+       app2ext_move                    move;
+       app2ext_enable                  enable;
+       app2ext_disable                 disable;
+} app2ext_interface;
+
+/**
+ * This structure defines app2ext handle .Each storage type maps to a different plugin
+ * type                                : storage type
+ * plugin_handle                       : plugin handle
+ */
+typedef struct {
+       app2ext_install_location        type;
+       void                    *plugin_handle;
+       app2ext_interface               interface;
+} app2ext_handle;
+
+/**
+ * This structure defines directory details
+ * name                        : directory name
+ * type                        : permission (rw/ro)
+ */
+typedef struct {
+       char *          name;
+       app2ext_dir_type        type;
+} app2ext_dir_details;
+
+/**
+ * @brief : This API initializes the appropriate plugin based on storage type.
+ *     It should be called before installation/uninstallation/upgrade
+ * @param[in] storage_type     Location where package should be installed
+ *                             [Ex: SD card, MicroUSB, Cloud]
+ * @return     app2ext_handle pointer if success, NULL if fail
+ *
+ @code
+ #include <app2ext_interface.h>
+ app2ext_handle *handle = NULL;
+ GLIst *dir_list = NULL;
+ handle = app2ext_init(APP2EXT_SD_CARD); //Initializes SD card plug-in
+ if(handle)
+ {
+       printf("\n SUCCESS");
+       // Perform package install/uninstall/upgrade/move here
+       // Packge install example
+       // Package manager should polulate dir_list with directory structure information of the package
+       ret = handle->interface.pre_install("com.samsung.calculator", dir_list, 20);
+       if (ret) {
+               printf("\n TC : pre app install API fail. Reason %s", error_list[ret]);
+               return -1;
+       }
+
+       // Package manager installs the package
+
+       ret = handle->interface.post_install("com.samsung.calculator", APP2EXT_STATUS_SUCCESS);
+       if (ret) {
+               printf("\n TC : post app install API fail Reason %s", error_list[ret]);
+
+               return -1;
+       }
+       // Package manager should free dir_list
+       return;
+ } else
+        printf("\n FAILURE");
+ @endcode
+ */
+API app2ext_handle *app2ext_init(int storage_type);
+
+/**
+ * @brief : This API deinitializes the plugin
+ *         This should be called when use of the plugin is completed
+ * @param[in] handle   pointer to app2ext_handle which is to be deinitialized
+ * @pre                Initialization is done for the storage handle
+ * @return     0 if success,  error code(>0) if fail
+ *
+ @code
+ #include <app2ext_interface.h>
+ app2ext_handle *handle = NULL;
+ handle = app2ext_init(APP2EXT_SD_CARD); //Initializes SD card plug-in
+ int ret = -1;
+ ret = app2ext_deinit(handle); // De-initializes the SD plugin
+ if(!ret)
+ {
+        printf("\n SUCCESS");
+ }
+ else
+ printf("\n FAILURE");
+ @endcode
+ */
+API int app2ext_deinit(app2ext_handle *handle);
+
+/**
+ * @brief : This API returns the application location
+ *                     by refering to package manager DB
+ *         This should be called to know location of an application
+ * @param[in] appname  name of the application
+ * @return     APP2EXT_SD_CARD if app is in SD card,
+ *             APP2EXT_INTERNAL_MEM if app is in internal memory
+ *             error code(>0) if fail
+ *@remarks see app2ext_install_location for more details
+ @code
+ #include <app2ext_interface.h>
+int ret = -1;
+
+ret = app2ext_get_app_location("com.samsung.calculator");
+if (ret == APP2EXT_SD_CARD) {
+       printf("\n app is in sd card ");
+} else if (ret == APP2EXT_INTERNAL_MEM) {
+       printf("\n app is in internal memory ");
+} else {
+       printf("\napp is not installed");
+}
+ @endcode
+ */
+API int app2ext_get_app_location(const char *appname);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/packaging/app2sd.spec b/packaging/app2sd.spec
new file mode 100755 (executable)
index 0000000..012342c
--- /dev/null
@@ -0,0 +1,60 @@
+Name:       app2sd
+Summary:    Application installation on external memory
+Version:    0.5
+Release:    8
+Group:      TO_BE/FILLED_IN
+License:    Apache2.0
+Source0:    %{name}-%{version}.tar.gz
+
+Requires(post): /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
+BuildRequires:  pkgconfig(libssl)
+BuildRequires:  pkgconfig(vconf)
+BuildRequires:  pkgconfig(dlog)
+BuildRequires:  pkgconfig(openssl)
+BuildRequires:  pkgconfig(db-util)
+BuildRequires:  cmake
+
+%description
+Tizen application installation on external memory
+
+%package devel
+Summary:    Application install on external memory (devel)
+Group:      Development/Libraries
+Requires:   app2sd = %{version}-%{release}
+
+%description devel
+Tizen application installation on external memory (devel)
+
+%prep
+%setup -q
+
+%build
+cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix}
+
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+%make_install
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+%files
+%manifest app2sd.manifest
+%defattr(-,root,root,-)
+%{_libdir}/libapp2ext.so.*
+%{_libdir}/libapp2sd.so*
+
+
+%files devel
+%defattr(-,root,root,-)
+%{_includedir}/app2ext_interface.h
+%{_libdir}/pkgconfig/app2sd.pc
+%{_libdir}/libapp2sd.so
+%{_libdir}/libapp2ext.so
+
+
+
diff --git a/plugin/app2sd/CMakeLists.txt b/plugin/app2sd/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..ceff836
--- /dev/null
@@ -0,0 +1,44 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(app2sd C)
+
+### Required packages
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED libssl dlog openssl db-util)
+
+FOREACH(flag ${pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+pkg_check_modules(libpkgs REQUIRED libssl dlog openssl db-util)
+
+FOREACH(flag ${libpkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+### Local include directories
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/inc ${CMAKE_SOURCE_DIR}/src)
+
+## build app2sd library
+SET(app2sd_dir "${CMAKE_SOURCE_DIR}/plugin/app2sd")
+SET(app2sd_inc_dir "${app2sd_dir}/inc")
+SET(app2sd_src_dir "${app2sd_dir}/src")
+SET(APP2SD "app2sd")
+SET(libapp2sd_SOURCES ${app2sd_src_dir}/app2sd_internals.c ${app2sd_src_dir}/app2sd_interface.c ${app2sd_src_dir}/app2sd_internals_registry.c ${app2sd_src_dir}/app2sd_internals_utils.c)
+SET(libapp2sd_LDFLAGS " -L/usr/lib -lcrypto -module -avoid-version ")
+SET(libapp2sd_CFLAGS  " ${CFLAGS} -fPIC -I${app2sd_inc_dir} ")
+
+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})
+
+SET(CMAKE_INSTALL_PREFIX "/usr")
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+
+
+INSTALL(TARGETS ${APP2SD} DESTINATION lib COMPONENT RuntimeLibraries)
+
+
diff --git a/plugin/app2sd/inc/SLP_app2sd_PG.h b/plugin/app2sd/inc/SLP_app2sd_PG.h
new file mode 100755 (executable)
index 0000000..4933bc1
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * app2sd
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Garima Shrivastava<garima.s@samsung.com>
+ *     Jyotsna Dhumale <jyotsna.a@samsung.com>
+ *     Venkatesha Sarpangala <sarpangala.v@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ *
+ * @ingroup SLP_PG
+ * @defgroup app2sd_PG App2sd
+ * @{
+
+<h1 class="pg">Introduction</h1>
+App2sd is a feature that enables package installers to install applications on sdcard.
+It also provides API to move installed applications from sd card to internal memory and vice versa.
+App2sd provides an API for validating the integrity of the package before launching by the launchpad.
+
+<h1 class="pg">App2sd process view</h1>
+\image html app2sd_diag.png "Picture 1. Process View Diagram"
+\image rtf app2sd_diag.png "Picture 1. Process View Diagram"
+
+<h1 class="pg">Installation to SD Card</h1>
+Package installer should call the App2sd pre-install setup API before installation.
+This API creates directory structure in SD card.
+Refer to Picture 2. for flow diagram.
+
+<h1 class="pg">App2sd Installation Setup  Flow</h1>
+\image html app2sd_install_diag.png "Picture 2. Installation Flow  Diagram"
+\image rtf app2sd_install_diag.png "Picture 2. Installation Flow  Diagram"
+
+<h1 class="pg">Uninstallation to SD Card</h1>
+Package installer should call the App2sd pre-uninstall setup API before uninstallation.
+Once the uninstallation is done by the package installer
+then App2sd post-uninstall setup API should be called.
+This API will clean up the directory structure and remove password from sqlite db.
+Refer to Picture 3. for flow diagram.
+<h1 class="pg">App2sd Uninstallation Setup  Flow</h1>
+\image html app2sd_uninstall_diag.png "Picture 3. Uninstallation Flow Diagram"
+\image rtf app2sd_uninstall_diag.png "Picture 3. Uninstallation Flow Diagram"
+
+<h1 class="pg">API list and description</h1>
+<ul>
+       <li>app2sd_pre_app_install() : Pre app installation setup.</li>
+       <li>app2sd_post_app_install() : Post app installation setup.</li>
+       <li>app2sd_pre_app_upgrade() : Pre app upgrade setup.</li>
+       <li>app2sd_post_app_upgrade() : Post app upgarde setup.</li>
+       <li>app2sd_pre_app_uninstall() : Pre app uninstall setup.</li>
+       <li>app2sd_post_app_uninstall() : Post app uninstall setup.</li>
+       <li>app2sd_move_installed_app() : Move installed application to/from sdcard</li>
+       <li>app2sd_get_app_install_location() : Get application installation location[external\internal memory].</li>
+       <li>app2sd_on_demand_setup_init() : Enables the application installed in sdcard.</li>
+       <li>app2sd_on_demand_setup_exit() : Disables the application installed in sdcard.</li>
+       <li></li>
+</ul>
+
+ * @}
+ */
diff --git a/plugin/app2sd/inc/app2sd_interface.h b/plugin/app2sd/inc/app2sd_interface.h
new file mode 100755 (executable)
index 0000000..a59cb9a
--- /dev/null
@@ -0,0 +1,404 @@
+/*
+ * app2ext
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Garima Shrivastava<garima.s@samsung.com>
+ *     Jyotsna Dhumale <jyotsna.a@samsung.com>
+ *     Venkatesha Sarpangala <sarpangala.v@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __APPTOSD_INTERFACE_H__
+#define __APPTOSD_INTERFACE_H__
+
+/**
+ * @file app2sd_interface.h
+ * @version 0.2
+ * @brief    This file declares API of app2sd library
+ */
+/**
+ * @addtogroup APPLICATION_FRAMEWORK
+ * @{
+ *
+ * @defgroup app2sd
+ * @version    0.2
+ *
+ * @section    Header to use them:
+ * @code
+ * #include <app2sd_interface.h>
+ * @endcode
+ *
+ * @addtogroup app2sd
+ * @{
+ */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <app2ext_interface.h>
+
+
+       /**
+        * @brief : This API prepares the setup for installation in SD card.
+        *              It should be called before actual installation is done.
+        * @pre                 vfat type sd card must be present.
+        * @post                Installation is done by package installer.
+                       Encryption password is saved in db /opt/dbspace/.app2sd.db
+        * @param[in] appname           application package name
+         *                             [Ex: com.samsung.calculator]
+        *This entry is parsed from application package control/manifest file.
+        * @param[in] dir_list          directory structure of the application
+        * @param[in] size      size of memory required by application(in MB).
+        *This entry is parsed from application package control/manifest file.
+        * @return      0 if success,  error code(>0) if fail
+        * @remark      None.
+        *
+        *
+        @code
+        #include <app2sd_interface.h>
+        int ret = -1;
+        GList* dir_list = NULL;
+        // Package manager populates dir_list with directory structure information
+        ret= app2sd_pre_app_install
+               ("com.samsung.calculotor", dir_list, 10);
+        if(!ret)
+        {
+        printf("\n SUCCESS");
+               // Package installer performs installation
+               // app2sd_post_app_install() API should be called
+        return;
+        }
+        else
+        printf("\n FAILURE");
+        @endcode
+        */
+       API int app2sd_pre_app_install(const char *appname,
+                       GList* dir_list, int size);
+
+       /**
+        * @brief : This API does post installation operations after
+        *              the installation in SD card
+        * @param[in] appname           application package name
+         *                             [Ex: com.samsung.calculator]
+        * @param[in] install_status    Status of installation of package
+        *[ enum app2ext_status].If package installation failed then
+        * install_status= APP2EXT_STATUS_FAILURE else if installation
+        * was successful then install_status = APP2EXT_ISTATUS_SUCCESS.
+        * @pre         Installation should be done by package installer.
+        * @return      0 if success,  error code(>0) if fail
+        * @remark      @see enum app2sd_install_status
+        *
+        *
+        @code
+        #include <app2sd_interface.h>
+        int ret = -1;
+        ret= app2sd_pre_app_install
+               ("com.samsung.calculotor", APP2EXT_NATIVE_APP, 10);
+        if(!ret)
+        {
+                printf("\n SUCCESS");
+               // Package installer performs installation
+       //Package was installed successfully.
+       if(package_installation _success)
+        {
+        ret = app2sd_post_app_install
+        ("com.samsung.calculator",APP2EXT_STATUS_SUCCESS);
+        if(!ret)
+        printf("\n SUCCESS");
+        else
+        printf("\n FAILURE");
+        return;
+        }
+        else
+        {
+        //Package installation failed
+        ret = app2sd_post_app_install
+        ("com.samsung.calculator",APP2EXT_STATUS_FAILURE);
+        if(!ret)
+        printf("\n SUCCESS");
+        else
+        printf("\n FAILURE");
+        return;
+        }
+        }
+        else
+        printf("\n FAILURE");
+        @endcode
+        */
+       API int app2sd_post_app_install(const char *appname,
+                       app2ext_status install_status);
+
+       /**
+        * @brief : This API prepares the setup for upgradation of
+        *               application package
+        * @pre                 vfat type sd card must be present.
+        * @post                Upgradation is done by package installer.
+        * @param[in] appname           application package name
+         *                             [Ex: com.samsung.calculator]
+        * @param[in] dir_list          directory structure of the application
+        * @param[in] size      size of memory required by application(in MB).
+        *This entry is parsed from application package control/manifest file.
+        * @return      0 if success,  error code(>0) if fail
+        * @remark      None.
+        *
+        *
+        @code
+        #include <app2sd_interface.h>
+        int ret = -1;
+        GList* dir_list = NULL;
+        // Package manager populates dir_list with directory structure information
+        ret= app2sd_pre_app_upgrade
+               ("com.samsung.calculator", dir_list, 10);
+        if(!ret)
+        {
+        printf("\n SUCCESS");
+               // Package installer performs upgradation
+               // app2sd_post_app_upgrade() API should be called
+        return;
+        }
+        else
+        printf("\n FAILURE");
+        @endcode
+        */
+       API int app2sd_pre_app_upgrade(const char *appname,
+                       GList* dir_list, int size);
+
+       /**
+        * @brief : This API does post upgradation operations after
+        *              the installation in SD card
+        * @param[in] appname           application package name
+         *                             [Ex: com.samsung.calculator]
+        * @param[in] install_status    Status of installation of package
+        *[ enum app2extl_status].If package upgradation failed then
+        * upgrade_status= APP2EXT_STATUS_FAILURE else if upgradation
+        * was successful then upgrade_status = APP2EXT_STATUS_SUCCESS.
+        * @pre         Upgradation should be done by package installer.
+        * @return      0 if success,  error code(>0) if fail
+        * @remark      @see enum app2ext_status
+        *
+        *
+        @code
+        #include <app2sd_interface.h>
+        int ret = -1;
+        ret= app2sd_pre_app_upgrade
+               ("com.samsung.calculator", APP2EXT_NATIVE_APP, 10);
+        if(!ret)
+        {
+        printf("\n SUCCESS");
+               // Package installer performs upgradation
+       //Package was upgraded successfully.
+       if(package_upgradation _success)
+        {
+        ret = app2sd_post_app_upgrade
+        ("com.samsung.calculator",APP2EXT_STATUS_SUCCESS);
+        if(!ret)
+        printf("\n SUCCESS");
+        else
+        printf("\n FAILURE");
+        return;
+        }
+        else
+        {
+        //Package upgradation failed
+        ret = app2sd_post_app_upgrade
+        ("com.samsung.calculator",APP2EXT_STATUS_FAILURE);
+        if(!ret)
+        printf("\n SUCCESS");
+        else
+        printf("\n FAILURE");
+        return;
+        }
+        }
+        else
+        printf("\n FAILURE");
+        @endcode
+        */
+       API int app2sd_post_app_upgrade(const char *appname,
+                                       app2ext_status upgrade_status);
+
+       /**
+        * @brief: This API prepares the setup for uninstallation
+        * @pre                 Package must be installed in sdcard.
+        * @post        Package is uninstalled by the package installer.
+        * @param[in] appname           application package name
+         *                             [Ex: com.samsung.calculator]
+        * @return      0 if success,  error code(>0) if fail
+        * @remark      None.
+        *
+        *
+        @code
+        #include <app2sd_interface.h>
+        int ret = -1;
+        ret= app2sd_pre_app_uninstall
+               ("com.samsung.calculator");
+        if(!ret)
+        {
+        printf("\n SUCCESS");
+               // Package installer performs uninstallation
+               // app2sd_post_app_uninstall() API should be called
+        return;
+        }
+        else
+        printf("\n FAILURE");
+        @endcode
+        */
+       API int app2sd_pre_app_uninstall(const char *appname);
+
+       /**
+        * @brief This API removes the resources created during
+        app2sd setup.It is called after uninstallation.
+        * @pre                 Package must be uninstalled .
+        * @post                Encryption password is removed from sqlite db.
+        * @param[in] appname           application package name
+         *                             [Ex: com.samsung.calculator]
+        * @return      0 if success,  error code(>0) if fail
+        * @remark      None.
+        *
+        *
+        @code
+        #include <app2sd_interface.h>
+        int ret = -1;
+        ret= app2sd_pre_app_uninstall
+               ("com.samsung.calculator");
+        if(!ret)
+        {
+        printf("\n SUCCESS");
+               // Package installer performs uninstallation
+        ret = app2sd_post_app_uninstall("com.samsung.calculator");
+        if(!ret)
+        printf("\n SUCCESS");
+        else
+        printf("\n FAILURE");
+        return;
+        }
+        else
+        printf("\n FAILURE");
+        @endcode
+        */
+       API int app2sd_post_app_uninstall(const char *appname);
+
+       /**
+        * @brief : This API moves the package from sd card
+        to internal memory and vice versa.
+        * @param[in] pkgid             application package id
+         *                             [Ex: com.samsung.calculator]
+        * @param[in] move_type         Move type[enum app2ext_move_type]
+        *                      [sd card to internal/internal to sd card]
+        * @param[in] dir_list          directory structure of the application
+        * @pre                 Package must be installed and its installation
+        * location should be known.Use app2sd_get_app_install_location()
+        * to get installation location.
+        * @see app2sd_get_app_install_location().
+        * @post        Package is moved to new location.
+        * @return      0 if success,  error code(>0) if fail
+        * @remark      None.
+        *
+        *
+        @code
+        #include <app2sd_interface.h>
+        int ret = -1;
+        GList* dir_list = NULL;
+        // Package manager populates dir_list with directory structure information
+        ret = app2sd_get_app_install_location("com.samsung.calculator");
+        if(ret == APP2SD_INTERNAL_MEM)
+        {
+        ret= app2sd_move_installed_app("com.samsung.calculator",
+        dir_list, APP2EXT_MOVE_TO_EXT);
+        if(!ret)
+        printf("\n SUCCESS");
+        else
+        printf("\n FAILURE");
+        }
+        else if(ret == APP2SD_EXTERNAL_MEM)
+        {
+        ret= app2sd_move_installed_app("com.samsung.calculator",
+        dir_list, APP2SD_MOVE_TO PHONE);
+        if(!ret)
+        printf("\n SUCCESS");
+        else
+        printf("\n FAILURE");
+        }
+        @endcode
+        */
+       API int app2sd_move_installed_app(const char *pkgid,
+                                       GList* dir_list, app2ext_move_type move_type);
+
+       /**
+        * @brief : This API Enables the application in sd card
+        for use. This API should be called by AUL.
+        * @param[in] pkgid             application package id
+       *                               [Ex: com.samsung.calculator]
+        * @pre                 Package must be installed
+        * @post        application is enabled in SD card.
+        * @return      0 if success,  error code(>0) if fail
+        * @remark      None.
+        *
+        *
+        @code
+        #include <app2sd_interface.h>
+        int ret = -1;
+        ret= app2sd_on_demand_setup_init("com.samsung.calculator");
+        if(!ret)
+        printf("\n SUCCESS");
+        else
+        printf("\n FAILURE");
+        }
+        @endcode
+        */
+       API int app2sd_on_demand_setup_init(const char *pkgid);
+
+
+       /**
+        * @brief : This API Disables the application in sd card
+        . This API should be called by Launchpad callback which will be registered
+         during app launch for exit action of the application
+        * @param[in] pkgid             application package id
+       *                               [Ex: com.samsung.calculator]
+        * @pre                 Package must be installed and enabled
+        *                      and application must be running in SD card
+        * @post        application is disabked in SD card.
+        * @return      0 if success,  error code(>0) if fail
+        * @remark      None.
+        *
+        *
+        @code
+        #include <app2sd_interface.h>
+        int ret = -1;
+        ret= app2sd_on_demand_setup_exit("com.samsung.calculator");
+        if(!ret)
+        printf("\n SUCCESS");
+        else
+        printf("\n FAILURE");
+        }
+        @endcode
+        */
+       API int app2sd_on_demand_setup_exit(const char *pkgid);
+
+       /**
+        * @brief : This is the plug-in load function.
+                 The plugin has to bind its functions to function pointers of storage handle
+        * @param[in/out] st_interface          Specifies the storage interface.
+        * @return      None
+       */
+       API void app2ext_on_load(app2ext_interface *st_interface);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/plugin/app2sd/inc/app2sd_internals.h b/plugin/app2sd/inc/app2sd_internals.h
new file mode 100755 (executable)
index 0000000..c81ca7c
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * app2ext
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Garima Shrivastava<garima.s@samsung.com>
+ *     Jyotsna Dhumale <jyotsna.a@samsung.com>
+ *     Venkatesha Sarpangala <sarpangala.v@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _APP2SD_INTERNAL_H
+#define _APP2SD_INTERNAL_H
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#ifndef _BSD_SOURCE
+#define _BSD_SOURCE
+#endif
+
+/*Include Headers*/
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <stdarg.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <sys/mount.h>
+#include <app2sd_interface.h>
+
+#define DIR_PERMS (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
+
+#define BUF_SIZE 256
+#define MEM_BUF_SIZE   5       /*Memory buffer size in MB*/
+#define PKG_BUF_SIZE   2       /*Memory buffer size in MB*/
+
+/*Device entry defines*/
+#define DEV_MAJOR              7
+
+#define FS_TYPE                "ext4"
+
+typedef enum mount_type_t {
+       MOUNT_TYPE_RD = 0,
+       MOUNT_TYPE_RW,
+       MOUNT_TYPE_RW_NOEXEC,
+       MOUNT_TYPE_RD_REMOUNT,
+       MOUNT_TYPE_RW_REMOUNT
+} mount_type;
+
+typedef enum app2sd_cmd_t {
+       APP2SD_PRE_INSTALL = 1,
+       APP2SD_POST_INSTALL,
+       APP2SD_PRE_UNINSTALL,
+       APP2SD_POST_UNINSTALL,
+       APP2SD_PRE_UPGRADE,
+       APP2SD_POST_UPGRADE,
+       APP2SD_APP_LAUNCH,
+       APP2SD_APP_TERMINATE,
+       APP2SD_MOVE_APP_TO_MMC,
+       APP2SD_MOVE_APP_TO_PHONE
+} app2sd_cmd;
+
+/*This will store password in DB*/
+int _app2sd_set_passwod_in_db(const char *pkgid, const char *password);
+
+/*This will remove password from db*/
+int _app2sd_remove_password_from_db(const char *pkgid);
+
+/*This will fetch password from db*/
+char *_app2sd_get_passowrd_from_db(const char *pkgid);
+
+/*Checks whether mmc is present or not*/
+int _app2sd_check_mmc_status(void);
+
+/*this function is similar to system()*/
+int _xsystem(const char *argv[]);
+
+/*this function will return the free available memory on the SD Card*/
+int _app2sd_get_available_free_memory(const char *sd_path, int *free_mem);
+
+/*Function to move the application from/to SD Card*/
+int _app2sd_move_app(const char *pkgid, app2ext_move_type move_cmd, GList* dir_list);
+
+/*utility to delete the directory*/
+int _app2sd_delete_directory(char *dirname);
+
+/*utility to calculate the size of a directory in MB*/
+unsigned long long _app2sd_calculate_dir_size(char *dirname);
+
+/*utility to calculate the size of a file in MB*/
+unsigned long long _app2sd_calculate_file_size(const char *filename);
+
+/*Utility to copy a directory*/
+int _app2sd_copy_dir(const char *src, const char *dest);
+
+/*Utility to rename a directory*/
+int _app2sd_rename_dir(const char *old_name, const char *new_name);
+
+/*Utility to create application directory structure entry as per package type*/
+int _app2sd_create_directory_entry(const char *pkgid, GList* dir_list);
+
+/* Utility to create symlinks */
+int _app2sd_create_symlink(char *pkgid);
+
+/*This function finds the associated device node for the app*/
+char *_app2sd_find_associated_device_node(const char *pkgid);
+
+/*This function does the loopback encryption for app*/
+char *_app2sd_do_loopback_encryption_setup(const char *pkgid);
+
+/*This function detaches the loopback device*/
+char *_app2sd_detach_loop_device(const char *device);
+
+/*This function finds loopback device associated with the app*/
+char *_app2sd_find_associated_device(const char *mmc_app_path);
+
+/*This function creates loopback device*/
+int _app2sd_create_loopback_device(const char *pkgid, int size);
+
+/*This function deletes loopback device associated with the app*/
+int _app2sd_delete_loopback_device(const char *pkgid);
+
+/*This function creates ext4 FS on the device path*/
+int _app2sd_create_file_system(const char *device_path);
+
+/*This function mounts the app content on the device node*/
+int _app2sd_mount_app_content(const char *pkgid, const char *dev,
+                       int mount_type, GList* dir_list, app2sd_cmd cmd);
+
+/*This function unmounts the app content */
+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 updates loopback device size*/
+int _app2sd_update_loopback_device_size(const char *pkgid,
+       int size, GList* dir_list);
+
+/* This generates password */
+char *_app2sd_generate_password(const char *pkgid);
+
+/*This function encrypts device*/
+char *_app2sd_encrypt_device(const char *device, const char *pkgid,
+                              char *passwd);
+
+/*This function finds free device*/
+char *_app2sd_find_free_device(void);
+
+/*This function initializes app2sd DB*/
+int _app2sd_initialize_db();
+
+/*This function is used to get password from db*/
+char *_app2sd_get_password_from_db(const char *pkgid);
+
+/*This function removes password from db */
+int _app2sd_remove_password_from_db(const char *pkgid);
+
+/* This functions saved password in db */
+int _app2sd_set_password_in_db(const char *pkgid,
+                                     const char *passwd);
+
+#endif
diff --git a/plugin/app2sd/src/app2sd_interface.c b/plugin/app2sd/src/app2sd_interface.c
new file mode 100755 (executable)
index 0000000..3e9fe76
--- /dev/null
@@ -0,0 +1,722 @@
+/*
+ * app2ext
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Garima Shrivastava<garima.s@samsung.com>
+ *     Jyotsna Dhumale <jyotsna.a@samsung.com>
+ *     Venkatesha Sarpangala <sarpangala.v@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <app2sd_internals.h>
+#include <app2sd_interface.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+int app2sd_pre_app_install(const char *pkgid, GList* dir_list,
+                               int size)
+{
+       int ret = 0;
+       int free_mmc_mem = 0;
+       char *device_node = NULL;
+       char *devi = NULL;
+       char *result = NULL;
+
+       /*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 */
+       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 */
+       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("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));
+       if (ret) {
+               app2ext_print("App2Sd Error : Package already present\n");
+               return ret;
+       }
+       /*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 */
+       devi = _app2sd_find_associated_device_node(pkgid);
+       if (devi == NULL) {
+               app2ext_print("App2Sd Error : finding associated device node failed\n");
+               ret = APP2EXT_ERROR_DO_LOSETUP;
+               goto FINISH_OFF;
+       }
+
+       /*Format the loopback file system */
+       ret = _app2sd_create_file_system(device_node);
+       if (ret) {
+               app2ext_print("App2Sd Error : creating FS failed failed\n");
+               ret = APP2EXT_ERROR_CREATE_FS;
+               goto FINISH_OFF;
+       }
+
+       /*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) {
+               app2ext_print("App2Sd Error : mounting dev path to app install path failed\n");
+               ret = APP2EXT_ERROR_MOUNT_PATH;
+               goto FINISH_OFF;
+       }
+
+       /*Success */
+       ret = APP2EXT_SUCCESS;
+       goto END;
+
+FINISH_OFF:
+
+       if (device_node) {
+               result = _app2sd_detach_loop_device(device_node);
+               if (result) {
+                       free(result);
+                       result = NULL;
+               }
+               _app2sd_delete_loopback_device(pkgid);
+       }
+END:
+       if (device_node) {
+               free(device_node);
+               device_node = NULL;
+       }
+       if (devi) {
+               free(devi);
+               devi = NULL;
+       }
+       return ret;
+}
+
+int app2sd_post_app_install(const char *pkgid,
+                       app2ext_status install_status)
+{
+       char *device_name = NULL;
+       char buf_dir[FILENAME_MAX] = { 0, };
+       int ret = APP2EXT_SUCCESS;
+       /*Validate the function parameter recieved */
+       if (pkgid == NULL || install_status < APP2EXT_STATUS_FAILED
+               || install_status > APP2EXT_STATUS_SUCCESS) {
+               app2ext_print("Invalid func parameters\n");
+               return APP2EXT_ERROR_INVALID_ARGUMENTS;
+       }
+
+       /*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;
+       }
+       sync(); //2
+       /*Get the associated device node for SD card applicationer */
+       device_name = _app2sd_find_associated_device_node(pkgid);
+       if (NULL == device_name) {
+               return APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_NODE;
+       }
+       ret = _app2sd_unmount_app_content(pkgid);
+       if (ret) {
+               if (device_name) {
+                       free(device_name);
+                       device_name = NULL;
+               }
+               app2ext_print("Unable to unmount the app content %d\n", ret);
+               return APP2EXT_ERROR_UNMOUNT;
+       }
+       ret = _app2sd_remove_loopback_encryption_setup(pkgid);
+       if (ret) {
+               if (device_name) {
+                       free(device_name);
+                       device_name = NULL;
+               }
+               app2ext_print
+                   ("Unable to Detach the loopback encryption setup for the application");
+               return APP2EXT_ERROR_UNMOUNT;
+       }
+       if (device_name) {
+               free(device_name);
+               device_name = NULL;
+       }
+
+       /*Take appropriate action based on installation
+       status of application package */
+       if (install_status == APP2EXT_STATUS_FAILED) {
+               /*Delete the loopback device from the SD card */
+               ret = _app2sd_delete_loopback_device(pkgid);
+               if (ret) {
+                       app2ext_print
+                           ("App2Sd Error : Unable to delete the loopback device from the SD Card\n");
+                       return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
+               }
+               ret = _app2sd_remove_password_from_db(pkgid);
+
+               if (ret) {
+                       app2ext_print
+                           ("App2Sd Error : Unable to delete the password\n");
+               }
+
+               snprintf(buf_dir, FILENAME_MAX, "%s%s", APP_INSTALLATION_PATH, pkgid);
+
+               ret = _app2sd_delete_directory(buf_dir);
+
+               if (ret) {
+                       app2ext_print
+                           ("App2Sd Error : Unable to delete the directory %s\n",
+                            buf_dir);
+               }
+
+       }
+       return ret;
+}
+
+int app2sd_on_demand_setup_init(const char *pkgid)
+{
+       int ret = APP2EXT_SUCCESS;
+       char app_path[FILENAME_MAX] = { 0, };
+       char *device_node = NULL;
+       char *result = NULL;
+       FILE *fp = NULL;
+
+       /*Validate the function parameter recieved */
+       if (pkgid == NULL) {
+               app2ext_print
+                   ("App2Sd Error : Invalid function arguments to app launch setup\n");
+               return APP2EXT_ERROR_INVALID_ARGUMENTS;
+       }
+
+       /*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;
+       }
+
+       /*check app entry is there in sd card or not. */
+       snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
+                pkgid);
+       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);
+       result = (char *)_app2sd_find_associated_device(app_path);
+       /*process the string */
+       if ((result!=NULL) && strstr(result, "/dev") != NULL) {
+               app2ext_print("App2SD Error! Already associated\n");
+               free(result);
+               result = NULL;
+               return APP2EXT_ERROR_ALREADY_MOUNTED;
+       }
+
+       /*Do loopback setup */
+       device_node = _app2sd_do_loopback_encryption_setup(pkgid);
+       if (device_node == NULL) {
+               app2ext_print
+                   ("App2Sd Error : loopback encryption setup failed\n");
+               return APP2EXT_ERROR_DO_LOSETUP;
+       }
+
+       /*Do  mounting */
+       ret =
+           _app2sd_mount_app_content(pkgid, device_node, MOUNT_TYPE_RD,
+                               NULL, APP2SD_APP_LAUNCH);
+       if (ret) {
+               app2ext_print("App2Sd Error : Re-mount failed\n");
+               if (device_node) {
+                       free(device_node);
+                       device_node = NULL;
+               }
+               return APP2EXT_ERROR_MOUNT_PATH;
+       }
+       if (device_node) {
+               free(device_node);
+               device_node = NULL;
+       }
+       return ret;
+}
+
+int app2sd_on_demand_setup_exit(const char *pkgid)
+{
+       int ret = APP2EXT_SUCCESS;
+       char app_path[FILENAME_MAX] = { 0, };
+       FILE *fp = NULL;
+
+       /*Validate the function parameter recieved */
+       if (pkgid == NULL) {
+               app2ext_print
+                   ("App2Sd Error : Invalid function arguments to app launch setup\n");
+               return APP2EXT_ERROR_INVALID_ARGUMENTS;
+       }
+
+       /*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;
+       }
+       /*check app entry is there in sd card or not. */
+       snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
+                pkgid);
+       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);
+       ret = _app2sd_unmount_app_content(pkgid);
+       if (ret) {
+               app2ext_print
+                   ("App2SD Error: Unable to unmount the SD application\n");
+               return APP2EXT_ERROR_UNMOUNT;
+       }
+       ret = _app2sd_remove_loopback_encryption_setup(pkgid);
+       if (ret) {
+               app2ext_print("App2SD Error: Unable to remove loopback setup\n");
+               return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
+       }
+       return ret;
+}
+
+int app2sd_pre_app_uninstall(const char *pkgid)
+{
+       int ret = APP2EXT_SUCCESS;
+       char app_path[FILENAME_MAX] = { 0, };
+       char *device_node = NULL;
+       FILE*fp = NULL;
+
+       /*Validate the function parameter recieved */
+       if (pkgid == NULL) {
+               app2ext_print
+                   ("App2Sd Error : Invalid function arguments to app launch setup\n");
+               return APP2EXT_ERROR_INVALID_ARGUMENTS;
+       }
+       /*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;
+       }
+       /*check app entry is there in sd card or not. */
+       snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH, pkgid);
+       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 the associated device node for SD card applicationer */
+       device_node = _app2sd_find_associated_device_node(pkgid);
+       if (NULL == device_node) {
+               /*Do loopback setup */
+               device_node = _app2sd_do_loopback_encryption_setup(pkgid);
+
+               if (device_node == NULL) {
+                       app2ext_print
+                           ("App2Sd Error : loopback encryption setup failed\n");
+                       return APP2EXT_ERROR_DO_LOSETUP;
+               }
+               /*Do  mounting */
+               ret =
+                   _app2sd_mount_app_content(pkgid, device_node,
+                                       MOUNT_TYPE_RW, NULL,
+                                       APP2SD_PRE_UNINSTALL);
+
+               if (ret) {
+                       app2ext_print("App2Sd Error : RW-mount failed\n");
+                       if (device_node) {
+                               free(device_node);
+                               device_node = NULL;
+                       }
+                       return APP2EXT_ERROR_MOUNT_PATH;
+               }
+       } else {
+               /*Do  re-mounting */
+               ret =
+                   _app2sd_mount_app_content(pkgid, device_node,
+                                       MOUNT_TYPE_RW_REMOUNT, NULL,
+                                       APP2SD_PRE_UNINSTALL);
+
+               if (ret) {
+                       app2ext_print("App2Sd Error : Re-mount failed\n");
+                       if (device_node) {
+                               free(device_node);
+                               device_node = NULL;
+                       }
+                       return APP2EXT_ERROR_MOUNT_PATH;
+               }
+       }
+       if (device_node) {
+               free(device_node);
+               device_node = NULL;
+       }
+       return ret;
+}
+
+/*
+* app2sd_post_app_uninstall_setup
+* Uninstall Application and free all the allocated resources
+* Called after dpkg remove, It deallocates dev node and loopback
+*/
+int app2sd_post_app_uninstall(const char *pkgid)
+{
+       char buf_dir[FILENAME_MAX] = { 0, };
+       int ret = APP2EXT_SUCCESS;
+       int ret1 = APP2EXT_SUCCESS;
+       /*Validate the function parameter recieved */
+       if (pkgid == NULL) {
+               app2ext_print
+                   ("App2Sd Error : Invalid function arguments to Post Uninstall\n");
+               return APP2EXT_ERROR_INVALID_ARGUMENTS;
+       }
+       /*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;
+       }
+       /*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);
+               return APP2EXT_ERROR_UNMOUNT;
+       }
+       /*Detach the loopback encryption setup for the application */
+       ret = _app2sd_remove_loopback_encryption_setup(pkgid);
+       if (ret) {
+               app2ext_print
+                   ("Unable to Detach the loopback encryption setup for the application");
+               return APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE;
+       }
+       /*Delete the loopback device from the SD card */
+       ret = _app2sd_delete_loopback_device(pkgid);
+       if (ret) {
+               app2ext_print
+                   ("App2Sd Error : Unable to delete the loopback device from the SD Card\n");
+               return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
+       }
+       memset((void *)&buf_dir, '\0', FILENAME_MAX);
+       snprintf(buf_dir, FILENAME_MAX, "%s%s", APP_INSTALLATION_PATH, pkgid);
+       ret1 = _app2sd_delete_directory(buf_dir);
+       if (ret1) {
+               app2ext_print
+                   ("App2Sd Error : Unable to delete the directory %s\n",
+                    buf_dir);
+       }
+       /*remove encryption password from DB */
+       ret = _app2sd_initialize_db();
+       if (ret) {
+               app2ext_print("\n app2sd db initialize failed");
+               return APP2EXT_ERROR_SQLITE_REGISTRY;
+       }
+       ret = _app2sd_remove_password_from_db(pkgid);
+       if (ret) {
+               app2ext_print("cannot remove password from db \n");
+               return APP2EXT_ERROR_SQLITE_REGISTRY;
+       }
+       return ret;
+}
+
+int app2sd_move_installed_app(const char *pkgid, GList* dir_list,
+                       app2ext_move_type move_type)
+{
+       int ret = 0;
+
+       /*Validate function arguments*/
+       if (pkgid == NULL || dir_list == NULL
+               || move_type < APP2EXT_MOVE_TO_EXT
+               || move_type > APP2EXT_MOVE_TO_PHONE) {
+               app2ext_print("App2Sd Error : Invalid function arguments\n");
+               return APP2EXT_ERROR_INVALID_ARGUMENTS;
+       }
+
+       ret = _app2sd_move_app(pkgid, move_type, dir_list);
+       if (ret) {
+               app2ext_print("App2Sd Error : Unable to move application\n");
+               return ret;
+       }
+       return ret;
+}
+
+int app2sd_pre_app_upgrade(const char *pkgid, GList* dir_list,
+                       int size)
+{
+       int ret = APP2EXT_SUCCESS;
+       char app_path[FILENAME_MAX] = { 0, };
+       char *device_node = NULL;
+       unsigned long long curr_size = 0;
+       FILE *fp = NULL;
+
+       /*Validate function arguments*/
+       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 */
+       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;
+       }
+       /*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*/
+       curr_size = _app2sd_calculate_file_size(app_path);
+       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(APP2EXT_SUCCESS !=ret) {
+                       app2ext_print
+                           ("App2SD Error: _app2sd_update_loopback_device_size() failed\n");
+                       return ret;
+               }
+       }
+
+       /*Get the associated device node for SD card applicationer */
+       device_node = _app2sd_find_associated_device_node(pkgid);
+       if (NULL == device_node) {
+               /*Do loopback setup */
+               device_node = _app2sd_do_loopback_encryption_setup(pkgid);
+               if (device_node == NULL) {
+                       app2ext_print
+                           ("App2Sd Error : loopback encryption setup failed\n");
+                       return APP2EXT_ERROR_DO_LOSETUP;
+               }
+               /*Do  mounting */
+               ret =
+                   _app2sd_mount_app_content(pkgid, device_node,
+                                       MOUNT_TYPE_RW, NULL,
+                                       APP2SD_PRE_UPGRADE);
+               if (ret) {
+                       app2ext_print("App2Sd Error : Re-mount failed\n");
+                       if (device_node) {
+                               free(device_node);
+                               device_node = NULL;
+                       }
+                       return APP2EXT_ERROR_MOUNT_PATH;
+               }
+       } else {
+               /*Do  re-mounting */
+               ret =
+                   _app2sd_mount_app_content(pkgid, device_node,
+                                             MOUNT_TYPE_RW_REMOUNT, NULL,
+                                             APP2SD_PRE_UPGRADE);
+               if (ret) {
+                       app2ext_print("App2Sd Error : Re-mount failed\n");
+                       if (device_node) {
+                               free(device_node);
+                               device_node = NULL;
+                       }
+                       return APP2EXT_ERROR_MOUNT_PATH;
+               }
+       }
+
+       if (device_node) {
+               free(device_node);
+               device_node = NULL;
+       }
+       return ret;
+}
+
+
+int app2sd_post_app_upgrade(const char *pkgid,
+                       app2ext_status install_status)
+{
+       char *device_name = NULL;
+       int ret = APP2EXT_SUCCESS;
+       /*Validate the function parameter recieved */
+       if (pkgid == NULL || install_status < APP2EXT_STATUS_FAILED
+               || install_status > APP2EXT_STATUS_SUCCESS) {
+               app2ext_print("Invalid func parameters\n");
+               return APP2EXT_ERROR_INVALID_ARGUMENTS;
+       }
+       /*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;
+       }
+
+       /*Get the associated device node for SD card applicationer */
+       device_name = _app2sd_find_associated_device_node(pkgid);
+       if (NULL == device_name) {
+               return APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_NODE;
+       }
+       ret = _app2sd_unmount_app_content(pkgid);
+       if (ret) {
+               if (device_name) {
+                       free(device_name);
+                       device_name = NULL;
+               }
+               app2ext_print("Unable to unmount the app content %d\n", ret);
+               return APP2EXT_ERROR_UNMOUNT;
+       }
+       ret = _app2sd_remove_loopback_encryption_setup(pkgid);
+       if (ret) {
+               if (device_name) {
+                       free(device_name);
+                       device_name = NULL;
+               }
+               app2ext_print
+                   ("Unable to Detach the loopback encryption setup for the application");
+               return APP2EXT_ERROR_UNMOUNT;
+       }
+       if (device_name) {
+               free(device_name);
+               device_name = NULL;
+       }
+       return ret;
+}
+
+/**
+ * Reserved API for forced cleanup
+ *
+ */
+int app2sd_force_cleanup(const char *pkgid){
+       char *device_name = NULL;
+       char buf_dir[FILENAME_MAX] = { 0, };
+       int ret = APP2EXT_SUCCESS;
+       FILE *fp = NULL;
+
+       /*Validate the function parameter recieved */
+       if (pkgid == NULL) {
+               app2ext_print("invalid func parameters\n");
+               return APP2EXT_ERROR_INVALID_ARGUMENTS;
+       }
+       memset((void *)&buf_dir, '\0', FILENAME_MAX);
+       snprintf(buf_dir, FILENAME_MAX, "%s%s", APP2SD_PATH, pkgid);
+       fp = fopen(buf_dir, "r+");
+       if (fp == NULL) {
+               app2ext_print("\"%s\" not installed on SD Card\n", pkgid);
+               return APP2EXT_ERROR_INVALID_PACKAGE;
+       }
+       fclose(fp);
+       /*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;
+       }
+
+       /*Get the associated device node for SD card applicationer */
+       device_name = _app2sd_find_associated_device_node(pkgid);
+       if (NULL != device_name) {
+               free(device_name);
+               device_name = NULL;
+               ret = _app2sd_unmount_app_content(pkgid);
+               if (ret) {
+                       app2ext_print("Unable to unmount the app content %d\n", ret);
+                       return APP2EXT_ERROR_UNMOUNT;
+               }
+               ret = _app2sd_remove_loopback_encryption_setup(pkgid);
+               if (ret) {
+                       app2ext_print
+                           ("Unable to Detach the loopback encryption setup for the application");
+                       return APP2EXT_ERROR_UNMOUNT;
+               }
+       }
+
+       memset((void *)&buf_dir, '\0', FILENAME_MAX);
+       snprintf(buf_dir, FILENAME_MAX, "%s%s", APP_INSTALLATION_PATH, pkgid);
+       ret = _app2sd_delete_directory(buf_dir);
+       if (ret) {
+               app2ext_print
+                   ("App2Sd Error : Unable to delete the directory %s\n",
+                    buf_dir);
+       }
+
+       /*remove passwrd from DB*/
+       ret = _app2sd_initialize_db();
+       if (ret) {
+               app2ext_print("\n app2sd db initialize failed");
+               return APP2EXT_ERROR_SQLITE_REGISTRY;
+       }
+       ret = _app2sd_remove_password_from_db(pkgid);
+       if (ret) {
+               app2ext_print("cannot remove password from db \n");
+               return APP2EXT_ERROR_SQLITE_REGISTRY;
+       }
+       return ret;
+}
+
+/* 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.
+*/
+void
+app2ext_on_load(app2ext_interface *st_interface)
+{
+       /*Plug-in Binding.*/
+       st_interface->pre_install= app2sd_pre_app_install;
+       st_interface->post_install= app2sd_post_app_install;
+       st_interface->pre_uninstall= app2sd_pre_app_uninstall;
+       st_interface->post_uninstall= app2sd_post_app_uninstall;
+       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->enable= app2sd_on_demand_setup_init;
+       st_interface->disable= app2sd_on_demand_setup_exit;
+}
+
diff --git a/plugin/app2sd/src/app2sd_internals.c b/plugin/app2sd/src/app2sd_internals.c
new file mode 100755 (executable)
index 0000000..e3942ea
--- /dev/null
@@ -0,0 +1,1371 @@
+/*
+ * app2ext
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Garima Shrivastava<garima.s@samsung.com>
+ *     Jyotsna Dhumale <jyotsna.a@samsung.com>
+ *     Venkatesha Sarpangala <sarpangala.v@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <app2sd_internals.h>
+#include <app2sd_interface.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <openssl/sha.h>
+#include <fcntl.h>
+#include <time.h>
+#include <dlog.h>
+
+/*
+########### Internal APIs ##################
+ */
+
+char *_app2sd_find_associated_device_node(const char *pkgid)
+{
+       char *ret_result = NULL;
+       char delims[] = ":";
+       char *result = NULL;
+       char app_path[FILENAME_MAX] = { '\0' };
+
+       snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
+                pkgid);
+       result = (char *)_app2sd_find_associated_device(app_path);
+       if (result == NULL) {
+               app2ext_print
+                   ("App2SD Error! Unable to find the associated File\n");
+               return NULL;
+       }
+       /*process the string*/
+       if (strstr(result, "/dev") == NULL) {
+               app2ext_print
+                   ("App2SD Error! Unable to find the associated File\n");
+               return NULL;
+       } else {
+               ret_result = strtok(result, delims);
+       }
+
+       return ret_result;
+
+}
+
+char *_app2sd_create_loopdevice_node(void)
+{
+       char *ret_result = NULL;
+       mode_t mode = DIR_PERMS;
+       int count = 0;
+       int ret = APP2EXT_SUCCESS;
+       char *result = NULL;
+       FILE *fp = NULL;
+
+       result = (char *)_app2sd_find_free_device();
+       /*validate the result */
+       if (result == NULL || strstr(result, "/dev") == NULL) {
+               app2ext_print("No device found, creating device node...\n");
+
+               if (result) {
+                       free(result);
+                       result = NULL;
+               }
+               count = 0;
+               char dev_path[BUF_SIZE] = { 0, };
+               snprintf(dev_path, BUF_SIZE, "/dev/loop%d", count);
+               while ((fp = fopen(dev_path, "r+")) != NULL) {
+                       count = count + 1;
+                       snprintf(dev_path, BUF_SIZE, "/dev/loop%d", count);
+                       app2ext_print("next dev path for checking is %s\n",
+                                    dev_path);
+                       fclose(fp);
+               }
+               app2ext_print("Device node candidate is %s \n", dev_path);
+               dev_t dev_node;
+               dev_node = makedev(DEV_MAJOR, count);
+               if ((ret = mknod(dev_path, S_IFBLK | mode, dev_node)) < 0) {
+                       app2ext_print
+                           ("Error while creating the device node: errno is %d\n",
+                            errno);
+                       return NULL;
+               }
+               ret_result = (char *)malloc(strlen(dev_path) + 1);
+               if (ret_result == NULL) {
+                       app2ext_print("Unable to allocate memory\n");
+                       return NULL;
+               }
+               memset(ret_result, '\0', strlen(dev_path) + 1);
+               memcpy(ret_result, dev_path, strlen(dev_path));
+       } else {
+               ret_result = (char *)malloc(strlen(result) + 1);
+               if (ret_result == NULL) {
+                       app2ext_print("Malloc failed!\n");
+                       free(result);
+                       result = NULL;
+                       return NULL;
+               }
+               memset(ret_result, '\0', strlen(result) + 1);
+               if (strlen(result) > 0) {
+                       memcpy(ret_result, result, strlen(result) - 1);
+               }
+               free(result);
+               result = NULL;
+
+       }
+       return ret_result;
+}
+
+char *_app2sd_do_loopback_encryption_setup(const char *pkgid)
+{
+       int ret = APP2EXT_SUCCESS;
+       char *passwd = NULL;
+       char app_path[FILENAME_MAX] = { '\0' };
+       char *result = NULL;
+       char *device_node = NULL;
+       if (pkgid == NULL) {
+               app2ext_print("App2Sd Error: Invalid argument\n");
+               return NULL;
+       }
+
+       snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
+                pkgid);
+       /* Get password for loopback encryption */
+       ret = _app2sd_initialize_db();
+       if (ret) {
+               app2ext_print("\n app2sd db initialize failed");
+               return NULL;
+       }
+       if ((passwd = _app2sd_get_password_from_db(pkgid)) == NULL) {
+               passwd = (char *)_app2sd_generate_password(pkgid);
+               if (NULL == passwd) {
+                       app2ext_print
+                           ("App2Sd Error: Unable to generate password\n");
+                       return NULL;
+               } else {
+                       app2ext_print("Password is %s\n", passwd);
+                       if ((ret = _app2sd_set_password_in_db(pkgid,
+                                       passwd)) < 0) {
+                               app2ext_print
+                               ("App2Sd Error: Unable to save password\n");
+                               free(passwd);
+                               passwd = NULL;
+                               return NULL;
+                       }
+               }
+       }
+
+       /*Get Free device node*/
+       device_node = _app2sd_create_loopdevice_node();
+       if (NULL == device_node) {
+               free(passwd);
+               passwd = NULL;
+               app2ext_print
+                   ("App2Sd Error: Unable to find free loopback node\n");
+               return NULL;
+       }
+       result = (char *)_app2sd_encrypt_device(device_node, app_path, passwd);
+       if (result == NULL) {
+               app2ext_print("App2Sd Error: Encryption failed!\n\n");
+               free(passwd);
+               passwd = NULL;
+               return NULL;
+       } else {
+               free(result);
+               result = NULL;
+               free(passwd);
+               passwd = NULL;
+               return device_node;
+       }
+}
+
+char *_app2sd_do_loopback_duplicate_encryption_setup(const char *pkgid, const char * dup_appname)
+{
+       int ret = APP2EXT_SUCCESS;
+       char *passwd = NULL;
+       char app_path[FILENAME_MAX] = { '\0' };
+       char *result = NULL;
+       char *device_node = NULL;
+       if (pkgid == NULL || dup_appname == NULL) {
+               app2ext_print("App2Sd Error: Invalid argument\n");
+               return NULL;
+       }
+
+       snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
+                dup_appname);
+       /* Get password for loopback encryption */
+       ret = _app2sd_initialize_db();
+       if (ret) {
+               app2ext_print("\n app2sd db initialize failed");
+               return NULL;
+       }
+       if ((passwd = _app2sd_get_password_from_db(pkgid)) == NULL) {
+               passwd = (char *)_app2sd_generate_password(pkgid);
+               if (NULL == passwd) {
+                       app2ext_print
+                           ("App2Sd Error: Unable to generate password\n");
+                       return NULL;
+               } else {
+                       app2ext_print("Password is %s\n", passwd);
+                       if ((ret = _app2sd_set_password_in_db(pkgid,
+                                       passwd)) < 0) {
+                               app2ext_print
+                               ("App2Sd Error: Unable to save password\n");
+                               free(passwd);
+                               passwd = NULL;
+                               return NULL;
+                       }
+               }
+
+       }
+       /*Get Free device node*/
+       device_node = _app2sd_create_loopdevice_node();
+       if (NULL == device_node) {
+               free(passwd);
+               passwd = NULL;
+               app2ext_print
+                   ("App2Sd Error: Unable to find free loopback node\n");
+               return NULL;
+       }
+       result = (char *)_app2sd_encrypt_device(device_node, app_path, passwd);
+       if (result == NULL) {
+               app2ext_print("App2Sd Error: Encryption failed!\n\n");
+               free(passwd);
+               passwd = NULL;
+               return NULL;
+       } else {
+               if (strlen(result) == 0) {
+                       free(result);
+                       result = NULL;
+                       free(passwd);
+                       passwd = NULL;
+                       return device_node;
+               } else {
+                       app2ext_print("App2Sd Error: Error is %s\n", result);
+                       free(result);
+                       result = NULL;
+                       free(passwd);
+                       passwd = NULL;
+                       return NULL;
+               }
+       }
+       return device_node;
+}
+
+int _app2sd_remove_loopback_encryption_setup(const char *pkgid)
+{
+       int ret = APP2EXT_SUCCESS;
+       char *result = NULL;
+       char *dev_node = NULL;
+       if ((dev_node = _app2sd_find_associated_device_node(pkgid)) == NULL) {
+               app2ext_print("Unable to find the association\n");
+               ret = APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_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;
+       } 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;
+       char command[FILENAME_MAX] = { 0, };
+       mode_t mode = DIR_PERMS;
+       char external_storage_path[FILENAME_MAX] = { 0, };
+       char buff[BUF_SIZE] = { 0, };
+       char app_path[FILENAME_MAX] = { 0, };
+       FILE *fp = NULL;
+
+       if (NULL == pkgid || size <= 0) {
+               app2ext_print("App2Sd Error: Invalid argument\n");
+               return APP2EXT_ERROR_INVALID_ARGUMENTS;
+       }
+       snprintf(command, FILENAME_MAX, "of=%s%s", APP2SD_PATH,
+                pkgid);
+       snprintf(buff, BUF_SIZE, "count=%d", size);
+       const char *argv1[] =
+           { "dd", "if=/dev/zero", command, "bs=1M", buff, NULL };
+       snprintf(external_storage_path, FILENAME_MAX, "%s",
+                APP2SD_PATH);
+       ret = mkdir(external_storage_path, mode);
+       if (ret) {
+               if (errno != EEXIST) {
+                       app2ext_print
+                           ("App2sd Error : Create directory failed, error no is %d\n",
+                            errno);
+                       return APP2EXT_ERROR_CREATE_DIRECTORY;
+               }
+       }
+       snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
+                pkgid);
+       if ((fp = fopen(app_path, "r+")) != NULL) {
+               app2ext_print("Application already exists %s\n", app_path);
+               fclose(fp);
+               return APP2EXT_ERROR_PKG_EXISTS;
+       }
+
+       ret = _xsystem(argv1);
+       if (ret) {
+               app2ext_print("App2Sd Error : command \"%s\" failed \n",
+                            command);
+               return ret;
+       }
+       return ret;
+}
+
+int _app2sd_delete_loopback_device(const char *pkgid)
+{
+       int ret = APP2EXT_SUCCESS;
+       char loopback_device[FILENAME_MAX] = { 0, };
+
+       snprintf(loopback_device, FILENAME_MAX, "%s%s", APP2SD_PATH,
+                pkgid);
+
+       ret = unlink(loopback_device);
+       if (ret) {
+               if (errno == ENOENT) {
+                       app2ext_print("Unable to access file %s\n", loopback_device);
+               } else {
+                       app2ext_print("Unable to delete %s\n", loopback_device);
+                       return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
+               }
+       }
+       return ret;
+}
+
+int _app2sd_create_file_system(const char *device_path)
+{
+       int ret = APP2EXT_SUCCESS;
+       FILE *fp = NULL;
+       if (NULL == device_path) {
+               app2ext_print("App2Sd Error: invalid param [NULL]\n");
+               return APP2EXT_ERROR_INVALID_ARGUMENTS;
+       }
+
+       /*Format the filesystem [create a filesystem]*/
+       const char *argv[] = { "mkfs.ext4", device_path, NULL };
+       fp = fopen(device_path, "r+");
+       if (fp == NULL) {
+               app2ext_print
+                   ("App2sd Error: Unable to access %s [System errono is %d.....%s]\n",
+                    device_path, errno, strerror(errno));
+               return APP2EXT_ERROR_ACCESS_FILE;
+       } else {
+               fclose(fp);
+       }
+       ret = _xsystem(argv);
+       if (ret) {
+               app2ext_print
+                   ("App2Sd Error : creating file system failed [System error is %s\n",
+                    strerror(errno));
+               return APP2EXT_ERROR_CREATE_FS;
+       }
+       return ret;
+}
+
+static int _app2sd_create_dir_with_link(const char *pkgid,
+                                        const char *dir_name)
+{
+       mode_t mode = DIR_PERMS;
+       int ret = APP2EXT_SUCCESS;
+       char app_dir_mmc_path[FILENAME_MAX] = { 0, };
+       char app_dir_path[FILENAME_MAX] = { 0, };
+       snprintf(app_dir_mmc_path, FILENAME_MAX, "%s%s/.mmc/%s",APP_INSTALLATION_PATH,
+                pkgid, dir_name);
+       snprintf(app_dir_path, FILENAME_MAX, "%s%s/%s", APP_INSTALLATION_PATH, pkgid,
+                dir_name);
+
+       ret = mkdir(app_dir_mmc_path, mode);
+       if (ret) {
+               if (errno != EEXIST) {
+                       app2ext_print
+                           ("App2sd Error : Create directory failed, error no is %d\n",
+                            errno);
+                       return APP2EXT_ERROR_CREATE_DIRECTORY;
+               }
+       }
+
+       if ((ret = symlink(app_dir_mmc_path, app_dir_path)) < 0) {
+               if (errno == EEXIST) {
+                       app2ext_print
+                           ("App2sd : File with Symlink name present %s\n",
+                            app_dir_path);
+               } else {
+                       app2ext_print
+                           ("A2Sd Error : Symbolic link creation failed, error no is %d\n",
+                            errno);
+                       return APP2EXT_ERROR_CREATE_SYMLINK;
+               }
+       }
+
+       return ret;
+}
+
+int _app2sd_create_directory_entry(const char *pkgid, GList* dir_list)
+{
+       int ret = APP2EXT_SUCCESS;
+       char app_dir_path[FILENAME_MAX] = { 0, };
+       GList *list = NULL;
+       app2ext_dir_details* dir_detail = NULL;
+
+       snprintf(app_dir_path, FILENAME_MAX, "%s%s", APP_INSTALLATION_PATH,
+                pkgid);
+
+       list = g_list_first(dir_list);
+       while (list) {
+               dir_detail = (app2ext_dir_details *)list->data;
+               if (dir_detail && dir_detail->name
+                       && dir_detail->type == APP2EXT_DIR_RO) {
+                       ret = _app2sd_create_dir_with_link(pkgid, dir_detail->name);
+                       if (ret) {
+                               return ret;
+                       }
+               }
+               list = g_list_next(list);
+       }
+       return APP2EXT_SUCCESS;
+}
+
+
+/*
+ *
+ * _app2sd_mount_app_content
+ This function is to create the path for mmc and mount the content
+Example usage: _app2sd_mount_app_content("deb.com.samsung.helloworld","/dev/loop0",MOUNT_TYPE_RD)
+*/
+int _app2sd_mount_app_content(const char *pkgid, const char *dev,
+                       int mount_type, GList* dir_list, app2sd_cmd cmd)
+{
+       int ret = APP2EXT_SUCCESS;
+       mode_t mode = DIR_PERMS;
+       char app_dir_path[FILENAME_MAX] = { 0, };
+       char app_dir_mmc_path[FILENAME_MAX] = { 0, };
+       if (NULL == pkgid || NULL == dev) {
+               app2ext_print("App2Sd Error : Input param is NULL %s %s \n",
+                            pkgid, dev);
+               return APP2EXT_ERROR_INVALID_ARGUMENTS;
+       }
+       snprintf(app_dir_path, FILENAME_MAX, "%s%s", APP_INSTALLATION_PATH, pkgid);
+       ret = mkdir(app_dir_path, mode);
+       if (ret) {
+               if (errno != EEXIST) {
+                       app2ext_print
+                           ("App2Sd Error : Create directory failed, error no is %d\n",
+                            errno);
+                       return APP2EXT_ERROR_CREATE_DIRECTORY;
+               }
+       }
+       snprintf(app_dir_mmc_path, FILENAME_MAX, "%s%s/.mmc", APP_INSTALLATION_PATH, pkgid);
+       ret = mkdir(app_dir_mmc_path, mode);
+       if (ret) {
+               if (errno != EEXIST) {
+                       app2ext_print
+                           ("App2Sd Error : Create directory failed, error no is %d\n",
+                            errno);
+                       return APP2EXT_ERROR_CREATE_DIRECTORY;
+               }
+       }
+
+       switch (mount_type) {
+       case MOUNT_TYPE_RD:
+               {
+                       if ((ret =
+                            mount(dev, app_dir_mmc_path, FS_TYPE,
+                                  MS_MGC_VAL | MS_RDONLY, 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);
+                               ret = APP2EXT_ERROR_MOUNT;
+                       }
+                       break;
+               }
+       case MOUNT_TYPE_RW:
+               {
+                       if ((ret =
+                            mount(dev, app_dir_mmc_path, FS_TYPE, MS_MGC_VAL,
+                                  NULL)) < 0) {
+                               app2ext_print
+                                   ("App2Sd Error : Read Write Mount failed [System Erro no is %d]\n",
+                                    errno);
+                               ret = APP2EXT_ERROR_MOUNT;
+                       }
+                       break;
+               }
+       case MOUNT_TYPE_RW_NOEXEC:
+               {
+                       if ((ret =
+                            mount(dev, app_dir_mmc_path, FS_TYPE,
+                                  MS_MGC_VAL | MS_NOEXEC, NULL)) < 0) {
+                               app2ext_print
+                                   ("App2Sd Error : RWX Mount failed [System Erro no is %d]\n",
+                                    errno);
+                               ret = APP2EXT_ERROR_MOUNT;
+                       }
+                       break;
+               }
+       case MOUNT_TYPE_RD_REMOUNT:
+               {
+                       if ((ret =
+                            mount(dev, app_dir_mmc_path, FS_TYPE,
+                                  MS_MGC_VAL | MS_RDONLY | MS_REMOUNT,
+                                  NULL)) < 0) {
+                               app2ext_print
+                                   ("App2Sd Error : RWX Mount failed [System Erro no is %d]\n",
+                                    errno);
+                               ret = APP2EXT_ERROR_MOUNT;
+                       }
+                       break;
+               }
+       case MOUNT_TYPE_RW_REMOUNT:
+               {
+                       if ((ret =
+                            mount(dev, app_dir_mmc_path, FS_TYPE,
+                                  MS_MGC_VAL | MS_REMOUNT, NULL)) < 0) {
+                               app2ext_print
+                                   ("App2Sd Error : RWX Mount failed [System Erro no is %d]\n",
+                                    errno);
+                               ret = APP2EXT_ERROR_MOUNT;
+                       }
+                       break;
+               }
+
+       default:
+               {
+                       app2ext_print("App2Sd Error: Invalid mount type\n");
+                       break;
+               }
+       }
+       if (cmd == APP2SD_PRE_INSTALL || cmd == APP2SD_MOVE_APP_TO_MMC) {
+               ret = _app2sd_create_directory_entry(pkgid, dir_list);
+       }
+       return ret;
+}
+
+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));
+       }
+       return ret;
+}
+
+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;
+               }
+       }
+       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;
+               }
+       }
+       return ret;
+}
+
+int _app2sd_move_app_to_external(const char *pkgid, GList* dir_list)
+{
+       int ret = APP2EXT_SUCCESS;
+       char app_path[FILENAME_MAX] = { 0, };
+       char path[FILENAME_MAX] = { 0, };
+       char app_mmc_path[FILENAME_MAX] = { 0, };
+       char app_archive_path[FILENAME_MAX] = { 0, };
+       char mmc_path[FILENAME_MAX] = { 0, };
+       unsigned long long total_size = 0;
+       int reqd_size = 0;
+       char *device_node = NULL;
+       char *devi = NULL;
+       mode_t mode = DIR_PERMS;
+       int free_mmc_mem = 0;
+       FILE *fp = NULL;
+       GList *list = NULL;
+       app2ext_dir_details* dir_detail = NULL;
+
+       /*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;
+       }
+
+       snprintf(mmc_path, FILENAME_MAX,
+                "%s%s", APP2SD_PATH, pkgid);
+
+       /*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\n",
+                    pkgid);
+               fclose(fp);
+               return APP2EXT_ERROR_ALREADY_FILE_PRESENT;
+       }
+
+       snprintf(app_mmc_path, FILENAME_MAX,
+                "%s%s/.mmc", APP_INSTALLATION_PATH, pkgid);
+       snprintf(app_archive_path, FILENAME_MAX,
+                "%s%s/.archive", APP_INSTALLATION_PATH, pkgid);
+
+       ret = mkdir(app_archive_path, mode);
+       if (ret) {
+               if (errno != EEXIST) {
+                       app2ext_print
+                           ("App2sd Error: Unable to create directory for archiving, error no is %d\n",
+                            errno);
+                       return APP2EXT_ERROR_CREATE_DIRECTORY;
+               }
+       }
+
+       list = g_list_first(dir_list);
+       while (list) {
+               dir_detail = (app2ext_dir_details *)list->data;
+               if (dir_detail && dir_detail->name
+                       && dir_detail->type == APP2EXT_DIR_RO) {
+                       memset((void *)&app_path, '\0',
+                              FILENAME_MAX);
+                       snprintf(app_path, FILENAME_MAX,
+                                "%s%s/%s",APP_INSTALLATION_PATH,
+                                pkgid,
+                                dir_detail->name);
+                       total_size +=
+                           _app2sd_calculate_dir_size
+                           (app_path);
+               }
+               list = g_list_next(list);
+       }
+
+       reqd_size = ((total_size / 1024) / 1024) + 2;
+
+       /*Find avialable 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 (reqd_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 */
+       ret =
+           _app2sd_create_loopback_device(pkgid, (reqd_size+PKG_BUF_SIZE));
+       if (ret) {
+               app2ext_print
+                   ("App2Sd Error : loopback node creation failed\n");
+               return APP2EXT_ERROR_CREATE_DEVICE;
+       }
+       /*Perform Loopback encryption setup */
+       device_node =
+           _app2sd_do_loopback_encryption_setup(pkgid);
+       if (!device_node) {
+               app2ext_print
+                   ("App2Sd Error : losetup failed, device node is %s\n",
+                    device_node);
+               return APP2EXT_ERROR_DO_LOSETUP;
+       }
+       /*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 :  _app2sd_find_associated_device_node  losetup failed\n");
+               return APP2EXT_ERROR_DO_LOSETUP;
+       } else {
+               free(devi);
+               devi = NULL;
+       }
+       /*Format the loopback file system */
+       ret = _app2sd_create_file_system(device_node);
+       if (ret) {
+               app2ext_print
+                   ("App2Sd Error : create ext4 filesystem failed\n");
+               return APP2EXT_ERROR_CREATE_FS;
+       }
+       /********Archiving code begin***********/
+       list = g_list_first(dir_list);
+       while (list) {
+               dir_detail = (app2ext_dir_details *)list->data;
+               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_move_to_archive
+                           (path,
+                            app_archive_path);
+                       if (ret) {
+                               if (ret == APP2EXT_ERROR_ACCESS_FILE) {
+                                       app2ext_print
+                                           ("App2Sd Error : unable to access %s\n",
+                                            path);
+                               } else {
+                                       app2ext_print
+                                           ("App2Sd Error : unable to copy from %s to %s \n",
+                                            path,
+                                            app_archive_path);
+                                       return
+                                           APP2EXT_ERROR_MOVE;
+                               }
+                       }
+               }
+               list = g_list_next(list);
+       }
+       /********Archiving code ends***********/
+
+       /*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_MOVE_APP_TO_MMC);
+       if (ret) {
+               return ret;
+       }
+       /********restore Archive begin***********/
+       list = g_list_first(dir_list);
+       while (list) {
+               dir_detail = (app2ext_dir_details *)list->data;
+               if (dir_detail && dir_detail->name
+                       && dir_detail->type == APP2EXT_DIR_RO) {
+                       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_mmc_path);
+                       if (ret) {
+                               if (ret == APP2EXT_ERROR_ACCESS_FILE) {
+                                       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;
+                               }
+                       }
+                       ret =
+                           _app2sd_delete_directory
+                           (path);
+                       if (ret) {
+                               if (ret == APP2EXT_ERROR_ACCESS_FILE) {
+                                       app2ext_print
+                                           ("App2Sd Error : unable to access %s\n",
+                                            path);
+                               } else {
+                                       app2ext_print
+                                           ("App2Sd Error : unable to delete %s \n",
+                                            path);
+                                       return
+                                           APP2EXT_ERROR_DELETE_DIRECTORY;
+                               }
+                       }
+               }
+               list = g_list_next(list);
+       }
+
+       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;
+       }
+       /*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;
+       }
+       ret =
+           _app2sd_remove_loopback_encryption_setup(pkgid);
+       if (ret) {
+               app2ext_print
+                   ("App2Sd Error : unable to detach loopback setup for %s\n",
+                    pkgid);
+               return APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE;
+       }
+       return APP2EXT_SUCCESS;
+}
+
+int _app2sd_move_app_to_internal(const char *pkgid, GList* dir_list)
+{
+       int ret = APP2EXT_SUCCESS;
+       mode_t mode = DIR_PERMS;
+       char path[FILENAME_MAX] = { 0, };
+       char app_mmc_path[FILENAME_MAX] = { 0, };
+       char app_path[FILENAME_MAX] = { 0, };
+       char mmc_path[FILENAME_MAX] = { 0, };
+       char app_archive_path[FILENAME_MAX] = { 0, };
+       char *device_node = NULL;
+       FILE *fp = NULL;
+       GList *list = NULL;
+       app2ext_dir_details* dir_detail = NULL;
+
+       snprintf(app_mmc_path, FILENAME_MAX,
+                "%s%s/.mmc", APP_INSTALLATION_PATH,  pkgid);
+       snprintf(app_path, FILENAME_MAX, "%s%s/", APP_INSTALLATION_PATH,
+                pkgid);
+       snprintf(app_archive_path, FILENAME_MAX,
+                "%s%s/.archive", APP_INSTALLATION_PATH, pkgid);
+       snprintf(mmc_path, FILENAME_MAX,
+                "%s%s", APP2SD_PATH, pkgid);
+
+       /*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;
+       }
+
+       /*check whether application is in external memory or not */
+       fp = fopen(mmc_path, "r+");
+       if (fp == NULL) {
+               app2ext_print
+                   ("Application %s is not installed on SD Card\n",
+                    pkgid);
+               return APP2EXT_ERROR_FILE_ABSENT;
+       } else {
+               fclose(fp);
+               fp = NULL;
+       }
+
+       /*Get the associated device node for SD card applicationer */
+       device_node =
+           _app2sd_find_associated_device_node(pkgid);
+       if (NULL == device_node) {
+               /*Do loopback setup */
+               device_node =
+                   _app2sd_do_loopback_encryption_setup
+                   (pkgid);
+               if (device_node == NULL) {
+                       app2ext_print
+                           ("App2Sd Error : loopback encryption setup failed\n");
+                       return APP2EXT_ERROR_DO_LOSETUP;
+               }
+               /*Do  mounting */
+               ret =
+                   _app2sd_mount_app_content(pkgid,
+                                             device_node,
+                                             MOUNT_TYPE_RW,
+                                             dir_list,
+                                             APP2SD_MOVE_APP_TO_PHONE);
+               if (ret) {
+                       app2ext_print
+                           ("App2Sd Error : Re-mount failed\n");
+                       return APP2EXT_ERROR_MOUNT_PATH;
+               }
+       } else {
+               /*Do  re-mounting */
+               ret =
+                   _app2sd_mount_app_content(pkgid,
+                                             device_node,
+                                             MOUNT_TYPE_RW_REMOUNT,
+                                             dir_list,
+                                             APP2SD_MOVE_APP_TO_PHONE);
+               if (ret) {
+                       app2ext_print
+                           ("App2Sd Error : Re-mount failed\n");
+                       return APP2EXT_ERROR_MOUNT_PATH;
+               }
+       }
+       ret = mkdir(app_archive_path, mode);
+       if (ret) {
+               app2ext_print
+                   ("App2Sd Error : unable to create directory%s\n",
+                    app_archive_path);
+               return APP2EXT_ERROR_CREATE_DIRECTORY;
+       }
+
+
+       list = g_list_first(dir_list);
+       while (list) {
+               dir_detail = (app2ext_dir_details *)list->data;
+               if (dir_detail && dir_detail->name
+                       && dir_detail->type == APP2EXT_DIR_RO) {
+                               /*Archiving code */
+                               memset((void *)&path, '\0',
+                                      FILENAME_MAX);
+                               snprintf(path, FILENAME_MAX,
+                                        "%s%s/.mmc/%s", APP_INSTALLATION_PATH,
+                                        pkgid,
+                                        dir_detail->name);
+                               ret =
+                                   _app2sd_copy_dir
+                                   (path,
+                                    app_archive_path);
+                               if (ret) {
+                                       if (ret == APP2EXT_ERROR_ACCESS_FILE) {
+                                               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;
+                                       }
+                               }
+
+                               /*Delete the symbolic link files [bin, lib, res]*/
+                               memset((void *)&path, '\0',
+                                      FILENAME_MAX);
+                               snprintf(path, FILENAME_MAX,
+                                        "%s%s/%s", APP_INSTALLATION_PATH,
+                                        pkgid,
+                                        dir_detail->name);
+                               ret = unlink(path);
+                               if (ret) {
+                                       if (errno == ENOENT) {
+                                               app2ext_print
+                                                   ("App2Sd Error : Directory %s does not exist\n",
+                                                    path);
+                                       } else {
+                                               app2ext_print
+                                                   ("App2Sd Error : unable to remove the symbolic link file %s\n",
+                                                    path);
+                                               return
+                                                   APP2EXT_ERROR_DELETE_LINK_FILE;
+                                       }
+                               }
+
+                               /*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);
+                               if (ret) {
+                                       if (ret == APP2EXT_ERROR_ACCESS_FILE) {
+                                               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;
+                                       }
+                               }
+               }
+               list = g_list_next(list);
+       }
+
+       ret = _app2sd_unmount_app_content(pkgid);
+       if (ret) {
+               app2ext_print
+                   ("App2Sd Error : unable to unmount SD directory for app %s\n",
+                    pkgid);
+               return APP2EXT_ERROR_UNMOUNT;
+       }
+       ret =
+           _app2sd_remove_loopback_encryption_setup(pkgid);
+       if (ret) {
+               app2ext_print
+                   ("App2Sd Error : unable to detach loopback setup for %s\n",
+                    pkgid);
+               return APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE;
+       }
+       ret = _app2sd_delete_loopback_device(pkgid);
+       if (ret) {
+               app2ext_print
+                   ("App2Sd Error : unable to delete the loopback device for %s\n",
+                    pkgid);
+               return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
+       }
+       ret = _app2sd_delete_directory(app_mmc_path);
+       if (ret) {
+               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;
+       }
+       return APP2EXT_SUCCESS;
+}
+
+int _app2sd_move_app(const char *pkgid, app2ext_move_type move_cmd, GList* dir_list)
+{
+       int ret = APP2EXT_SUCCESS;
+
+       /*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;
+       }
+
+       switch (move_cmd) {
+       case APP2EXT_MOVE_TO_EXT:
+               {
+                       ret = _app2sd_move_app_to_external(pkgid, dir_list);
+                       if (ret) {
+                               app2ext_print
+                                   ("App2Sd Error : move app to external memory failed %d\n",
+                                    ret);
+                               return ret;
+                       }
+                       break;
+               }
+       case APP2EXT_MOVE_TO_PHONE:
+               {
+                       ret = _app2sd_move_app_to_internal(pkgid, dir_list);
+                       if (ret) {
+                               app2ext_print
+                                   ("App2Sd Error : move app to internal memory failed %d\n",
+                                    ret);
+                               return ret;
+                       }
+                       break;
+               }
+       default:
+               {
+                       app2ext_print("App2Sd Error : invalid argument\n");
+                       return APP2EXT_ERROR_INVALID_ARGUMENTS;
+               }
+       }
+
+       return ret;
+
+}
+
+int _app2sd_copy_ro_content(const char *src, const char *dest, GList* dir_list)
+{
+       char path[FILENAME_MAX] = { 0, };
+       int ret =       APP2EXT_SUCCESS;
+       GList *list = NULL;
+       app2ext_dir_details* dir_detail = NULL;
+
+       list = g_list_first(dir_list);
+       while (list) {
+               dir_detail = (app2ext_dir_details *)list->data;
+               if (dir_detail && dir_detail->name
+                       && dir_detail->type == APP2EXT_DIR_RO) {
+                       memset((void *)&path, '\0',
+                              FILENAME_MAX);
+                       snprintf(path, FILENAME_MAX,
+                                "%s/%s", src,
+                                dir_detail->name);
+                       ret =
+                           _app2sd_copy_dir
+                           (path,
+                            dest);
+                       if (ret) {
+                               if (ret == APP2EXT_ERROR_ACCESS_FILE) {
+                                       app2ext_print
+                                           ("App2Sd Error : unable to access %s\n",
+                                            path);
+                               } else {
+                                       app2ext_print
+                                           ("App2Sd Error : unable to copy from %s to %s .....errno is %d\n",
+                                            path,
+                                            dest,
+                                            errno);
+                                       return
+                                           APP2EXT_ERROR_MOVE;
+                               }
+                       }
+               }
+               list = g_list_next(list);
+       }
+
+       return APP2EXT_SUCCESS;
+}
+
+int _app2sd_duplicate_device(const char *pkgid, GList* dir_list, char *dev_node, int size)
+{
+       int ret = 0;
+       char temp_pkgid[FILENAME_MAX] = { 0, };
+       char *devi = NULL;
+       int err_res = 0;
+       char *result = NULL;
+
+       /*Create a new loopback device */
+       snprintf(temp_pkgid, FILENAME_MAX,
+                "%s.new", pkgid);
+       ret = _app2sd_create_loopback_device(temp_pkgid, (size+PKG_BUF_SIZE));
+       if (ret) {
+               app2ext_print("App2Sd Error : Package already present\n");
+               return ret;
+       }
+       app2ext_print("App2Sd  : _app2sd_create_loopback_device SUCCESS\n");
+       /*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);
+               _app2sd_delete_loopback_device(pkgid);
+               app2ext_print("App2Sd Error : create ext filesystem failed\n");
+               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 */
+       devi = _app2sd_find_associated_device_node(temp_pkgid);
+       if (devi == NULL) {
+               app2ext_print("App2Sd Error : finding associated device node failed\n");
+               err_res = APP2EXT_ERROR_DO_LOSETUP;
+               goto FINISH_OFF;
+       }
+       app2ext_print("App2Sd  : _app2sd_find_associated_device_node SUCCESS\n");
+       /*Format the loopback file system */
+       ret = _app2sd_create_file_system(dev_node);
+       if (ret) {
+               app2ext_print("App2Sd Error : creating FS failed failed\n");
+               err_res = APP2EXT_ERROR_CREATE_FS;
+               goto FINISH_OFF;
+       }
+       app2ext_print("App2Sd  : _app2sd_create_file_system SUCCESS\n");
+       /*Do  mounting for new dev*/
+       ret =
+           _app2sd_mount_app_content(temp_pkgid, dev_node, MOUNT_TYPE_RW,
+                               dir_list, APP2SD_PRE_UPGRADE);
+       if (ret) {
+               app2ext_print("App2Sd Error : Re-mount failed\n");
+               err_res = APP2EXT_ERROR_MOUNT_PATH;
+               goto FINISH_OFF;
+       }
+       if (devi) {
+               free(devi);
+               devi = NULL;
+       }
+       return APP2EXT_SUCCESS;
+
+FINISH_OFF:
+       if (dev_node) {
+               result = _app2sd_detach_loop_device(dev_node);
+               if (result) {
+                       free(result);
+                       result = NULL;
+               }
+               _app2sd_delete_loopback_device(pkgid);
+               free(dev_node);
+               dev_node = NULL;
+       }
+
+       if (devi) {
+               free(devi);
+               devi = NULL;
+       }
+       return err_res;
+}
+
+int _app2sd_update_loopback_device_size(const char *pkgid,
+       int size, GList* dir_list)
+{
+       int ret = 0;
+       char *device_node = NULL;
+       char *old_device_node = NULL;
+       char *result = NULL;
+       int err_res = 0;
+       char app_mmc_path[FILENAME_MAX] = { 0, };
+       char app_archive_path[FILENAME_MAX] = { 0, };
+       char temp_pkgid[FILENAME_MAX] = { 0, };
+       char app_path[FILENAME_MAX] = { 0, };
+
+       snprintf(temp_pkgid, FILENAME_MAX,
+                "%s.new", pkgid);
+
+       ret = _app2sd_duplicate_device(pkgid, dir_list, device_node, size);
+       if (ret) {
+               app2ext_print("App2Sd Error : Creating duplicate device failed\n");
+               return ret;
+       }
+
+       app2ext_print("App2Sd  : _app2sd_mount_app_content SUCCESS\n");
+       /*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 */
+       old_device_node = _app2sd_find_associated_device_node(pkgid);
+       if (NULL == old_device_node) {
+               /*Do loopback setup */
+               old_device_node = _app2sd_do_loopback_encryption_setup(pkgid);
+               if (old_device_node == NULL) {
+                       app2ext_print
+                           ("App2Sd Error : loopback encryption setup failed\n");
+                       err_res = APP2EXT_ERROR_DO_LOSETUP;
+                       goto FINISH_OFF;
+               }
+               /*Do  mounting */
+               ret =
+                   _app2sd_mount_app_content(pkgid, old_device_node,
+                                             MOUNT_TYPE_RW, dir_list,
+                                             APP2SD_PRE_UPGRADE);
+               if (ret) {
+                       app2ext_print("App2Sd Error : Re-mount failed\n");
+                       err_res = APP2EXT_ERROR_MOUNT_PATH;
+                       goto FINISH_OFF;
+               }
+       } else {
+               /*Do  re-mounting */
+               ret =
+                   _app2sd_mount_app_content(pkgid, old_device_node,
+                                             MOUNT_TYPE_RW_REMOUNT, dir_list,
+                                             APP2SD_PRE_UPGRADE);
+               if (ret) {
+                       app2ext_print("App2Sd Error : Re-mount failed\n");
+                       err_res = APP2EXT_ERROR_MOUNT_PATH;
+                       goto FINISH_OFF;
+               }
+       }
+
+       snprintf(app_mmc_path, FILENAME_MAX,
+                "%s%s/.mmc", APP_INSTALLATION_PATH, pkgid);
+       snprintf(app_archive_path, FILENAME_MAX,
+               "%s%s/.mmc", APP_INSTALLATION_PATH, temp_pkgid);
+
+       ret = _app2sd_copy_ro_content(app_mmc_path, app_archive_path, dir_list);
+       if (ret) {
+               app2ext_print("App2Sd Error : copy ro content  failed\n");
+               err_res = ret;
+               goto FINISH_OFF;
+       }
+
+       ret = _app2sd_unmount_app_content(pkgid);
+       if (ret) {
+               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) {
+               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(temp_pkgid);
+       if (ret) {
+               app2ext_print("App2SD Error: Unable to remove loopback setup\n");
+               err_res = APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
+               goto FINISH_OFF;
+       }
+       snprintf(app_archive_path, FILENAME_MAX,
+               "%s%s", APP2SD_PATH, temp_pkgid);
+       ret = _app2sd_delete_directory(app_path);
+       if (ret) {
+               app2ext_print
+                   ("App2Sd Error : unable to delete %s \n",
+                    app_path);
+               err_res = APP2EXT_ERROR_DELETE_DIRECTORY;
+               goto FINISH_OFF;
+       }
+       ret = _app2sd_rename_dir(app_archive_path, app_path);
+       if (ret) {
+               app2ext_print
+                   ("App2Sd Error : unable to rename %s \n",
+                    app_archive_path);
+               err_res = APP2EXT_ERROR_MOVE;
+               goto FINISH_OFF;
+       }
+       snprintf(app_path, FILENAME_MAX,
+               "%s%s", APP_INSTALLATION_PATH, temp_pkgid);
+       ret = _app2sd_delete_directory(app_path);
+       if (ret) {
+               app2ext_print
+                   ("App2Sd Error : unable to delete %s \n",
+                    app_path);
+               err_res = APP2EXT_ERROR_DELETE_DIRECTORY;
+               goto FINISH_OFF;
+       }
+       return APP2EXT_SUCCESS;
+
+FINISH_OFF:
+       if (old_device_node) {
+               free(old_device_node);
+               old_device_node = NULL;
+       }
+
+       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;
+       }
+       return err_res;
+}
diff --git a/plugin/app2sd/src/app2sd_internals_registry.c b/plugin/app2sd/src/app2sd_internals_registry.c
new file mode 100755 (executable)
index 0000000..6f29fc9
--- /dev/null
@@ -0,0 +1,252 @@
+/*
+ * app2ext
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Garima Shrivastava<garima.s@samsung.com>
+ *     Jyotsna Dhumale <jyotsna.a@samsung.com>
+ *     Venkatesha Sarpangala <sarpangala.v@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <app2sd_internals.h>
+#include <app2sd_interface.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <dlog.h>
+#include <time.h>
+#include <db-util.h>
+#define MAX_QUERY_LEN 4096
+#define PASSWORD_LENGTH 64
+/*
+########### Internal APIs ##################
+ */
+
+/*sqlite  db code*/
+#define APP2SD_DB_FILE "/opt/dbspace/.app2sd.db"
+sqlite3 *app2sd_db;
+#define QUERY_CREATE_TABLE_APP2SD "create table app2sd \
+       (pkgid text primary key,\
+        password text\
+       )"
+
+/*
+ *@_app2sd_initialize_db
+ *This function is to initialize sqlite db.
+ * return: On success, it will return zero else  if fail then return val<0.
+ */
+int _app2sd_initialize_db()
+{
+       char *error_message = NULL;
+       int ret;
+       FILE * fp = NULL;
+       fp = fopen(APP2SD_DB_FILE, "r");
+       if (fp != NULL) {
+               fclose(fp);
+               ret =
+                   db_util_open(APP2SD_DB_FILE, &app2sd_db,
+                                DB_UTIL_REGISTER_HOOK_METHOD);
+
+               if (ret != SQLITE_OK) {
+                       app2ext_print("====>>>> connect menu_db [%s] failed!\n",
+                                    APP2SD_DB_FILE);
+                       return -1;
+               }
+               return 0;
+       }
+
+       ret =
+           db_util_open(APP2SD_DB_FILE, &app2sd_db,
+                        DB_UTIL_REGISTER_HOOK_METHOD);
+
+       if (ret != SQLITE_OK) {
+               app2ext_print("====>>>> connect menu_db [%s] failed!\n",
+                            APP2SD_DB_FILE);
+               return -1;
+       }
+
+       if (SQLITE_OK !=
+           sqlite3_exec(app2sd_db, QUERY_CREATE_TABLE_APP2SD,
+                        NULL, NULL, &error_message)) {
+               app2ext_print("Don't execute query = %s, "
+                            "error message = %s\n",
+                            QUERY_CREATE_TABLE_APP2SD, error_message);
+               return -1;
+       }
+
+       app2ext_print("\n db_initialize_done ");
+       return 0;
+}
+
+/*
+ *@_app2sd_set_password_in_db
+ *This function is to store password into  db.
+ * param[in]: pkgid: package id
+ * param[in]: password: password string
+ * return: On success, it will return 0.
+ * Else appropriate error will be returned.
+ */
+int _app2sd_set_password_in_db(const char *pkgid,
+                                     const char *passwd)
+{
+       char query[MAX_QUERY_LEN] = { 0, };
+       char *error_message = NULL;
+
+       snprintf(query, MAX_QUERY_LEN, "insert into app2sd(pkgid,password)\
+                       values ('%s','%s')", 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);
+               return APP2EXT_ERROR_SQLITE_REGISTRY;
+       }
+       app2ext_print("\n sqlite insertion done ");
+       return APP2EXT_SUCCESS;
+}
+
+/*
+ *@_app2sd_remove_password_from_db
+ *This function is to remove passwod from  db.
+ * param[in]: pkgid: package id
+ * return: On success, it will return 0.
+ * Else appropriate error will be returned.
+ */
+int _app2sd_remove_password_from_db(const char *pkgid)
+{
+       char query[MAX_QUERY_LEN] = { 0 };
+       char *error_message = NULL;
+
+       snprintf(query, MAX_QUERY_LEN,
+                "delete from app2sd where pkgid LIKE '%s'", 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);
+               return APP2EXT_ERROR_SQLITE_REGISTRY;
+       }
+
+       app2ext_print("\n app2sd password deletion done ");
+       return APP2EXT_SUCCESS;
+
+}
+
+/*
+ *@_app2sd_access_password_from_db
+ *This function is to find out whther password exists for an application.
+ * param[in]: pkgid: package id
+ * return: On success, it will return zero , else value<0 if fail.
+ */
+int _app2sd_access_password_from_db(const char *pkgid)
+{
+       char query[MAX_QUERY_LEN] = { 0 };
+       int access_flag = 0;
+       int i;
+       sqlite3_stmt *stmt = NULL;
+       const char *tail = NULL;
+
+       snprintf(query, MAX_QUERY_LEN,
+                "select * from app2sd where pkgid LIKE '%s'", pkgid);
+       app2ext_print("\n access querys is %s ", query);
+
+       if (SQLITE_OK != sqlite3_prepare(app2sd_db, query,
+                                        strlen(query), &stmt, &tail)) {
+               app2ext_print("sqlite3_prepare error\n");
+               return -1;
+       }
+       for (i = 0; SQLITE_ROW == sqlite3_step(stmt); i++) {
+               app2ext_print("\n entry available in sqlite");
+               access_flag = 1;
+
+       }
+       if (SQLITE_OK != sqlite3_finalize(stmt)) {
+               app2ext_print("error : sqlite3_finalize\n");
+               return -1;
+       }
+       if (access_flag == 1) {
+               app2ext_print("\n app2sd  value is accessible  ");
+               return APP2EXT_SUCCESS;
+       } else {
+               app2ext_print("\n app2sd  value is  not accessible  ");
+               return -1;
+       }
+}
+
+/*
+ *@_app2sd_get_password_from_db
+ *This function is to retrive password from DB
+ * param[in]: pkgid: package id
+ * return: On success, it will return the password, else NULL.
+ */
+char *_app2sd_get_password_from_db(const char *pkgid)
+{
+       char query[MAX_QUERY_LEN] = { 0 };
+       sqlite3_stmt *stmt = NULL;
+       const char *tail = NULL;
+       int rc = 0;
+       char *passwd = NULL;
+
+       snprintf(query, MAX_QUERY_LEN,
+                "select * from app2sd where pkgid LIKE '%s'", pkgid);
+       app2ext_print("\n access querys is %s ", query);
+
+       if (SQLITE_OK != sqlite3_prepare(app2sd_db, query,
+                                        strlen(query), &stmt, &tail)) {
+               app2ext_print("sqlite3_prepare error\n");
+               return NULL;
+       }
+
+       rc = sqlite3_step(stmt);
+       if (rc != SQLITE_ROW || rc == SQLITE_DONE) {
+               app2ext_print("No records found");
+               goto FINISH_OFF;
+       }
+       passwd = malloc(PASSWORD_LENGTH + 1);
+       if (passwd == NULL) {
+               app2ext_print("memory allocation failed\n");
+               goto FINISH_OFF;
+       }
+
+       app2ext_print("\n entry available in sqlite");
+       strncpy(passwd, (const char*)sqlite3_column_text(stmt, 1),
+               PASSWORD_LENGTH);
+       if (passwd == NULL) {
+               app2ext_print("\n password is NULL ");
+               goto FINISH_OFF;
+       }
+       app2ext_print("\n passwd is %s ", passwd);
+       if (SQLITE_OK != sqlite3_finalize(stmt)) {
+               app2ext_print("error : sqlite3_finalize\n");
+               goto FINISH_OFF;
+       }
+       return passwd;
+
+FINISH_OFF:
+       rc = sqlite3_finalize(stmt);
+       if (rc != SQLITE_OK) {
+               app2ext_print(" sqlite3_finalize failed - %d", rc);
+       }
+       if (passwd)
+               free(passwd);
+       return NULL;
+}
diff --git a/plugin/app2sd/src/app2sd_internals_utils.c b/plugin/app2sd/src/app2sd_internals_utils.c
new file mode 100755 (executable)
index 0000000..23a8c30
--- /dev/null
@@ -0,0 +1,470 @@
+/*
+ * app2ext
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Garima Shrivastava<garima.s@samsung.com>
+ *     Jyotsna Dhumale <jyotsna.a@samsung.com>
+ *     Venkatesha Sarpangala <sarpangala.v@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <app2sd_internals.h>
+#include <app2sd_interface.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <dlog.h>
+#include <sys/statvfs.h>
+#include <errno.h>
+
+#define        PASSWD_LEN              8
+#define        ASCII_PASSWD_CHAR       94
+
+/*
+########### Internal APIs ##################
+ */
+
+/*Note: Don't use any printf statement inside this function*/
+/*This function is similar to Linux's "system()"  for executing a process.*/
+int _xsystem(const char *argv[])
+{
+       int status = 0;
+       pid_t pid;
+       pid = fork();
+       switch (pid) {
+       case -1:
+               perror("fork failed");
+               return -1;
+       case 0:
+               /* child */
+               execvp(argv[0], (char *const *)argv);
+               _exit(-1);
+       default:
+               /* parent */
+               break;
+       }
+       if (waitpid(pid, &status, 0) == -1) {
+               perror("waitpid failed");
+               return -1;
+       }
+       if (WIFSIGNALED(status)) {
+               perror("signal");
+               return -1;
+       }
+       if (!WIFEXITED(status)) {
+               /* shouldn't happen */
+               perror("should not happen");
+               return -1;
+       }
+       return WEXITSTATUS(status);
+}
+
+
+/*
+* @_app2sd_check_mmc_status
+* This function checks and returns MMC status
+*/
+int _app2sd_check_mmc_status(void)
+{
+       FILE *fp1 = NULL;
+       char line[512];
+       fp1 = fopen("/etc/mtab", "r");
+       if (fp1 == NULL) {
+               fprintf(stderr, "failed to open file\n");
+               app2ext_print("failed to open file /etc/mtab\n");
+               return APP2EXT_ERROR_MMC_STATUS;
+       }
+       while (fgets(line, 512, fp1) != NULL) {
+               if (strstr(line, MMC_PATH) != NULL) {
+                       fclose(fp1);
+                       return APP2EXT_SUCCESS;
+               }
+       }
+       fclose(fp1);
+       return APP2EXT_ERROR_MMC_STATUS;
+}
+
+/*
+ * @_app2sd_get_available_free_memory
+ * This function returns the available free memory in the SD Card.
+ * param [in]: sd_path: This is sd card access path.
+ * param [out]: free_mem: Result will be available in this.
+ * User has to pass valid memory address.
+ * return: On success, it will return 0.
+ * Else, appropriate error no will be returned.
+ */
+int _app2sd_get_available_free_memory(const char *sd_path, int *free_mem)
+{
+       struct statvfs buf;
+       int ret = 0;
+       if (sd_path == NULL || free_mem == NULL) {
+               app2ext_print("App2Sd Error : Invalid input parameter\n");
+               return -1;
+       }
+       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");
+               return APP2EXT_ERROR_MMC_INFORMATION;
+       }
+       *free_mem = ((buf.f_bfree * buf.f_bsize) / 1024) / 1024;
+       return 0;
+}
+
+int _app2sd_delete_directory(char *dirname)
+{
+       DIR *dp = NULL;
+       struct dirent *ep = NULL;
+       char abs_filename[FILENAME_MAX] = { 0, };
+       int ret = 0;
+       dp = opendir(dirname);
+       if (dp != NULL) {
+               while ((ep = readdir(dp)) != NULL) {
+                       struct stat stFileInfo;
+
+                       snprintf(abs_filename, FILENAME_MAX, "%s/%s", dirname,
+                               ep->d_name);
+
+                       if (lstat(abs_filename, &stFileInfo) < 0) {
+                               perror(abs_filename);
+                               return -1;
+                       }
+
+                       if (S_ISDIR(stFileInfo.st_mode)) {
+                               if (strcmp(ep->d_name, ".")
+                                   && strcmp(ep->d_name, "..")) {
+                                       ret = _app2sd_delete_directory(abs_filename);
+                                       if (ret <0)
+                                               return -1;
+                               }
+                       } else {
+                               ret = remove(abs_filename);
+                               if (ret <0)
+                                       return -1;
+                       }
+               }
+               (void)closedir(dp);
+               ret = remove(dirname);
+               if (ret <0)
+                       return -1;
+       } else {
+               app2ext_print("Couldn't open the directory\n");
+       }
+       return 0;
+}
+
+int _app2sd_copy_dir(const char *src, const char *dest)
+{
+       int ret = APP2EXT_SUCCESS;
+       const char *argv_bin[] = { "/bin/cp", "-raf", src, dest, NULL };
+       ret = _xsystem(argv_bin);
+       if (ret) {
+               app2ext_print("copy fail\n");
+               return APP2EXT_ERROR_MOVE;
+       }
+       return ret;
+}
+
+int _app2sd_rename_dir(const char *old_name, const char *new_name)
+{
+       int ret = APP2EXT_SUCCESS;
+       const char *argv_bin[] = { "/bin/mv", old_name, new_name, NULL };
+       ret = _xsystem(argv_bin);
+       if (ret) {
+               app2ext_print("mv/rename fail\n");
+               return APP2EXT_ERROR_MOVE;
+       }
+       return ret;
+}
+
+unsigned long long _app2sd_calculate_dir_size(char *dirname)
+{
+       static unsigned long long total = 0;
+       DIR *dp = NULL;
+       struct dirent *ep = NULL;
+       char abs_filename[FILENAME_MAX] = { 0, };;
+       dp = opendir(dirname);
+       if (dp != NULL) {
+               while ((ep = readdir(dp)) != NULL) {
+                       struct stat stFileInfo;
+
+                       snprintf(abs_filename, FILENAME_MAX, "%s/%s", dirname,
+                                ep->d_name);
+
+                       if (stat(abs_filename, &stFileInfo) < 0)
+                               perror(abs_filename);
+                       else {
+                               total += stFileInfo.st_size;
+
+                               if (S_ISDIR(stFileInfo.st_mode)) {
+                                       if (strcmp(ep->d_name, ".")
+                                           && strcmp(ep->d_name, "..")) {
+                                               _app2sd_calculate_dir_size
+                                                   (abs_filename);
+                                       }
+                               } else {
+                                       /*Do Nothing */
+                               }
+                       }
+               }
+               (void)closedir(dp);
+       } else {
+               app2ext_print("\n error in opening directory ");
+       }
+       return total;
+}
+
+unsigned long long _app2sd_calculate_file_size(const char *filename)
+{
+       struct stat stFileInfo;
+       app2ext_print("\n Calculating file size for %s\n", filename);
+
+       if (stat(filename, &stFileInfo) < 0) {
+               perror(filename);
+               return 0;
+       } else
+               return stFileInfo.st_size;
+}
+
+/*Note: Don't use any printf statement inside this function*/
+char *_app2sd_encrypt_device(const char *device, const char *pkgid,
+                             char *passwd)
+{
+       const char *argv[] =
+           { "/sbin/losetup", "-e", "aes", device, pkgid, "-k", passwd, NULL };
+       pid_t pid = 0;
+       int my_pipe[2] = { 0, };
+       char buf[FILENAME_MAX] = { 0, };
+       char *ret_result = NULL;
+       int result = 0;
+       if (pipe(my_pipe) < 0) {
+               fprintf(stderr, "Unable to create pipe\n");
+               return NULL;
+       }
+       pid = fork();
+       switch (pid) {
+       case -1:
+               perror("fork failed");
+               return NULL;
+       case 0:
+               /* child */
+               close(1);
+               close(2);
+               result = dup(my_pipe[1]);
+               result = dup(my_pipe[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 */
+               }
+               _exit(-1);
+       default:
+               /* parent */
+               close(my_pipe[1]);
+               result = read(my_pipe[0], buf, FILENAME_MAX);
+               break;
+       }
+
+       ret_result = (char *)malloc(strlen(buf) + 1);
+       if (ret_result == NULL) {
+               app2ext_print("Malloc failed!\n");
+               return NULL;
+       }
+       memset(ret_result, '\0', strlen(buf) + 1);
+       memcpy(ret_result, buf, strlen(buf));
+       return ret_result;
+}
+
+/*Note: Don't use any printf statement inside this function*/
+char *_app2sd_detach_loop_device(const char *device)
+{
+       const char *argv[] = { "/sbin/losetup", "-d", device, NULL };
+       pid_t pid;
+       int my_pipe[2] = { 0, };
+       char buf[FILENAME_MAX] = { 0, };
+       char *ret_result = NULL;
+       int result = 0;
+       if (pipe(my_pipe) < 0) {
+               fprintf(stderr, "Unable to create pipe\n");
+               return NULL;
+       }
+       pid = fork();
+       switch (pid) {
+       case -1:
+               perror("fork failed");
+               return NULL;
+       case 0:
+               /* child */
+               close(1);
+               close(2);
+               result = dup(my_pipe[1]);
+               result = dup(my_pipe[1]);
+               if (execvp(argv[0], (char *const *)argv) < 0) {
+                       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);
+               break;
+       }
+
+       ret_result = (char *)malloc(strlen(buf) + 1);
+       if (ret_result == NULL) {
+               app2ext_print("Malloc failed!\n");
+               return NULL;
+       }
+       memset(ret_result, '\0', strlen(buf) + 1);
+       memcpy(ret_result, buf, strlen(buf));
+
+       return ret_result;
+}
+
+/*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 };
+       pid_t pid;
+       int my_pipe[2] = { 0, };
+       char buf[FILENAME_MAX] = { 0, };
+       char *ret_result = NULL;
+       int result = 0;
+       if (pipe(my_pipe) < 0) {
+               fprintf(stderr, "Unable to create pipe\n");
+               return NULL;
+       }
+       pid = fork();
+       switch (pid) {
+       case -1:
+               perror("fork failed");
+               return NULL;
+       case 0:
+               /* child */
+               close(1);
+               close(2);
+               result = dup(my_pipe[1]);
+               result = dup(my_pipe[1]);
+               if (execvp(argv[0], (char *const *)argv) < 0) {
+                       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);
+               break;
+       }
+
+       ret_result = (char *)malloc(strlen(buf) + 1);
+       if (ret_result == NULL) {
+               app2ext_print("Malloc failed!\n");
+               return NULL;
+       }
+       memset(ret_result, '\0', strlen(buf) + 1);
+       memcpy(ret_result, buf, strlen(buf));
+
+       return ret_result;
+}
+
+/*Note: Don't use any printf statement inside this function*/
+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 *ret_result = NULL;
+       int result = 0;
+       if (pipe(my_pipe) < 0) {
+               fprintf(stderr, "Unable to create pipe\n");
+               return NULL;
+       }
+       pid = fork();
+       switch (pid) {
+       case -1:
+               perror("fork failed");
+               return NULL;
+       case 0:
+               /* child */
+               close(1);
+               close(2);
+               result = dup(my_pipe[1]);
+               result = dup(my_pipe[1]);
+               if (execvp(argv[0], (char *const *)argv) < 0) {
+                       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);
+               break;
+       }
+
+       ret_result = (char *)malloc(strlen(buf) + 1);
+       if (ret_result == NULL) {
+               app2ext_print("Malloc failed!\n");
+               return NULL;
+       }
+       memset(ret_result, '\0', strlen(buf) + 1);
+       memcpy(ret_result, buf, strlen(buf));
+
+       return ret_result;
+}
+
+/*@_app2sd_generate_password
+* This is a simple password generator
+* return: On success, it will return the password, else NULL.
+*/
+char *_app2sd_generate_password(const char *pkgid)
+{
+       char passwd[PASSWD_LEN+1] = { 0, };
+       char *ret_result = NULL;
+       char set[ASCII_PASSWD_CHAR+1] = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
+       unsigned char char_1;
+       unsigned char char_2;
+       int i = 0;
+       int appname_len = strlen(pkgid);
+       int j = appname_len;
+
+       /* Length of the password */
+       ret_result = (char*)malloc(PASSWD_LEN+1);
+       if (NULL == ret_result) {
+               app2ext_print("Unable to Allocate memory\n");
+               return NULL;
+       }
+       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;
+               passwd[i] = set[char_1];
+               passwd[i+1] = set[(pkgid[j--])*2];
+               if (i<PASSWD_LEN-3)
+                       passwd[i+2] = set[char_2];
+               i++;
+       }
+
+       app2ext_print("Password is %s\n", passwd);
+       memcpy(ret_result, passwd, PASSWD_LEN+1);
+       return ret_result;
+}
diff --git a/src/app2ext_interface.c b/src/app2ext_interface.c
new file mode 100755 (executable)
index 0000000..a1dc9bf
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * app2ext
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jyotsna Dhumale <jyotsna.a@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <app2ext_interface.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <dlfcn.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#define APP2EXT_SD_PLUGIN_PATH "/usr/lib/libapp2sd.so"
+
+app2ext_handle *app2ext_init(int storage_type)
+{
+       /*Validate the function parameter recieved */
+       if (storage_type < APP2EXT_INTERNAL_MEM ||
+               storage_type > APP2EXT_CLOUD) {
+               app2ext_print("App2Ext Error : Invalid function arguments\n");
+               return NULL;
+       }
+       if (storage_type != APP2EXT_SD_CARD ) {
+               app2ext_print("App2Ext Error : Storage type currently not supported\n");
+               return NULL;
+       }
+
+       /* allocate memory for app2ext handle*/
+       app2ext_handle *handle = (app2ext_handle *)calloc(1, sizeof(app2ext_handle));
+       if (handle == NULL) {
+               app2ext_print("App2Ext Error : Memory allocation failure\n");
+               return NULL;
+       }
+       void *dl_handle = NULL;
+       int (*dl_on_load)(app2ext_interface *)=NULL;
+
+       /* Load SD plugin*/
+       handle->type = APP2EXT_SD_CARD;
+       dl_handle = dlopen(APP2EXT_SD_PLUGIN_PATH, RTLD_LAZY|RTLD_GLOBAL);
+       if (NULL == dl_handle)
+       {
+               app2ext_print("App2Ext Error : dlopen(%s) failed.\n", APP2EXT_SD_PLUGIN_PATH);
+               free(handle);
+               return NULL;
+       }
+       handle->plugin_handle = dl_handle;
+       dl_on_load = dlsym(dl_handle, "app2ext_on_load");
+       if (NULL == dl_on_load)
+       {
+               app2ext_print("App2Ext Error : Cannot find app2ext_on_load symbol in %s.", APP2EXT_SD_PLUGIN_PATH);
+               dlclose(dl_handle);
+               free(handle);
+               return NULL;
+       }
+
+       /*Initialize the SD plugin*/
+       if(!dl_on_load(&(handle->interface)))
+       {
+               app2ext_print("App2Ext Error : [%s] app2ext_on_load() failed.", APP2EXT_SD_PLUGIN_PATH);
+               dlclose(dl_handle);
+               free(handle);
+               return NULL;
+       }
+
+       app2ext_print("App2Ext: %s plugin loaded\n", APP2EXT_SD_PLUGIN_PATH);
+
+       return handle;
+}
+
+int app2ext_deinit(app2ext_handle *handle)
+{
+       /*Validate the function parameter recieved */
+       if (handle == NULL || handle->plugin_handle == NULL){
+               app2ext_print("App2Ext Error : Invalid function arguments\n");
+               return APP2EXT_ERROR_INVALID_ARGUMENTS;
+       }
+
+       /* Close the plugin handle*/
+       dlclose(handle->plugin_handle);
+
+       /* Free allocated memory during installtion*/
+       free(handle);
+       return APP2EXT_SUCCESS;
+}
+
+int app2ext_get_app_location(const char *appname)
+{
+       /*Validate the function parameter received */
+       if (appname == NULL) {
+               app2ext_print("invalid func parameters\n");
+               return APP2EXT_ERROR_INVALID_ARGUMENTS;
+       }
+       FILE *fp = NULL;
+       char app_mmc_path[FILENAME_MAX] = { 0, };
+       char app_dir_path[FILENAME_MAX] = { 0, };
+       char app_mmc_internal_path[FILENAME_MAX] = { 0, };
+       snprintf(app_dir_path, FILENAME_MAX,
+       "%s%s", APP_INSTALLATION_PATH, appname);
+       snprintf(app_mmc_path, FILENAME_MAX,
+       "%s%s", APP2SD_PATH, appname);
+       snprintf(app_mmc_internal_path, FILENAME_MAX,
+       "%s%s/.mmc", APP_INSTALLATION_PATH, appname);
+
+
+       /*check whether application is in external memory or not */
+       fp = fopen(app_mmc_path, "r");
+       if (fp == NULL) {
+               app2ext_print
+               (" app path in external memory not accesible\n");
+       } else {
+               fclose(fp);
+               fp = NULL;
+               return APP2EXT_SD_CARD;
+       }
+
+       /*check whether application is in internal or not */
+       fp = fopen(app_dir_path, "r");
+       if (fp == NULL) {
+               app2ext_print
+               (" app path in internal memory not accesible\n");
+               return APP2EXT_NOT_INSTALLED;
+       } else {
+               fclose(fp);
+               /*check whether the application is installed in SD card
+                       but SD card is not present*/
+               fp = fopen(app_mmc_internal_path, "r");
+               if (fp == NULL) {
+                       return APP2EXT_INTERNAL_MEM;
+               } else {
+                       fclose(fp);
+                       return APP2EXT_ERROR_MMC_STATUS;
+               }
+       }
+}