Clean up repository
[platform/core/appfw/app2sd.git] / plugin / app2sd / server / 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, loopback_device, 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_without_restart_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 *image_path = NULL;
843         char mmc_path[FILENAME_MAX] = { 0, };
844
845         /* validate function arguments */
846         if (pkgid == NULL || dir_list == NULL
847                 || move_type < APP2EXT_MOVE_TO_EXT
848                 || move_type > APP2EXT_MOVE_TO_PHONE) {
849                 _E("invalid function arguments");
850                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
851         }
852
853         /* check whether MMC is present or not */
854         ret = _app2sd_check_mmc_status(&sdpath);
855         if (ret) {
856                 _E("MMC not present OR Not ready(%d)", ret);
857                 return APP2EXT_ERROR_MMC_STATUS;
858         }
859         snprintf(mmc_path, FILENAME_MAX - 1, "%s", sdpath);
860         free(sdpath);
861         sync();
862
863         ret = __app2sd_create_app2sd_directories(uid, mmc_path);
864         if (ret) {
865                 _E("failed to create app2sd dirs");
866                 return ret;
867         }
868
869         ret = _app2sd_usr_move_app(pkgid, move_type, dir_list, uid, mmc_path, &image_path);
870         if (ret) {
871                 _D("unable to move application");
872                 return ret;
873         }
874
875         /* if move is completed, then update installed storage to pkgmgr_parser db */
876         if (move_type == APP2EXT_MOVE_TO_EXT) {
877                 if (!image_path) {
878                         _E("image_path is NULL");
879                         return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
880                 }
881                 pkgmgr_ret = pkgmgrinfo_pkginfo_set_usr_installed_storage(pkgid,
882                                 INSTALL_EXTERNAL, image_path, uid);
883                 if (pkgmgr_ret < 0) {
884                         _E("failed to update installed location to db " \
885                                 "[%s, %s] of uid(%d), pkgmgr_ret(%d)",
886                                 pkgid, INSTALL_EXTERNAL, uid, pkgmgr_ret);
887                         return APP2EXT_ERROR_PKGMGR_ERROR;
888                 }
889         } else {
890                 pkgmgr_ret = pkgmgrinfo_pkginfo_set_usr_installed_storage(pkgid,
891                                 INSTALL_INTERNAL, image_path, uid);
892                 if (pkgmgr_ret < 0) {
893                         _E("failed to update installed location to db " \
894                                 "[%s, %s] of uid(%d), pkgmgr_ret(%d)",
895                                 pkgid, INSTALL_INTERNAL, uid, pkgmgr_ret);
896                         return APP2EXT_ERROR_PKGMGR_ERROR;
897                 }
898         }
899
900         if (image_path)
901                 free(image_path);
902
903         sync();
904         return APP2EXT_SUCCESS;
905 }
906
907 int app2sd_usr_post_move_installed_app(const char *pkgid,
908                 app2ext_move_type move_type, uid_t uid)
909 {
910         int ret = 0;
911         char mmc_path[FILENAME_MAX] = { 0, };
912         char application_path[FILENAME_MAX] = { 0, };
913         char loopback_device[FILENAME_MAX] = { 0, };
914         char *sdpath = NULL;
915         char *encoded_id = NULL;
916
917         /* validate function arguments */
918         if (pkgid == NULL || move_type < APP2EXT_MOVE_TO_EXT
919                 || move_type > APP2EXT_MOVE_TO_PHONE) {
920                 _E("invalid function arguments");
921                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
922         }
923
924         if (move_type == APP2EXT_MOVE_TO_PHONE)
925                 return APP2EXT_SUCCESS;
926
927         /* check whether MMC is present or not */
928         ret = _app2sd_check_mmc_status(&sdpath);
929         if (ret) {
930                 _E("MMC not present OR Not ready(%d)", ret);
931                 return APP2EXT_ERROR_MMC_STATUS;
932         }
933         snprintf(mmc_path, FILENAME_MAX - 1, "%s", sdpath);
934         free(sdpath);
935         sync();
936
937         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
938         if (encoded_id == NULL)
939                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
940
941         snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
942                         mmc_path, EXTIMG_DIR, encoded_id);
943         free(encoded_id);
944         if (_is_global(uid)) {
945                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
946                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
947         } else {
948                 tzplatform_set_user(uid);
949                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
950                         tzplatform_getenv(TZ_USER_APP), pkgid);
951                 tzplatform_reset_user();
952         }
953
954         ret = _app2sd_unmount_app_content(application_path);
955         if (ret)
956                 _E("unmount error (%d)", ret);
957
958 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
959         ret = _app2sd_dmcrypt_close_device(pkgid, uid);
960         if (ret)
961                 _E("close dmcrypt device error(%d)", ret);
962 #else
963         ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
964         if (ret)
965                 _E("unable to detach loopback setup for (%s)",
966                         loopback_device);
967 #endif
968
969         sync();
970         return APP2EXT_SUCCESS;
971 }
972
973 int app2sd_usr_pre_app_upgrade(const char *pkgid, GList *dir_list,
974                 int size, uid_t uid)
975 {
976         int ret = APP2EXT_SUCCESS;
977         char app2sd_path[FILENAME_MAX] = { 0, };
978         char loopback_device[FILENAME_MAX] = { 0, };
979         char application_path[FILENAME_MAX] = { 0, };
980         char temp_uid[32] = { 0, };
981         char *sdpath = NULL;
982         char *temp_pkgid = NULL;
983         char *temp_loopback_device = NULL;
984         char *temp_application_path = NULL;
985         char *device_node = NULL;
986         char *encoded_id = NULL;
987         char *temp_encoded_id = NULL;
988         int len = 0;
989         unsigned long long curr_size = 0;
990         FILE *fp = NULL;
991         int reqd_disk_size = size + ceil(size * 0.2);
992
993         /* validate function arguments*/
994         if (pkgid == NULL || dir_list == NULL || size <= 0) {
995                 _E("invalid function arguments");
996                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
997         }
998
999         /* check whether MMC is present or not */
1000         ret = _app2sd_check_mmc_status(&sdpath);
1001         if (ret) {
1002                 _E("MMC not present OR Not ready (%d)", ret);
1003                 return APP2EXT_ERROR_MMC_STATUS;
1004         }
1005         snprintf(app2sd_path, FILENAME_MAX - 1, "%s/%s",
1006                         sdpath, EXTIMG_DIR);
1007         free(sdpath);
1008         sync();
1009
1010         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
1011         if (encoded_id == NULL)
1012                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1013
1014         if (_is_global(uid)) {
1015                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1016                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
1017                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
1018                         app2sd_path, encoded_id);
1019         } else {
1020                 tzplatform_set_user(uid);
1021                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1022                         tzplatform_getenv(TZ_USER_APP), pkgid);
1023                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
1024                         app2sd_path, encoded_id);
1025                 tzplatform_reset_user();
1026         }
1027         free(encoded_id);
1028
1029         /* check app entry is there in sd card or not. */
1030         fp = fopen(loopback_device, "r+");
1031         if (fp == NULL) {
1032                 _E("app entry is not present in SD Card");
1033                 return APP2EXT_ERROR_INVALID_PACKAGE;
1034         }
1035         fclose(fp);
1036
1037         /* get installed app size*/
1038         curr_size = _app2sd_calculate_file_size(loopback_device);
1039         curr_size = (curr_size) / (1024 * 1024);
1040         if (curr_size == 0) {
1041                 _E("app entry is not present in SD Card");
1042                 return APP2EXT_ERROR_LOOPBACK_DEVICE_UNAVAILABLE;
1043         }
1044         if ((int)curr_size < reqd_disk_size) {
1045                 len = strlen(pkgid) + strlen(".new");
1046                 temp_pkgid = calloc(len + 1, sizeof(char));
1047                 if (temp_pkgid == NULL) {
1048                         _E("memory alloc failed");
1049                         return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1050                 }
1051                 snprintf(temp_pkgid, len + 1, "%s.new", pkgid);
1052
1053                 if (_is_global(uid)) {
1054                         len = strlen(tzplatform_getenv(TZ_SYS_RW_APP)) + strlen(temp_pkgid) + 1;
1055                         temp_application_path = calloc(len + 1, sizeof(char));
1056                         if (temp_application_path == NULL) {
1057                                 _E("memory alloc failed");
1058                                 free(temp_pkgid);
1059                                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1060                         }
1061                         snprintf(temp_application_path, len + 1, "%s/%s",
1062                                 tzplatform_getenv(TZ_SYS_RW_APP), temp_pkgid);
1063
1064                         temp_encoded_id = _app2sd_get_encoded_name((const char *)temp_pkgid, uid);
1065                         if (temp_encoded_id == NULL) {
1066                                 free(temp_pkgid);
1067                                 free(temp_application_path);
1068                                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1069                         }
1070                         len = strlen(app2sd_path) + strlen(temp_encoded_id) + 1;
1071                         temp_loopback_device = calloc(len + 1, sizeof(char));
1072                         if (temp_loopback_device == NULL) {
1073                                 _E("memory alloc failed");
1074                                 free(temp_pkgid);
1075                                 free(temp_application_path);
1076                                 free(temp_encoded_id);
1077                                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1078                         }
1079                         snprintf(temp_loopback_device, len + 1, "%s/%s",
1080                                 app2sd_path, temp_encoded_id);
1081                         free(temp_encoded_id);
1082                 } else {
1083                         tzplatform_set_user(uid);
1084                         len = strlen(tzplatform_getenv(TZ_USER_APP)) + strlen(temp_pkgid) + 1;
1085                         temp_application_path = calloc(len + 1, sizeof(char));
1086                         if (temp_application_path == NULL) {
1087                                 _E("memory alloc failed");
1088                                 free(temp_pkgid);
1089                                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1090                         }
1091                         snprintf(temp_application_path, len + 1, "%s/%s",
1092                                 tzplatform_getenv(TZ_USER_APP), temp_pkgid);
1093
1094                         temp_encoded_id = _app2sd_get_encoded_name((const char *)temp_pkgid, uid);
1095                         if (temp_encoded_id == NULL) {
1096                                 free(temp_pkgid);
1097                                 free(temp_application_path);
1098                                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1099                         }
1100                         snprintf(temp_uid, 32, "%d", uid);
1101                         len = strlen(app2sd_path) + strlen(temp_uid) + strlen(temp_encoded_id) + 2;
1102                         temp_loopback_device = calloc(len + 1, sizeof(char));
1103                         if (temp_loopback_device == NULL) {
1104                                 _E("memory alloc failed");
1105                                 free(temp_pkgid);
1106                                 free(temp_application_path);
1107                                 free(temp_encoded_id);
1108                                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1109                         }
1110                         snprintf(temp_loopback_device, len + 1, "%s/%s",
1111                                 app2sd_path, temp_encoded_id);
1112                         free(temp_encoded_id);
1113                         tzplatform_reset_user();
1114                 }
1115                 ret = _app2sd_update_loopback_device_size(pkgid,
1116                         loopback_device, application_path, temp_pkgid,
1117                         temp_loopback_device, temp_application_path,
1118                         reqd_disk_size, dir_list, uid);
1119                 free(temp_pkgid);
1120                 free(temp_application_path);
1121                 free(temp_loopback_device);
1122                 if (APP2EXT_SUCCESS != ret) {
1123                         _E("failed to update loopback device size");
1124                         return ret;
1125                 }
1126         }
1127
1128         /* get the associated device node for SD card applicationer */
1129 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1130         device_node =
1131                 _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
1132 #else
1133         device_node = _app2sd_find_associated_device_node(loopback_device);
1134 #endif
1135         if (NULL == device_node) {
1136                 /* do loopback setup */
1137 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1138                 ret = _app2sd_dmcrypt_open_device(pkgid, loopback_device,
1139                         false, uid, &device_node);
1140                 if (ret) {
1141                         _E("dmcrypt open device error");
1142                         return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
1143                 }
1144 #else
1145                 device_node = _app2sd_do_loopback_encryption_setup(pkgid,
1146                         loopback_device, uid);
1147                 if (device_node == NULL) {
1148                         _E("loopback encryption setup failed");
1149                         return APP2EXT_ERROR_DO_LOSETUP;
1150                 }
1151 #endif
1152
1153                 /* do mounting */
1154                 ret = _app2sd_mount_app_content(application_path, pkgid,
1155                         device_node, MOUNT_TYPE_RW, dir_list,
1156                         APP2SD_PRE_UPGRADE, uid);
1157                 if (ret) {
1158                         _E("mount failed");
1159                         if (device_node) {
1160                                 free(device_node);
1161                                 device_node = NULL;
1162                         }
1163                         return APP2EXT_ERROR_MOUNT_PATH;
1164                 }
1165         } else {
1166                 /* do re-mounting */
1167                 ret = _app2sd_mount_app_content(application_path, pkgid,
1168                         device_node, MOUNT_TYPE_RW_REMOUNT, NULL,
1169                         APP2SD_PRE_UPGRADE, uid);
1170                 if (ret) {
1171                         _E("remount failed");
1172                         if (device_node) {
1173                                 free(device_node);
1174                                 device_node = NULL;
1175                         }
1176                         return APP2EXT_ERROR_MOUNT_PATH;
1177                 }
1178         }
1179
1180         if (device_node) {
1181                 free(device_node);
1182                 device_node = NULL;
1183         }
1184
1185         sync();
1186         return ret;
1187 }
1188
1189 int app2sd_usr_post_app_upgrade(const char *pkgid,
1190                 app2ext_status install_status, uid_t uid)
1191 {
1192         char mmc_path[FILENAME_MAX] = { 0, };
1193         char loopback_device[FILENAME_MAX] = { 0, };
1194         char application_path[FILENAME_MAX] = { 0, };
1195         char *sdpath = NULL;
1196         char *device_name = NULL;
1197         char *encoded_id = NULL;
1198         int ret = APP2EXT_SUCCESS;
1199         int pkgmgr_ret = 0;
1200
1201         /* validate the function parameter recieved */
1202         if (pkgid == NULL || install_status < APP2EXT_STATUS_FAILED
1203                 || install_status > APP2EXT_STATUS_SUCCESS) {
1204                 _E("invalid func parameters");
1205                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
1206         }
1207
1208         /* check whether MMC is present or not */
1209         ret = _app2sd_check_mmc_status(&sdpath);
1210         if (ret) {
1211                 _E("MMC not present OR Not ready (%d)", ret);
1212                 return APP2EXT_ERROR_MMC_STATUS;
1213         }
1214         snprintf(mmc_path, FILENAME_MAX - 1, "%s", sdpath);
1215         free(sdpath);
1216         sync();
1217
1218         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
1219         if (encoded_id == NULL)
1220                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1221
1222         if (_is_global(uid)) {
1223                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1224                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
1225                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
1226                         mmc_path, EXTIMG_DIR, encoded_id);
1227         } else {
1228                 tzplatform_set_user(uid);
1229                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1230                         tzplatform_getenv(TZ_USER_APP), pkgid);
1231                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
1232                         mmc_path, EXTIMG_DIR, encoded_id);
1233                 tzplatform_reset_user();
1234         }
1235         free(encoded_id);
1236
1237         /* get the associated device node for SD card applicationer */
1238 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1239         device_name =
1240                 _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
1241         if (!device_name) {
1242                 _E("could not find associated dmcrypt device node" \
1243                         " (%s_%d)", pkgid, uid);
1244                 return APP2EXT_ERROR_FIND_ASSOCIATED_DMCRYPT_DEVICE_NODE;
1245         }
1246 #else
1247         device_name = _app2sd_find_associated_device_node(loopback_device);
1248         if (NULL == device_name)
1249                 return APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_NODE;
1250 #endif
1251
1252         ret = _app2sd_unmount_app_content(application_path);
1253         if (ret) {
1254                 if (device_name) {
1255                         free(device_name);
1256                         device_name = NULL;
1257                 }
1258                 _E("unable to unmount the app content (%d)", ret);
1259                 return APP2EXT_ERROR_UNMOUNT;
1260         }
1261
1262 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1263         ret = _app2sd_dmcrypt_close_device(pkgid, uid);
1264         if (ret) {
1265                 if (device_name) {
1266                         free(device_name);
1267                         device_name = NULL;
1268                 }
1269                 _E("close dmcrypt device error(%d)", ret);
1270                 return APP2EXT_ERROR_CLOSE_DMCRYPT_DEVICE;
1271         }
1272 #else
1273         ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
1274         if (ret) {
1275                 if (device_name) {
1276                         free(device_name);
1277                         device_name = NULL;
1278                 }
1279                 _E("unable to detach the loopback encryption " \
1280                         "setup for the application");
1281                 return APP2EXT_ERROR_UNMOUNT;
1282         }
1283 #endif
1284
1285         pkgmgr_ret = pkgmgrinfo_pkginfo_set_usr_installed_storage(pkgid,
1286                 INSTALL_EXTERNAL, loopback_device, uid);
1287         if (pkgmgr_ret < 0) {
1288                 _E("fail to update installed location " \
1289                         "to db[%s, %d] of uid(%d), pkgmgr ret(%d)",
1290                         pkgid, INSTALL_EXTERNAL, uid, pkgmgr_ret);
1291                 return APP2EXT_ERROR_PKGMGR_ERROR;
1292         }
1293
1294         if (device_name) {
1295                 free(device_name);
1296                 device_name = NULL;
1297         }
1298
1299         sync();
1300         return ret;
1301 }
1302
1303 int app2sd_usr_force_clean(const char *pkgid, uid_t uid)
1304 {
1305         char mmc_path[FILENAME_MAX] = { 0, };
1306         char loopback_device[FILENAME_MAX] = { 0, };
1307         char application_path[FILENAME_MAX] = { 0, };
1308         char *sdpath = NULL;
1309         char *encoded_id = NULL;
1310         int ret = APP2EXT_SUCCESS;
1311
1312         /* validate the function parameter recieved */
1313         if (pkgid == NULL) {
1314                 _E("invalid func parameters");
1315                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
1316         }
1317
1318         /* check whether MMC is present or not */
1319         ret = _app2sd_check_mmc_status(&sdpath);
1320         if (ret) {
1321                 _E("MMC not present OR Not ready (%d)", ret);
1322                 return APP2EXT_ERROR_MMC_STATUS;
1323         }
1324         snprintf(mmc_path, FILENAME_MAX - 1, "%s", sdpath);
1325         free(sdpath);
1326         sync();
1327
1328         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
1329         if (encoded_id == NULL)
1330                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1331
1332         if (_is_global(uid)) {
1333                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1334                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
1335                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
1336                         mmc_path, EXTIMG_DIR, encoded_id);
1337         } else {
1338                 tzplatform_set_user(uid);
1339                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1340                         tzplatform_getenv(TZ_USER_APP), pkgid);
1341                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
1342                         mmc_path, EXTIMG_DIR, encoded_id);
1343                 tzplatform_reset_user();
1344         }
1345         free(encoded_id);
1346
1347         ret = _app2sd_force_clean(pkgid, application_path, loopback_device, uid);
1348
1349         sync();
1350         return ret;
1351 }
1352
1353 int app2sd_enable_full_pkg(void)
1354 {
1355         int ret = APP2EXT_SUCCESS;
1356         int rc = 0;
1357         char buf[FILENAME_MAX] = { 0, };
1358         char app2sd_path[FILENAME_MAX] = { 0, };
1359         char loopback_device[FILENAME_MAX] = { 0, };
1360         char *sdpath = NULL;
1361         char *pkgid = NULL;
1362         DIR *dir = NULL;
1363         struct dirent entry;
1364         struct dirent *result = NULL;
1365         uid_t uid = 0;
1366
1367         /* check whether MMC is present or not */
1368         ret = _app2sd_check_mmc_status(&sdpath);
1369         if (ret) {
1370                 _E("MMC not present OR Not ready (%d)", ret);
1371                 return APP2EXT_ERROR_MMC_STATUS;
1372         }
1373         snprintf(app2sd_path, FILENAME_MAX - 1, "%s/%s",
1374                         sdpath, EXTIMG_DIR);
1375         free(sdpath);
1376
1377         dir = opendir(app2sd_path);
1378         if (!dir) {
1379                 strerror_r(errno, buf, sizeof(buf));
1380                 _E("failed to opendir (%s)", buf);
1381                 return APP2EXT_ERROR_OPEN_DIR;
1382         }
1383
1384         ret = _app2sd_initialize_db();
1385         if (ret) {
1386                 _E("app2sd db initialize failed");
1387                 closedir(dir);
1388                 return APP2EXT_ERROR_SQLITE_REGISTRY;
1389         }
1390
1391         for (rc = readdir_r(dir, &entry, &result);
1392                 rc == 0 && result != NULL;
1393                 rc = readdir_r(dir, &entry, &result)) {
1394                 if (strcmp(entry.d_name, ".") == 0 ||
1395                         strcmp(entry.d_name, "..") == 0)
1396                         continue;
1397                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
1398                         app2sd_path, entry.d_name);
1399                 ret = _app2sd_get_info_from_db(loopback_device,
1400                         &pkgid, &uid);
1401                 if (ret) {
1402                         _E("failed to get info from db");
1403                         break;;
1404                 }
1405                 if (pkgid) {
1406                         _D("pkgid(%s), uid(%d)", pkgid, uid);
1407                         ret = app2sd_usr_on_demand_setup_init(pkgid, uid);
1408                         if (ret) {
1409                                 _E("error(%d)", ret);
1410                                 break;
1411                         }
1412                         free(pkgid);
1413                         pkgid = NULL;
1414                 }
1415         }
1416
1417         if (pkgid) {
1418                 free(pkgid);
1419                 pkgid = NULL;
1420         }
1421         closedir(dir);
1422
1423         sync();
1424         return ret;
1425 }
1426
1427 static int _app2sd_info_cb_func(const char *pkgid, uid_t uid)
1428 {
1429         int ret = APP2EXT_SUCCESS;
1430
1431         if (pkgid) {
1432                 _D("pkgid(%s), uid(%d)", pkgid, uid);
1433                 ret = app2sd_usr_on_demand_setup_exit(pkgid, uid);
1434                 if (ret)
1435                         _E("error(%d)", ret);
1436         }
1437
1438         return ret;
1439 }
1440
1441 int app2sd_disable_full_pkg(void)
1442 {
1443         int ret = APP2EXT_SUCCESS;
1444
1445         ret = _app2sd_initialize_db();
1446         if (ret) {
1447                 _E("app2sd db initialize failed");
1448                 return APP2EXT_ERROR_SQLITE_REGISTRY;
1449         }
1450
1451         ret = _app2sd_get_foreach_info_from_db((app2sd_info_cb)_app2sd_info_cb_func);
1452         if (ret)
1453                 _E("disable full pkg error(%d)", ret);
1454
1455         sync();
1456         return ret;
1457 }