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