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