get mount path of sdcard using storage api instead of hard-coded path.
[platform/core/appfw/app2sd.git] / plugin / app2sd / src / app2sd_interface.c
1 /*
2  * app2ext
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Garima Shrivastava<garima.s@samsung.com>
7  *      Jyotsna Dhumale <jyotsna.a@samsung.com>
8  *      Venkatesha Sarpangala <sarpangala.v@samsung.com>
9  *
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
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
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.
21  *
22  */
23
24 #include <pkgmgr-info.h>
25 #include <aul.h>
26
27 #include "app2sd_internals.h"
28
29 static int __app2sd_create_app2sd_directories(uid_t uid, char *mmc_path)
30 {
31         int ret = 0;
32         char app2sd_path[FILENAME_MAX] = { 0, };
33         mode_t mode = DIR_PERMS;
34
35         snprintf(app2sd_path, FILENAME_MAX - 1, "%s/%s",
36                         mmc_path, EXTIMG_DIR);
37         ret = mkdir(app2sd_path, mode);
38         if (ret) {
39                 if (errno != EEXIST) {
40                         _E("create directory failed," \
41                                 " error no is (%d)", errno);
42                         return APP2EXT_ERROR_CREATE_DIRECTORY;
43                 }
44         }
45
46         return APP2EXT_SUCCESS;
47 }
48
49 int app2sd_usr_pre_app_install(const char *pkgid, GList *dir_list, int size, uid_t uid)
50 {
51         int ret = 0;
52         int free_mmc_mem = 0;
53         char *sdpath = NULL;
54         char *device_node = NULL;
55 #if !defined(TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION)
56         char *devi = NULL;
57         char *result = NULL;
58 #endif
59         char mmc_path[FILENAME_MAX] = { 0, };
60         char application_path[FILENAME_MAX] = { 0, };
61         char loopback_device[FILENAME_MAX] = { 0, };
62         char *encoded_id = NULL;
63         int reqd_disk_size = size + ceil(size * 0.2);
64
65         /* validate the function parameter recieved */
66         if (pkgid == NULL || dir_list == NULL || size <= 0) {
67                 _E("invalid function arguments");
68                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
69         }
70
71         /* check whether MMC is present or not */
72         ret = _app2sd_check_mmc_status(&sdpath);
73         if (ret) {
74                 _E("MMC not present OR Not ready (%d)", ret);
75                 return APP2EXT_ERROR_MMC_STATUS;
76         }
77         snprintf(mmc_path, FILENAME_MAX - 1, "%s", sdpath);
78         free(sdpath);
79         sync();
80
81         /* find available free memory in the MMC card */
82         ret = _app2sd_get_available_free_memory(mmc_path, &free_mmc_mem);
83         if (ret) {
84                 _E("unable to get available free memory in MMC (%d)", ret);
85                 return APP2EXT_ERROR_MMC_STATUS;
86         }
87         _D("size details for application installation:" \
88                 " size=(%d)MB, reqd_disk_size=(%d)MB, free_mmc_size=(%d)MB",
89                 size, reqd_disk_size, free_mmc_mem);
90
91         /* if avaialalbe free memory in MMC is less than required size + 5MB,
92          * return error
93          */
94         if ((reqd_disk_size + PKG_BUF_SIZE + MEM_BUF_SIZE) > free_mmc_mem) {
95                 _E("insufficient memory in MMC for"
96                         " application installation (%d)", ret);
97                 return APP2EXT_ERROR_MMC_INSUFFICIENT_MEMORY;
98         }
99
100         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
101         if (encoded_id == NULL)
102                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
103
104         if (_is_global(uid)) {
105                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
106                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
107                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
108                         mmc_path, EXTIMG_DIR, encoded_id);
109         } else {
110                 tzplatform_set_user(uid);
111                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
112                         tzplatform_getenv(TZ_USER_APP), pkgid);
113                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
114                         mmc_path, EXTIMG_DIR, encoded_id);
115                 tzplatform_reset_user();
116         }
117         free(encoded_id);
118
119         ret = __app2sd_create_app2sd_directories(uid, mmc_path);
120         if (ret) {
121                 _E("failed to create app2sd dirs");
122                 return ret;
123         }
124
125         /* create a loopback device */
126         ret = _app2sd_create_loopback_device(pkgid, loopback_device,
127                 (reqd_disk_size + PKG_BUF_SIZE));
128
129 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
130         ret = _app2sd_dmcrypt_setup_device(pkgid, loopback_device, false, uid);
131         if (ret) {
132                 _E("dmcrypt setup device error");
133                 return APP2EXT_ERROR_SETUP_DMCRYPT_DEVICE;
134         }
135
136         ret = _app2sd_dmcrypt_open_device(pkgid, loopback_device,
137                 false, uid, &device_node);
138         if (ret) {
139                 _E("dmcrypt open device error");
140                 return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
141         }
142 #else
143         /* perform loopback encryption setup */
144         device_node = _app2sd_do_loopback_encryption_setup(pkgid,
145                 loopback_device, uid);
146         if (!device_node) {
147                 _E("loopback encryption setup failed");
148                 _app2sd_delete_loopback_device(loopback_device);
149                 return APP2EXT_ERROR_DO_LOSETUP;
150         }
151
152         /* check whether loopback device is associated
153          * with device node or not
154          */
155         devi = _app2sd_find_associated_device_node(loopback_device);
156         if (devi == NULL) {
157                 _E("finding associated device node failed");
158                 ret = APP2EXT_ERROR_DO_LOSETUP;
159                 goto FINISH_OFF;
160         }
161 #endif
162
163         /* format the loopback file system */
164         ret = _app2sd_create_file_system(device_node);
165         if (ret) {
166                 _E("creating FS failed failed");
167                 ret = APP2EXT_ERROR_CREATE_FS;
168                 goto FINISH_OFF;
169         }
170
171         /* mount the loopback encrypted pseudo device on application
172          * installation path as with Read Write permission
173          */
174         ret = _app2sd_mount_app_content(application_path, pkgid,
175                 device_node, MOUNT_TYPE_RW, dir_list,
176                 APP2SD_PRE_INSTALL, uid);
177         if (ret) {
178                 _E("mounting dev path to app install path failed");
179                 ret = APP2EXT_ERROR_MOUNT_PATH;
180                 goto FINISH_OFF;
181         }
182
183         /* Success */
184         ret = APP2EXT_SUCCESS;
185         goto END;
186
187 FINISH_OFF:
188         if (device_node) {
189 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
190         ret = _app2sd_dmcrypt_close_device(pkgid, uid);
191         if (ret)
192                 _E("close dmcrypt device error(%d)", ret);
193         _app2sd_delete_loopback_device(loopback_device);
194 #else
195                 result = _app2sd_detach_loop_device(device_node);
196                 if (result) {
197                         free(result);
198                         result = NULL;
199                 }
200                 _app2sd_delete_loopback_device(loopback_device);
201 #endif
202         }
203
204 END:
205         if (device_node) {
206                 free(device_node);
207                 device_node = NULL;
208         }
209
210 #if !defined(TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION)
211         if (devi) {
212                 free(devi);
213                 devi = NULL;
214         }
215 #endif
216
217         sync();
218         return ret;
219 }
220
221 int app2sd_usr_post_app_install(const char *pkgid,
222                 app2ext_status install_status, uid_t uid)
223 {
224         char *device_name = NULL;
225         char *sdpath = NULL;
226         char mmc_path[FILENAME_MAX] = { 0, };
227         char application_path[FILENAME_MAX] = { 0, };
228         char application_mmc_path[FILENAME_MAX] = { 0, };
229         char loopback_device[FILENAME_MAX] = { 0, };
230         char *encoded_id = NULL;
231         int ret = APP2EXT_SUCCESS;
232         int pkgmgr_ret = 0;
233
234         /* validate the function parameter recieved */
235         if (pkgid == NULL || install_status < APP2EXT_STATUS_FAILED
236                 || install_status > APP2EXT_STATUS_SUCCESS) {
237                 _E("invalid func parameters");
238                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
239         }
240
241         /* check whether MMC is present or not */
242         ret = _app2sd_check_mmc_status(&sdpath);
243         if (ret) {
244                 _E("MMC not present OR Not ready (%d)", ret);
245                 return APP2EXT_ERROR_MMC_STATUS;
246         }
247         snprintf(mmc_path, FILENAME_MAX - 1, "%s", sdpath);
248         free(sdpath);
249         sync();
250
251         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
252         if (encoded_id == NULL)
253                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
254
255         if (_is_global(uid)) {
256                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
257                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
258                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
259                         mmc_path, EXTIMG_DIR, encoded_id);
260         } else {
261                 tzplatform_set_user(uid);
262                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
263                         tzplatform_getenv(TZ_USER_APP), pkgid);
264                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
265                         mmc_path, EXTIMG_DIR, encoded_id);
266                 tzplatform_reset_user();
267         }
268         free(encoded_id);
269         snprintf(application_mmc_path, FILENAME_MAX - 1, "%s/.mmc",
270                 application_path);
271
272         /* get the associated device node for SD card applicationer */
273 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
274         device_name =
275                 _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
276         if (!device_name)
277                 return APP2EXT_ERROR_FIND_ASSOCIATED_DMCRYPT_DEVICE_NODE;
278 #else
279         device_name = _app2sd_find_associated_device_node(loopback_device);
280         if (NULL == device_name)
281                 return APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_NODE;
282 #endif
283
284         ret = _app2sd_unmount_app_content(application_path);
285         if (ret) {
286                 if (device_name) {
287                         free(device_name);
288                         device_name = NULL;
289                 }
290                 _E("unable to unmount the app content (%d)", ret);
291                 return APP2EXT_ERROR_UNMOUNT;
292         }
293
294 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
295         ret = _app2sd_dmcrypt_close_device(pkgid, uid);
296         if (ret) {
297                 if (device_name) {
298                         free(device_name);
299                         device_name = NULL;
300                 }
301                 _E("close dmcrypt device error(%d)", ret);
302                 return ret;
303         }
304 #else
305         ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
306         if (ret) {
307                 if (device_name) {
308                         free(device_name);
309                         device_name = NULL;
310                 }
311                 _E("unable to detach the loopback encryption setup" \
312                         " for the application");
313                 return APP2EXT_ERROR_UNMOUNT;
314         }
315 #endif
316
317         if (device_name) {
318                 free(device_name);
319                 device_name = NULL;
320         }
321
322         /* take appropriate action based on
323          * installation status of application package
324          */
325         if (install_status == APP2EXT_STATUS_FAILED) {
326                 /* delete the loopback device from the SD card */
327                 ret = _app2sd_delete_loopback_device(loopback_device);
328                 if (ret) {
329                         _E("unable to delete the loopback device from the SD Card");
330                         return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
331                 }
332                 ret = _app2sd_remove_info_from_db(pkgid, uid);
333                 if (ret)
334                         _E("unable to delete info");
335
336                 ret = _app2sd_delete_directory(application_mmc_path);
337                 if (ret)
338                         _E("unable to delete the directory (%s)", application_path);
339         } else {
340                 /* if the status is success, then update installed storage
341                  * to pkgmgr_parser db
342                  */
343                 pkgmgr_ret = pkgmgrinfo_pkginfo_set_usr_installed_storage(pkgid,
344                         INSTALL_EXTERNAL, uid);
345                 if (pkgmgr_ret < 0) {
346                         _E("fail to update installed location " \
347                                 "to db[%s, %d] of uid(%d), pkgmgr ret(%d)",
348                                 pkgid, INSTALL_EXTERNAL, uid, pkgmgr_ret);
349                         return APP2EXT_ERROR_PKGMGR_ERROR;
350                 }
351         }
352
353         sync();
354         return ret;
355 }
356
357 int app2sd_usr_on_demand_setup_init(const char *pkgid, uid_t uid)
358 {
359         int ret = APP2EXT_SUCCESS;
360         char mmc_path[FILENAME_MAX] = { 0, };
361         char application_path[FILENAME_MAX] = { 0, };
362         char loopback_device[FILENAME_MAX] = { 0, };
363         char *sdpath = NULL;
364         char *encoded_id = NULL;
365         char *device_node = NULL;
366 #if !defined(TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION)
367         char *result = NULL;
368 #endif
369         FILE *fp = NULL;
370
371         /* validate the function parameter recieved */
372         if (pkgid == NULL) {
373                 _E("invalid function arguments to app launch setup");
374                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
375         }
376
377         /* check whether MMC is present or not */
378         ret = _app2sd_check_mmc_status(&sdpath);
379         if (ret) {
380                 _E("MMC not present OR Not ready (%d)", ret);
381                 return APP2EXT_ERROR_MMC_STATUS;
382         }
383         snprintf(mmc_path, FILENAME_MAX - 1, "%s", sdpath);
384         free(sdpath);
385
386         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
387         if (encoded_id == NULL)
388                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
389
390         /* check app entry is there in sd card or not. */
391         if (_is_global(uid)) {
392                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
393                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
394                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
395                         mmc_path, EXTIMG_DIR, encoded_id);
396         } else {
397                 tzplatform_set_user(uid);
398                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
399                         tzplatform_getenv(TZ_USER_APP), pkgid);
400                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
401                         mmc_path, EXTIMG_DIR, encoded_id);
402                 tzplatform_reset_user();
403         }
404         free(encoded_id);
405
406         fp = fopen(loopback_device, "r+");
407         if (fp == NULL) {
408                 _E("app entry is not present in SD Card");
409                 return APP2EXT_ERROR_INVALID_PACKAGE;
410         }
411         fclose(fp);
412
413 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
414         device_node =
415                 _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
416         if (device_node) {
417                 _E("device_node(%s_%d) already associated", pkgid, uid);
418                 return APP2EXT_ERROR_ALREADY_MOUNTED;
419         }
420
421         ret = _app2sd_dmcrypt_open_device(pkgid, loopback_device,
422                 false, uid, &device_node);
423         if (ret) {
424                 _E("dmcrypt open device error(%d)", ret);
425                 return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
426         }
427 #else
428         result = (char *)_app2sd_find_associated_device(loopback_device);
429         /* process the string */
430         if ((result != NULL) && strstr(result, "/dev") != NULL) {
431                 _E("already associated");
432                 free(result);
433                 result = NULL;
434                 return APP2EXT_ERROR_ALREADY_MOUNTED;
435         }
436
437         /* do loopback setup */
438         device_node = _app2sd_do_loopback_encryption_setup(pkgid,
439                 loopback_device, uid);
440         if (device_node == NULL) {
441                 _E("loopback encryption setup failed");
442                 return APP2EXT_ERROR_DO_LOSETUP;
443         }
444 #endif
445
446         /* do mounting */
447         ret = _app2sd_mount_app_content(application_path, pkgid,
448                 device_node, MOUNT_TYPE_RD, NULL, APP2SD_APP_LAUNCH, uid);
449         if (ret) {
450                 _E("mount failed");
451                 if (device_node) {
452                         free(device_node);
453                         device_node = NULL;
454                 }
455                 return APP2EXT_ERROR_MOUNT_PATH;
456         }
457
458         if (device_node) {
459                 free(device_node);
460                 device_node = NULL;
461         }
462
463         return ret;
464 }
465
466 static int _app2sd_application_handler(const pkgmgrinfo_appinfo_h handle, void *data)
467 {
468         int ret = 0;
469         int pid = 0;
470         char *appid = NULL;
471         uid_t uid = *(uid_t *)data;
472
473         ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
474         if (ret < 0) {
475                 _E("failed to get appid");
476                 return APP2EXT_ERROR_PKGMGR_ERROR;
477         }
478
479         _D("appid(%s), uid(%d)", appid, uid);
480
481         ret = aul_app_is_running_for_uid(appid, uid);
482         if (ret == 0)
483                 return APP2EXT_SUCCESS;
484
485         pid = aul_app_get_pid_for_uid(appid, uid);
486         if (pid < 0) {
487                 _E("failed to get pid");
488                 return APP2EXT_ERROR_KILLAPP_ERROR;
489         }
490
491         ret = aul_terminate_pid_sync_for_uid(pid, uid);
492         if (ret != AUL_R_OK) {
493                 _E("failed to kill app");
494                 return APP2EXT_ERROR_KILLAPP_ERROR;
495         }
496
497         return APP2EXT_SUCCESS;
498 }
499
500 static int _app2sd_kill_running_app(const char *pkgid, uid_t uid)
501 {
502         int ret = 0;
503         pkgmgrinfo_pkginfo_h handle;
504
505         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &handle);
506         if (ret < 0) {
507                 _E("failed to get pkginfo");
508                 return APP2EXT_ERROR_PKGMGR_ERROR;
509         }
510
511         ret = pkgmgrinfo_appinfo_get_usr_list(handle,
512                 PMINFO_ALL_APP, _app2sd_application_handler, &uid, uid);
513         if (ret < 0) {
514                 _E("failed to get appinfo");
515                 return APP2EXT_ERROR_PKGMGR_ERROR;
516         }
517
518         ret = pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
519         if (ret < 0) {
520                 _E("failed to destroy pkginfo");
521                 return APP2EXT_ERROR_PKGMGR_ERROR;
522         }
523
524         return APP2EXT_SUCCESS;
525 }
526
527 int app2sd_usr_on_demand_setup_exit(const char *pkgid, uid_t uid)
528 {
529         int ret = APP2EXT_SUCCESS;
530         char mmc_path[FILENAME_MAX] = { 0, };
531         char application_path[FILENAME_MAX] = { 0, };
532         char loopback_device[FILENAME_MAX] = { 0, };
533         char *sdpath = NULL;
534         char *encoded_id = NULL;
535         FILE *fp = NULL;
536         int mmc_present = 1;
537
538         /* validate the function parameter recieved */
539         if (pkgid == NULL) {
540                 _E("invalid function arguments to app launch setup");
541                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
542         }
543
544         _app2sd_kill_running_app(pkgid, uid);
545
546         /* check whether MMC is present or not */
547         ret = _app2sd_check_mmc_status(&sdpath);
548         if (ret) {
549                 _W("MMC not present OR Not ready (%d)", ret);
550                 mmc_present = 0;
551         }
552         snprintf(mmc_path, FILENAME_MAX - 1, "%s", sdpath);
553         free(sdpath);
554
555         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
556         if (encoded_id == NULL)
557                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
558
559         /* check app entry is there in sd card or not. */
560         if (_is_global(uid)) {
561                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
562                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
563                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
564                         mmc_path, EXTIMG_DIR, encoded_id);
565         } else {
566                 tzplatform_set_user(uid);
567                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
568                         tzplatform_getenv(TZ_USER_APP), pkgid);
569                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
570                         mmc_path, EXTIMG_DIR, encoded_id);
571                 tzplatform_reset_user();
572         }
573         free(encoded_id);
574
575         if (mmc_present) {
576                 fp = fopen(loopback_device, "r+");
577                 if (fp == NULL) {
578                         _E("app entry is not present in SD Card");
579                         return APP2EXT_ERROR_INVALID_PACKAGE;
580                 }
581                 fclose(fp);
582         }
583
584         ret = _app2sd_unmount_app_content(application_path);
585         if (ret) {
586                 _E("unable to unmount the SD application");
587                 return APP2EXT_ERROR_UNMOUNT;
588         }
589
590 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
591         ret = _app2sd_dmcrypt_close_device(pkgid, uid);
592         if (ret)
593                 _E("close dmcrypt device error(%d)", ret);
594 #else
595         ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
596         if (ret) {
597                 _E("unable to remove loopback setup");
598                 return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
599         }
600 #endif
601
602         return ret;
603 }
604
605 int app2sd_usr_pre_app_uninstall(const char *pkgid, uid_t uid)
606 {
607         int ret = APP2EXT_SUCCESS;
608         char mmc_path[FILENAME_MAX] = { 0, };
609         char application_path[FILENAME_MAX] = { 0, };
610         char loopback_device[FILENAME_MAX] = { 0, };
611         char *sdpath = NULL;
612         char *encoded_id = NULL;
613         char *device_node = NULL;
614         FILE *fp = NULL;
615
616         /* validate the function parameter recieved */
617         if (pkgid == NULL) {
618                 _E("invalid function arguments to app launch setup");
619                 ret = APP2EXT_ERROR_INVALID_ARGUMENTS;
620                 goto END;
621         }
622
623         /* check whether MMC is present or not */
624         ret = _app2sd_check_mmc_status(&sdpath);
625         if (ret) {
626                 _E("MMC not present OR Not ready (%d)", ret);
627                 ret = APP2EXT_ERROR_MMC_STATUS;
628                 goto END;
629         }
630         snprintf(mmc_path, FILENAME_MAX - 1, "%s", sdpath);
631         free(sdpath);
632         sync();
633
634         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
635         if (encoded_id == NULL)
636                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
637
638         if (_is_global(uid)) {
639                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
640                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
641                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
642                         mmc_path, EXTIMG_DIR, encoded_id);
643         } else {
644                 tzplatform_set_user(uid);
645                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
646                         tzplatform_getenv(TZ_USER_APP), pkgid);
647                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
648                         mmc_path, EXTIMG_DIR, encoded_id);
649                 tzplatform_reset_user();
650         }
651         free(encoded_id);
652
653         /* check app entry is there in sd card or not. */
654         fp = fopen(loopback_device, "r+");
655         if (fp == NULL) {
656                 _E("app entry is not present in SD Card");
657                 ret = APP2EXT_ERROR_INVALID_PACKAGE;
658                 goto END;
659         }
660         fclose(fp);
661
662         /* get the associated device node for SD card applicationer */
663 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
664         device_node =
665                 _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
666 #else
667         device_node = _app2sd_find_associated_device_node(loopback_device);
668 #endif
669         if (NULL == device_node) {
670                 /* do loopback setup */
671 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
672                 ret = _app2sd_dmcrypt_open_device(pkgid, loopback_device,
673                         false, uid, &device_node);
674                 if (ret) {
675                         _E("dmcrypt open device error(%d)", ret);
676                         return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
677                 }
678 #else
679                 device_node = _app2sd_do_loopback_encryption_setup(pkgid,
680                         loopback_device, uid);
681                 if (device_node == NULL) {
682                         _E("loopback encryption setup failed");
683                         ret = APP2EXT_ERROR_DO_LOSETUP;
684                         goto END;
685                 }
686 #endif
687                 /* do mounting */
688                 ret = _app2sd_mount_app_content(application_path, pkgid,
689                         device_node, MOUNT_TYPE_RW, NULL,
690                         APP2SD_PRE_UNINSTALL, uid);
691                 if (ret) {
692                         _E("mount failed");
693                         if (device_node) {
694                                 free(device_node);
695                                 device_node = NULL;
696                         }
697                         ret = APP2EXT_ERROR_MOUNT_PATH;
698                         goto END;
699                 }
700         } else {
701                 /* do re-mounting */
702                 ret = _app2sd_mount_app_content(application_path, pkgid,
703                         device_node, MOUNT_TYPE_RW_REMOUNT, NULL,
704                         APP2SD_PRE_UNINSTALL, uid);
705                 if (ret) {
706                         _E("remount failed");
707                         if (device_node) {
708                                 free(device_node);
709                                 device_node = NULL;
710                         }
711                         ret = APP2EXT_ERROR_MOUNT_PATH;
712                         goto END;
713                 }
714         }
715         if (device_node) {
716                 free(device_node);
717                 device_node = NULL;
718         }
719
720 END:
721         sync();
722         return ret;
723 }
724
725 int app2sd_usr_post_app_uninstall(const char *pkgid, uid_t uid)
726 {
727         char mmc_path[FILENAME_MAX] = { 0, };
728         char application_path[FILENAME_MAX] = { 0, };
729         char application_mmc_path[FILENAME_MAX] = { 0, };
730         char loopback_device[FILENAME_MAX] = { 0, };
731         char *sdpath = NULL;
732         char *encoded_id = NULL;
733         int ret = APP2EXT_SUCCESS;
734
735         /* validate the function parameter recieved */
736         if (pkgid == NULL) {
737                 _E("invalid function arguments");
738                 ret = APP2EXT_ERROR_INVALID_ARGUMENTS;
739                 goto END;
740         }
741
742         /* check whether MMC is present or not */
743         ret = _app2sd_check_mmc_status(&sdpath);
744         if (ret) {
745                 _E("MMC not present OR Not ready (%d)", ret);
746                 ret = APP2EXT_ERROR_MMC_STATUS;
747                 goto END;
748         }
749         snprintf(mmc_path, FILENAME_MAX - 1, "%s", sdpath);
750         free(sdpath);
751         sync();
752
753         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
754         if (encoded_id == NULL)
755                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
756
757         if (_is_global(uid)) {
758                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
759                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
760                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
761                         mmc_path, EXTIMG_DIR, encoded_id);
762         } else {
763                 tzplatform_set_user(uid);
764                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
765                         tzplatform_getenv(TZ_USER_APP), pkgid);
766                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
767                         mmc_path, EXTIMG_DIR, encoded_id);
768                 tzplatform_reset_user();
769         }
770         free(encoded_id);
771         snprintf(application_mmc_path, FILENAME_MAX - 1, "%s/.mmc",
772                 application_path);
773
774         /* unmount the loopback encrypted pseudo device from
775          * the application installation path
776          */
777         ret = _app2sd_unmount_app_content(application_path);
778         if (ret) {
779                 _E("unable to unmount the app content (%d)", ret);
780                 ret = APP2EXT_ERROR_UNMOUNT;
781                 goto END;
782         }
783         /* detach the loopback encryption setup for the application */
784 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
785         ret = _app2sd_dmcrypt_close_device(pkgid, uid);
786         if (ret) {
787                 _E("close dmcrypt device error(%d)", ret);
788                 goto END;
789         }
790 #else
791         ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
792         if (ret) {
793                 _E("unable to Detach the loopback encryption setup" \
794                         " for the application");
795                 ret = APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE;
796                 goto END;
797         }
798 #endif
799
800         /* delete the loopback device from the SD card */
801         ret = _app2sd_delete_loopback_device(loopback_device);
802         if (ret) {
803                 _E("unable to delete the " \
804                         "loopback device from the SD Card");
805                 ret =  APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
806                 goto END;
807         }
808
809         ret = _app2sd_delete_directory(application_mmc_path);
810         if (ret) {
811                 _E("unable to delete the directory (%s)",
812                 application_path);
813                 goto END;
814         }
815
816         /* remove encryption password from DB */
817         ret = _app2sd_initialize_db();
818         if (ret) {
819                 _E("app2sd db initialize failed");
820                 ret = APP2EXT_ERROR_SQLITE_REGISTRY;
821                 goto END;
822         }
823
824         ret = _app2sd_remove_info_from_db(pkgid, uid);
825         if (ret) {
826                 _E("cannot remove info from db");
827                 ret = APP2EXT_ERROR_SQLITE_REGISTRY;
828                 goto END;
829         }
830
831 END:
832         sync();
833         return ret;
834 }
835
836 int app2sd_usr_pre_move_installed_app(const char *pkgid,
837                 GList *dir_list, app2ext_move_type move_type, uid_t uid)
838 {
839         int ret = 0;
840         int pkgmgr_ret = 0;
841         char *sdpath = NULL;
842         char mmc_path[FILENAME_MAX] = { 0, };
843
844         /* validate function arguments */
845         if (pkgid == NULL || dir_list == NULL
846                 || move_type < APP2EXT_MOVE_TO_EXT
847                 || move_type > APP2EXT_MOVE_TO_PHONE) {
848                 _E("invalid function arguments");
849                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
850         }
851
852         /* check whether MMC is present or not */
853         ret = _app2sd_check_mmc_status(&sdpath);
854         if (ret) {
855                 _E("MMC not present OR Not ready(%d)", ret);
856                 return APP2EXT_ERROR_MMC_STATUS;
857         }
858         snprintf(mmc_path, FILENAME_MAX - 1, "%s", sdpath);
859         free(sdpath);
860         sync();
861
862         ret = __app2sd_create_app2sd_directories(uid, mmc_path);
863         if (ret) {
864                 _E("failed to create app2sd dirs");
865                 return ret;
866         }
867
868         ret = _app2sd_usr_move_app(pkgid, move_type, dir_list, uid, mmc_path);
869         if (ret) {
870                 _D("unable to move application");
871                 return ret;
872         }
873
874         /* if move is completed, then update installed storage to pkgmgr_parser db */
875         if (move_type == APP2EXT_MOVE_TO_EXT) {
876                 pkgmgr_ret = pkgmgrinfo_pkginfo_set_usr_installed_storage(pkgid,
877                                 INSTALL_EXTERNAL, uid);
878                 if (pkgmgr_ret < 0) {
879                         _E("failed to update installed location to db " \
880                                 "[%s, %s] of uid(%d), pkgmgr_ret(%d)",
881                                 pkgid, INSTALL_EXTERNAL, uid, pkgmgr_ret);
882                         return APP2EXT_ERROR_PKGMGR_ERROR;
883                 }
884         } else {
885                 pkgmgr_ret = pkgmgrinfo_pkginfo_set_usr_installed_storage(pkgid,
886                                 INSTALL_INTERNAL, uid);
887                 if (pkgmgr_ret < 0) {
888                         _E("failed to update installed location to db " \
889                                 "[%s, %s] of uid(%d), pkgmgr_ret(%d)",
890                                 pkgid, INSTALL_INTERNAL, uid, pkgmgr_ret);
891                         return APP2EXT_ERROR_PKGMGR_ERROR;
892                 }
893         }
894
895         sync();
896         return APP2EXT_SUCCESS;
897 }
898
899 int app2sd_usr_post_move_installed_app(const char *pkgid,
900                 app2ext_move_type move_type, uid_t uid)
901 {
902         int ret = 0;
903         char mmc_path[FILENAME_MAX] = { 0, };
904         char application_path[FILENAME_MAX] = { 0, };
905         char loopback_device[FILENAME_MAX] = { 0, };
906         char *sdpath = NULL;
907         char *encoded_id = NULL;
908
909         /* validate function arguments */
910         if (pkgid == NULL || move_type < APP2EXT_MOVE_TO_EXT
911                 || move_type > APP2EXT_MOVE_TO_PHONE) {
912                 _E("invalid function arguments");
913                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
914         }
915
916         if (move_type == APP2EXT_MOVE_TO_PHONE)
917                 return APP2EXT_SUCCESS;
918
919         /* check whether MMC is present or not */
920         ret = _app2sd_check_mmc_status(&sdpath);
921         if (ret) {
922                 _E("MMC not present OR Not ready(%d)", ret);
923                 return APP2EXT_ERROR_MMC_STATUS;
924         }
925         snprintf(mmc_path, FILENAME_MAX - 1, "%s", sdpath);
926         free(sdpath);
927         sync();
928
929         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
930         if (encoded_id == NULL)
931                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
932
933         snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
934                         mmc_path, EXTIMG_DIR, encoded_id);
935         free(encoded_id);
936         if (_is_global(uid)) {
937                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
938                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
939         } else {
940                 tzplatform_set_user(uid);
941                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
942                         tzplatform_getenv(TZ_USER_APP), pkgid);
943                 tzplatform_reset_user();
944         }
945
946         ret = _app2sd_unmount_app_content(application_path);
947         if (ret)
948                 _E("unmount error (%d)", ret);
949
950 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
951         ret = _app2sd_dmcrypt_close_device(pkgid, uid);
952         if (ret)
953                 _E("close dmcrypt device error(%d)", ret);
954 #else
955         ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
956         if (ret)
957                 _E("unable to detach loopback setup for (%s)",
958                         loopback_device);
959 #endif
960
961         sync();
962         return APP2EXT_SUCCESS;
963 }
964
965 int app2sd_usr_pre_app_upgrade(const char *pkgid, GList *dir_list,
966                 int size, uid_t uid)
967 {
968         int ret = APP2EXT_SUCCESS;
969         char app2sd_path[FILENAME_MAX] = { 0, };
970         char loopback_device[FILENAME_MAX] = { 0, };
971         char application_path[FILENAME_MAX] = { 0, };
972         char temp_uid[32] = { 0, };
973         char *sdpath = NULL;
974         char *temp_pkgid = NULL;
975         char *temp_loopback_device = NULL;
976         char *temp_application_path = NULL;
977         char *device_node = NULL;
978         char *encoded_id = NULL;
979         char *temp_encoded_id = NULL;
980         int len = 0;
981         unsigned long long curr_size = 0;
982         FILE *fp = NULL;
983         int reqd_disk_size = size + ceil(size * 0.2);
984
985         /* validate function arguments*/
986         if (pkgid == NULL || dir_list == NULL || size <= 0) {
987                 _E("invalid function arguments");
988                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
989         }
990
991         /* check whether MMC is present or not */
992         ret = _app2sd_check_mmc_status(&sdpath);
993         if (ret) {
994                 _E("MMC not present OR Not ready (%d)", ret);
995                 return APP2EXT_ERROR_MMC_STATUS;
996         }
997         snprintf(app2sd_path, FILENAME_MAX - 1, "%s/%s",
998                         sdpath, EXTIMG_DIR);
999         free(sdpath);
1000         sync();
1001
1002         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
1003         if (encoded_id == NULL)
1004                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1005
1006         if (_is_global(uid)) {
1007                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1008                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
1009                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
1010                         app2sd_path, encoded_id);
1011         } else {
1012                 tzplatform_set_user(uid);
1013                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1014                         tzplatform_getenv(TZ_USER_APP), pkgid);
1015                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
1016                         app2sd_path, encoded_id);
1017                 tzplatform_reset_user();
1018         }
1019         free(encoded_id);
1020
1021         /* check app entry is there in sd card or not. */
1022         fp = fopen(loopback_device, "r+");
1023         if (fp == NULL) {
1024                 _E("app entry is not present in SD Card");
1025                 return APP2EXT_ERROR_INVALID_PACKAGE;
1026         }
1027         fclose(fp);
1028
1029         /* get installed app size*/
1030         curr_size = _app2sd_calculate_file_size(loopback_device);
1031         curr_size = (curr_size) / (1024 * 1024);
1032         if (curr_size == 0) {
1033                 _E("app entry is not present in SD Card");
1034                 return APP2EXT_ERROR_LOOPBACK_DEVICE_UNAVAILABLE;
1035         }
1036         if ((int)curr_size < reqd_disk_size) {
1037                 len = strlen(pkgid) + strlen(".new");
1038                 temp_pkgid = calloc(len + 1, sizeof(char));
1039                 if (temp_pkgid == NULL) {
1040                         _E("memory alloc failed");
1041                         return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1042                 }
1043                 snprintf(temp_pkgid, len + 1, "%s.new", pkgid);
1044
1045                 if (_is_global(uid)) {
1046                         len = strlen(tzplatform_getenv(TZ_SYS_RW_APP)) + strlen(temp_pkgid) + 1;
1047                         temp_application_path = calloc(len + 1, sizeof(char));
1048                         if (temp_application_path == NULL) {
1049                                 _E("memory alloc failed");
1050                                 free(temp_pkgid);
1051                                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1052                         }
1053                         snprintf(temp_application_path, len + 1, "%s/%s",
1054                                 tzplatform_getenv(TZ_SYS_RW_APP), temp_pkgid);
1055
1056                         temp_encoded_id = _app2sd_get_encoded_name((const char *)temp_pkgid, uid);
1057                         if (temp_encoded_id == NULL) {
1058                                 free(temp_pkgid);
1059                                 free(temp_application_path);
1060                                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1061                         }
1062                         len = strlen(app2sd_path) + strlen(temp_encoded_id) + 1;
1063                         temp_loopback_device = calloc(len + 1, sizeof(char));
1064                         if (temp_loopback_device == NULL) {
1065                                 _E("memory alloc failed");
1066                                 free(temp_pkgid);
1067                                 free(temp_application_path);
1068                                 free(temp_encoded_id);
1069                                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1070                         }
1071                         snprintf(temp_loopback_device, len + 1, "%s/%s",
1072                                 app2sd_path, temp_encoded_id);
1073                         free(temp_encoded_id);
1074                 } else {
1075                         tzplatform_set_user(uid);
1076                         len = strlen(tzplatform_getenv(TZ_USER_APP)) + strlen(temp_pkgid) + 1;
1077                         temp_application_path = calloc(len + 1, sizeof(char));
1078                         if (temp_application_path == NULL) {
1079                                 _E("memory alloc failed");
1080                                 free(temp_pkgid);
1081                                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1082                         }
1083                         snprintf(temp_application_path, len + 1, "%s/%s",
1084                                 tzplatform_getenv(TZ_USER_APP), temp_pkgid);
1085
1086                         temp_encoded_id = _app2sd_get_encoded_name((const char *)temp_pkgid, uid);
1087                         if (temp_encoded_id == NULL) {
1088                                 free(temp_pkgid);
1089                                 free(temp_application_path);
1090                                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1091                         }
1092                         snprintf(temp_uid, 32, "%d", uid);
1093                         len = strlen(app2sd_path) + strlen(temp_uid) + strlen(temp_encoded_id) + 2;
1094                         temp_loopback_device = calloc(len + 1, sizeof(char));
1095                         if (temp_loopback_device == NULL) {
1096                                 _E("memory alloc failed");
1097                                 free(temp_pkgid);
1098                                 free(temp_application_path);
1099                                 free(temp_encoded_id);
1100                                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1101                         }
1102                         snprintf(temp_loopback_device, len + 1, "%s/%s",
1103                                 app2sd_path, temp_encoded_id);
1104                         free(temp_encoded_id);
1105                         tzplatform_reset_user();
1106                 }
1107                 ret = _app2sd_update_loopback_device_size(pkgid,
1108                         loopback_device, application_path, temp_pkgid,
1109                         temp_loopback_device, temp_application_path,
1110                         reqd_disk_size, dir_list, uid);
1111                 free(temp_pkgid);
1112                 free(temp_application_path);
1113                 free(temp_loopback_device);
1114                 if (APP2EXT_SUCCESS != ret) {
1115                         _E("failed to update loopback device size");
1116                         return ret;
1117                 }
1118         }
1119
1120         /* get the associated device node for SD card applicationer */
1121 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1122         device_node =
1123                 _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
1124 #else
1125         device_node = _app2sd_find_associated_device_node(loopback_device);
1126 #endif
1127         if (NULL == device_node) {
1128                 /* do loopback setup */
1129 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1130                 ret = _app2sd_dmcrypt_open_device(pkgid, loopback_device,
1131                         false, uid, &device_node);
1132                 if (ret) {
1133                         _E("dmcrypt open device error");
1134                         return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
1135                 }
1136 #else
1137                 device_node = _app2sd_do_loopback_encryption_setup(pkgid,
1138                         loopback_device, uid);
1139                 if (device_node == NULL) {
1140                         _E("loopback encryption setup failed");
1141                         return APP2EXT_ERROR_DO_LOSETUP;
1142                 }
1143 #endif
1144
1145                 /* do mounting */
1146                 ret = _app2sd_mount_app_content(application_path, pkgid,
1147                         device_node, MOUNT_TYPE_RW, dir_list,
1148                         APP2SD_PRE_UPGRADE, uid);
1149                 if (ret) {
1150                         _E("mount failed");
1151                         if (device_node) {
1152                                 free(device_node);
1153                                 device_node = NULL;
1154                         }
1155                         return APP2EXT_ERROR_MOUNT_PATH;
1156                 }
1157         } else {
1158                 /* do re-mounting */
1159                 ret = _app2sd_mount_app_content(application_path, pkgid,
1160                         device_node, MOUNT_TYPE_RW_REMOUNT, NULL,
1161                         APP2SD_PRE_UPGRADE, uid);
1162                 if (ret) {
1163                         _E("remount failed");
1164                         if (device_node) {
1165                                 free(device_node);
1166                                 device_node = NULL;
1167                         }
1168                         return APP2EXT_ERROR_MOUNT_PATH;
1169                 }
1170         }
1171
1172         if (device_node) {
1173                 free(device_node);
1174                 device_node = NULL;
1175         }
1176
1177         sync();
1178         return ret;
1179 }
1180
1181 int app2sd_usr_post_app_upgrade(const char *pkgid,
1182                 app2ext_status install_status, uid_t uid)
1183 {
1184         char mmc_path[FILENAME_MAX] = { 0, };
1185         char loopback_device[FILENAME_MAX] = { 0, };
1186         char application_path[FILENAME_MAX] = { 0, };
1187         char *sdpath = NULL;
1188         char *device_name = NULL;
1189         char *encoded_id = NULL;
1190         int ret = APP2EXT_SUCCESS;
1191
1192         /* validate the function parameter recieved */
1193         if (pkgid == NULL || install_status < APP2EXT_STATUS_FAILED
1194                 || install_status > APP2EXT_STATUS_SUCCESS) {
1195                 _E("invalid func parameters");
1196                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
1197         }
1198
1199         /* check whether MMC is present or not */
1200         ret = _app2sd_check_mmc_status(&sdpath);
1201         if (ret) {
1202                 _E("MMC not present OR Not ready (%d)", ret);
1203                 return APP2EXT_ERROR_MMC_STATUS;
1204         }
1205         snprintf(mmc_path, FILENAME_MAX - 1, "%s", sdpath);
1206         free(sdpath);
1207         sync();
1208
1209         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
1210         if (encoded_id == NULL)
1211                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1212
1213         if (_is_global(uid)) {
1214                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1215                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
1216                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
1217                         mmc_path, EXTIMG_DIR, encoded_id);
1218         } else {
1219                 tzplatform_set_user(uid);
1220                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1221                         tzplatform_getenv(TZ_USER_APP), pkgid);
1222                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
1223                         mmc_path, EXTIMG_DIR, encoded_id);
1224                 tzplatform_reset_user();
1225         }
1226         free(encoded_id);
1227
1228         /* get the associated device node for SD card applicationer */
1229 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1230         device_name =
1231                 _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
1232         if (!device_name) {
1233                 _E("could not find associated dmcrypt device node" \
1234                         " (%s_%d)", pkgid, uid);
1235                 return APP2EXT_ERROR_FIND_ASSOCIATED_DMCRYPT_DEVICE_NODE;
1236         }
1237 #else
1238         device_name = _app2sd_find_associated_device_node(loopback_device);
1239         if (NULL == device_name)
1240                 return APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_NODE;
1241 #endif
1242
1243         ret = _app2sd_unmount_app_content(application_path);
1244         if (ret) {
1245                 if (device_name) {
1246                         free(device_name);
1247                         device_name = NULL;
1248                 }
1249                 _E("unable to unmount the app content (%d)", ret);
1250                 return APP2EXT_ERROR_UNMOUNT;
1251         }
1252
1253 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1254         ret = _app2sd_dmcrypt_close_device(pkgid, uid);
1255         if (ret) {
1256                 if (device_name) {
1257                         free(device_name);
1258                         device_name = NULL;
1259                 }
1260                 _E("close dmcrypt device error(%d)", ret);
1261                 return APP2EXT_ERROR_CLOSE_DMCRYPT_DEVICE;
1262         }
1263 #else
1264         ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
1265         if (ret) {
1266                 if (device_name) {
1267                         free(device_name);
1268                         device_name = NULL;
1269                 }
1270                 _E("unable to detach the loopback encryption " \
1271                         "setup for the application");
1272                 return APP2EXT_ERROR_UNMOUNT;
1273         }
1274 #endif
1275
1276         if (device_name) {
1277                 free(device_name);
1278                 device_name = NULL;
1279         }
1280
1281         sync();
1282         return ret;
1283 }
1284
1285 int app2sd_usr_force_clean(const char *pkgid, uid_t uid)
1286 {
1287         char mmc_path[FILENAME_MAX] = { 0, };
1288         char loopback_device[FILENAME_MAX] = { 0, };
1289         char application_path[FILENAME_MAX] = { 0, };
1290         char *sdpath = NULL;
1291         char *encoded_id = NULL;
1292         int ret = APP2EXT_SUCCESS;
1293
1294         /* validate the function parameter recieved */
1295         if (pkgid == NULL) {
1296                 _E("invalid func parameters");
1297                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
1298         }
1299
1300         /* check whether MMC is present or not */
1301         ret = _app2sd_check_mmc_status(&sdpath);
1302         if (ret) {
1303                 _E("MMC not present OR Not ready (%d)", ret);
1304                 return APP2EXT_ERROR_MMC_STATUS;
1305         }
1306         snprintf(mmc_path, FILENAME_MAX - 1, "%s", sdpath);
1307         free(sdpath);
1308         sync();
1309
1310         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
1311         if (encoded_id == NULL)
1312                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1313
1314         if (_is_global(uid)) {
1315                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1316                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
1317                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
1318                         mmc_path, EXTIMG_DIR, encoded_id);
1319         } else {
1320                 tzplatform_set_user(uid);
1321                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1322                         tzplatform_getenv(TZ_USER_APP), pkgid);
1323                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
1324                         mmc_path, EXTIMG_DIR, encoded_id);
1325                 tzplatform_reset_user();
1326         }
1327         free(encoded_id);
1328
1329         ret = _app2sd_force_clean(pkgid, application_path, loopback_device, uid);
1330
1331         sync();
1332         return ret;
1333 }
1334
1335 int app2sd_enable_full_pkg(void)
1336 {
1337         int ret = APP2EXT_SUCCESS;
1338         int rc = 0;
1339         char buf[FILENAME_MAX] = { 0, };
1340         char app2sd_path[FILENAME_MAX] = { 0, };
1341         char loopback_device[FILENAME_MAX] = { 0, };
1342         char *sdpath = NULL;
1343         char *pkgid = NULL;
1344         DIR *dir = NULL;
1345         struct dirent entry;
1346         struct dirent *result = NULL;
1347         uid_t uid = 0;
1348
1349         /* check whether MMC is present or not */
1350         ret = _app2sd_check_mmc_status(&sdpath);
1351         if (ret) {
1352                 _E("MMC not present OR Not ready (%d)", ret);
1353                 return APP2EXT_ERROR_MMC_STATUS;
1354         }
1355         snprintf(app2sd_path, FILENAME_MAX - 1, "%s/%s",
1356                         sdpath, EXTIMG_DIR);
1357         free(sdpath);
1358
1359         dir = opendir(app2sd_path);
1360         if (!dir) {
1361                 strerror_r(errno, buf, sizeof(buf));
1362                 _E("failed to opendir (%s)", buf);
1363                 return APP2EXT_ERROR_OPEN_DIR;
1364         }
1365
1366         ret = _app2sd_initialize_db();
1367         if (ret) {
1368                 _E("app2sd db initialize failed");
1369                 closedir(dir);
1370                 return APP2EXT_ERROR_SQLITE_REGISTRY;
1371         }
1372
1373         for (rc = readdir_r(dir, &entry, &result);
1374                 rc == 0 && result != NULL;
1375                 rc = readdir_r(dir, &entry, &result)) {
1376                 if (strcmp(entry.d_name, ".") == 0 ||
1377                         strcmp(entry.d_name, "..") == 0)
1378                         continue;
1379                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
1380                         app2sd_path, entry.d_name);
1381                 ret = _app2sd_get_info_from_db(loopback_device,
1382                         &pkgid, &uid);
1383                 if (ret) {
1384                         _E("failed to get info from db");
1385                         break;;
1386                 }
1387                 if (pkgid) {
1388                         _D("pkgid(%s), uid(%d)", pkgid, uid);
1389                         ret = app2sd_usr_on_demand_setup_init(pkgid, uid);
1390                         if (ret) {
1391                                 _E("error(%d)", ret);
1392                                 break;
1393                         }
1394                         free(pkgid);
1395                         pkgid = NULL;
1396                 }
1397         }
1398
1399         if (pkgid) {
1400                 free(pkgid);
1401                 pkgid = NULL;
1402         }
1403         closedir(dir);
1404
1405         sync();
1406         return ret;
1407 }
1408
1409 static int _app2sd_info_cb_func(const char *pkgid, uid_t uid)
1410 {
1411         int ret = APP2EXT_SUCCESS;
1412
1413         if (pkgid) {
1414                 _D("pkgid(%s), uid(%d)", pkgid, uid);
1415                 ret = app2sd_usr_on_demand_setup_exit(pkgid, uid);
1416                 if (ret)
1417                         _E("error(%d)", ret);
1418         }
1419
1420         return ret;
1421 }
1422
1423 int app2sd_disable_full_pkg(void)
1424 {
1425         int ret = APP2EXT_SUCCESS;
1426
1427         ret = _app2sd_initialize_db();
1428         if (ret) {
1429                 _E("app2sd db initialize failed");
1430                 return APP2EXT_ERROR_SQLITE_REGISTRY;
1431         }
1432
1433         ret = _app2sd_get_foreach_info_from_db((app2sd_info_cb)_app2sd_info_cb_func);
1434         if (ret)
1435                 _E("disable full pkg error(%d)", ret);
1436
1437         sync();
1438         return ret;
1439 }