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 ##################
45 char *_app2sd_find_associated_device_node(const char *pkgid)
47 char *ret_result = NULL;
50 char app_path[FILENAME_MAX] = { '\0' };
52 snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
54 result = (char *)_app2sd_find_associated_device(app_path);
57 ("App2SD Error! Unable to find the associated File\n");
60 /*process the string*/
61 if (strstr(result, "/dev") == NULL) {
63 ("App2SD Error! Unable to find the associated File\n");
66 ret_result = strtok(result, delims);
73 char *_app2sd_create_loopdevice_node(void)
75 char *ret_result = NULL;
76 mode_t mode = DIR_PERMS;
78 int ret = APP2EXT_SUCCESS;
82 result = (char *)_app2sd_find_free_device();
83 /*validate the result */
84 if (result == NULL || strstr(result, "/dev") == NULL) {
85 app2ext_print("No device found, creating device node...\n");
92 char dev_path[BUF_SIZE] = { 0, };
93 snprintf(dev_path, BUF_SIZE, "/dev/loop%d", count);
94 while ((fp = fopen(dev_path, "r+")) != NULL) {
96 snprintf(dev_path, BUF_SIZE, "/dev/loop%d", count);
97 app2ext_print("next dev path for checking is %s\n",
101 app2ext_print("Device node candidate is %s \n", dev_path);
103 dev_node = makedev(DEV_MAJOR, count);
104 if ((ret = mknod(dev_path, S_IFBLK | mode, dev_node)) < 0) {
106 ("Error while creating the device node: errno is %d\n",
110 ret_result = (char *)malloc(strlen(dev_path) + 1);
111 if (ret_result == NULL) {
112 app2ext_print("Unable to allocate memory\n");
115 memset(ret_result, '\0', strlen(dev_path) + 1);
116 memcpy(ret_result, dev_path, strlen(dev_path));
118 ret_result = (char *)malloc(strlen(result) + 1);
119 if (ret_result == NULL) {
120 app2ext_print("Malloc failed!\n");
125 memset(ret_result, '\0', strlen(result) + 1);
126 if (strlen(result) > 0) {
127 memcpy(ret_result, result, strlen(result) - 1);
136 char *_app2sd_do_loopback_encryption_setup(const char *pkgid)
138 int ret = APP2EXT_SUCCESS;
140 char app_path[FILENAME_MAX] = { '\0' };
142 char *device_node = NULL;
144 app2ext_print("App2Sd Error: Invalid argument\n");
148 snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
150 /* Get password for loopback encryption */
151 ret = _app2sd_initialize_db();
153 app2ext_print("\n app2sd db initialize failed");
156 if ((passwd = _app2sd_get_password_from_db(pkgid)) == NULL) {
157 passwd = (char *)_app2sd_generate_password(pkgid);
158 if (NULL == passwd) {
160 ("App2Sd Error: Unable to generate password\n");
163 app2ext_print("Password is %s\n", passwd);
164 if ((ret = _app2sd_set_password_in_db(pkgid,
167 ("App2Sd Error: Unable to save password\n");
175 /*Get Free device node*/
176 device_node = _app2sd_create_loopdevice_node();
177 if (NULL == device_node) {
181 ("App2Sd Error: Unable to find free loopback node\n");
184 result = (char *)_app2sd_encrypt_device(device_node, app_path, passwd);
185 if (result == NULL) {
186 app2ext_print("App2Sd Error: Encryption failed!\n\n");
199 char *_app2sd_do_loopback_duplicate_encryption_setup(const char *pkgid, const char * dup_appname)
201 int ret = APP2EXT_SUCCESS;
203 char app_path[FILENAME_MAX] = { '\0' };
205 char *device_node = NULL;
206 if (pkgid == NULL || dup_appname == NULL) {
207 app2ext_print("App2Sd Error: Invalid argument\n");
211 snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
213 /* Get password for loopback encryption */
214 ret = _app2sd_initialize_db();
216 app2ext_print("\n app2sd db initialize failed");
219 if ((passwd = _app2sd_get_password_from_db(pkgid)) == NULL) {
220 passwd = (char *)_app2sd_generate_password(pkgid);
221 if (NULL == passwd) {
223 ("App2Sd Error: Unable to generate password\n");
226 app2ext_print("Password is %s\n", passwd);
227 if ((ret = _app2sd_set_password_in_db(pkgid,
230 ("App2Sd Error: Unable to save password\n");
238 /*Get Free device node*/
239 device_node = _app2sd_create_loopdevice_node();
240 if (NULL == device_node) {
244 ("App2Sd Error: Unable to find free loopback node\n");
247 result = (char *)_app2sd_encrypt_device(device_node, app_path, passwd);
248 if (result == NULL) {
249 app2ext_print("App2Sd Error: Encryption failed!\n\n");
254 if (strlen(result) == 0) {
261 app2ext_print("App2Sd Error: Error is %s\n", result);
272 int _app2sd_remove_loopback_encryption_setup(const char *pkgid)
274 int ret = APP2EXT_SUCCESS;
276 char *dev_node = NULL;
277 if ((dev_node = _app2sd_find_associated_device_node(pkgid)) == NULL) {
278 app2ext_print("Unable to find the association\n");
279 ret = APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_NODE;
281 result = (char *)_app2sd_detach_loop_device(dev_node);
282 if (result == NULL) {
283 app2ext_print("App2sd Error: Error in detaching\n");
284 ret = APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE;
296 int _app2sd_create_loopback_device(const char *pkgid, int size)
298 int ret = APP2EXT_SUCCESS;
299 char command[FILENAME_MAX] = { 0, };
300 mode_t mode = DIR_PERMS;
301 char external_storage_path[FILENAME_MAX] = { 0, };
302 char buff[BUF_SIZE] = { 0, };
303 char app_path[FILENAME_MAX] = { 0, };
306 if (NULL == pkgid || size <= 0) {
307 app2ext_print("App2Sd Error: Invalid argument\n");
308 return APP2EXT_ERROR_INVALID_ARGUMENTS;
310 snprintf(command, FILENAME_MAX, "of=%s%s", APP2SD_PATH,
312 snprintf(buff, BUF_SIZE, "count=%d", size);
313 const char *argv1[] =
314 { "dd", "if=/dev/zero", command, "bs=1M", buff, NULL };
315 snprintf(external_storage_path, FILENAME_MAX, "%s",
317 ret = mkdir(external_storage_path, mode);
319 if (errno != EEXIST) {
321 ("App2sd Error : Create directory failed, error no is %d\n",
323 return APP2EXT_ERROR_CREATE_DIRECTORY;
326 snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
328 if ((fp = fopen(app_path, "r+")) != NULL) {
329 app2ext_print("Application already exists %s\n", app_path);
331 return APP2EXT_ERROR_PKG_EXISTS;
334 ret = _xsystem(argv1);
336 app2ext_print("App2Sd Error : command \"%s\" failed \n",
343 int _app2sd_delete_loopback_device(const char *pkgid)
345 int ret = APP2EXT_SUCCESS;
346 char loopback_device[FILENAME_MAX] = { 0, };
348 snprintf(loopback_device, FILENAME_MAX, "%s%s", APP2SD_PATH,
351 ret = unlink(loopback_device);
353 if (errno == ENOENT) {
354 app2ext_print("Unable to access file %s\n", loopback_device);
356 app2ext_print("Unable to delete %s\n", loopback_device);
357 return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
363 int _app2sd_create_file_system(const char *device_path)
365 int ret = APP2EXT_SUCCESS;
367 if (NULL == device_path) {
368 app2ext_print("App2Sd Error: invalid param [NULL]\n");
369 return APP2EXT_ERROR_INVALID_ARGUMENTS;
372 /*Format the filesystem [create a filesystem]*/
373 const char *argv[] = { "/sbin/mkfs.ext4", device_path, NULL };
374 fp = fopen(device_path, "r+");
377 ("App2sd Error: Unable to access %s [System errono is %d.....%s]\n",
378 device_path, errno, strerror(errno));
379 return APP2EXT_ERROR_ACCESS_FILE;
383 ret = _xsystem(argv);
386 ("App2Sd Error : creating file system failed [System error is %s\n",
388 return APP2EXT_ERROR_CREATE_FS;
393 static int _app2sd_create_dir_with_link(const char *pkgid,
394 const char *dir_name)
396 mode_t mode = DIR_PERMS;
397 int ret = APP2EXT_SUCCESS;
398 char app_dir_mmc_path[FILENAME_MAX] = { 0, };
399 char app_dir_path[FILENAME_MAX] = { 0, };
400 snprintf(app_dir_mmc_path, FILENAME_MAX, "%s%s/.mmc/%s",APP_INSTALLATION_PATH,
402 snprintf(app_dir_path, FILENAME_MAX, "%s%s/%s", APP_INSTALLATION_PATH, pkgid,
405 ret = mkdir(app_dir_mmc_path, mode);
407 if (errno != EEXIST) {
409 ("App2sd Error : Create directory failed, error no is %d\n",
411 return APP2EXT_ERROR_CREATE_DIRECTORY;
415 if ((ret = symlink(app_dir_mmc_path, app_dir_path)) < 0) {
416 if (errno == EEXIST) {
418 ("App2sd : File with Symlink name present %s\n",
422 ("A2Sd Error : Symbolic link creation failed, error no is %d\n",
424 return APP2EXT_ERROR_CREATE_SYMLINK;
431 int _app2sd_create_directory_entry(const char *pkgid, GList* dir_list)
433 int ret = APP2EXT_SUCCESS;
434 char app_dir_path[FILENAME_MAX] = { 0, };
436 app2ext_dir_details* dir_detail = NULL;
438 snprintf(app_dir_path, FILENAME_MAX, "%s%s", APP_INSTALLATION_PATH,
441 list = g_list_first(dir_list);
443 dir_detail = (app2ext_dir_details *)list->data;
444 if (dir_detail && dir_detail->name
445 && dir_detail->type == APP2EXT_DIR_RO) {
446 ret = _app2sd_create_dir_with_link(pkgid, dir_detail->name);
451 list = g_list_next(list);
453 return APP2EXT_SUCCESS;
459 * _app2sd_mount_app_content
460 This function is to create the path for mmc and mount the content
461 Example usage: _app2sd_mount_app_content("deb.com.samsung.helloworld","/dev/loop0",MOUNT_TYPE_RD)
463 int _app2sd_mount_app_content(const char *pkgid, const char *dev,
464 int mount_type, GList* dir_list, app2sd_cmd cmd)
466 int ret = APP2EXT_SUCCESS;
467 mode_t mode = DIR_PERMS;
468 char app_dir_path[FILENAME_MAX] = { 0, };
469 char app_dir_mmc_path[FILENAME_MAX] = { 0, };
470 if (NULL == pkgid || NULL == dev) {
471 app2ext_print("App2Sd Error : Input param is NULL %s %s \n",
473 return APP2EXT_ERROR_INVALID_ARGUMENTS;
475 snprintf(app_dir_path, FILENAME_MAX, "%s%s", APP_INSTALLATION_PATH, pkgid);
476 ret = mkdir(app_dir_path, mode);
478 if (errno != EEXIST) {
480 ("App2Sd Error : Create directory failed, error no is %d\n",
482 return APP2EXT_ERROR_CREATE_DIRECTORY;
485 snprintf(app_dir_mmc_path, FILENAME_MAX, "%s%s/.mmc", APP_INSTALLATION_PATH, pkgid);
486 ret = mkdir(app_dir_mmc_path, mode);
488 if (errno != EEXIST) {
490 ("App2Sd Error : Create directory failed, error no is %d\n",
492 return APP2EXT_ERROR_CREATE_DIRECTORY;
496 switch (mount_type) {
500 mount(dev, app_dir_mmc_path, FS_TYPE,
501 MS_MGC_VAL | MS_RDONLY, NULL)) < 0) {
503 ("App2Sd Error : Read Only Mount failed [System Erro no is %d], dev is %s path is %s\n",
504 errno, dev, app_dir_mmc_path);
505 ret = APP2EXT_ERROR_MOUNT;
512 mount(dev, app_dir_mmc_path, FS_TYPE, MS_MGC_VAL,
515 ("App2Sd Error : Read Write Mount failed [System Erro no is %d]\n",
517 ret = APP2EXT_ERROR_MOUNT;
521 case MOUNT_TYPE_RW_NOEXEC:
524 mount(dev, app_dir_mmc_path, FS_TYPE,
525 MS_MGC_VAL | MS_NOEXEC, NULL)) < 0) {
527 ("App2Sd Error : RWX Mount failed [System Erro no is %d]\n",
529 ret = APP2EXT_ERROR_MOUNT;
533 case MOUNT_TYPE_RD_REMOUNT:
536 mount(dev, app_dir_mmc_path, FS_TYPE,
537 MS_MGC_VAL | MS_RDONLY | MS_REMOUNT,
540 ("App2Sd Error : RWX Mount failed [System Erro no is %d]\n",
542 ret = APP2EXT_ERROR_MOUNT;
546 case MOUNT_TYPE_RW_REMOUNT:
549 mount(dev, app_dir_mmc_path, FS_TYPE,
550 MS_MGC_VAL | MS_REMOUNT, NULL)) < 0) {
552 ("App2Sd Error : RWX Mount failed [System Erro no is %d]\n",
554 ret = APP2EXT_ERROR_MOUNT;
561 app2ext_print("App2Sd Error: Invalid mount type\n");
565 if (cmd == APP2SD_PRE_INSTALL || cmd == APP2SD_MOVE_APP_TO_MMC) {
566 ret = _app2sd_create_directory_entry(pkgid, dir_list);
571 int _app2sd_unmount_app_content(const char *pkgid)
573 int ret = APP2EXT_SUCCESS;
574 char app_dir_mmc_path[FILENAME_MAX] = { 0, };
575 snprintf(app_dir_mmc_path, FILENAME_MAX, "%s%s/.mmc", APP_INSTALLATION_PATH, pkgid);
576 if ((ret = umount(app_dir_mmc_path)) < 0) {
577 app2ext_print("Unable to umount the dir %s\n", strerror(errno));
582 static int _app2sd_move_to_archive(const char *src_path, const char *arch_path)
584 int ret = APP2EXT_SUCCESS;
586 ret = _app2sd_copy_dir(src_path, arch_path);
588 if (ret != APP2EXT_ERROR_ACCESS_FILE) {
590 ("App2Sd Error : unable to copy from %s to %s .....err is %s\n",
591 src_path, arch_path, strerror(errno));
592 return APP2EXT_ERROR_MOVE;
595 ret = _app2sd_delete_directory((char *)src_path);
597 if (ret != APP2EXT_ERROR_ACCESS_FILE) {
598 app2ext_print("App2Sd Error : unable to delete %s \n", src_path);
599 return APP2EXT_ERROR_DELETE_DIRECTORY;
605 int _app2sd_move_app_to_external(const char *pkgid, GList* dir_list)
607 int ret = APP2EXT_SUCCESS;
608 char app_path[FILENAME_MAX] = { 0, };
609 char path[FILENAME_MAX] = { 0, };
610 char app_mmc_path[FILENAME_MAX] = { 0, };
611 char app_archive_path[FILENAME_MAX] = { 0, };
612 char mmc_path[FILENAME_MAX] = { 0, };
613 unsigned long long total_size = 0;
615 char *device_node = NULL;
617 mode_t mode = DIR_PERMS;
618 int free_mmc_mem = 0;
621 app2ext_dir_details* dir_detail = NULL;
623 /*Check whether MMC is present or not */
624 ret = _app2sd_check_mmc_status();
627 ("App2Sd Error : MMC not preset OR Not ready %d\n",
629 return APP2EXT_ERROR_MMC_STATUS;
632 snprintf(mmc_path, FILENAME_MAX,
633 "%s%s", APP2SD_PATH, pkgid);
635 /*check whether application is in external memory or not */
636 fp = fopen(mmc_path, "r+");
639 ("Already %s entry is present in the SD Card\n",
642 return APP2EXT_ERROR_ALREADY_FILE_PRESENT;
645 snprintf(app_mmc_path, FILENAME_MAX,
646 "%s%s/.mmc", APP_INSTALLATION_PATH, pkgid);
647 snprintf(app_archive_path, FILENAME_MAX,
648 "%s%s/.archive", APP_INSTALLATION_PATH, pkgid);
650 ret = mkdir(app_archive_path, mode);
652 if (errno != EEXIST) {
654 ("App2sd Error: Unable to create directory for archiving, error no is %d\n",
656 return APP2EXT_ERROR_CREATE_DIRECTORY;
660 list = g_list_first(dir_list);
662 dir_detail = (app2ext_dir_details *)list->data;
663 if (dir_detail && dir_detail->name
664 && dir_detail->type == APP2EXT_DIR_RO) {
665 memset((void *)&app_path, '\0',
667 snprintf(app_path, FILENAME_MAX,
668 "%s%s/%s",APP_INSTALLATION_PATH,
672 _app2sd_calculate_dir_size
675 list = g_list_next(list);
678 reqd_size = ((total_size / 1024) / 1024) + 2;
680 /*Find avialable free memory in the MMC card */
682 _app2sd_get_available_free_memory
683 (MMC_PATH, &free_mmc_mem);
686 ("App2Sd Error : Unable to get available free memory in MMC %d\n",
688 return APP2EXT_ERROR_MMC_STATUS;
690 /*If avaialalbe free memory in MMC is less than required size + 5MB , return error */
691 if (reqd_size > free_mmc_mem) {
693 ("App2Sd Error : Insufficient memory in MMC for application installation %d\n",
695 return APP2EXT_ERROR_MMC_INSUFFICIENT_MEMORY;
697 /*Create a loopback device */
699 _app2sd_create_loopback_device(pkgid, (reqd_size+PKG_BUF_SIZE));
702 ("App2Sd Error : loopback node creation failed\n");
703 return APP2EXT_ERROR_CREATE_DEVICE;
705 /*Perform Loopback encryption setup */
707 _app2sd_do_loopback_encryption_setup(pkgid);
710 ("App2Sd Error : losetup failed, device node is %s\n",
712 return APP2EXT_ERROR_DO_LOSETUP;
714 /*Check whether loopback device is associated with device node or not */
715 devi = _app2sd_find_associated_device_node(pkgid);
718 ("App2Sd Error : _app2sd_find_associated_device_node losetup failed\n");
719 return APP2EXT_ERROR_DO_LOSETUP;
724 /*Format the loopback file system */
725 ret = _app2sd_create_file_system(device_node);
728 ("App2Sd Error : create ext4 filesystem failed\n");
729 return APP2EXT_ERROR_CREATE_FS;
731 /********Archiving code begin***********/
732 list = g_list_first(dir_list);
734 dir_detail = (app2ext_dir_details *)list->data;
735 if (dir_detail && dir_detail->name
736 && dir_detail->type == APP2EXT_DIR_RO) {
737 snprintf(path, FILENAME_MAX,
738 "%s%s/%s",APP_INSTALLATION_PATH,
742 _app2sd_move_to_archive
746 if (ret == APP2EXT_ERROR_ACCESS_FILE) {
748 ("App2Sd Error : unable to access %s\n",
752 ("App2Sd Error : unable to copy from %s to %s \n",
760 list = g_list_next(list);
762 /********Archiving code ends***********/
764 /*mount the loopback encrypted pseudo device on application installation path as with Read Write permission */
766 _app2sd_mount_app_content(pkgid, device_node,
767 MOUNT_TYPE_RW, dir_list,
768 APP2SD_MOVE_APP_TO_MMC);
772 /********restore Archive begin***********/
773 list = g_list_first(dir_list);
775 dir_detail = (app2ext_dir_details *)list->data;
776 if (dir_detail && dir_detail->name
777 && dir_detail->type == APP2EXT_DIR_RO) {
778 memset((void *)&path, '\0',
780 snprintf(path, FILENAME_MAX,
781 "%s%s/.archive/%s",APP_INSTALLATION_PATH,
789 if (ret == APP2EXT_ERROR_ACCESS_FILE) {
791 ("App2Sd Error : unable to access %s\n",
795 ("App2Sd Error : unable to copy from %s to %s .....err is %s\n",
805 _app2sd_delete_directory
808 if (ret == APP2EXT_ERROR_ACCESS_FILE) {
810 ("App2Sd Error : unable to access %s\n",
814 ("App2Sd Error : unable to delete %s \n",
817 APP2EXT_ERROR_DELETE_DIRECTORY;
821 list = g_list_next(list);
824 ret = _app2sd_delete_directory(app_archive_path);
827 ("App2Sd Error : unable to delete %s \n",
829 return APP2EXT_ERROR_DELETE_DIRECTORY;
831 /*Restore archive ends */
832 /*Re-mount the loopback encrypted pseudo device on application installation path as with Read Only permission */
833 ret = _app2sd_unmount_app_content(pkgid);
835 return APP2EXT_ERROR_REMOUNT;
838 _app2sd_remove_loopback_encryption_setup(pkgid);
841 ("App2Sd Error : unable to detach loopback setup for %s\n",
843 return APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE;
845 return APP2EXT_SUCCESS;
848 int _app2sd_move_app_to_internal(const char *pkgid, GList* dir_list)
850 int ret = APP2EXT_SUCCESS;
851 mode_t mode = DIR_PERMS;
852 char path[FILENAME_MAX] = { 0, };
853 char app_mmc_path[FILENAME_MAX] = { 0, };
854 char app_path[FILENAME_MAX] = { 0, };
855 char mmc_path[FILENAME_MAX] = { 0, };
856 char app_archive_path[FILENAME_MAX] = { 0, };
857 char *device_node = NULL;
860 app2ext_dir_details* dir_detail = NULL;
862 snprintf(app_mmc_path, FILENAME_MAX,
863 "%s%s/.mmc", APP_INSTALLATION_PATH, pkgid);
864 snprintf(app_path, FILENAME_MAX, "%s%s/", APP_INSTALLATION_PATH,
866 snprintf(app_archive_path, FILENAME_MAX,
867 "%s%s/.archive", APP_INSTALLATION_PATH, pkgid);
868 snprintf(mmc_path, FILENAME_MAX,
869 "%s%s", APP2SD_PATH, pkgid);
871 /*Check whether MMC is present or not */
872 ret = _app2sd_check_mmc_status();
875 ("App2Sd Error : MMC not preset OR Not ready %d\n",
877 return APP2EXT_ERROR_MMC_STATUS;
880 /*check whether application is in external memory or not */
881 fp = fopen(mmc_path, "r+");
884 ("Application %s is not installed on SD Card\n",
886 return APP2EXT_ERROR_FILE_ABSENT;
892 /*Get the associated device node for SD card applicationer */
894 _app2sd_find_associated_device_node(pkgid);
895 if (NULL == device_node) {
896 /*Do loopback setup */
898 _app2sd_do_loopback_encryption_setup
900 if (device_node == NULL) {
902 ("App2Sd Error : loopback encryption setup failed\n");
903 return APP2EXT_ERROR_DO_LOSETUP;
907 _app2sd_mount_app_content(pkgid,
911 APP2SD_MOVE_APP_TO_PHONE);
914 ("App2Sd Error : Re-mount failed\n");
915 return APP2EXT_ERROR_MOUNT_PATH;
920 _app2sd_mount_app_content(pkgid,
922 MOUNT_TYPE_RW_REMOUNT,
924 APP2SD_MOVE_APP_TO_PHONE);
927 ("App2Sd Error : Re-mount failed\n");
928 return APP2EXT_ERROR_MOUNT_PATH;
931 ret = mkdir(app_archive_path, mode);
934 ("App2Sd Error : unable to create directory%s\n",
936 return APP2EXT_ERROR_CREATE_DIRECTORY;
940 list = g_list_first(dir_list);
942 dir_detail = (app2ext_dir_details *)list->data;
943 if (dir_detail && dir_detail->name
944 && dir_detail->type == APP2EXT_DIR_RO) {
946 memset((void *)&path, '\0',
948 snprintf(path, FILENAME_MAX,
949 "%s%s/.mmc/%s", APP_INSTALLATION_PATH,
957 if (ret == APP2EXT_ERROR_ACCESS_FILE) {
959 ("App2Sd Error : unable to access %s\n",
963 ("App2Sd Error : unable to copy from %s to %s .....err is %s\n",
973 /*Delete the symbolic link files [bin, lib, res]*/
974 memset((void *)&path, '\0',
976 snprintf(path, FILENAME_MAX,
977 "%s%s/%s", APP_INSTALLATION_PATH,
982 if (errno == ENOENT) {
984 ("App2Sd Error : Directory %s does not exist\n",
988 ("App2Sd Error : unable to remove the symbolic link file %s\n",
991 APP2EXT_ERROR_DELETE_LINK_FILE;
995 /*Copy content to destination */
996 memset((void *)&path, '\0',
998 snprintf(path, FILENAME_MAX,
999 "%s%s/.archive/%s", APP_INSTALLATION_PATH,
1006 if (ret == APP2EXT_ERROR_ACCESS_FILE) {
1008 ("App2Sd Error : unable to access %s\n",
1012 ("App2Sd Error : unable to copy from %s to %s .....err is %s\n",
1022 list = g_list_next(list);
1025 ret = _app2sd_unmount_app_content(pkgid);
1028 ("App2Sd Error : unable to unmount SD directory for app %s\n",
1030 return APP2EXT_ERROR_UNMOUNT;
1033 _app2sd_remove_loopback_encryption_setup(pkgid);
1036 ("App2Sd Error : unable to detach loopback setup for %s\n",
1038 return APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE;
1040 ret = _app2sd_delete_loopback_device(pkgid);
1043 ("App2Sd Error : unable to delete the loopback device for %s\n",
1045 return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
1047 ret = _app2sd_delete_directory(app_mmc_path);
1050 ("App2Sd Error : unable to delete %s \n",
1052 return APP2EXT_ERROR_DELETE_DIRECTORY;
1054 ret = _app2sd_delete_directory(app_archive_path);
1057 ("App2Sd Error : unable to delete %s \n",
1059 return APP2EXT_ERROR_DELETE_DIRECTORY;
1061 return APP2EXT_SUCCESS;
1064 int _app2sd_move_app(const char *pkgid, app2ext_move_type move_cmd, GList* dir_list)
1066 int ret = APP2EXT_SUCCESS;
1068 /*Check whether MMC is present or not */
1069 ret = _app2sd_check_mmc_status();
1072 ("App2Sd Error : MMC not preset OR Not ready %d\n",
1074 return APP2EXT_ERROR_MMC_STATUS;
1078 case APP2EXT_MOVE_TO_EXT:
1080 ret = _app2sd_move_app_to_external(pkgid, dir_list);
1083 ("App2Sd Error : move app to external memory failed %d\n",
1089 case APP2EXT_MOVE_TO_PHONE:
1091 ret = _app2sd_move_app_to_internal(pkgid, dir_list);
1094 ("App2Sd Error : move app to internal memory failed %d\n",
1102 app2ext_print("App2Sd Error : invalid argument\n");
1103 return APP2EXT_ERROR_INVALID_ARGUMENTS;
1111 int _app2sd_copy_ro_content(const char *src, const char *dest, GList* dir_list)
1113 char path[FILENAME_MAX] = { 0, };
1114 int ret = APP2EXT_SUCCESS;
1116 app2ext_dir_details* dir_detail = NULL;
1118 list = g_list_first(dir_list);
1120 dir_detail = (app2ext_dir_details *)list->data;
1121 if (dir_detail && dir_detail->name
1122 && dir_detail->type == APP2EXT_DIR_RO) {
1123 memset((void *)&path, '\0',
1125 snprintf(path, FILENAME_MAX,
1133 if (ret == APP2EXT_ERROR_ACCESS_FILE) {
1135 ("App2Sd Error : unable to access %s\n",
1139 ("App2Sd Error : unable to copy from %s to %s .....errno is %d\n",
1148 list = g_list_next(list);
1151 return APP2EXT_SUCCESS;
1154 int _app2sd_duplicate_device(const char *pkgid, GList* dir_list, char *dev_node, int size)
1157 char temp_pkgid[FILENAME_MAX] = { 0, };
1160 char *result = NULL;
1162 /*Create a new loopback device */
1163 snprintf(temp_pkgid, FILENAME_MAX,
1165 ret = _app2sd_create_loopback_device(temp_pkgid, (size+PKG_BUF_SIZE));
1167 app2ext_print("App2Sd Error : Package already present\n");
1170 app2ext_print("App2Sd : _app2sd_create_loopback_device SUCCESS\n");
1171 /*Perform Loopback encryption setup */
1172 dev_node = _app2sd_do_loopback_duplicate_encryption_setup(pkgid, temp_pkgid);
1174 app2ext_print("App2Sd Error : losetup failed, device node is %s\n", dev_node);
1175 _app2sd_delete_loopback_device(pkgid);
1176 app2ext_print("App2Sd Error : create ext filesystem failed\n");
1177 return APP2EXT_ERROR_DO_LOSETUP;
1179 app2ext_print("App2Sd : _app2sd_do_loopback_duplicate_encryption_setup SUCCESS\n");
1180 /*Check whether loopback device is associated with device node or not */
1181 devi = _app2sd_find_associated_device_node(temp_pkgid);
1183 app2ext_print("App2Sd Error : finding associated device node failed\n");
1184 err_res = APP2EXT_ERROR_DO_LOSETUP;
1187 app2ext_print("App2Sd : _app2sd_find_associated_device_node SUCCESS\n");
1188 /*Format the loopback file system */
1189 ret = _app2sd_create_file_system(dev_node);
1191 app2ext_print("App2Sd Error : creating FS failed failed\n");
1192 err_res = APP2EXT_ERROR_CREATE_FS;
1195 app2ext_print("App2Sd : _app2sd_create_file_system SUCCESS\n");
1196 /*Do mounting for new dev*/
1198 _app2sd_mount_app_content(temp_pkgid, dev_node, MOUNT_TYPE_RW,
1199 dir_list, APP2SD_PRE_UPGRADE);
1201 app2ext_print("App2Sd Error : Re-mount failed\n");
1202 err_res = APP2EXT_ERROR_MOUNT_PATH;
1209 return APP2EXT_SUCCESS;
1213 result = _app2sd_detach_loop_device(dev_node);
1218 _app2sd_delete_loopback_device(pkgid);
1230 int _app2sd_update_loopback_device_size(const char *pkgid,
1231 int size, GList* dir_list)
1234 char *device_node = NULL;
1235 char *old_device_node = NULL;
1236 char *result = NULL;
1238 char app_mmc_path[FILENAME_MAX] = { 0, };
1239 char app_archive_path[FILENAME_MAX] = { 0, };
1240 char temp_pkgid[FILENAME_MAX] = { 0, };
1241 char app_path[FILENAME_MAX] = { 0, };
1243 snprintf(temp_pkgid, FILENAME_MAX,
1246 ret = _app2sd_duplicate_device(pkgid, dir_list, device_node, size);
1248 app2ext_print("App2Sd Error : Creating duplicate device failed\n");
1252 app2ext_print("App2Sd : _app2sd_mount_app_content SUCCESS\n");
1253 /*check app entry is there in sd card or not. */
1254 snprintf(app_path, FILENAME_MAX, "%s%s", APP2SD_PATH,
1257 /*Get the associated device node for SD card applicatione */
1258 old_device_node = _app2sd_find_associated_device_node(pkgid);
1259 if (NULL == old_device_node) {
1260 /*Do loopback setup */
1261 old_device_node = _app2sd_do_loopback_encryption_setup(pkgid);
1262 if (old_device_node == NULL) {
1264 ("App2Sd Error : loopback encryption setup failed\n");
1265 err_res = APP2EXT_ERROR_DO_LOSETUP;
1270 _app2sd_mount_app_content(pkgid, old_device_node,
1271 MOUNT_TYPE_RW, dir_list,
1272 APP2SD_PRE_UPGRADE);
1274 app2ext_print("App2Sd Error : Re-mount failed\n");
1275 err_res = APP2EXT_ERROR_MOUNT_PATH;
1281 _app2sd_mount_app_content(pkgid, old_device_node,
1282 MOUNT_TYPE_RW_REMOUNT, dir_list,
1283 APP2SD_PRE_UPGRADE);
1285 app2ext_print("App2Sd Error : Re-mount failed\n");
1286 err_res = APP2EXT_ERROR_MOUNT_PATH;
1291 snprintf(app_mmc_path, FILENAME_MAX,
1292 "%s%s/.mmc", APP_INSTALLATION_PATH, pkgid);
1293 snprintf(app_archive_path, FILENAME_MAX,
1294 "%s%s/.mmc", APP_INSTALLATION_PATH, temp_pkgid);
1296 ret = _app2sd_copy_ro_content(app_mmc_path, app_archive_path, dir_list);
1298 app2ext_print("App2Sd Error : copy ro content failed\n");
1303 ret = _app2sd_unmount_app_content(pkgid);
1306 ("App2SD Error: Unable to unmount the SD application\n");
1307 err_res = APP2EXT_ERROR_UNMOUNT;
1310 ret = _app2sd_remove_loopback_encryption_setup(pkgid);
1312 app2ext_print("App2SD Error: Unable to remove loopback setup\n");
1313 err_res = APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
1316 ret = _app2sd_unmount_app_content(temp_pkgid);
1319 ("App2SD Error: Unable to unmount the SD application\n");
1320 err_res = APP2EXT_ERROR_UNMOUNT;
1323 ret = _app2sd_remove_loopback_encryption_setup(temp_pkgid);
1325 app2ext_print("App2SD Error: Unable to remove loopback setup\n");
1326 err_res = APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
1329 snprintf(app_archive_path, FILENAME_MAX,
1330 "%s%s", APP2SD_PATH, temp_pkgid);
1331 ret = _app2sd_delete_directory(app_path);
1334 ("App2Sd Error : unable to delete %s \n",
1336 err_res = APP2EXT_ERROR_DELETE_DIRECTORY;
1339 ret = _app2sd_rename_dir(app_archive_path, app_path);
1342 ("App2Sd Error : unable to rename %s \n",
1344 err_res = APP2EXT_ERROR_MOVE;
1347 snprintf(app_path, FILENAME_MAX,
1348 "%s%s", APP_INSTALLATION_PATH, temp_pkgid);
1349 ret = _app2sd_delete_directory(app_path);
1352 ("App2Sd Error : unable to delete %s \n",
1354 err_res = APP2EXT_ERROR_DELETE_DIRECTORY;
1357 return APP2EXT_SUCCESS;
1360 if (old_device_node) {
1361 free(old_device_node);
1362 old_device_node = NULL;
1365 ret = _app2sd_remove_loopback_encryption_setup(pkgid);
1367 app2ext_print("App2SD Error: Unable to remove loopback setup\n");
1368 err_res = APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;