f08abe73da21068fd0dcc282bae8532a08b06b75
[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
527         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &handle);
528         if (ret < 0) {
529                 _E("failed to get pkginfo");
530                 return APP2EXT_ERROR_PKGMGR_ERROR;
531         }
532
533         ret = pkgmgrinfo_appinfo_get_usr_list(handle,
534                 PMINFO_ALL_APP, _app2sd_application_handler, &uid, uid);
535         if (ret < 0) {
536                 _E("failed to get appinfo");
537                 return APP2EXT_ERROR_PKGMGR_ERROR;
538         }
539
540         ret = pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
541         if (ret < 0) {
542                 _E("failed to destroy pkginfo");
543                 return APP2EXT_ERROR_PKGMGR_ERROR;
544         }
545
546         return APP2EXT_SUCCESS;
547 }
548
549 int app2sd_usr_on_demand_setup_exit(const char *pkgid, uid_t uid)
550 {
551         int ret = APP2EXT_SUCCESS;
552         char application_path[FILENAME_MAX] = { 0, };
553         char loopback_device[FILENAME_MAX] = { 0, };
554 #if !defined(TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION)
555         char mmc_path[FILENAME_MAX] = { 0, };
556         char *sdpath = NULL;
557         char *encoded_id = NULL;
558 #endif
559
560         /* validate the function parameter recieved */
561         if (pkgid == NULL) {
562                 _E("invalid function arguments to app launch setup");
563                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
564         }
565
566         _app2sd_kill_running_app(pkgid, uid);
567
568 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
569         if (_is_global(uid)) {
570                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
571                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
572         } else {
573                 tzplatform_set_user(uid);
574                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
575                         tzplatform_getenv(TZ_USER_APP), pkgid);
576                 tzplatform_reset_user();
577         }
578 #else
579         /* check whether MMC is present or not */
580         ret = _app2sd_check_mmc_status(&sdpath);
581         if (ret)
582                 _W("MMC not present OR Not ready (%d)", ret);
583
584         snprintf(mmc_path, FILENAME_MAX - 1, "%s", sdpath);
585         free(sdpath);
586
587         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
588         if (encoded_id == NULL)
589                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
590
591         if (_is_global(uid)) {
592                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
593                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
594                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
595                         mmc_path, EXTIMG_DIR, encoded_id);
596         } else {
597                 tzplatform_set_user(uid);
598                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
599                         tzplatform_getenv(TZ_USER_APP), pkgid);
600                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
601                         mmc_path, EXTIMG_DIR, encoded_id);
602                 tzplatform_reset_user();
603         }
604         free(encoded_id);
605 #endif
606
607         ret = __app2sd_finalize_device_setup(pkgid, loopback_device,
608                 application_path, uid);
609         if (ret) {
610                 _E("failed to finalize device setup");
611                 return ret;
612         }
613
614         return ret;
615 }
616
617 int app2sd_usr_pre_app_uninstall(const char *pkgid, uid_t uid)
618 {
619         int ret = APP2EXT_SUCCESS;
620         char mmc_path[FILENAME_MAX] = { 0, };
621         char application_path[FILENAME_MAX] = { 0, };
622         char loopback_device[FILENAME_MAX] = { 0, };
623         char *sdpath = NULL;
624         char *encoded_id = NULL;
625         char *device_node = NULL;
626         FILE *fp = NULL;
627
628         /* validate the function parameter recieved */
629         if (pkgid == NULL) {
630                 _E("invalid function arguments to app launch setup");
631                 ret = APP2EXT_ERROR_INVALID_ARGUMENTS;
632                 goto END;
633         }
634
635         /* check whether MMC is present or not */
636         ret = _app2sd_check_mmc_status(&sdpath);
637         if (ret) {
638                 _E("MMC not present OR Not ready (%d)", ret);
639                 ret = APP2EXT_ERROR_MMC_STATUS;
640                 goto END;
641         }
642         snprintf(mmc_path, FILENAME_MAX - 1, "%s", sdpath);
643         free(sdpath);
644         sync();
645
646         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
647         if (encoded_id == NULL)
648                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
649
650         if (_is_global(uid)) {
651                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
652                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
653                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
654                         mmc_path, EXTIMG_DIR, encoded_id);
655         } else {
656                 tzplatform_set_user(uid);
657                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
658                         tzplatform_getenv(TZ_USER_APP), pkgid);
659                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
660                         mmc_path, EXTIMG_DIR, encoded_id);
661                 tzplatform_reset_user();
662         }
663         free(encoded_id);
664
665         /* check app entry is there in sd card or not. */
666         fp = fopen(loopback_device, "r+");
667         if (fp == NULL) {
668                 _E("app entry is not present in SD Card");
669                 ret = APP2EXT_ERROR_INVALID_PACKAGE;
670                 goto END;
671         }
672         fclose(fp);
673
674         /* get the associated device node for SD card applicationer */
675 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
676         device_node =
677                 _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
678 #else
679         device_node = _app2sd_find_associated_device_node(loopback_device);
680 #endif
681         if (NULL == device_node) {
682                 /* do loopback setup */
683 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
684                 ret = _app2sd_dmcrypt_open_device(pkgid, loopback_device,
685                         false, uid, &device_node);
686                 if (ret) {
687                         _E("dmcrypt open device error(%d)", ret);
688                         return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
689                 }
690 #else
691                 device_node = _app2sd_do_loopback_encryption_setup(pkgid,
692                         loopback_device, uid);
693                 if (device_node == NULL) {
694                         _E("loopback encryption setup failed");
695                         ret = APP2EXT_ERROR_DO_LOSETUP;
696                         goto END;
697                 }
698 #endif
699                 /* do mounting */
700                 ret = _app2sd_mount_app_content(application_path, pkgid,
701                         device_node, MOUNT_TYPE_RW, NULL,
702                         APP2SD_PRE_UNINSTALL, uid);
703                 if (ret) {
704                         _E("mount failed");
705                         if (device_node) {
706                                 free(device_node);
707                                 device_node = NULL;
708                         }
709                         ret = APP2EXT_ERROR_MOUNT_PATH;
710                         goto END;
711                 }
712         } else {
713                 /* do re-mounting */
714                 ret = _app2sd_mount_app_content(application_path, pkgid,
715                         device_node, MOUNT_TYPE_RW_REMOUNT, NULL,
716                         APP2SD_PRE_UNINSTALL, uid);
717                 if (ret) {
718                         _E("remount failed");
719                         if (device_node) {
720                                 free(device_node);
721                                 device_node = NULL;
722                         }
723                         ret = APP2EXT_ERROR_MOUNT_PATH;
724                         goto END;
725                 }
726         }
727         if (device_node) {
728                 free(device_node);
729                 device_node = NULL;
730         }
731
732 END:
733         sync();
734         return ret;
735 }
736
737 int app2sd_usr_post_app_uninstall(const char *pkgid, uid_t uid)
738 {
739         char mmc_path[FILENAME_MAX] = { 0, };
740         char application_path[FILENAME_MAX] = { 0, };
741         char application_mmc_path[FILENAME_MAX] = { 0, };
742         char loopback_device[FILENAME_MAX] = { 0, };
743         char *sdpath = NULL;
744         char *encoded_id = NULL;
745         int ret = APP2EXT_SUCCESS;
746
747         /* validate the function parameter recieved */
748         if (pkgid == NULL) {
749                 _E("invalid function arguments");
750                 ret = APP2EXT_ERROR_INVALID_ARGUMENTS;
751                 goto END;
752         }
753
754         /* check whether MMC is present or not */
755         ret = _app2sd_check_mmc_status(&sdpath);
756         if (ret) {
757                 _E("MMC not present OR Not ready (%d)", ret);
758                 ret = APP2EXT_ERROR_MMC_STATUS;
759                 goto END;
760         }
761         snprintf(mmc_path, FILENAME_MAX - 1, "%s", sdpath);
762         free(sdpath);
763         sync();
764
765         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
766         if (encoded_id == NULL)
767                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
768
769         if (_is_global(uid)) {
770                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
771                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
772                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
773                         mmc_path, EXTIMG_DIR, encoded_id);
774         } else {
775                 tzplatform_set_user(uid);
776                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
777                         tzplatform_getenv(TZ_USER_APP), pkgid);
778                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
779                         mmc_path, EXTIMG_DIR, encoded_id);
780                 tzplatform_reset_user();
781         }
782         free(encoded_id);
783
784         ret = __app2sd_finalize_device_setup(pkgid, loopback_device,
785                 application_path, uid);
786         if (ret) {
787                 _E("failed to finalize device setup");
788                 return ret;
789         }
790
791         /* delete the loopback device from the SD card */
792         ret = _app2sd_delete_loopback_device(loopback_device);
793         if (ret) {
794                 _E("unable to delete the " \
795                         "loopback device from the SD Card");
796                 ret =  APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
797                 goto END;
798         }
799
800         snprintf(application_mmc_path, FILENAME_MAX - 1, "%s/.mmc",
801                 application_path);
802         ret = _app2sd_delete_directory(application_mmc_path);
803         if (ret) {
804                 _E("unable to delete the directory (%s)",
805                 application_path);
806                 goto END;
807         }
808
809         /* remove encryption password from DB */
810         ret = _app2sd_initialize_db();
811         if (ret) {
812                 _E("app2sd db initialize failed");
813                 ret = APP2EXT_ERROR_SQLITE_REGISTRY;
814                 goto END;
815         }
816
817         ret = _app2sd_remove_info_from_db(pkgid, uid);
818         if (ret) {
819                 _E("cannot remove info from db");
820                 ret = APP2EXT_ERROR_SQLITE_REGISTRY;
821                 goto END;
822         }
823
824 END:
825         sync();
826         return ret;
827 }
828
829 int app2sd_usr_pre_move_installed_app(const char *pkgid,
830                 GList *dir_list, app2ext_move_type move_type, uid_t uid)
831 {
832         int ret = 0;
833         int pkgmgr_ret = 0;
834         char *sdpath = NULL;
835         char *image_path = NULL;
836         char mmc_path[FILENAME_MAX] = { 0, };
837
838         /* validate function arguments */
839         if (pkgid == NULL || dir_list == NULL
840                 || move_type < APP2EXT_MOVE_TO_EXT
841                 || move_type > APP2EXT_MOVE_TO_PHONE) {
842                 _E("invalid function arguments");
843                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
844         }
845
846         /* check whether MMC is present or not */
847         ret = _app2sd_check_mmc_status(&sdpath);
848         if (ret) {
849                 _E("MMC not present OR Not ready(%d)", ret);
850                 return APP2EXT_ERROR_MMC_STATUS;
851         }
852         snprintf(mmc_path, FILENAME_MAX - 1, "%s", sdpath);
853         free(sdpath);
854         sync();
855
856         ret = __app2sd_create_app2sd_directories(uid, mmc_path);
857         if (ret) {
858                 _E("failed to create app2sd dirs");
859                 return ret;
860         }
861
862         ret = _app2sd_usr_move_app(pkgid, move_type, dir_list, uid, mmc_path, &image_path);
863         if (ret) {
864                 _D("unable to move application");
865                 return ret;
866         }
867
868         /* if move is completed, then update installed storage to pkgmgr_parser db */
869         if (move_type == APP2EXT_MOVE_TO_EXT) {
870                 if (!image_path) {
871                         _E("image_path is NULL");
872                         return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
873                 }
874                 pkgmgr_ret = pkgmgrinfo_pkginfo_set_usr_installed_storage(pkgid,
875                                 INSTALL_EXTERNAL, image_path, uid);
876                 if (pkgmgr_ret < 0) {
877                         _E("failed to update installed location to db " \
878                                 "[%s, %s] of uid(%d), pkgmgr_ret(%d)",
879                                 pkgid, INSTALL_EXTERNAL, uid, pkgmgr_ret);
880                         return APP2EXT_ERROR_PKGMGR_ERROR;
881                 }
882         } else {
883                 pkgmgr_ret = pkgmgrinfo_pkginfo_set_usr_installed_storage(pkgid,
884                                 INSTALL_INTERNAL, image_path, uid);
885                 if (pkgmgr_ret < 0) {
886                         _E("failed to update installed location to db " \
887                                 "[%s, %s] of uid(%d), pkgmgr_ret(%d)",
888                                 pkgid, INSTALL_INTERNAL, uid, pkgmgr_ret);
889                         return APP2EXT_ERROR_PKGMGR_ERROR;
890                 }
891         }
892
893         if (image_path)
894                 free(image_path);
895
896         sync();
897         return APP2EXT_SUCCESS;
898 }
899
900 int app2sd_usr_post_move_installed_app(const char *pkgid,
901                 app2ext_move_type move_type, uid_t uid)
902 {
903         int ret = 0;
904         char mmc_path[FILENAME_MAX] = { 0, };
905         char application_path[FILENAME_MAX] = { 0, };
906         char loopback_device[FILENAME_MAX] = { 0, };
907         char *sdpath = NULL;
908         char *encoded_id = NULL;
909
910         /* validate function arguments */
911         if (pkgid == NULL || move_type < APP2EXT_MOVE_TO_EXT
912                 || move_type > APP2EXT_MOVE_TO_PHONE) {
913                 _E("invalid function arguments");
914                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
915         }
916
917         if (move_type == APP2EXT_MOVE_TO_PHONE)
918                 return APP2EXT_SUCCESS;
919
920         /* check whether MMC is present or not */
921         ret = _app2sd_check_mmc_status(&sdpath);
922         if (ret) {
923                 _E("MMC not present OR Not ready(%d)", ret);
924                 return APP2EXT_ERROR_MMC_STATUS;
925         }
926         snprintf(mmc_path, FILENAME_MAX - 1, "%s", sdpath);
927         free(sdpath);
928         sync();
929
930         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
931         if (encoded_id == NULL)
932                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
933
934         snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
935                         mmc_path, EXTIMG_DIR, encoded_id);
936         free(encoded_id);
937         if (_is_global(uid)) {
938                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
939                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
940         } else {
941                 tzplatform_set_user(uid);
942                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
943                         tzplatform_getenv(TZ_USER_APP), pkgid);
944                 tzplatform_reset_user();
945         }
946
947         ret = __app2sd_finalize_device_setup(pkgid, loopback_device,
948                 application_path, uid);
949         if (ret) {
950                 _E("failed to finalize device setup");
951                 return ret;
952         }
953
954         sync();
955         return APP2EXT_SUCCESS;
956 }
957
958 int app2sd_usr_pre_app_upgrade(const char *pkgid, GList *dir_list,
959                 int size, uid_t uid)
960 {
961         int ret = APP2EXT_SUCCESS;
962         char app2sd_path[FILENAME_MAX] = { 0, };
963         char loopback_device[FILENAME_MAX] = { 0, };
964         char application_path[FILENAME_MAX] = { 0, };
965         char temp_uid[32] = { 0, };
966         char *sdpath = NULL;
967         char *temp_pkgid = NULL;
968         char *temp_loopback_device = NULL;
969         char *temp_application_path = NULL;
970         char *device_node = NULL;
971         char *encoded_id = NULL;
972         char *temp_encoded_id = NULL;
973         int len = 0;
974         unsigned long long curr_size = 0;
975         FILE *fp = NULL;
976         int reqd_disk_size = size + ceil(size * 0.2);
977
978         /* validate function arguments*/
979         if (pkgid == NULL || dir_list == NULL || size <= 0) {
980                 _E("invalid function arguments");
981                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
982         }
983
984         /* check whether MMC is present or not */
985         ret = _app2sd_check_mmc_status(&sdpath);
986         if (ret) {
987                 _E("MMC not present OR Not ready (%d)", ret);
988                 return APP2EXT_ERROR_MMC_STATUS;
989         }
990         snprintf(app2sd_path, FILENAME_MAX - 1, "%s/%s",
991                         sdpath, EXTIMG_DIR);
992         free(sdpath);
993         sync();
994
995         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
996         if (encoded_id == NULL)
997                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
998
999         if (_is_global(uid)) {
1000                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1001                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
1002                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
1003                         app2sd_path, encoded_id);
1004         } else {
1005                 tzplatform_set_user(uid);
1006                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1007                         tzplatform_getenv(TZ_USER_APP), pkgid);
1008                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
1009                         app2sd_path, encoded_id);
1010                 tzplatform_reset_user();
1011         }
1012         free(encoded_id);
1013
1014         /* check app entry is there in sd card or not. */
1015         fp = fopen(loopback_device, "r+");
1016         if (fp == NULL) {
1017                 _E("app entry is not present in SD Card");
1018                 return APP2EXT_ERROR_INVALID_PACKAGE;
1019         }
1020         fclose(fp);
1021
1022         /* get installed app size*/
1023         curr_size = _app2sd_calculate_file_size(loopback_device);
1024         curr_size = (curr_size) / (1024 * 1024);
1025         if (curr_size == 0) {
1026                 _E("app entry is not present in SD Card");
1027                 return APP2EXT_ERROR_LOOPBACK_DEVICE_UNAVAILABLE;
1028         }
1029         if ((int)curr_size < reqd_disk_size) {
1030                 len = strlen(pkgid) + strlen(".new");
1031                 temp_pkgid = calloc(len + 1, sizeof(char));
1032                 if (temp_pkgid == NULL) {
1033                         _E("memory alloc failed");
1034                         return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1035                 }
1036                 snprintf(temp_pkgid, len + 1, "%s.new", pkgid);
1037
1038                 if (_is_global(uid)) {
1039                         len = strlen(tzplatform_getenv(TZ_SYS_RW_APP)) + strlen(temp_pkgid) + 1;
1040                         temp_application_path = calloc(len + 1, sizeof(char));
1041                         if (temp_application_path == NULL) {
1042                                 _E("memory alloc failed");
1043                                 free(temp_pkgid);
1044                                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1045                         }
1046                         snprintf(temp_application_path, len + 1, "%s/%s",
1047                                 tzplatform_getenv(TZ_SYS_RW_APP), temp_pkgid);
1048
1049                         temp_encoded_id = _app2sd_get_encoded_name((const char *)temp_pkgid, uid);
1050                         if (temp_encoded_id == NULL) {
1051                                 free(temp_pkgid);
1052                                 free(temp_application_path);
1053                                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1054                         }
1055                         len = strlen(app2sd_path) + strlen(temp_encoded_id) + 1;
1056                         temp_loopback_device = calloc(len + 1, sizeof(char));
1057                         if (temp_loopback_device == NULL) {
1058                                 _E("memory alloc failed");
1059                                 free(temp_pkgid);
1060                                 free(temp_application_path);
1061                                 free(temp_encoded_id);
1062                                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1063                         }
1064                         snprintf(temp_loopback_device, len + 1, "%s/%s",
1065                                 app2sd_path, temp_encoded_id);
1066                         free(temp_encoded_id);
1067                 } else {
1068                         tzplatform_set_user(uid);
1069                         len = strlen(tzplatform_getenv(TZ_USER_APP)) + strlen(temp_pkgid) + 1;
1070                         temp_application_path = calloc(len + 1, sizeof(char));
1071                         if (temp_application_path == NULL) {
1072                                 _E("memory alloc failed");
1073                                 free(temp_pkgid);
1074                                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1075                         }
1076                         snprintf(temp_application_path, len + 1, "%s/%s",
1077                                 tzplatform_getenv(TZ_USER_APP), temp_pkgid);
1078
1079                         temp_encoded_id = _app2sd_get_encoded_name((const char *)temp_pkgid, uid);
1080                         if (temp_encoded_id == NULL) {
1081                                 free(temp_pkgid);
1082                                 free(temp_application_path);
1083                                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1084                         }
1085                         snprintf(temp_uid, 32, "%d", uid);
1086                         len = strlen(app2sd_path) + strlen(temp_uid) + strlen(temp_encoded_id) + 2;
1087                         temp_loopback_device = calloc(len + 1, sizeof(char));
1088                         if (temp_loopback_device == NULL) {
1089                                 _E("memory alloc failed");
1090                                 free(temp_pkgid);
1091                                 free(temp_application_path);
1092                                 free(temp_encoded_id);
1093                                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1094                         }
1095                         snprintf(temp_loopback_device, len + 1, "%s/%s",
1096                                 app2sd_path, temp_encoded_id);
1097                         free(temp_encoded_id);
1098                         tzplatform_reset_user();
1099                 }
1100                 ret = _app2sd_update_loopback_device_size(pkgid,
1101                         loopback_device, application_path, temp_pkgid,
1102                         temp_loopback_device, temp_application_path,
1103                         reqd_disk_size, dir_list, uid);
1104                 free(temp_pkgid);
1105                 free(temp_application_path);
1106                 free(temp_loopback_device);
1107                 if (APP2EXT_SUCCESS != ret) {
1108                         _E("failed to update loopback device size");
1109                         return ret;
1110                 }
1111         }
1112
1113         /* get the associated device node for SD card applicationer */
1114 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1115         device_node =
1116                 _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
1117 #else
1118         device_node = _app2sd_find_associated_device_node(loopback_device);
1119 #endif
1120         if (NULL == device_node) {
1121                 /* do loopback setup */
1122 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1123                 ret = _app2sd_dmcrypt_open_device(pkgid, loopback_device,
1124                         false, uid, &device_node);
1125                 if (ret) {
1126                         _E("dmcrypt open device error");
1127                         return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
1128                 }
1129 #else
1130                 device_node = _app2sd_do_loopback_encryption_setup(pkgid,
1131                         loopback_device, uid);
1132                 if (device_node == NULL) {
1133                         _E("loopback encryption setup failed");
1134                         return APP2EXT_ERROR_DO_LOSETUP;
1135                 }
1136 #endif
1137
1138                 /* do mounting */
1139                 ret = _app2sd_mount_app_content(application_path, pkgid,
1140                         device_node, MOUNT_TYPE_RW, dir_list,
1141                         APP2SD_PRE_UPGRADE, uid);
1142                 if (ret) {
1143                         _E("mount failed");
1144                         if (device_node) {
1145                                 free(device_node);
1146                                 device_node = NULL;
1147                         }
1148                         return APP2EXT_ERROR_MOUNT_PATH;
1149                 }
1150         } else {
1151                 /* do re-mounting */
1152                 ret = _app2sd_mount_app_content(application_path, pkgid,
1153                         device_node, MOUNT_TYPE_RW_REMOUNT, NULL,
1154                         APP2SD_PRE_UPGRADE, uid);
1155                 if (ret) {
1156                         _E("remount failed");
1157                         if (device_node) {
1158                                 free(device_node);
1159                                 device_node = NULL;
1160                         }
1161                         return APP2EXT_ERROR_MOUNT_PATH;
1162                 }
1163         }
1164
1165         if (device_node) {
1166                 free(device_node);
1167                 device_node = NULL;
1168         }
1169
1170         sync();
1171         return ret;
1172 }
1173
1174 int app2sd_usr_post_app_upgrade(const char *pkgid,
1175                 app2ext_status install_status, uid_t uid)
1176 {
1177         char mmc_path[FILENAME_MAX] = { 0, };
1178         char loopback_device[FILENAME_MAX] = { 0, };
1179         char application_path[FILENAME_MAX] = { 0, };
1180         char *sdpath = NULL;
1181         char *encoded_id = NULL;
1182         int ret = APP2EXT_SUCCESS;
1183         int pkgmgr_ret = 0;
1184
1185         /* validate the function parameter recieved */
1186         if (pkgid == NULL || install_status < APP2EXT_STATUS_FAILED
1187                 || install_status > APP2EXT_STATUS_SUCCESS) {
1188                 _E("invalid func parameters");
1189                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
1190         }
1191
1192         /* check whether MMC is present or not */
1193         ret = _app2sd_check_mmc_status(&sdpath);
1194         if (ret) {
1195                 _E("MMC not present OR Not ready (%d)", ret);
1196                 return APP2EXT_ERROR_MMC_STATUS;
1197         }
1198         snprintf(mmc_path, FILENAME_MAX - 1, "%s", sdpath);
1199         free(sdpath);
1200         sync();
1201
1202         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
1203         if (encoded_id == NULL)
1204                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1205
1206         if (_is_global(uid)) {
1207                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1208                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
1209                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
1210                         mmc_path, EXTIMG_DIR, encoded_id);
1211         } else {
1212                 tzplatform_set_user(uid);
1213                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1214                         tzplatform_getenv(TZ_USER_APP), pkgid);
1215                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
1216                         mmc_path, EXTIMG_DIR, encoded_id);
1217                 tzplatform_reset_user();
1218         }
1219         free(encoded_id);
1220
1221         ret = __app2sd_finalize_device_setup(pkgid, loopback_device,
1222                 application_path, uid);
1223         if (ret) {
1224                 _E("failed to finalize device setup");
1225                 return ret;
1226         }
1227
1228         pkgmgr_ret = pkgmgrinfo_pkginfo_set_usr_installed_storage(pkgid,
1229                 INSTALL_EXTERNAL, loopback_device, uid);
1230         if (pkgmgr_ret < 0) {
1231                 _E("fail to update installed location " \
1232                         "to db[%s, %d] of uid(%d), pkgmgr ret(%d)",
1233                         pkgid, INSTALL_EXTERNAL, uid, pkgmgr_ret);
1234                 return APP2EXT_ERROR_PKGMGR_ERROR;
1235         }
1236
1237         sync();
1238         return ret;
1239 }
1240
1241 int app2sd_usr_force_clean(const char *pkgid, uid_t uid)
1242 {
1243         char mmc_path[FILENAME_MAX] = { 0, };
1244         char loopback_device[FILENAME_MAX] = { 0, };
1245         char application_path[FILENAME_MAX] = { 0, };
1246         char *sdpath = NULL;
1247         char *encoded_id = NULL;
1248         int ret = APP2EXT_SUCCESS;
1249
1250         /* validate the function parameter recieved */
1251         if (pkgid == NULL) {
1252                 _E("invalid func parameters");
1253                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
1254         }
1255
1256         /* check whether MMC is present or not */
1257         ret = _app2sd_check_mmc_status(&sdpath);
1258         if (ret) {
1259                 _E("MMC not present OR Not ready (%d)", ret);
1260                 return APP2EXT_ERROR_MMC_STATUS;
1261         }
1262         snprintf(mmc_path, FILENAME_MAX - 1, "%s", sdpath);
1263         free(sdpath);
1264         sync();
1265
1266         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
1267         if (encoded_id == NULL)
1268                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1269
1270         if (_is_global(uid)) {
1271                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1272                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
1273                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
1274                         mmc_path, EXTIMG_DIR, encoded_id);
1275         } else {
1276                 tzplatform_set_user(uid);
1277                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1278                         tzplatform_getenv(TZ_USER_APP), pkgid);
1279                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s/%s",
1280                         mmc_path, EXTIMG_DIR, encoded_id);
1281                 tzplatform_reset_user();
1282         }
1283         free(encoded_id);
1284
1285         ret = _app2sd_force_clean(pkgid, application_path, loopback_device, uid);
1286
1287         sync();
1288         return ret;
1289 }
1290
1291 int app2sd_enable_full_pkg(void)
1292 {
1293         int ret = APP2EXT_SUCCESS;
1294         char buf[FILENAME_MAX] = { 0, };
1295         char app2sd_path[FILENAME_MAX] = { 0, };
1296         char loopback_device[FILENAME_MAX] = { 0, };
1297         char *sdpath = NULL;
1298         char *pkgid = NULL;
1299         DIR *dir = NULL;
1300         struct dirent *entry = NULL;
1301         uid_t uid = 0;
1302
1303         /* check whether MMC is present or not */
1304         ret = _app2sd_check_mmc_status(&sdpath);
1305         if (ret) {
1306                 _E("MMC not present OR Not ready (%d)", ret);
1307                 return APP2EXT_ERROR_MMC_STATUS;
1308         }
1309         snprintf(app2sd_path, FILENAME_MAX - 1, "%s/%s",
1310                         sdpath, EXTIMG_DIR);
1311         free(sdpath);
1312
1313         dir = opendir(app2sd_path);
1314         if (!dir) {
1315                 strerror_r(errno, buf, sizeof(buf));
1316                 _E("failed to opendir (%s)", buf);
1317                 return APP2EXT_ERROR_OPEN_DIR;
1318         }
1319
1320         ret = _app2sd_initialize_db();
1321         if (ret) {
1322                 _E("app2sd db initialize failed");
1323                 closedir(dir);
1324                 return APP2EXT_ERROR_SQLITE_REGISTRY;
1325         }
1326
1327         while ((entry = readdir(dir)) != NULL) {
1328                 if (strcmp(entry->d_name, ".") == 0 ||
1329                         strcmp(entry->d_name, "..") == 0)
1330                         continue;
1331                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
1332                         app2sd_path, entry->d_name);
1333                 ret = _app2sd_get_info_from_db(loopback_device,
1334                         &pkgid, &uid);
1335                 if (ret) {
1336                         _W("failed to get info from db, continue");
1337                         continue;
1338                 }
1339                 if (pkgid) {
1340                         _D("pkgid(%s), uid(%d)", pkgid, uid);
1341                         ret = app2sd_usr_on_demand_setup_init(pkgid, uid);
1342                         if (ret) {
1343                                 _E("error(%d)", ret);
1344                                 continue;
1345                         }
1346                         free(pkgid);
1347                         pkgid = NULL;
1348                 }
1349         }
1350
1351         if (pkgid) {
1352                 free(pkgid);
1353                 pkgid = NULL;
1354         }
1355         closedir(dir);
1356
1357         sync();
1358         return ret;
1359 }
1360
1361 static int _app2sd_info_cb_func(const char *pkgid, uid_t uid)
1362 {
1363         int ret = APP2EXT_SUCCESS;
1364
1365         if (pkgid) {
1366                 _D("pkgid(%s), uid(%d)", pkgid, uid);
1367                 ret = app2sd_usr_on_demand_setup_exit(pkgid, uid);
1368                 if (ret)
1369                         _E("error(%d)", ret);
1370         }
1371
1372         return ret;
1373 }
1374
1375 int app2sd_disable_full_pkg(void)
1376 {
1377         int ret = APP2EXT_SUCCESS;
1378
1379         ret = _app2sd_initialize_db();
1380         if (ret) {
1381                 _E("app2sd db initialize failed");
1382                 return APP2EXT_ERROR_SQLITE_REGISTRY;
1383         }
1384
1385         ret = _app2sd_get_foreach_info_from_db((app2sd_info_cb)_app2sd_info_cb_func);
1386         if (ret)
1387                 _E("disable full pkg error(%d)", ret);
1388
1389         sync();
1390         return ret;
1391 }
1392
1393 static int _app2sd_migrate_legacy_image(const char *pkgid, const char *passwd,
1394                 const char *mmc_path, uid_t uid)
1395 {
1396         int ret = 0;
1397         char *device_node = NULL;
1398         char *encoded_id = NULL;
1399         char new_image[FILENAME_MAX] = { 0, };
1400         char legacy_image[FILENAME_MAX] = { 0, };
1401         char application_path[FILENAME_MAX] = { 0, };
1402         uid_t default_uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
1403
1404         if (_is_global(uid)) {
1405                 snprintf(application_path, sizeof(application_path), "%s/%s",
1406                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
1407         } else {
1408                 tzplatform_set_user(uid);
1409                 snprintf(application_path, sizeof(application_path), "%s/%s",
1410                         tzplatform_getenv(TZ_USER_APP), pkgid);
1411                 tzplatform_reset_user();
1412         }
1413
1414         /* make the information and insert to DB */
1415         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
1416         if (encoded_id == NULL)
1417                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1418         snprintf(new_image, sizeof(new_image), "%s/%s",
1419                 mmc_path, encoded_id);
1420         free(encoded_id);
1421
1422         snprintf(legacy_image, sizeof(legacy_image), "%s/%s",
1423                 mmc_path, pkgid);
1424
1425         ret = _app2sd_rename_dir(legacy_image, new_image);
1426         if (ret) {
1427                 _E("unable to rename (%s)", legacy_image);
1428                 return APP2EXT_ERROR_ACCESS_FILE;
1429         }
1430
1431         ret = pkgmgrinfo_pkginfo_set_usr_installed_storage(pkgid,
1432                 INSTALL_EXTERNAL, new_image, uid);
1433         if (ret < 0) {
1434                 _E("fail to update installed location " \
1435                         "to db[%s, %d] of uid(%d), ret(%d)",
1436                         pkgid, INSTALL_EXTERNAL, uid, ret);
1437                 return APP2EXT_ERROR_PKGMGR_ERROR;
1438         }
1439
1440         /* update app2sd db */
1441         if (_is_global(uid)) {
1442                 ret = _app2sd_remove_info_from_db(pkgid, default_uid);
1443                 if (ret) {
1444                         _E("cannot remove info from db");
1445                         return APP2EXT_ERROR_SQLITE_REGISTRY;
1446                 }
1447         }
1448         ret = _app2sd_set_info_in_db(pkgid, passwd, new_image, uid);
1449         if (ret) {
1450                 _E("unable to save info");
1451                 return APP2EXT_ERROR_SQLITE_REGISTRY;
1452         }
1453
1454 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1455         device_node =
1456                 _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
1457         if (device_node) {
1458                 _E("device_node(%s_%d) already associated", pkgid, uid);
1459                 free(device_node);
1460                 return APP2EXT_ERROR_ALREADY_MOUNTED;
1461         }
1462
1463         ret = _app2sd_dmcrypt_open_device(pkgid, new_image, false,
1464                 uid, &device_node);
1465         if (ret) {
1466                 _E("dmcrypt open device error(%d)", ret);
1467                 return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
1468         }
1469 #else
1470         result = (char *)_app2sd_find_associated_device(new_image);
1471         /* process the string */
1472         if ((result != NULL) && strstr(result, "/dev") != NULL) {
1473                 _E("already associated");
1474                 free(result);
1475                 result = NULL;
1476                 return APP2EXT_ERROR_ALREADY_MOUNTED;
1477         }
1478
1479         /* do loopback setup */
1480         device_node = _app2sd_do_loopback_encryption_setup(pkgid,
1481                 new_image, uid);
1482         if (device_node == NULL) {
1483                 _E("loopback encryption setup failed");
1484                 return APP2EXT_ERROR_DO_LOSETUP;
1485         }
1486 #endif
1487
1488         /* do mounting */
1489         ret = _app2sd_mount_app_content(application_path, pkgid,
1490                 device_node, MOUNT_TYPE_RW, NULL,
1491                 APP2SD_MIGRATE_LEGACY, uid);
1492         if (ret) {
1493                 _E("mount failed");
1494                 if (device_node) {
1495                         free(device_node);
1496                         device_node = NULL;
1497                 }
1498                 return APP2EXT_ERROR_MOUNT_PATH;
1499         }
1500
1501         if (device_node) {
1502                 free(device_node);
1503                 device_node = NULL;
1504         }
1505
1506         sync();
1507         return APP2EXT_SUCCESS;
1508 }
1509
1510 int app2sd_pre_migrate_legacy(const char *pkgid, uid_t uid)
1511 {
1512         int ret = APP2EXT_SUCCESS;
1513         char *passwd = NULL;
1514         char *sdpath = NULL;
1515         char mmc_path[FILENAME_MAX] = { 0, };
1516         char file_path[FILENAME_MAX] = { 0, };
1517         uid_t default_uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
1518         char *filename;
1519
1520         /* check whether MMC is present or not */
1521         ret = _app2sd_check_mmc_status(&sdpath);
1522         if (ret) {
1523                 _E("MMC not present OR Not ready (%d)", ret);
1524                 return APP2EXT_ERROR_MMC_STATUS;
1525         }
1526         snprintf(mmc_path, sizeof(mmc_path), "%s/%s", sdpath, EXTIMG_DIR);
1527         free(sdpath);
1528         snprintf(file_path, sizeof(file_path), "%s/%s", mmc_path, pkgid);
1529
1530         ret = _app2sd_initialize_db();
1531         if (ret) {
1532                 _E("app2sd db initialize failed");
1533                 return APP2EXT_ERROR_SQLITE_REGISTRY;
1534         }
1535
1536         /* In the upgrade script, the information
1537          * of legacy image are filled with default user-id,
1538          * pkgid(from old db), passwd(from old db) and
1539          * empty filename in app2sd db. */
1540         filename = _app2sd_get_filename_from_db(pkgid, default_uid);
1541         if (filename == NULL) {
1542                 passwd = _app2sd_get_password_from_db(pkgid, default_uid);
1543                 if (passwd) {
1544                         ret = _app2sd_migrate_legacy_image(pkgid, passwd,
1545                                 mmc_path, uid);
1546                         free(passwd);
1547                         passwd = NULL;
1548                 } else {
1549                         _E("invalid package info");
1550                         return APP2EXT_ERROR_INVALID_PACKAGE;
1551                 }
1552         } else {
1553                 free(filename);
1554                 _W("same pkg exists, remove legacy file (%s)", file_path);
1555                 ret = remove(file_path);
1556                 if (ret < 0)
1557                         _E("failed to remove, errno(%d)", errno);
1558                 return APP2EXT_ERROR_PKG_EXISTS;
1559         }
1560
1561         return ret;
1562 }
1563
1564 int app2sd_post_migrate_legacy(const char *pkgid, uid_t uid)
1565 {
1566         int ret = APP2EXT_SUCCESS;
1567         char *sdpath = NULL;
1568         char *encoded_id = NULL;
1569         char mmc_path[FILENAME_MAX] = { 0, };
1570         char application_path[FILENAME_MAX] = { 0, };
1571         char loopback_device[FILENAME_MAX] = { 0, };
1572
1573         /* check whether MMC is present or not */
1574         ret = _app2sd_check_mmc_status(&sdpath);
1575         if (ret) {
1576                 _E("MMC not present OR Not ready (%d)", ret);
1577                 return APP2EXT_ERROR_MMC_STATUS;
1578         }
1579         snprintf(mmc_path, sizeof(mmc_path), "%s/%s",
1580                 sdpath, EXTIMG_DIR);
1581         free(sdpath);
1582
1583         if (_is_global(uid)) {
1584                 snprintf(application_path, sizeof(application_path), "%s/%s",
1585                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
1586         } else {
1587                 tzplatform_set_user(uid);
1588                 snprintf(application_path, sizeof(application_path), "%s/%s",
1589                         tzplatform_getenv(TZ_USER_APP), pkgid);
1590                 tzplatform_reset_user();
1591         }
1592
1593         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
1594         if (encoded_id == NULL) {
1595                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1596         }
1597         snprintf(loopback_device, sizeof(loopback_device), "%s/%s",
1598                 mmc_path, encoded_id);
1599         free(encoded_id);
1600
1601         ret = __app2sd_finalize_device_setup(pkgid, loopback_device,
1602                 application_path, uid);
1603         if (ret) {
1604                 _E("failed to finalize device setup");
1605                 return ret;
1606         }
1607
1608         return APP2EXT_SUCCESS;
1609 }
1610
1611 /* this function is called when sdcard is inserted */
1612 int app2sd_migrate_legacy_all(void)
1613 {
1614         int ret = APP2EXT_SUCCESS;
1615         int rc = 0;
1616         char buf[FILENAME_MAX] = { 0, };
1617         char app2sd_path[FILENAME_MAX] = { 0, };
1618         char loopback_device[FILENAME_MAX] = { 0, };
1619         char *sdpath = NULL;
1620         DIR *dir = NULL;
1621         struct dirent entry;
1622         struct dirent *result = NULL;
1623         uid_t default_uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
1624         pkgmgr_client *pc;
1625
1626         /* check whether MMC is present or not */
1627         ret = _app2sd_check_mmc_status(&sdpath);
1628         if (ret) {
1629                 _E("MMC not present OR Not ready (%d)", ret);
1630                 return APP2EXT_ERROR_MMC_STATUS;
1631         }
1632         snprintf(app2sd_path, sizeof(app2sd_path), "%s/%s",
1633                 sdpath, EXTIMG_DIR);
1634         free(sdpath);
1635
1636         dir = opendir(app2sd_path);
1637         if (!dir) {
1638                 strerror_r(errno, buf, sizeof(buf));
1639                 _E("failed to opendir (%s)", buf);
1640                 return APP2EXT_ERROR_OPEN_DIR;
1641         }
1642
1643         pc = pkgmgr_client_new(PC_REQUEST);
1644         if (pc == NULL) {
1645                 _E("failed to create pkgmgr client");
1646                 closedir(dir);
1647                 return APP2EXT_ERROR_PKGMGR_ERROR;
1648         }
1649
1650         for (rc = readdir_r(dir, &entry, &result);
1651                 rc == 0 && result != NULL;
1652                 rc = readdir_r(dir, &entry, &result)) {
1653                 if (strcmp(entry.d_name, ".") == 0 ||
1654                         strcmp(entry.d_name, "..") == 0)
1655                         continue;
1656                 snprintf(loopback_device, sizeof(loopback_device), "%s/%s",
1657                         app2sd_path, entry.d_name);
1658                 /* check losetup image */
1659                 if (_app2sd_check_is_luks_device(loopback_device) == 0) {
1660                         /* call installer backend
1661                          * to change access-rule and broadcast this update */
1662                         ret = pkgmgr_client_usr_migrate_external_image(pc,
1663                                 entry.d_name, default_uid);
1664                         if (ret < 0)
1665                                 _E("failed to request migration, ret(%d)", ret);
1666                 }
1667         }
1668
1669         pkgmgr_client_free(pc);
1670         closedir(dir);
1671
1672         return ret;
1673 }
1674