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