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.
29 #include "app2sd_internals.h"
31 #define DMCRYPT_ITER_TIME 50
32 #define DMCRYPT_KEY_LEN 128
34 static int _app2sd_make_directory(const char *path, uid_t uid)
38 mode_t mode = DIR_PERMS;
40 struct passwd *pwd_result;
43 ret = _app2sd_delete_directory(path);
45 _E("unable to delete (%s), errno(%d)", path, errno);
46 return APP2EXT_ERROR_DELETE_DIRECTORY;
49 ret = getpwuid_r(uid, &pwd, buf, sizeof(buf), &pwd_result);
50 if (ret != 0 || pwd_result == NULL) {
51 _E("get uid failed(%d)", ret);
52 return APP2EXT_ERROR_ACCESS_FILE;
54 _D("uid(%d), gid(%d)", uid, pwd.pw_gid);
56 /* create directory */
57 ret = mkdir(path, mode);
59 if (errno != EEXIST) {
60 _E("create directory failed, error is (%d)", errno);
61 return APP2EXT_ERROR_CREATE_DIRECTORY;
65 fd = open(path, O_RDONLY|O_DIRECTORY);
67 _E("can't open path(%s)", path);
68 return APP2EXT_ERROR_OPEN_DIR;
71 ret = fchmod(fd, 0755);
73 _E("change file permission error");
75 return APP2EXT_ERROR_ACCESS_FILE;
78 ret = fchown(fd, uid, pwd.pw_gid);
80 _E("change file owner error");
82 return APP2EXT_ERROR_ACCESS_FILE;
87 return APP2EXT_SUCCESS;
90 int _app2sd_dmcrypt_setup_device(const char *pkgid,
91 const char *loopback_device, bool is_dup, uid_t uid)
95 char dmcrypt_setup_cmd[BUF_SIZE];
96 char err_buf[BUF_SIZE];
99 if (pkgid == NULL || loopback_device == NULL) {
100 _E("invalid argument");
101 return APP2EXT_ERROR_INVALID_ARGUMENTS;
104 /* get password for dmcrypt encryption */
105 ret = _app2sd_initialize_db();
107 _E("app2sd db initialize failed");
108 return APP2EXT_ERROR_DB_INITIALIZE;
111 passwd = _app2sd_get_password_from_db(pkgid, uid);
112 if (passwd == NULL) {
114 _E("no password found for (%s)", pkgid);
115 return APP2EXT_ERROR_SQLITE_REGISTRY;
117 passwd = _app2sd_generate_password();
118 if (passwd == NULL) {
119 _E("unable to generate password");
120 return APP2EXT_ERROR_PASSWD_GENERATION;
123 ret = _app2sd_set_info_in_db(pkgid, passwd, loopback_device,
126 _E("unable to save password");
128 return APP2EXT_ERROR_SQLITE_REGISTRY;
132 snprintf(dmcrypt_setup_cmd, sizeof(dmcrypt_setup_cmd),
133 "/bin/echo '%s' | /sbin/cryptsetup -q -i %d "
134 "-c aes-cbc-lmk -s %d --align-payload=8 luksFormat %s",
135 passwd, DMCRYPT_ITER_TIME, DMCRYPT_KEY_LEN,
138 ret = system(dmcrypt_setup_cmd);
140 err_str = strerror_r(errno, err_buf, sizeof(err_buf));
141 _E("Error setting up dmcrypt on app2sd file, error:%s, ret:%d",
143 return APP2EXT_ERROR_SETUP_DMCRYPT_DEVICE;
149 int _app2sd_dmcrypt_open_device(const char *pkgid, const char *loopback_device,
150 bool is_dup, uid_t uid, char **dev_node)
154 char dmcrypt_open_cmd[BUF_SIZE];
155 char dev_name[BUF_SIZE];
159 if (pkgid == NULL || loopback_device == NULL) {
160 _E("invalid argument");
161 return APP2EXT_ERROR_INVALID_ARGUMENTS;
165 snprintf(dev_name, sizeof(dev_name), "%s.new_%d", pkgid, uid);
167 snprintf(dev_name, sizeof(dev_name), "%s_%d", pkgid, uid);
169 /* get password for dmcrypt encryption */
170 ret = _app2sd_initialize_db();
172 _E("app2sd db initialize failed");
173 return APP2EXT_ERROR_DB_INITIALIZE;
176 passwd = _app2sd_get_password_from_db(pkgid, uid);
177 if (passwd == NULL) {
178 _E("no password found for [%s]", pkgid);
179 return APP2EXT_ERROR_SQLITE_REGISTRY;
182 if (_app2sd_check_is_luks_device(loopback_device) == 0) {
183 _W("legacy image format!");
184 snprintf(dmcrypt_open_cmd, sizeof(dmcrypt_open_cmd),
185 "/bin/echo '%s' | /sbin/cryptsetup "
186 "-M plain -c aes-cbc-plain -h plain open %s %s",
187 passwd, loopback_device, dev_name);
189 snprintf(dmcrypt_open_cmd, sizeof(dmcrypt_open_cmd),
190 "/bin/echo '%s' | /sbin/cryptsetup -q luksOpen "
192 passwd, loopback_device, dev_name);
196 ret = system(dmcrypt_open_cmd);
198 err_str = strerror_r(errno, buf, sizeof(buf));
199 _E("error opening dmcrypt device, error: [%s]", err_str);
200 return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
203 snprintf(buf, sizeof(buf), "/dev/mapper/%s", dev_name);
204 *dev_node = strdup(buf);
205 if (*dev_node == NULL) {
206 _E("memory alloc failed");
207 return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
213 int _app2sd_dmcrypt_close_device(const char *pkgid, uid_t uid)
216 char dev_node[BUF_SIZE];
217 char dmcrypt_close_cmd[BUF_SIZE];
218 char err_buf[BUF_SIZE];
223 _E("invalid argument");
224 return APP2EXT_ERROR_INVALID_ARGUMENTS;
227 t_dev_node = _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
229 _W("no associated device node(%s_%d) found", pkgid, uid);
230 return APP2EXT_ERROR_DMCRYPT_DEVICE_UNAVAILABLE;
235 snprintf(dev_node, sizeof(dev_node), "/dev/mapper/%s_%d", pkgid, uid);
236 snprintf(dmcrypt_close_cmd, sizeof(dmcrypt_close_cmd),
237 "/sbin/cryptsetup -q luksClose %s", dev_node);
238 ret = system(dmcrypt_close_cmd);
240 err_str = strerror_r(errno, err_buf, sizeof(err_buf));
241 _E("error closing dmcrypt on app2sd file: %s", err_str);
242 return APP2EXT_ERROR_CLOSE_DMCRYPT_DEVICE;
248 char *_app2sd_find_associated_dmcrypt_device_node(const char *pkgid, uid_t uid)
253 snprintf(buf, sizeof(buf), "/dev/mapper/%s_%d", pkgid, uid);
254 if (access(buf, F_OK) == 0) {
255 dev_node = strdup(buf);
256 if (dev_node == NULL) {
257 _E("memory alloc failed");
260 _D("device_node: (%s)", dev_node);
263 _D("can not access dev_node(%s), errno(%d)", buf, errno);
268 char *_app2sd_dmcrypt_duplicate_encryption_setup(const char *pkgid,
269 const char *temp_loopback_device, uid_t uid)
274 if (pkgid == NULL || temp_loopback_device == NULL) {
275 _E("invalid argument");
279 ret = _app2sd_dmcrypt_setup_device(pkgid, temp_loopback_device, true,
282 _E("dmcrypt setup device error(%d)", ret);
286 ret = _app2sd_dmcrypt_open_device(pkgid, temp_loopback_device, true,
289 _E("dmcrypt open device error");
296 int _app2sd_create_loopback_device(const char *pkgid,
297 const char *loopback_device, int size)
300 char command[FILENAME_MAX];
303 const char *argv[] = { "/bin/dd", "if=/dev/zero", command,
304 "bs=1M", buff, NULL };
306 if (pkgid == NULL || size <= 0) {
307 _E("invalid argument");
308 return APP2EXT_ERROR_INVALID_ARGUMENTS;
311 fp = fopen(loopback_device, "r+");
313 _W("encrypted file already exists (%s)", loopback_device);
315 return APP2EXT_ERROR_PKG_EXISTS;
318 snprintf(command, sizeof(command), "of=%s", loopback_device);
319 snprintf(buff, sizeof(buff), "count=%d", size);
321 ret = _xsystem(argv);
323 _E("command (%s) failed, ret(%d), errno(%d)",
324 command, ret, errno);
329 int _app2sd_delete_loopback_device(const char *loopback_device)
333 ret = unlink(loopback_device);
335 if (errno == ENOENT) {
336 _W("unable to access file (%s)", loopback_device);
338 _E("unable to delete (%s)", loopback_device);
339 return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
343 return APP2EXT_SUCCESS;
346 int _app2sd_create_file_system(const char *device_path)
352 const char *argv[] = { "/sbin/mkfs.ext4", device_path, NULL };
354 if (device_path == NULL) {
356 return APP2EXT_ERROR_INVALID_ARGUMENTS;
359 /* Format the filesystem [create a filesystem]*/
360 fp = fopen(device_path, "r+");
362 err_str = strerror_r(errno, err_buf, sizeof(err_buf));
363 _E("unable to access (%s) error is (%d, %s)",
364 device_path, errno, err_buf);
365 return APP2EXT_ERROR_ACCESS_FILE;
369 ret = _xsystem(argv);
371 err_str = strerror_r(errno, err_buf, sizeof(err_buf));
372 _E("creating file system failed, error is (%s)", err_str);
373 return APP2EXT_ERROR_CREATE_FS;
378 static int _app2sd_create_dir_with_link(const char *application_path,
379 const char *pkgid, const char *dir_name, uid_t uid)
382 char app_dir_mmc_path[FILENAME_MAX];
383 char app_dir_path[FILENAME_MAX];
385 snprintf(app_dir_mmc_path, sizeof(app_dir_mmc_path), "%s/.mmc/%s",
386 application_path, dir_name);
387 snprintf(app_dir_path, sizeof(app_dir_path), "%s/%s",
388 application_path, dir_name);
390 ret = _app2sd_make_directory(app_dir_mmc_path, uid);
392 _E("create directory failed");
393 return APP2EXT_ERROR_CREATE_DIRECTORY;
396 ret = symlink(app_dir_mmc_path, app_dir_path);
398 if (errno == EEXIST) {
399 _D("file with symlink name present (%s)", app_dir_path);
401 _E("symbolic link creation failed, error: %d", errno);
402 return APP2EXT_ERROR_CREATE_SYMLINK;
406 return APP2EXT_SUCCESS;
409 static int _app2sd_create_directory_entry(const char *application_path,
410 const char *pkgid, GList *dir_list, uid_t uid)
414 app2ext_dir_details *dir_detail;
416 for (list = g_list_first(dir_list); list; list = g_list_next(list)) {
417 dir_detail = (app2ext_dir_details *)list->data;
418 if (dir_detail == NULL || dir_detail->name == NULL ||
419 dir_detail->type != APP2EXT_DIR_RO)
421 ret = _app2sd_create_dir_with_link(application_path,
422 pkgid, dir_detail->name, uid);
426 return APP2EXT_SUCCESS;
429 int _app2sd_mount_app_content(const char *application_path, const char *pkgid,
430 const char *dev, int mount_type, GList *dir_list,
431 app2sd_cmd cmd, uid_t uid)
435 char app_mmc_path[FILENAME_MAX];
436 char temp_path[FILENAME_MAX];
439 struct timespec time = {
441 .tv_nsec = 1000 * 1000 * 200
443 char mountflags_str[BUF_SIZE];
444 const char *argv_mount[] = { "/bin/app2sd-mount-helper", dev,
445 app_mmc_path, FS_TYPE, mountflags_str, NULL };
448 _E("input param is NULL (%s)", dev);
449 return APP2EXT_ERROR_INVALID_ARGUMENTS;
452 /* check directory existence */
453 fd = open(application_path, O_RDONLY | O_DIRECTORY);
455 _E("path(%s) error(%d)", application_path, errno);
456 return APP2EXT_ERROR_OPEN_DIR;
460 snprintf(app_mmc_path, sizeof(app_mmc_path), "%s/.mmc",
462 fd = open(app_mmc_path, O_RDONLY | O_DIRECTORY);
464 _E("path(%s) error(%d)", app_mmc_path, errno);
465 return APP2EXT_ERROR_OPEN_DIR;
469 nanosleep(&time, NULL); /* 200ms sleep */
470 _D("give a delay for mount");
472 switch (mount_type) {
474 snprintf(mountflags_str, sizeof(mountflags_str), "%u",
475 MS_MGC_VAL | MS_RDONLY | MS_NOSUID);
476 ret = _xsystem(argv_mount);
478 _E("read only mount failed, errono is (%d), "
479 "dev is (%s) path is (%s)",
480 ret, dev, app_mmc_path);
481 ret = APP2EXT_ERROR_MOUNT;
485 snprintf(mountflags_str, sizeof(mountflags_str), "%u",
486 MS_MGC_VAL | MS_NOSUID);
487 ret = _xsystem(argv_mount);
489 _E("read write mount failed, errno is (%d)", ret);
490 ret = APP2EXT_ERROR_MOUNT;
493 case MOUNT_TYPE_RW_NOEXEC:
494 snprintf(mountflags_str, sizeof(mountflags_str), "%u",
495 MS_MGC_VAL | MS_NOEXEC | MS_NOSUID);
496 ret = _xsystem(argv_mount);
498 _E("rwnx mount failed errno is (%d)", ret);
499 ret = APP2EXT_ERROR_MOUNT;
502 case MOUNT_TYPE_RD_REMOUNT:
503 snprintf(mountflags_str, sizeof(mountflags_str), "%u",
504 MS_MGC_VAL | MS_RDONLY | MS_REMOUNT |
506 ret = _xsystem(argv_mount);
508 _E("read remount failed errno is (%d)", ret);
509 ret = APP2EXT_ERROR_MOUNT;
512 case MOUNT_TYPE_RW_REMOUNT:
513 snprintf(mountflags_str, sizeof(mountflags_str), "%u",
514 MS_MGC_VAL | MS_REMOUNT | MS_NOSUID);
515 ret = _xsystem(argv_mount);
516 err_str = strerror_r(ret, err_buf, sizeof(err_buf));
518 _E("read write remount failed errno(%d), errstr(%s)",
520 ret = APP2EXT_ERROR_MOUNT;
524 _E("invalid mount type");
528 if (cmd == APP2SD_PRE_INSTALL || cmd == APP2SD_MOVE_APP_TO_MMC ||
529 cmd == APP2SD_PRE_UPGRADE) {
530 ret = _app2sd_create_directory_entry(application_path,
531 pkgid, dir_list, uid);
534 if (mount_type != MOUNT_TYPE_RD &&
535 mount_type != MOUNT_TYPE_RD_REMOUNT) {
536 /* change lost+found permission */
537 snprintf(temp_path, sizeof(temp_path), "%s/lost+found",
539 ret = _app2sd_make_directory(temp_path, uid);
541 _E("create directory(%s) failed", temp_path);
542 return APP2EXT_ERROR_CREATE_DIRECTORY;
549 int _app2sd_unmount_app_content(const char *application_path)
552 char app_mmc_path[FILENAME_MAX];
556 snprintf(app_mmc_path, sizeof(app_mmc_path), "%s/.mmc",
558 ret = umount(app_mmc_path);
560 err_str = strerror_r(errno, err_buf, sizeof(err_buf));
561 _D("unable to umount the dir, ret(%d) error(%d, %s)",
562 ret, errno, err_str);
568 static int _app2sd_move_to_archive(const char *src_path, const char *arch_path)
574 ret = _app2sd_copy_dir(src_path, arch_path);
575 if (ret && ret != APP2EXT_ERROR_ACCESS_FILE) {
576 err_str = strerror_r(errno, err_buf, sizeof(err_buf));
577 _E("unable to copy from (%s) to (%s), err is (%s)",
578 src_path, arch_path, err_str);
579 return APP2EXT_ERROR_MOVE;
582 ret = _app2sd_delete_directory(src_path);
584 _E("unable to delete (%s)", src_path);
585 return APP2EXT_ERROR_DELETE_DIRECTORY;
591 static int _app2sd_move_app_to_external(const char *pkgid, GList *dir_list,
592 uid_t uid, char *mmc_path, char **image_path)
595 mode_t mode = DIR_PERMS;
596 char temp_dir_path[FILENAME_MAX];
597 char app_mmc_path[FILENAME_MAX];
598 char app_archive_path[FILENAME_MAX];
599 char application_path[FILENAME_MAX];
600 char loopback_device[FILENAME_MAX];
601 unsigned long long total_size = 0;
608 app2ext_dir_details *dir_detail;
612 ret = _app2sd_get_loopback_device_path(mmc_path, pkgid, uid,
613 loopback_device, sizeof(loopback_device));
617 _app2sd_set_application_path(pkgid, uid, application_path,
618 sizeof(application_path));
620 /* check whether application is in external memory or not */
621 fp = fopen(loopback_device, "r+");
623 _W("Already %s entry is present in the SD Card, "
624 "delete entry and go on without return", pkgid);
626 _app2sd_force_clean(pkgid, application_path, loopback_device,
630 snprintf(app_mmc_path, sizeof(app_mmc_path), "%s/.mmc",
632 snprintf(app_archive_path, sizeof(app_archive_path), "%s/.archive",
635 ret = mkdir(app_mmc_path, mode);
637 if (errno != EEXIST) {
638 _E("unable to create directory for archiving,"
639 " error(%d)", errno);
640 return APP2EXT_ERROR_CREATE_DIRECTORY;
644 ret = mkdir(app_archive_path, mode);
646 if (errno != EEXIST) {
647 _E("unable to create directory for archiving,"
648 " error(%d)", errno);
649 return APP2EXT_ERROR_CREATE_DIRECTORY;
653 for (list = g_list_first(dir_list); list; list = g_list_next(list)) {
654 dir_detail = (app2ext_dir_details *)list->data;
655 if (dir_detail == NULL || dir_detail->name == NULL ||
656 dir_detail->type != APP2EXT_DIR_RO)
658 snprintf(temp_dir_path, sizeof(temp_dir_path), "%s/%s",
659 application_path, dir_detail->name);
660 _D("cal size of app dirs, temp_dir_path(%s)", temp_dir_path);
661 total_size += _app2sd_calculate_dir_size(temp_dir_path);
664 reqd_size = ((total_size) / (1024 * 1024)) + 2;
665 reqd_disk_size = reqd_size + ceil(reqd_size * 0.2);
667 /* find avialable free memory in the MMC card */
668 ret = _app2sd_get_available_free_memory(mmc_path, &free_mmc_mem);
670 _E("unable to get available free memory in MMC (%d)", ret);
671 return APP2EXT_ERROR_MMC_STATUS;
673 /* if avaialalbe free memory in MMC is less than
674 * required size + 5MB, return error
676 if (reqd_disk_size > free_mmc_mem) {
677 _E("insufficient memory in MMC for "
678 "application installation (%d)", ret);
679 return APP2EXT_ERROR_MMC_INSUFFICIENT_MEMORY;
681 /* create a loopback device */
682 ret = _app2sd_create_loopback_device(pkgid, loopback_device,
683 (reqd_disk_size + PKG_BUF_SIZE));
685 _E("loopback node creation failed");
689 ret = _app2sd_dmcrypt_setup_device(pkgid, loopback_device, false, uid);
691 _E("dmcrypt setup device error(%d)", ret);
692 return APP2EXT_ERROR_SETUP_DMCRYPT_DEVICE;
695 ret = _app2sd_dmcrypt_open_device(pkgid, loopback_device, false,
698 _E("dmcrypt open device error");
699 return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
701 /* format the loopback file system */
702 ret = _app2sd_create_file_system(device_node);
704 _E("create ext4 filesystem failed");
705 ret = APP2EXT_ERROR_CREATE_FS;
709 for (list = g_list_first(dir_list); list; list = g_list_next(list)) {
710 dir_detail = (app2ext_dir_details *)list->data;
711 if (dir_detail == NULL || dir_detail->name == NULL ||
712 dir_detail->type != APP2EXT_DIR_RO)
714 snprintf(temp_dir_path, sizeof(temp_dir_path), "%s/%s",
715 application_path, dir_detail->name);
716 _D("app2archive, temp_dir_path(%s)", temp_dir_path);
717 ret = _app2sd_move_to_archive(temp_dir_path, app_archive_path);
719 _E("unable to copy from (%s) to (%s)",
720 temp_dir_path, app_archive_path);
725 /* mount the loopback encrypted pseudo device on
726 * application installation path as with Read Write permission
728 ret = _app2sd_mount_app_content(application_path, pkgid, device_node,
729 MOUNT_TYPE_RW, dir_list, APP2SD_MOVE_APP_TO_MMC, uid);
735 for (list = g_list_first(dir_list); list; list = g_list_next(list)) {
736 dir_detail = (app2ext_dir_details *)list->data;
737 if (dir_detail == NULL || dir_detail->name == NULL ||
738 dir_detail->type != APP2EXT_DIR_RO)
740 snprintf(temp_dir_path, sizeof(temp_dir_path), "%s/%s",
741 app_archive_path, dir_detail->name);
742 _D("archive2mmc, temp_dir_path(%s)", temp_dir_path);
743 ret = _app2sd_copy_dir(temp_dir_path, app_mmc_path);
745 if (ret == APP2EXT_ERROR_ACCESS_FILE) {
746 _E("unable to access (%s)", temp_dir_path);
748 err_str = strerror_r(errno, err_buf,
750 _E("unable to copy from (%s) to (%s),"
751 " error is (%s)", temp_dir_path,
752 app_mmc_path, err_str);
756 ret = _app2sd_delete_directory(temp_dir_path);
758 _E("unable to delete (%s)", temp_dir_path);
763 ret = _app2sd_delete_directory(app_archive_path);
765 _E("unable to delete (%s)", app_archive_path);
766 ret = APP2EXT_ERROR_DELETE_DIRECTORY;
770 *image_path = strdup(loopback_device);
771 return APP2EXT_SUCCESS;
781 static int _app2sd_move_app_to_internal(const char *pkgid, GList *dir_list,
782 uid_t uid, char *mmc_path)
785 mode_t mode = DIR_PERMS;
786 char temp_dir_path[FILENAME_MAX];
787 char app_mmc_path[FILENAME_MAX];
788 char app_archive_path[FILENAME_MAX];
789 char application_path[FILENAME_MAX];
790 char loopback_device[FILENAME_MAX];
794 app2ext_dir_details *dir_detail;
796 int free_internal_mem;
797 unsigned long long temp = 0;
802 ret = _app2sd_get_loopback_device_path(mmc_path, pkgid, uid,
803 loopback_device, sizeof(loopback_device));
807 _app2sd_set_application_path(pkgid, uid, application_path,
808 sizeof(application_path));
810 /* check whether application is in external memory or not */
811 fp = fopen(loopback_device, "r+");
813 _E("application (%s) is not installed on SD Card",
815 return APP2EXT_ERROR_FILE_ABSENT;
819 /* find avialable free memory in the internal storage */
820 ret = _app2sd_get_available_free_memory(INTERNAL_STORAGE_PATH,
823 _E("unable to get available free memory in internal (%d)", ret);
824 return APP2EXT_ERROR_MMC_STATUS;
827 fp = fopen(loopback_device, "r+");
829 _E("app entry is not present in SD card");
830 return APP2EXT_ERROR_INVALID_PACKAGE;
834 /* get installed app size*/
835 temp = _app2sd_calculate_file_size(loopback_device);
836 reqd_size = (int)((temp) / (1024 * 1024));
837 _D("reqd size is (%d)", reqd_size);
839 if (reqd_size == 0) {
840 _E("app entry is not present in SD Card");
841 return APP2EXT_ERROR_LOOPBACK_DEVICE_UNAVAILABLE;
844 _I("reqd size: (%d)MB, free internal mem: (%d)MB",
845 reqd_size, free_internal_mem);
847 /* if avaialalbe free memory in internal storage is
848 * less than required size, return error
850 if (reqd_size > free_internal_mem) {
851 _E("innsufficient memory in internal storage"
852 " for application installation (%d)", ret);
853 return APP2EXT_ERROR_MMC_INSUFFICIENT_MEMORY;
857 _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
858 if (device_node == NULL) {
859 /* do loopback setup */
860 ret = _app2sd_dmcrypt_open_device(pkgid, loopback_device,
861 false, uid, &device_node);
863 _E("dmcrypt open device error(%d)", ret);
864 return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
866 mount_type = MOUNT_TYPE_RW;
868 mount_type = MOUNT_TYPE_RW_REMOUNT;
871 ret = _app2sd_mount_app_content(application_path,
872 pkgid, device_node, mount_type,
873 dir_list, APP2SD_MOVE_APP_TO_PHONE, uid);
876 ret = APP2EXT_ERROR_MOUNT_PATH;
880 snprintf(app_mmc_path, sizeof(app_mmc_path), "%s/.mmc",
882 snprintf(app_archive_path, sizeof(app_archive_path), "%s/.archive",
885 ret = mkdir(app_archive_path, mode);
887 if (errno != EEXIST) {
888 _E("unable to create directory for archiving,"
889 " error(%d)", errno);
890 ret = APP2EXT_ERROR_CREATE_DIRECTORY;
895 for (list = g_list_first(dir_list); list; list = g_list_next(list)) {
896 dir_detail = (app2ext_dir_details *)list->data;
897 if (dir_detail == NULL || dir_detail->name == NULL ||
898 dir_detail->type != APP2EXT_DIR_RO)
901 snprintf(temp_dir_path, sizeof(temp_dir_path), "%s/%s",
902 app_mmc_path, dir_detail->name);
903 _D("mmc2archive, temp_dir_path(%s)", temp_dir_path);
904 ret = _app2sd_copy_dir(temp_dir_path, app_archive_path);
906 if (ret == APP2EXT_ERROR_ACCESS_FILE) {
907 _E("unable to access (%s)", temp_dir_path);
909 err_str = strerror_r(errno, err_buf,
911 _E("unable to copy from (%s) to (%s),"
912 "error is (%s)", temp_dir_path,
913 app_archive_path, err_str);
917 /* delete the symbolic link files [bin, lib, res]*/
918 snprintf(temp_dir_path, sizeof(temp_dir_path), "%s/%s",
919 application_path, dir_detail->name);
920 _D("unlink, temp_dir_path(%s)", temp_dir_path);
921 ret = unlink(temp_dir_path);
923 if (errno == ENOENT) {
924 _W("(%s) does not exist", temp_dir_path);
926 _E("unable to remove the symbolic link file "
927 "(%s), it is already unlinked",
932 /* Copy content to destination */
933 snprintf(temp_dir_path, sizeof(temp_dir_path), "%s/%s",
934 app_archive_path, dir_detail->name);
935 _D("archive2app, temp_dir_path(%s)", temp_dir_path);
936 ret = _app2sd_copy_dir(temp_dir_path, application_path);
938 if (ret == APP2EXT_ERROR_ACCESS_FILE) {
939 _E("unable to access (%s)", temp_dir_path);
941 err_str = strerror_r(errno, err_buf,
943 _E("unable to copy from (%s) to (%s), "
944 "error is (%s)", temp_dir_path,
945 application_path, err_str);
951 _D("copying file completed");
952 ret = _app2sd_unmount_app_content(application_path);
954 _E("unable to unmount SD directory for app (%s)", pkgid);
956 ret = _app2sd_dmcrypt_close_device(pkgid, uid);
958 _E("close dmcrypt device error(%d)", ret);
960 ret = _app2sd_delete_loopback_device(loopback_device);
962 _E("unable to delete the loopback device for (%s)", pkgid);
964 ret = _app2sd_delete_directory(app_mmc_path);
966 _E("unable to delete (%s)", app_mmc_path);
968 ret = _app2sd_delete_directory(app_archive_path);
970 _E("unable to delete (%s)", app_archive_path);
972 /* remove passwrd from DB */
973 ret = _app2sd_initialize_db();
975 _E("app2sd db initialize failed");
977 ret = _app2sd_remove_info_from_db(pkgid, uid);
979 _E("cannot remove info from db");
981 return APP2EXT_SUCCESS;
990 int _app2sd_usr_move_app(const char *pkgid, app2ext_move_type move_type,
991 GList *dir_list, uid_t uid, char *mmc_path, char **image_path)
996 case APP2EXT_MOVE_TO_EXT:
997 ret = _app2sd_move_app_to_external(pkgid, dir_list,
998 uid, mmc_path, image_path);
1000 _E("move app to external memory failed(%d)", ret);
1004 case APP2EXT_MOVE_TO_PHONE:
1005 ret = _app2sd_move_app_to_internal(pkgid, dir_list,
1008 _E("move app to internal memory failed(%d)", ret);
1013 _E("invalid argument");
1014 return APP2EXT_ERROR_INVALID_ARGUMENTS;
1020 int _app2sd_copy_ro_content(const char *src, const char *dest, GList *dir_list)
1022 char path[FILENAME_MAX];
1025 app2ext_dir_details *dir_detail;
1027 for (list = g_list_first(dir_list); list; list = g_list_next(list)) {
1028 dir_detail = (app2ext_dir_details *)list->data;
1029 if (dir_detail == NULL || dir_detail->name == NULL ||
1030 dir_detail->type != APP2EXT_DIR_RO)
1033 snprintf(path, sizeof(path), "%s/%s", src, dir_detail->name);
1034 ret = _app2sd_copy_dir(path, dest);
1036 if (ret == APP2EXT_ERROR_ACCESS_FILE) {
1037 _E("unable to access (%s)", path);
1039 _E("unable to copy from (%s) "
1040 "to (%s), errno is (%d)",
1042 return APP2EXT_ERROR_MOVE;
1047 return APP2EXT_SUCCESS;
1050 int _app2sd_duplicate_device(const char *pkgid, const char *loopback_device,
1051 const char *temp_pkgid, const char *temp_application_path,
1052 const char *temp_loopback_device, GList *dir_list,
1053 char *dev_node, int size, uid_t uid)
1058 /* create a new loopback device */
1059 ret = _app2sd_create_loopback_device(temp_pkgid,
1060 temp_loopback_device, (size + PKG_BUF_SIZE));
1062 _E("package already present");
1066 /* perform loopback encryption setup */
1067 dev_node = _app2sd_dmcrypt_duplicate_encryption_setup(pkgid,
1068 temp_loopback_device, uid);
1070 _E("dmcrypt duplicate encryption setup failed");
1071 _app2sd_delete_loopback_device(temp_loopback_device);
1072 return APP2EXT_ERROR_SETUP_DMCRYPT_DEVICE;
1075 /* format the loopback file system */
1076 ret = _app2sd_create_file_system(dev_node);
1078 _E("creating fs failed");
1079 err_res = APP2EXT_ERROR_CREATE_FS;
1082 _D("create filesystem SUCCESS");
1084 /* do mounting for new dev*/
1085 ret = _app2sd_mount_app_content(temp_application_path, pkgid,
1086 dev_node, MOUNT_TYPE_RW, dir_list,
1087 APP2SD_PRE_UPGRADE, uid);
1089 _E("remount failed");
1090 err_res = APP2EXT_ERROR_MOUNT_PATH;
1094 return APP2EXT_SUCCESS;
1098 ret = _app2sd_dmcrypt_close_device(temp_pkgid, uid);
1100 _E("close dmcrypt device error(%d)", ret);
1101 _app2sd_delete_loopback_device(temp_loopback_device);
1108 int _app2sd_update_loopback_device_size(const char *pkgid,
1109 const char *loopback_device, const char *application_path,
1110 const char *temp_pkgid, const char *temp_loopback_device,
1111 const char *temp_application_path, int size, GList *dir_list,
1115 char *old_device_node;
1117 char app_mmc_path[FILENAME_MAX];
1118 char temp_app_mmc_path[FILENAME_MAX];
1121 ret = _app2sd_duplicate_device(pkgid, loopback_device, temp_pkgid,
1122 temp_application_path, temp_loopback_device,
1123 dir_list, NULL, size, uid);
1125 _E("creating duplicate device failed");
1129 /* get the associated device node for SD card applicatione */
1131 _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
1132 if (old_device_node == NULL) {
1133 /* do loopback setup */
1134 ret = _app2sd_dmcrypt_open_device(pkgid, loopback_device,
1135 false, uid, &old_device_node);
1137 _E("dmcrypt open device error");
1138 err_res = APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
1141 mount_type = MOUNT_TYPE_RW;
1143 mount_type = MOUNT_TYPE_RW_REMOUNT;
1147 ret = _app2sd_mount_app_content(application_path, pkgid,
1148 old_device_node, mount_type, dir_list,
1149 APP2SD_PRE_UPGRADE, uid);
1151 _E("remount failed");
1152 err_res = APP2EXT_ERROR_MOUNT_PATH;
1155 snprintf(app_mmc_path, sizeof(app_mmc_path),
1156 "%s/.mmc", application_path);
1157 snprintf(temp_app_mmc_path, sizeof(temp_app_mmc_path),
1158 "%s/.mmc", temp_application_path);
1160 ret = _app2sd_copy_ro_content(app_mmc_path,
1161 temp_app_mmc_path, dir_list);
1163 _E("copy ro content failed");
1167 ret = _app2sd_unmount_app_content(application_path);
1169 _E("unable to unmount the SD application");
1170 err_res = APP2EXT_ERROR_UNMOUNT;
1173 ret = _app2sd_unmount_app_content(temp_application_path);
1175 _E("unable to unmount the SD application");
1176 err_res = APP2EXT_ERROR_UNMOUNT;
1180 ret = _app2sd_dmcrypt_close_device(pkgid, uid);
1182 _E("close dmcrypt device error(%d)", ret);
1183 err_res = APP2EXT_ERROR_CLOSE_DMCRYPT_DEVICE;
1187 ret = _app2sd_dmcrypt_close_device(temp_pkgid, uid);
1189 _E("close dmcrypt device error(%d)", ret);
1190 err_res = APP2EXT_ERROR_CLOSE_DMCRYPT_DEVICE;
1194 ret = _app2sd_delete_directory(loopback_device);
1196 _E("unable to delete (%s)", loopback_device);
1197 err_res = APP2EXT_ERROR_DELETE_DIRECTORY;
1201 ret = _app2sd_rename_dir(temp_loopback_device, loopback_device);
1203 _E("unable to rename (%s)", temp_loopback_device);
1204 err_res = APP2EXT_ERROR_MOVE;
1208 ret = _app2sd_delete_directory(temp_application_path);
1210 _E("unable to delete (%s)", temp_application_path);
1211 err_res = APP2EXT_ERROR_DELETE_DIRECTORY;
1215 return APP2EXT_SUCCESS;
1218 if (old_device_node)
1219 free(old_device_node);
1221 ret = _app2sd_dmcrypt_close_device(pkgid, uid);
1223 _E("close dmcrypt device error(%d)", ret);
1225 ret = _app2sd_dmcrypt_close_device(temp_pkgid, uid);
1227 _E("close dmcrypt device error(%d)", ret);
1229 _app2sd_delete_loopback_device(temp_loopback_device);
1231 ret = _app2sd_delete_directory(temp_application_path);
1233 _E("unable to delete (%s)", temp_application_path);
1238 int _app2sd_force_clean(const char *pkgid, const char *application_path,
1239 const char *loopback_device, uid_t uid)
1243 /* unmount the loopback encrypted pseudo device from
1244 * the application installation path
1246 ret = _app2sd_unmount_app_content(application_path);
1248 _W("unable to unmount the app content (%d)", ret);
1250 /* detach the loopback encryption setup for the application */
1251 ret = _app2sd_dmcrypt_close_device(pkgid, uid);
1253 _W("close dmcrypt device error (%d)", ret);
1255 /* delete the loopback device from the SD card */
1256 ret = _app2sd_delete_loopback_device(loopback_device);
1258 _W("unable to detach the loopback encryption setup for "
1261 /* delete symlink */
1262 _app2sd_delete_symlink(application_path);
1264 /* remove passwrd from DB */
1265 ret = _app2sd_initialize_db();
1267 _W("app2sd db initialize failed");
1269 ret = _app2sd_remove_info_from_db(pkgid, uid);
1271 _W("cannot remove info from db");