4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Garima Shrivastava<garima.s@samsung.com>
7 * Jyotsna Dhumale <jyotsna.a@samsung.com>
8 * Venkatesha Sarpangala <sarpangala.v@samsung.com>
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
24 #include <app2sd_internals.h>
25 #include <app2sd_interface.h>
27 #include <sys/types.h>
36 #include <openssl/sha.h>
42 ########### Internal APIs ##################
53 static int _app2sd_apply_app_smack(const char *pkgid, GList* dir_list, const char *groupid)
55 int ret = APP2EXT_SUCCESS;
57 app2ext_dir_details* dir_detail = NULL;
58 char path[FILENAME_MAX] = { 0, };
60 list = g_list_first(dir_list);
62 dir_detail = (app2ext_dir_details *)list->data;
63 if (dir_detail && dir_detail->name
64 && dir_detail->type == APP2EXT_DIR_RO) {
65 snprintf(path, FILENAME_MAX, "%s%s/%s",APP_INSTALLATION_PATH, pkgid, dir_detail->name);
66 ret = _app2sd_setup_path(pkgid, path, PATH_ANY_LABEL, groupid);
68 app2ext_print ("App2Sd Error : unable to smack %s\n", path);
69 return APP2EXT_ERROR_MOVE;
72 list = g_list_next(list);
75 return APP2EXT_SUCCESS;
78 static int _app2sd_apply_mmc_smack(const char *pkgid, GList* dir_list, const char *groupid)
80 int ret = APP2EXT_SUCCESS;
82 app2ext_dir_details* dir_detail = NULL;
83 char path[FILENAME_MAX] = { 0, };
85 list = g_list_first(dir_list);
87 dir_detail = (app2ext_dir_details *)list->data;
88 if (dir_detail && dir_detail->name
89 && dir_detail->type == APP2EXT_DIR_RO) {
90 snprintf(path, FILENAME_MAX, "%s%s/.mmc/%s",APP_INSTALLATION_PATH, pkgid, dir_detail->name);
92 ret = _app2sd_setup_path(pkgid, path, PATH_ANY_LABEL, groupid);
94 app2ext_print ("App2Sd Error : unable to smack %s\n", path);
95 return APP2EXT_ERROR_MOVE;
98 list = g_list_next(list);
101 return APP2EXT_SUCCESS;
104 char *_app2sd_find_associated_device_node(const char *pkgid)
106 char *ret_result = NULL;
109 char app_path[FILENAME_MAX] = { '\0' };
110 char dev[FILENAME_MAX] = {0,};
111 char *devnode = NULL;
112 snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
114 result = (char *)_app2sd_find_associated_device(app_path);
115 if (result == NULL) {
117 ("App2SD Error! Unable to find the associated File\n");
120 /*process the string*/
121 snprintf(dev, FILENAME_MAX-1, "%s", result);
122 if (strstr(dev, "/dev") == NULL) {
124 ("App2SD Error! Unable to find the associated File\n");
129 ret_result = strtok(dev, delims);
131 devnode = strdup(ret_result);
137 char *_app2sd_create_loopdevice_node(void)
139 char *ret_result = NULL;
140 mode_t mode = DIR_PERMS;
142 int ret = APP2EXT_SUCCESS;
146 result = (char *)_app2sd_find_free_device();
147 /*validate the result */
148 if (result == NULL || strstr(result, "/dev") == NULL) {
149 app2ext_print("No device found, creating device node...\n");
156 char dev_path[BUF_SIZE] = { 0, };
157 snprintf(dev_path, BUF_SIZE, "/dev/loop%d", count);
158 while ((fp = fopen(dev_path, "r+")) != NULL) {
160 snprintf(dev_path, BUF_SIZE, "/dev/loop%d", count);
161 app2ext_print("next dev path for checking is %s\n",
165 app2ext_print("Device node candidate is %s \n", dev_path);
167 dev_node = makedev(DEV_MAJOR, count);
168 ret = mknod(dev_path, S_IFBLK | mode, dev_node);
171 ("Error while creating the device node: errno is %d\n",
175 ret_result = (char *)malloc(strlen(dev_path) + 1);
176 if (ret_result == NULL) {
177 app2ext_print("Unable to allocate memory\n");
180 memset(ret_result, '\0', strlen(dev_path) + 1);
181 memcpy(ret_result, dev_path, strlen(dev_path));
183 ret_result = (char *)malloc(strlen(result) + 1);
184 if (ret_result == NULL) {
185 app2ext_print("Malloc failed!\n");
190 memset(ret_result, '\0', strlen(result) + 1);
191 if (strlen(result) > 0) {
192 memcpy(ret_result, result, strlen(result) - 1);
201 char *_app2sd_do_loopback_encryption_setup(const char *pkgid)
203 int ret = APP2EXT_SUCCESS;
205 char app_path[FILENAME_MAX] = { '\0' };
207 char *device_node = NULL;
209 app2ext_print("App2Sd Error: Invalid argument\n");
213 snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
215 /* Get password for loopback encryption */
216 ret = _app2sd_initialize_db();
218 app2ext_print("\n app2sd db initialize failed");
221 if ((passwd = _app2sd_get_password_from_db(pkgid)) == NULL) {
222 passwd = (char *)_app2sd_generate_password(pkgid);
223 if (NULL == passwd) {
225 ("App2Sd Error: Unable to generate password\n");
228 app2ext_print("Password is %s\n", passwd);
229 if ((ret = _app2sd_set_password_in_db(pkgid,
232 ("App2Sd Error: Unable to save password\n");
240 /*Get Free device node*/
241 device_node = _app2sd_create_loopdevice_node();
242 if (NULL == device_node) {
246 ("App2Sd Error: Unable to find free loopback node\n");
249 result = (char *)_app2sd_encrypt_device(device_node, app_path, passwd);
250 if (result == NULL) {
251 app2ext_print("App2Sd Error: Encryption failed!\n\n");
264 char *_app2sd_do_loopback_duplicate_encryption_setup(const char *pkgid, const char * dup_appname)
266 int ret = APP2EXT_SUCCESS;
268 char app_path[FILENAME_MAX] = { '\0' };
270 char *device_node = NULL;
271 if (pkgid == NULL || dup_appname == NULL) {
272 app2ext_print("App2Sd Error: Invalid argument\n");
276 snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
278 /* Get password for loopback encryption */
279 ret = _app2sd_initialize_db();
281 app2ext_print("\n app2sd db initialize failed");
284 if ((passwd = _app2sd_get_password_from_db(pkgid)) == NULL) {
285 passwd = (char *)_app2sd_generate_password(pkgid);
286 if (NULL == passwd) {
288 ("App2Sd Error: Unable to generate password\n");
291 app2ext_print("Password is %s\n", passwd);
292 if ((ret = _app2sd_set_password_in_db(pkgid,
295 ("App2Sd Error: Unable to save password\n");
303 /*Get Free device node*/
304 device_node = _app2sd_create_loopdevice_node();
305 if (NULL == device_node) {
309 ("App2Sd Error: Unable to find free loopback node\n");
312 result = (char *)_app2sd_encrypt_device(device_node, app_path, passwd);
313 if (result == NULL) {
314 app2ext_print("App2Sd Error: Encryption failed!\n\n");
319 if (strlen(result) == 0) {
326 app2ext_print("App2Sd Error: Error is %s\n", result);
337 int _app2sd_remove_loopback_encryption_setup(const char *pkgid)
339 int ret = APP2EXT_SUCCESS;
341 char *dev_node = NULL;
342 if ((dev_node = _app2sd_find_associated_device_node(pkgid)) == NULL) {
343 app2ext_print("Unable to find the association\n");
344 ret = APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_NODE;
346 result = (char *)_app2sd_detach_loop_device(dev_node);
347 if (result == NULL) {
348 app2ext_print("App2sd Error: Error in detaching\n");
349 ret = APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE;
361 int _app2sd_create_loopback_device(const char *pkgid, int size)
363 int ret = APP2EXT_SUCCESS;
364 char command[FILENAME_MAX] = { 0, };
365 mode_t mode = DIR_PERMS;
366 char external_storage_path[FILENAME_MAX] = { 0, };
367 char buff[BUF_SIZE] = { 0, };
368 char app_path[FILENAME_MAX] = { 0, };
371 if (NULL == pkgid || size <= 0) {
372 app2ext_print("App2Sd Error: Invalid argument\n");
373 return APP2EXT_ERROR_INVALID_ARGUMENTS;
375 snprintf(command, FILENAME_MAX, "of=%s%s", APP2SD_PATH,
377 snprintf(buff, BUF_SIZE, "count=%d", size);
378 const char *argv1[] =
379 { "dd", "if=/dev/zero", command, "bs=1M", buff, NULL };
380 snprintf(external_storage_path, FILENAME_MAX, "%s",
382 ret = mkdir(external_storage_path, mode);
384 if (errno != EEXIST) {
386 ("App2sd Error : Create directory failed, error no is %d\n",
388 return APP2EXT_ERROR_CREATE_DIRECTORY;
391 snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
393 if ((fp = fopen(app_path, "r+")) != NULL) {
394 app2ext_print("Application already exists %s\n", app_path);
396 return APP2EXT_ERROR_PKG_EXISTS;
399 ret = _xsystem(argv1);
401 app2ext_print("App2Sd Error : command \"%s\" failed \n",
408 int _app2sd_delete_loopback_device(const char *pkgid)
410 int ret = APP2EXT_SUCCESS;
411 char loopback_device[FILENAME_MAX] = { 0, };
413 snprintf(loopback_device, FILENAME_MAX, "%s%s", APP2SD_PATH,
416 ret = unlink(loopback_device);
418 if (errno == ENOENT) {
419 app2ext_print("Unable to access file %s\n", loopback_device);
421 app2ext_print("Unable to delete %s\n", loopback_device);
422 return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
428 int _app2sd_create_file_system(const char *device_path)
430 int ret = APP2EXT_SUCCESS;
432 if (NULL == device_path) {
433 app2ext_print("App2Sd Error: invalid param [NULL]\n");
434 return APP2EXT_ERROR_INVALID_ARGUMENTS;
437 /*Format the filesystem [create a filesystem]*/
438 const char *argv[] = { "/sbin/mkfs.ext4", device_path, NULL };
439 fp = fopen(device_path, "r+");
442 ("App2sd Error: Unable to access %s [System errono is %d.....%s]\n",
443 device_path, errno, strerror(errno));
444 return APP2EXT_ERROR_ACCESS_FILE;
448 ret = _xsystem(argv);
451 ("App2Sd Error : creating file system failed [System error is %s\n",
453 return APP2EXT_ERROR_CREATE_FS;
458 static int _app2sd_create_dir_with_link(const char *pkgid,
459 const char *dir_name)
461 mode_t mode = DIR_PERMS;
462 int ret = APP2EXT_SUCCESS;
463 char app_dir_mmc_path[FILENAME_MAX] = { 0, };
464 char app_dir_path[FILENAME_MAX] = { 0, };
465 snprintf(app_dir_mmc_path, FILENAME_MAX, "%s%s/.mmc/%s",APP_INSTALLATION_PATH,
467 snprintf(app_dir_path, FILENAME_MAX, "%s%s/%s", APP_INSTALLATION_PATH, pkgid,
470 ret = mkdir(app_dir_mmc_path, mode);
472 if (errno != EEXIST) {
474 ("App2sd Error : Create directory failed, error no is %d\n",
476 return APP2EXT_ERROR_CREATE_DIRECTORY;
480 if ((ret = symlink(app_dir_mmc_path, app_dir_path)) < 0) {
481 if (errno == EEXIST) {
483 ("App2sd : File with Symlink name present %s\n",
487 ("A2Sd Error : Symbolic link creation failed, error no is %d\n",
489 return APP2EXT_ERROR_CREATE_SYMLINK;
493 ret = _app2sd_setup_path(pkgid, app_dir_path, PATH_ANY_LABEL, pkgid);
495 app2ext_print ("App2Sd Error : unable to smack %s\n", app_dir_mmc_path);
496 return APP2EXT_ERROR_MOVE;
502 int _app2sd_create_directory_entry(const char *pkgid, GList* dir_list)
504 int ret = APP2EXT_SUCCESS;
505 char app_dir_path[FILENAME_MAX] = { 0, };
507 app2ext_dir_details* dir_detail = NULL;
509 snprintf(app_dir_path, FILENAME_MAX, "%s%s", APP_INSTALLATION_PATH,
512 list = g_list_first(dir_list);
514 dir_detail = (app2ext_dir_details *)list->data;
515 if (dir_detail && dir_detail->name
516 && dir_detail->type == APP2EXT_DIR_RO) {
517 ret = _app2sd_create_dir_with_link(pkgid, dir_detail->name);
522 list = g_list_next(list);
524 return APP2EXT_SUCCESS;
530 * _app2sd_mount_app_content
531 This function is to create the path for mmc and mount the content
532 Example usage: _app2sd_mount_app_content("deb.com.samsung.helloworld","/dev/loop0",MOUNT_TYPE_RD)
534 int _app2sd_mount_app_content(const char *pkgid, const char *dev,
535 int mount_type, GList* dir_list, app2sd_cmd cmd)
537 int ret = APP2EXT_SUCCESS;
538 mode_t mode = DIR_PERMS;
539 char app_dir_path[FILENAME_MAX] = { 0, };
540 char app_dir_mmc_path[FILENAME_MAX] = { 0, };
541 if (NULL == pkgid || NULL == dev) {
542 app2ext_print("App2Sd Error : Input param is NULL %s %s \n",
544 return APP2EXT_ERROR_INVALID_ARGUMENTS;
546 snprintf(app_dir_path, FILENAME_MAX, "%s%s", APP_INSTALLATION_PATH, pkgid);
547 ret = mkdir(app_dir_path, mode);
549 if (errno != EEXIST) {
551 ("App2Sd Error : Create directory failed, error no is %d\n",
553 return APP2EXT_ERROR_CREATE_DIRECTORY;
556 snprintf(app_dir_mmc_path, FILENAME_MAX, "%s%s/.mmc", APP_INSTALLATION_PATH, pkgid);
557 ret = mkdir(app_dir_mmc_path, mode);
559 if (errno != EEXIST) {
561 ("App2Sd Error : Create directory failed, error no is %d\n",
563 return APP2EXT_ERROR_CREATE_DIRECTORY;
567 usleep(200 * 1000); /* 200ms sleep*/
568 app2ext_print ("App2Sd info : give a delay for mount\n");
570 switch (mount_type) {
574 mount(dev, app_dir_mmc_path, FS_TYPE,
575 MS_MGC_VAL | MS_RDONLY, NULL)) < 0) {
577 ("App2Sd Error : Read Only Mount failed [System Erro no is %d], dev is %s path is %s\n",
578 errno, dev, app_dir_mmc_path);
579 ret = APP2EXT_ERROR_MOUNT;
586 mount(dev, app_dir_mmc_path, FS_TYPE, MS_MGC_VAL,
589 ("App2Sd Error : Read Write Mount failed [System Erro no is %d]\n",
591 ret = APP2EXT_ERROR_MOUNT;
595 case MOUNT_TYPE_RW_NOEXEC:
598 mount(dev, app_dir_mmc_path, FS_TYPE,
599 MS_MGC_VAL | MS_NOEXEC, NULL)) < 0) {
601 ("App2Sd Error : RWX Mount failed [System Erro no is %d]\n",
603 ret = APP2EXT_ERROR_MOUNT;
607 case MOUNT_TYPE_RD_REMOUNT:
610 mount(dev, app_dir_mmc_path, FS_TYPE,
611 MS_MGC_VAL | MS_RDONLY | MS_REMOUNT,
614 ("App2Sd Error : RWX Mount failed [System Erro no is %d]\n",
616 ret = APP2EXT_ERROR_MOUNT;
620 case MOUNT_TYPE_RW_REMOUNT:
623 mount(dev, app_dir_mmc_path, FS_TYPE,
624 MS_MGC_VAL | MS_REMOUNT, NULL)) < 0) {
626 ("App2Sd Error : RWX Mount failed [System Erro no is %d]\n",
628 ret = APP2EXT_ERROR_MOUNT;
635 app2ext_print("App2Sd Error: Invalid mount type\n");
639 if (cmd == APP2SD_PRE_INSTALL || cmd == APP2SD_MOVE_APP_TO_MMC) {
640 ret = _app2sd_create_directory_entry(pkgid, dir_list);
645 int _app2sd_unmount_app_content(const char *pkgid)
647 int ret = APP2EXT_SUCCESS;
648 char app_dir_mmc_path[FILENAME_MAX] = { 0, };
649 snprintf(app_dir_mmc_path, FILENAME_MAX, "%s%s/.mmc", APP_INSTALLATION_PATH, pkgid);
650 if ((ret = umount(app_dir_mmc_path)) < 0) {
651 app2ext_print("Unable to umount the dir %s\n", strerror(errno));
656 static int _app2sd_move_to_archive(const char *src_path, const char *arch_path)
658 int ret = APP2EXT_SUCCESS;
660 ret = _app2sd_copy_dir(src_path, arch_path);
662 if (ret != APP2EXT_ERROR_ACCESS_FILE) {
664 ("App2Sd Error : unable to copy from %s to %s .....err is %s\n",
665 src_path, arch_path, strerror(errno));
666 return APP2EXT_ERROR_MOVE;
669 ret = _app2sd_delete_directory((char *)src_path);
671 if (ret != APP2EXT_ERROR_ACCESS_FILE) {
672 app2ext_print("App2Sd Error : unable to delete %s \n", src_path);
673 return APP2EXT_ERROR_DELETE_DIRECTORY;
679 int _app2sd_move_app_to_external(const char *pkgid, GList* dir_list)
681 int ret = APP2EXT_SUCCESS;
682 char app_path[FILENAME_MAX] = { 0, };
683 char path[FILENAME_MAX] = { 0, };
684 char app_mmc_path[FILENAME_MAX] = { 0, };
685 char app_archive_path[FILENAME_MAX] = { 0, };
686 char mmc_path[FILENAME_MAX] = { 0, };
687 unsigned long long total_size = 0;
689 char *device_node = NULL;
691 mode_t mode = DIR_PERMS;
692 int free_mmc_mem = 0;
695 app2ext_dir_details* dir_detail = NULL;
697 /*Check whether MMC is present or not */
698 ret = _app2sd_check_mmc_status();
701 ("App2Sd Error : MMC not preset OR Not ready %d\n",
703 return APP2EXT_ERROR_MMC_STATUS;
706 snprintf(mmc_path, FILENAME_MAX,
707 "%s%s", APP2SD_PATH, pkgid);
709 /*check whether application is in external memory or not */
710 fp = fopen(mmc_path, "r+");
713 ("Already %s entry is present in the SD Card, delete entry and go on without return\n",
716 // return APP2EXT_ERROR_ALREADY_FILE_PRESENT;
719 snprintf(app_mmc_path, FILENAME_MAX,
720 "%s%s/.mmc", APP_INSTALLATION_PATH, pkgid);
721 snprintf(app_archive_path, FILENAME_MAX,
722 "%s%s/.archive", APP_INSTALLATION_PATH, pkgid);
724 ret = mkdir(app_archive_path, mode);
726 if (errno != EEXIST) {
728 ("App2sd Error: Unable to create directory for archiving, error no is %d\n",
730 // return APP2EXT_ERROR_CREATE_DIRECTORY;
734 list = g_list_first(dir_list);
736 dir_detail = (app2ext_dir_details *)list->data;
737 if (dir_detail && dir_detail->name
738 && dir_detail->type == APP2EXT_DIR_RO) {
739 memset((void *)&app_path, '\0',
741 snprintf(app_path, FILENAME_MAX,
742 "%s%s/%s",APP_INSTALLATION_PATH,
746 _app2sd_calculate_dir_size
749 list = g_list_next(list);
752 reqd_size = ((total_size / 1024) / 1024) + 2;
754 /*Find avialable free memory in the MMC card */
756 _app2sd_get_available_free_memory
757 (MMC_PATH, &free_mmc_mem);
760 ("App2Sd Error : Unable to get available free memory in MMC %d\n",
762 return APP2EXT_ERROR_MMC_STATUS;
764 /*If avaialalbe free memory in MMC is less than required size + 5MB , return error */
765 if (reqd_size > free_mmc_mem) {
767 ("App2Sd Error : Insufficient memory in MMC for application installation %d\n",
769 return APP2EXT_ERROR_MMC_INSUFFICIENT_MEMORY;
771 /*Create a loopback device */
773 _app2sd_create_loopback_device(pkgid, (reqd_size+PKG_BUF_SIZE));
776 ("App2Sd Error : loopback node creation failed\n");
777 // return APP2EXT_ERROR_CREATE_DEVICE;
779 /*Perform Loopback encryption setup */
781 _app2sd_do_loopback_encryption_setup(pkgid);
784 ("App2Sd Error : losetup failed, device node is %s\n",
786 return APP2EXT_ERROR_DO_LOSETUP;
788 /*Check whether loopback device is associated with device node or not */
789 devi = _app2sd_find_associated_device_node(pkgid);
792 ("App2Sd Error : _app2sd_find_associated_device_node losetup failed\n");
793 return APP2EXT_ERROR_DO_LOSETUP;
798 /*Format the loopback file system */
799 ret = _app2sd_create_file_system(device_node);
802 ("App2Sd Error : create ext4 filesystem failed\n");
803 return APP2EXT_ERROR_CREATE_FS;
805 /********Archiving code begin***********/
806 list = g_list_first(dir_list);
808 dir_detail = (app2ext_dir_details *)list->data;
809 if (dir_detail && dir_detail->name
810 && dir_detail->type == APP2EXT_DIR_RO) {
811 snprintf(path, FILENAME_MAX,
812 "%s%s/%s",APP_INSTALLATION_PATH,
816 _app2sd_move_to_archive
820 if (ret == APP2EXT_ERROR_ACCESS_FILE) {
822 ("App2Sd Error : unable to access %s\n",
826 ("App2Sd Error : unable to copy from %s to %s \n",
829 // return APP2EXT_ERROR_MOVE;
833 list = g_list_next(list);
835 /********Archiving code ends***********/
837 /*mount the loopback encrypted pseudo device on application installation path as with Read Write permission */
839 _app2sd_mount_app_content(pkgid, device_node,
840 MOUNT_TYPE_RW, dir_list,
841 APP2SD_MOVE_APP_TO_MMC);
845 /********restore Archive begin***********/
846 list = g_list_first(dir_list);
848 dir_detail = (app2ext_dir_details *)list->data;
849 if (dir_detail && dir_detail->name
850 && dir_detail->type == APP2EXT_DIR_RO) {
851 memset((void *)&path, '\0',
853 snprintf(path, FILENAME_MAX,
854 "%s%s/.archive/%s",APP_INSTALLATION_PATH,
862 if (ret == APP2EXT_ERROR_ACCESS_FILE) {
864 ("App2Sd Error : unable to access %s\n",
868 ("App2Sd Error : unable to copy from %s to %s .....err is %s\n",
873 // return APP2EXT_ERROR_MOVE;
877 _app2sd_delete_directory
880 if (ret == APP2EXT_ERROR_ACCESS_FILE) {
882 ("App2Sd Error : unable to access %s\n",
886 ("App2Sd Error : unable to delete %s \n",
889 APP2EXT_ERROR_DELETE_DIRECTORY;
893 list = g_list_next(list);
896 ret = _app2sd_delete_directory(app_archive_path);
899 ("App2Sd Error : unable to delete %s \n",
901 // return APP2EXT_ERROR_DELETE_DIRECTORY;
904 ret = _app2sd_apply_mmc_smack(pkgid, dir_list, pkgid);
906 app2ext_print("App2Sd Error : unable to apply app smack\n");
907 return APP2EXT_ERROR_MOVE;
910 /*Restore archive ends */
911 /*Re-mount the loopback encrypted pseudo device on application installation path as with Read Only permission */
912 ret = _app2sd_unmount_app_content(pkgid);
914 return APP2EXT_ERROR_REMOUNT;
917 _app2sd_remove_loopback_encryption_setup(pkgid);
920 ("App2Sd Error : unable to detach loopback setup for %s\n",
922 return APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE;
924 return APP2EXT_SUCCESS;
927 int _app2sd_move_app_to_internal(const char *pkgid, GList* dir_list)
929 int ret = APP2EXT_SUCCESS;
930 mode_t mode = DIR_PERMS;
931 char path[FILENAME_MAX] = { 0, };
932 char app_mmc_path[FILENAME_MAX] = { 0, };
933 char app_path[FILENAME_MAX] = { 0, };
934 char mmc_path[FILENAME_MAX] = { 0, };
935 char app_archive_path[FILENAME_MAX] = { 0, };
936 char *device_node = NULL;
939 app2ext_dir_details* dir_detail = NULL;
941 snprintf(app_mmc_path, FILENAME_MAX,
942 "%s%s/.mmc", APP_INSTALLATION_PATH, pkgid);
943 snprintf(app_path, FILENAME_MAX, "%s%s/", APP_INSTALLATION_PATH,
945 snprintf(app_archive_path, FILENAME_MAX,
946 "%s%s/.archive", APP_INSTALLATION_PATH, pkgid);
947 snprintf(mmc_path, FILENAME_MAX,
948 "%s%s", APP2SD_PATH, pkgid);
950 /*Check whether MMC is present or not */
951 ret = _app2sd_check_mmc_status();
954 ("App2Sd Error : MMC not preset OR Not ready %d\n",
956 return APP2EXT_ERROR_MMC_STATUS;
959 /*check whether application is in external memory or not */
960 fp = fopen(mmc_path, "r+");
963 ("Application %s is not installed on SD Card\n",
965 return APP2EXT_ERROR_FILE_ABSENT;
971 /*Get the associated device node for SD card applicationer */
973 _app2sd_find_associated_device_node(pkgid);
974 if (NULL == device_node) {
975 /*Do loopback setup */
977 _app2sd_do_loopback_encryption_setup
979 if (device_node == NULL) {
981 ("App2Sd Error : loopback encryption setup failed\n");
982 return APP2EXT_ERROR_DO_LOSETUP;
986 _app2sd_mount_app_content(pkgid,
990 APP2SD_MOVE_APP_TO_PHONE);
993 ("App2Sd Error : Re-mount failed\n");
994 return APP2EXT_ERROR_MOUNT_PATH;
999 _app2sd_mount_app_content(pkgid,
1001 MOUNT_TYPE_RW_REMOUNT,
1003 APP2SD_MOVE_APP_TO_PHONE);
1006 ("App2Sd Error : Re-mount failed\n");
1007 return APP2EXT_ERROR_MOUNT_PATH;
1010 ret = mkdir(app_archive_path, mode);
1013 ("App2Sd Error : unable to create directory%s\n",
1015 // return APP2EXT_ERROR_CREATE_DIRECTORY;
1019 list = g_list_first(dir_list);
1021 dir_detail = (app2ext_dir_details *)list->data;
1022 if (dir_detail && dir_detail->name
1023 && dir_detail->type == APP2EXT_DIR_RO) {
1025 memset((void *)&path, '\0',
1027 snprintf(path, FILENAME_MAX,
1028 "%s%s/.mmc/%s", APP_INSTALLATION_PATH,
1036 if (ret == APP2EXT_ERROR_ACCESS_FILE) {
1038 ("App2Sd Error : unable to access %s\n",
1042 ("App2Sd Error : unable to copy from %s to %s .....err is %s\n",
1047 // return APP2EXT_ERROR_MOVE;
1051 /*Delete the symbolic link files [bin, lib, res]*/
1052 memset((void *)&path, '\0',
1054 snprintf(path, FILENAME_MAX,
1055 "%s%s/%s", APP_INSTALLATION_PATH,
1060 if (errno == ENOENT) {
1062 ("App2Sd Error : Directory %s does not exist\n",
1066 ("App2Sd Error : unable to remove the symbolic link file %s, it is already unlinked!!!\n",
1068 // return APP2EXT_ERROR_DELETE_LINK_FILE;
1072 /*Copy content to destination */
1073 memset((void *)&path, '\0',
1075 snprintf(path, FILENAME_MAX,
1076 "%s%s/.archive/%s", APP_INSTALLATION_PATH,
1083 if (ret == APP2EXT_ERROR_ACCESS_FILE) {
1085 ("App2Sd Error : unable to access %s\n",
1089 ("App2Sd Error : unable to copy from %s to %s .....err is %s\n",
1094 // return APP2EXT_ERROR_MOVE;
1098 list = g_list_next(list);
1101 ret = _app2sd_unmount_app_content(pkgid);
1104 ("App2Sd Error : unable to unmount SD directory for app %s\n",
1106 return APP2EXT_ERROR_UNMOUNT;
1109 _app2sd_remove_loopback_encryption_setup(pkgid);
1112 ("App2Sd Error : unable to detach loopback setup for %s\n",
1114 return APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE;
1116 ret = _app2sd_delete_loopback_device(pkgid);
1119 ("App2Sd Error : unable to delete the loopback device for %s\n",
1121 return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
1123 ret = _app2sd_delete_directory(app_mmc_path);
1126 ("App2Sd Error : unable to delete %s \n",
1128 // return APP2EXT_ERROR_DELETE_DIRECTORY;
1130 ret = _app2sd_delete_directory(app_archive_path);
1133 ("App2Sd Error : unable to delete %s \n",
1135 // return APP2EXT_ERROR_DELETE_DIRECTORY;
1138 ret = _app2sd_apply_app_smack(pkgid, dir_list, pkgid);
1140 app2ext_print("App2Sd Error : unable to apply app smack\n");
1141 return APP2EXT_ERROR_MOVE;
1144 return APP2EXT_SUCCESS;
1147 int _app2sd_move_app(const char *pkgid, app2ext_move_type move_cmd, GList* dir_list)
1149 int ret = APP2EXT_SUCCESS;
1151 /*Check whether MMC is present or not */
1152 ret = _app2sd_check_mmc_status();
1155 ("App2Sd Error : MMC not preset OR Not ready %d\n",
1157 return APP2EXT_ERROR_MMC_STATUS;
1161 case APP2EXT_MOVE_TO_EXT:
1163 ret = _app2sd_move_app_to_external(pkgid, dir_list);
1166 ("App2Sd Error : move app to external memory failed %d\n",
1172 case APP2EXT_MOVE_TO_PHONE:
1174 ret = _app2sd_move_app_to_internal(pkgid, dir_list);
1177 ("App2Sd Error : move app to internal memory failed %d\n",
1185 app2ext_print("App2Sd Error : invalid argument\n");
1186 return APP2EXT_ERROR_INVALID_ARGUMENTS;
1194 int _app2sd_copy_ro_content(const char *src, const char *dest, GList* dir_list)
1196 char path[FILENAME_MAX] = { 0, };
1197 int ret = APP2EXT_SUCCESS;
1199 app2ext_dir_details* dir_detail = NULL;
1201 list = g_list_first(dir_list);
1203 dir_detail = (app2ext_dir_details *)list->data;
1204 if (dir_detail && dir_detail->name
1205 && dir_detail->type == APP2EXT_DIR_RO) {
1206 memset((void *)&path, '\0',
1208 snprintf(path, FILENAME_MAX,
1216 if (ret == APP2EXT_ERROR_ACCESS_FILE) {
1218 ("App2Sd Error : unable to access %s\n",
1222 ("App2Sd Error : unable to copy from %s to %s .....errno is %d\n",
1231 list = g_list_next(list);
1234 return APP2EXT_SUCCESS;
1237 int _app2sd_duplicate_device(const char *pkgid, GList* dir_list, char *dev_node, int size)
1240 char temp_pkgid[FILENAME_MAX] = { 0, };
1243 char *result = NULL;
1245 /*Create a new loopback device */
1246 snprintf(temp_pkgid, FILENAME_MAX,
1248 ret = _app2sd_create_loopback_device(temp_pkgid, (size+PKG_BUF_SIZE));
1250 app2ext_print("App2Sd Error : Package already present\n");
1253 app2ext_print("App2Sd : _app2sd_create_loopback_device SUCCESS\n");
1254 /*Perform Loopback encryption setup */
1255 dev_node = _app2sd_do_loopback_duplicate_encryption_setup(pkgid, temp_pkgid);
1257 app2ext_print("App2Sd Error : losetup failed, device node is %s\n", dev_node);
1258 _app2sd_delete_loopback_device(pkgid);
1259 app2ext_print("App2Sd Error : create ext filesystem failed\n");
1260 return APP2EXT_ERROR_DO_LOSETUP;
1262 app2ext_print("App2Sd : _app2sd_do_loopback_duplicate_encryption_setup SUCCESS\n");
1263 /*Check whether loopback device is associated with device node or not */
1264 devi = _app2sd_find_associated_device_node(temp_pkgid);
1266 app2ext_print("App2Sd Error : finding associated device node failed\n");
1267 err_res = APP2EXT_ERROR_DO_LOSETUP;
1270 app2ext_print("App2Sd : _app2sd_find_associated_device_node SUCCESS\n");
1271 /*Format the loopback file system */
1272 ret = _app2sd_create_file_system(dev_node);
1274 app2ext_print("App2Sd Error : creating FS failed failed\n");
1275 err_res = APP2EXT_ERROR_CREATE_FS;
1278 app2ext_print("App2Sd : _app2sd_create_file_system SUCCESS\n");
1279 /*Do mounting for new dev*/
1281 _app2sd_mount_app_content(temp_pkgid, dev_node, MOUNT_TYPE_RW,
1282 dir_list, APP2SD_PRE_UPGRADE);
1284 app2ext_print("App2Sd Error : Re-mount failed\n");
1285 err_res = APP2EXT_ERROR_MOUNT_PATH;
1292 return APP2EXT_SUCCESS;
1296 result = _app2sd_detach_loop_device(dev_node);
1301 _app2sd_delete_loopback_device(pkgid);
1313 int _app2sd_update_loopback_device_size(const char *pkgid,
1314 int size, GList* dir_list)
1317 char *device_node = NULL;
1318 char *old_device_node = NULL;
1320 char app_mmc_path[FILENAME_MAX] = { 0, };
1321 char app_archive_path[FILENAME_MAX] = { 0, };
1322 char temp_pkgid[FILENAME_MAX] = { 0, };
1323 char app_path[FILENAME_MAX] = { 0, };
1325 snprintf(temp_pkgid, FILENAME_MAX,
1328 ret = _app2sd_duplicate_device(pkgid, dir_list, device_node, size);
1330 app2ext_print("App2Sd Error : Creating duplicate device failed\n");
1334 app2ext_print("App2Sd : _app2sd_mount_app_content SUCCESS\n");
1335 /*check app entry is there in sd card or not. */
1336 snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
1339 /*Get the associated device node for SD card applicatione */
1340 old_device_node = _app2sd_find_associated_device_node(pkgid);
1341 if (NULL == old_device_node) {
1342 /*Do loopback setup */
1343 old_device_node = _app2sd_do_loopback_encryption_setup(pkgid);
1344 if (old_device_node == NULL) {
1346 ("App2Sd Error : loopback encryption setup failed\n");
1347 err_res = APP2EXT_ERROR_DO_LOSETUP;
1352 _app2sd_mount_app_content(pkgid, old_device_node,
1353 MOUNT_TYPE_RW, dir_list,
1354 APP2SD_PRE_UPGRADE);
1356 app2ext_print("App2Sd Error : Re-mount failed\n");
1357 err_res = APP2EXT_ERROR_MOUNT_PATH;
1363 _app2sd_mount_app_content(pkgid, old_device_node,
1364 MOUNT_TYPE_RW_REMOUNT, dir_list,
1365 APP2SD_PRE_UPGRADE);
1367 app2ext_print("App2Sd Error : Re-mount failed\n");
1368 err_res = APP2EXT_ERROR_MOUNT_PATH;
1373 snprintf(app_mmc_path, FILENAME_MAX,
1374 "%s%s/.mmc", APP_INSTALLATION_PATH, pkgid);
1375 snprintf(app_archive_path, FILENAME_MAX,
1376 "%s%s/.mmc", APP_INSTALLATION_PATH, temp_pkgid);
1378 ret = _app2sd_copy_ro_content(app_mmc_path, app_archive_path, dir_list);
1380 app2ext_print("App2Sd Error : copy ro content failed\n");
1385 ret = _app2sd_unmount_app_content(pkgid);
1388 ("App2SD Error: Unable to unmount the SD application\n");
1389 err_res = APP2EXT_ERROR_UNMOUNT;
1392 ret = _app2sd_remove_loopback_encryption_setup(pkgid);
1394 app2ext_print("App2SD Error: Unable to remove loopback setup\n");
1395 err_res = APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
1398 ret = _app2sd_unmount_app_content(temp_pkgid);
1401 ("App2SD Error: Unable to unmount the SD application\n");
1402 err_res = APP2EXT_ERROR_UNMOUNT;
1405 ret = _app2sd_remove_loopback_encryption_setup(temp_pkgid);
1407 app2ext_print("App2SD Error: Unable to remove loopback setup\n");
1408 err_res = APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
1411 snprintf(app_archive_path, FILENAME_MAX,
1412 "%s%s", APP2SD_PATH, temp_pkgid);
1413 ret = _app2sd_delete_directory(app_path);
1416 ("App2Sd Error : unable to delete %s \n",
1418 err_res = APP2EXT_ERROR_DELETE_DIRECTORY;
1421 ret = _app2sd_rename_dir(app_archive_path, app_path);
1424 ("App2Sd Error : unable to rename %s \n",
1426 err_res = APP2EXT_ERROR_MOVE;
1429 snprintf(app_path, FILENAME_MAX,
1430 "%s%s", APP_INSTALLATION_PATH, temp_pkgid);
1431 ret = _app2sd_delete_directory(app_path);
1434 ("App2Sd Error : unable to delete %s \n",
1436 err_res = APP2EXT_ERROR_DELETE_DIRECTORY;
1439 return APP2EXT_SUCCESS;
1442 if (old_device_node) {
1443 free(old_device_node);
1444 old_device_node = NULL;
1447 ret = _app2sd_remove_loopback_encryption_setup(pkgid);
1449 app2ext_print("App2SD Error: Unable to remove loopback setup\n");
1450 err_res = APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;