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