fix missing encoded_id related change & code clearing.
[platform/core/appfw/app2sd.git] / plugin / app2sd / src / app2sd_interface.c
1 /*
2  * app2ext
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Garima Shrivastava<garima.s@samsung.com>
7  *      Jyotsna Dhumale <jyotsna.a@samsung.com>
8  *      Venkatesha Sarpangala <sarpangala.v@samsung.com>
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  */
23
24 #include <pkgmgr-info.h>
25
26 #include "app2sd_internals.h"
27
28 static int __app2sd_create_app2sd_directories(uid_t uid)
29 {
30         int ret = 0;
31         mode_t mode = DIR_PERMS;
32
33         ret = mkdir(APP2SD_PATH, mode);
34         if (ret) {
35                 if (errno != EEXIST) {
36                         _E("create directory failed," \
37                                 " error no is (%d)", errno);
38                         return APP2EXT_ERROR_CREATE_DIRECTORY;
39                 }
40         }
41
42         return APP2EXT_SUCCESS;
43 }
44
45 int app2sd_usr_pre_app_install(const char *pkgid, GList* dir_list, int size, uid_t uid)
46 {
47         int ret = 0;
48         int free_mmc_mem = 0;
49         char *device_node = NULL;
50         char *devi = NULL;
51         char *result = NULL;
52         char application_path[FILENAME_MAX] = { 0, };
53         char loopback_device[FILENAME_MAX] = { 0, };
54         char *encoded_id = NULL;
55         int reqd_disk_size = size + ceil(size * 0.2);
56
57         /* validate the function parameter recieved */
58         if (pkgid == NULL || dir_list == NULL || size <= 0) {
59                 _E("invalid function arguments");
60                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
61         }
62
63         /* check whether MMC is present or not */
64         ret = _app2sd_check_mmc_status();
65         if (ret) {
66                 _E("MMC not preset OR Not ready (%d)", ret);
67                 return APP2EXT_ERROR_MMC_STATUS;
68         }
69
70         /* find available free memory in the MMC card */
71         ret = _app2sd_get_available_free_memory(MMC_PATH, &free_mmc_mem);
72         if (ret) {
73                 _E("unable to get available free memory in MMC (%d)",
74                         ret);
75                 return APP2EXT_ERROR_MMC_STATUS;
76         }
77         _D("size details for application installation:" \
78                 " size=(%d)MB, reqd_disk_size=(%d)MB, free_mmc_size=(%d)MB",
79                 size, reqd_disk_size, free_mmc_mem);
80
81         /* if avaialalbe free memory in MMC is less than required size + 5MB,
82          * return error
83          */
84         if ((reqd_disk_size + PKG_BUF_SIZE + MEM_BUF_SIZE) > free_mmc_mem) {
85                 _E("insufficient memory in MMC for"
86                         " application installation (%d)", ret);
87                 return APP2EXT_ERROR_MMC_INSUFFICIENT_MEMORY;
88         }
89
90         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
91         if (encoded_id == NULL) {
92                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
93         }
94         if (_is_global(uid)) {
95                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
96                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
97                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
98                         APP2SD_PATH, encoded_id);
99         } else {
100                 tzplatform_set_user(uid);
101                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
102                         tzplatform_getenv(TZ_USER_APP), pkgid);
103                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
104                         APP2SD_PATH, encoded_id);
105                 tzplatform_reset_user();
106         }
107         free(encoded_id);
108
109         ret = __app2sd_create_app2sd_directories(uid);
110         if (ret) {
111                 _E("failed to create app2sd dirs");
112                 return ret;
113         }
114
115         /* check same loopback_device existence */
116         result = (char *)_app2sd_find_associated_device(loopback_device);
117         if (result != NULL) {
118                 _E("there is same associated File (%s)", loopback_device);
119                 return APP2EXT_ERROR_SAME_LOOPBACK_DEVICE_EXISTS;
120         }
121
122         /* create a loopback device */
123         ret = _app2sd_create_loopback_device(pkgid, loopback_device,
124                 (reqd_disk_size + PKG_BUF_SIZE));
125         if (ret) {
126                 _W("package already present, delete app directory");
127                 ret = _app2sd_delete_directory(application_path);
128                 if (ret) {
129                         _E("unable to delete the directory (%s)",
130                                 application_path);
131                         return ret;
132                 }
133         }
134
135         /* perform loopback encryption setup */
136         device_node = _app2sd_do_loopback_encryption_setup(pkgid,
137                 loopback_device, uid);
138         if (!device_node) {
139                 _E("loopback encryption setup failed");
140                 _app2sd_delete_loopback_device(loopback_device);
141                 return APP2EXT_ERROR_DO_LOSETUP;
142         }
143
144         /* check whether loopback device is associated
145          * with device node or not
146          */
147         devi = _app2sd_find_associated_device_node(loopback_device);
148         if (devi == NULL) {
149                 _E("finding associated device node failed");
150                 ret = APP2EXT_ERROR_DO_LOSETUP;
151                 goto FINISH_OFF;
152         }
153
154         /* format the loopback file system */
155         ret = _app2sd_create_file_system(device_node);
156         if (ret) {
157                 _E("creating FS failed failed");
158                 ret = APP2EXT_ERROR_CREATE_FS;
159                 goto FINISH_OFF;
160         }
161
162         /* mount the loopback encrypted pseudo device on application
163          * installation path as with Read Write permission
164          */
165         ret =_app2sd_mount_app_content(application_path, pkgid,
166                 device_node, MOUNT_TYPE_RW, dir_list,
167                 APP2SD_PRE_INSTALL, uid);
168         if (ret) {
169                 _E("mounting dev path to app install path failed");
170                 ret = APP2EXT_ERROR_MOUNT_PATH;
171                 goto FINISH_OFF;
172         }
173
174         /* Success */
175         ret = APP2EXT_SUCCESS;
176         goto END;
177
178 FINISH_OFF:
179         if (device_node) {
180                 result = _app2sd_detach_loop_device(device_node);
181                 if (result) {
182                         free(result);
183                         result = NULL;
184                 }
185                 _app2sd_delete_loopback_device(loopback_device);
186         }
187
188 END:
189         if (device_node) {
190                 free(device_node);
191                 device_node = NULL;
192         }
193
194         if (devi) {
195                 free(devi);
196                 devi = NULL;
197         }
198
199         return ret;
200 }
201
202 int app2sd_usr_post_app_install(const char *pkgid,
203                 app2ext_status install_status, uid_t uid)
204 {
205         char *device_name = NULL;
206         char application_path[FILENAME_MAX] = { 0, };
207         char loopback_device[FILENAME_MAX] = { 0, };
208         char *encoded_id = NULL;
209         int ret = APP2EXT_SUCCESS;
210         int pkgmgr_ret = 0;
211
212         /* validate the function parameter recieved */
213         if (pkgid == NULL || install_status < APP2EXT_STATUS_FAILED
214                 || install_status > APP2EXT_STATUS_SUCCESS) {
215                 _E("invalid func parameters");
216                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
217         }
218
219         /* check whether MMC is present or not */
220         ret = _app2sd_check_mmc_status();
221         if (ret) {
222                 _E("MMC not present OR Not ready (%d)", ret);
223                 return APP2EXT_ERROR_MMC_STATUS;
224         }
225         sync();
226
227         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
228         if (encoded_id == NULL) {
229                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
230         }
231         if (_is_global(uid)) {
232                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
233                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
234                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
235                         APP2SD_PATH, encoded_id);
236         } else {
237                 tzplatform_set_user(uid);
238                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
239                         tzplatform_getenv(TZ_USER_APP), pkgid);
240                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
241                         APP2SD_PATH, encoded_id);
242                 tzplatform_reset_user();
243         }
244         free(encoded_id);
245
246         /* get the associated device node for SD card applicationer */
247         device_name = _app2sd_find_associated_device_node(loopback_device);
248         if (NULL == device_name) {
249                 return APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_NODE;
250         }
251
252         ret = _app2sd_unmount_app_content(application_path);
253         if (ret) {
254                 if (device_name) {
255                         free(device_name);
256                         device_name = NULL;
257                 }
258                 _E("unable to unmount the app content (%d)", ret);
259                 return APP2EXT_ERROR_UNMOUNT;
260         }
261
262         ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
263         if (ret) {
264                 if (device_name) {
265                         free(device_name);
266                         device_name = NULL;
267                 }
268                 _E("unable to detach the loopback encryption setup" \
269                         " for the application");
270                 return APP2EXT_ERROR_UNMOUNT;
271         }
272
273         if (device_name) {
274                 free(device_name);
275                 device_name = NULL;
276         }
277
278         /* take appropriate action based on
279          * installation status of application package
280          */
281         if (install_status == APP2EXT_STATUS_FAILED) {
282                 /* delete the loopback device from the SD card */
283                 ret = _app2sd_delete_loopback_device(loopback_device);
284                 if (ret) {
285                         _E("unable to delete the loopback device from the SD Card");
286                         return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
287                 }
288                 ret = _app2sd_remove_password_from_db(pkgid);
289
290                 if (ret)
291                         _E("unable to delete the password");
292
293                 ret = _app2sd_delete_directory(application_path);
294
295                 if (ret)
296                         _E("unable to delete the directory (%s)", application_path);
297         } else {
298                 /* if the status is success, then update installed storage
299                  * to pkgmgr_parser db
300                  */
301                 pkgmgr_ret = pkgmgrinfo_pkginfo_set_usr_installed_storage(pkgid,
302                         INSTALL_EXTERNAL, uid);
303                 if (pkgmgr_ret < 0) {
304                         _E("fail to update installed location " \
305                                 "to db[%s, %d] of uid(%d), pkgmgr ret(%d)",
306                                 pkgid, INSTALL_EXTERNAL, uid, pkgmgr_ret);
307                         return APP2EXT_ERROR_PKGMGR_ERROR;
308                 }
309         }
310
311         return ret;
312 }
313
314 int app2sd_usr_on_demand_setup_init(const char *pkgid, uid_t uid)
315 {
316         int ret = APP2EXT_SUCCESS;
317         char application_path[FILENAME_MAX] = { 0, };
318         char loopback_device[FILENAME_MAX] = { 0, };
319         char *encoded_id = NULL;
320         char *device_node = NULL;
321         char *result = NULL;
322         FILE *fp = NULL;
323
324         /* validate the function parameter recieved */
325         if (pkgid == NULL) {
326                 _E("invalid function arguments to app launch setup");
327                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
328         }
329
330         /* check whether MMC is present or not */
331         ret = _app2sd_check_mmc_status();
332         if (ret) {
333                 _E("MMC not preset OR Not ready (%d)", ret);
334                 return APP2EXT_ERROR_MMC_STATUS;
335         }
336
337         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
338         if (encoded_id == NULL) {
339                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
340         }
341         /* check app entry is there in sd card or not. */
342         if (_is_global(uid)) {
343                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
344                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
345                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
346                         APP2SD_PATH, encoded_id);
347         } else {
348                 tzplatform_set_user(uid);
349                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
350                         tzplatform_getenv(TZ_USER_APP), pkgid);
351                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
352                         APP2SD_PATH, encoded_id);
353                 tzplatform_reset_user();
354         }
355         free(encoded_id);
356
357         fp = fopen(loopback_device, "r+");
358         if (fp == NULL) {
359                 _E("app entry is not present in SD Card");
360                 return APP2EXT_ERROR_INVALID_PACKAGE;
361         }
362         fclose(fp);
363
364         result = (char *)_app2sd_find_associated_device(loopback_device);
365         /* process the string */
366         if ((result != NULL) && strstr(result, "/dev") != NULL) {
367                 _E("already associated");
368                 free(result);
369                 result = NULL;
370                 return APP2EXT_ERROR_ALREADY_MOUNTED;
371         }
372
373         /* do loopback setup */
374         device_node = _app2sd_do_loopback_encryption_setup(pkgid,
375                 loopback_device, uid);
376         if (device_node == NULL) {
377                 _E("loopback encryption setup failed");
378                 return APP2EXT_ERROR_DO_LOSETUP;
379         }
380
381         /* do mounting */
382         ret = _app2sd_mount_app_content(application_path, pkgid,
383                 device_node, MOUNT_TYPE_RD, NULL, APP2SD_APP_LAUNCH, uid);
384         if (ret) {
385                 _E("mount failed");
386                 if (device_node) {
387                         free(device_node);
388                         device_node = NULL;
389                 }
390                 return APP2EXT_ERROR_MOUNT_PATH;
391         }
392
393         if (device_node) {
394                 free(device_node);
395                 device_node = NULL;
396         }
397
398         return ret;
399 }
400
401 int app2sd_usr_on_demand_setup_exit(const char *pkgid, uid_t uid)
402 {
403         int ret = APP2EXT_SUCCESS;
404         char application_path[FILENAME_MAX] = { 0, };
405         char loopback_device[FILENAME_MAX] = { 0, };
406         char *encoded_id = NULL;
407         FILE *fp = NULL;
408
409         /* validate the function parameter recieved */
410         if (pkgid == NULL) {
411                 _E("invalid function arguments to app launch setup");
412                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
413         }
414
415         /* check whether MMC is present or not */
416         ret = _app2sd_check_mmc_status();
417         if (ret) {
418                 _E("MMC not preset OR Not ready (%d)", ret);
419                 return APP2EXT_ERROR_MMC_STATUS;
420         }
421
422         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
423         if (encoded_id == NULL) {
424                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
425         }
426         /* check app entry is there in sd card or not. */
427         if (_is_global(uid)) {
428                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
429                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
430                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
431                         APP2SD_PATH, encoded_id);
432         } else {
433                 tzplatform_set_user(uid);
434                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
435                         tzplatform_getenv(TZ_USER_APP), pkgid);
436                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
437                         APP2SD_PATH, encoded_id);
438                 tzplatform_reset_user();
439         }
440         free(encoded_id);
441
442         fp = fopen(loopback_device, "r+");
443         if (fp == NULL) {
444                 _E("app entry is not present in SD Card");
445                 return APP2EXT_ERROR_INVALID_PACKAGE;
446         }
447         fclose(fp);
448
449         ret = _app2sd_unmount_app_content(application_path);
450         if (ret) {
451                 _E("unable to unmount the SD application");
452                 return APP2EXT_ERROR_UNMOUNT;
453         }
454
455         ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
456         if (ret) {
457                 _E("unable to remove loopback setup");
458                 return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
459         }
460
461         return ret;
462 }
463
464 int app2sd_usr_pre_app_uninstall(const char *pkgid, uid_t uid)
465 {
466         int ret = APP2EXT_SUCCESS;
467         char application_path[FILENAME_MAX] = { 0, };
468         char loopback_device[FILENAME_MAX] = { 0, };
469         char *encoded_id = NULL;
470         char *device_node = NULL;
471         FILE *fp = NULL;
472
473         /* validate the function parameter recieved */
474         if (pkgid == NULL) {
475                 _E("invalid function arguments to app launch setup");
476                 ret = APP2EXT_ERROR_INVALID_ARGUMENTS;
477                 goto END;
478         }
479
480         /* check whether MMC is present or not */
481         ret = _app2sd_check_mmc_status();
482         if (ret) {
483                 _E("MMC not preset OR Not ready (%d)", ret);
484                 ret = APP2EXT_ERROR_MMC_STATUS;
485                 goto END;
486         }
487
488         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
489         if (encoded_id == NULL) {
490                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
491         }
492         if (_is_global(uid)) {
493                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
494                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
495                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
496                         APP2SD_PATH, encoded_id);
497         } else {
498                 tzplatform_set_user(uid);
499                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
500                         tzplatform_getenv(TZ_USER_APP), pkgid);
501                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
502                         APP2SD_PATH, encoded_id);
503                 tzplatform_reset_user();
504         }
505         free(encoded_id);
506
507         /* check app entry is there in sd card or not. */
508         fp = fopen(loopback_device, "r+");
509         if (fp == NULL) {
510                 _E("app entry is not present in SD Card");
511                 ret = APP2EXT_ERROR_INVALID_PACKAGE;
512                 goto END;
513         }
514         fclose(fp);
515
516         /* get the associated device node for SD card applicationer */
517         device_node = _app2sd_find_associated_device_node(loopback_device);
518         if (NULL == device_node) {
519                 /* do loopback setup */
520                 device_node = _app2sd_do_loopback_encryption_setup(pkgid,
521                         loopback_device, uid);
522                 if (device_node == NULL) {
523                         _E("loopback encryption setup failed");
524                         ret = APP2EXT_ERROR_DO_LOSETUP;
525                         goto END;
526                 }
527                 /* do mounting */
528                 ret = _app2sd_mount_app_content(application_path, pkgid,
529                         device_node, MOUNT_TYPE_RW, NULL,
530                         APP2SD_PRE_UNINSTALL, uid);
531                 if (ret) {
532                         _E("mount failed");
533                         if (device_node) {
534                                 free(device_node);
535                                 device_node = NULL;
536                         }
537                         ret = APP2EXT_ERROR_MOUNT_PATH;
538                         goto END;
539                 }
540         } else {
541                 /* do re-mounting */
542                 ret = _app2sd_mount_app_content(application_path, pkgid,
543                         device_node, MOUNT_TYPE_RW_REMOUNT, NULL,
544                         APP2SD_PRE_UNINSTALL, uid);
545                 if (ret) {
546                         _E("remount failed");
547                         if (device_node) {
548                                 free(device_node);
549                                 device_node = NULL;
550                         }
551                         ret = APP2EXT_ERROR_MOUNT_PATH;
552                         goto END;
553                 }
554         }
555         if (device_node) {
556                 free(device_node);
557                 device_node = NULL;
558         }
559
560 END:
561         return ret;
562 }
563
564 int app2sd_usr_post_app_uninstall(const char *pkgid, uid_t uid)
565 {
566         char application_path[FILENAME_MAX] = { 0, };
567         char loopback_device[FILENAME_MAX] = { 0, };
568         char *encoded_id = NULL;
569         int ret = APP2EXT_SUCCESS;
570
571         /* validate the function parameter recieved */
572         if (pkgid == NULL) {
573                 _E("invalid function arguments");
574                 ret = APP2EXT_ERROR_INVALID_ARGUMENTS;
575                 goto END;
576         }
577
578         /* check whether MMC is present or not */
579         ret = _app2sd_check_mmc_status();
580         if (ret) {
581                 _E("MMC not preset OR Not ready (%d)", ret);
582                 ret = APP2EXT_ERROR_MMC_STATUS;
583                 goto END;
584         }
585
586         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
587         if (encoded_id == NULL) {
588                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
589         }
590         if (_is_global(uid)) {
591                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
592                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
593                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
594                         APP2SD_PATH, encoded_id);
595         } else {
596                 tzplatform_set_user(uid);
597                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
598                         tzplatform_getenv(TZ_USER_APP), pkgid);
599                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
600                         APP2SD_PATH, encoded_id);
601                 tzplatform_reset_user();
602         }
603         free(encoded_id);
604
605         /* unmount the loopback encrypted pseudo device from
606          * the application installation path
607          */
608         ret = _app2sd_unmount_app_content(application_path);
609         if (ret) {
610                 _E("unable to unmount the app content (%d)", ret);
611                 ret = APP2EXT_ERROR_UNMOUNT;
612                 goto END;
613         }
614         /* detach the loopback encryption setup for the application */
615         ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
616         if (ret) {
617                 _E("unable to Detach the loopback encryption setup" \
618                         " for the application");
619                 ret = APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE;
620                 goto END;
621         }
622
623         /* delete the loopback device from the SD card */
624         ret = _app2sd_delete_loopback_device(loopback_device);
625         if (ret) {
626                 _E("unable to delete the " \
627                         "loopback device from the SD Card");
628                 ret =  APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
629                 goto END;
630         }
631
632         ret = _app2sd_delete_directory(application_path);
633         if (ret) {
634                 _E("unable to delete the directory (%s)",
635                 application_path);
636                 goto END;
637         }
638
639         /* remove encryption password from DB */
640         ret = _app2sd_initialize_db();
641         if (ret) {
642                 _E("app2sd db initialize failed");
643                 ret = APP2EXT_ERROR_SQLITE_REGISTRY;
644                 goto END;
645         }
646
647         ret = _app2sd_remove_password_from_db(pkgid);
648         if (ret) {
649                 _E("cannot remove password from db");
650                 ret = APP2EXT_ERROR_SQLITE_REGISTRY;
651                 goto END;
652         }
653
654 END:
655         return ret;
656 }
657
658 int app2sd_usr_move_installed_app(const char *pkgid, GList* dir_list,
659                 app2ext_move_type move_type, uid_t uid)
660 {
661         int ret = 0;
662         int pkgmgr_ret = 0;
663
664         /* validate function arguments */
665         if (pkgid == NULL || dir_list == NULL
666                 || move_type < APP2EXT_MOVE_TO_EXT
667                 || move_type > APP2EXT_MOVE_TO_PHONE) {
668                 _E("invalid function arguments");
669                 ret = APP2EXT_ERROR_INVALID_ARGUMENTS;
670                 goto END;
671         }
672
673         pkgmgrinfo_pkginfo_h info_handle = NULL;
674         pkgmgrinfo_installed_storage storage = PMINFO_INTERNAL_STORAGE;
675         pkgmgr_ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &info_handle);
676         if (pkgmgr_ret < 0) {
677                 _E("failed to get pkginfo for pkg(%s), uid(%d), pkgmgr_ret(%d)",
678                         pkgid, uid, pkgmgr_ret);
679         }
680         pkgmgr_ret = pkgmgrinfo_pkginfo_get_installed_storage(info_handle, &storage);
681         if (pkgmgr_ret < 0) {
682                 _E("failed to get installed storage for pkg(%s) of uid(%d), pkgmgr_ret(%d)",
683                         pkgid, uid, pkgmgr_ret);
684                 pkgmgrinfo_pkginfo_destroy_pkginfo(info_handle);
685                 goto END;
686         }
687
688         if ((move_type == APP2EXT_MOVE_TO_EXT && storage == PMINFO_EXTERNAL_STORAGE)
689                 || (move_type == APP2EXT_MOVE_TO_PHONE && storage == PMINFO_INTERNAL_STORAGE)) {
690                         ret = APP2EXT_ERROR_PKG_EXISTS;
691                         _E("PKG_EXISTS in [%d] STORAGE", storage);
692                         pkgmgrinfo_pkginfo_destroy_pkginfo(info_handle);
693                         goto END;
694         } else {
695                 _D("pkgid[%s] move to STORAGE [%d]", pkgid, storage);
696         }
697         pkgmgrinfo_pkginfo_destroy_pkginfo(info_handle);
698
699         ret = _app2sd_usr_move_app(pkgid, move_type, dir_list, uid);
700         if (ret) {
701                 _D("unable to move application");
702                 goto END;
703         }
704
705         /* if move is completed, then update installed storage to pkgmgr_parser db */
706         if (move_type == APP2EXT_MOVE_TO_EXT) {
707                 pkgmgr_ret = pkgmgrinfo_pkginfo_set_usr_installed_storage(pkgid,
708                                 INSTALL_EXTERNAL, uid);
709                 if (pkgmgr_ret < 0) {
710                         _E("failed to update installed location to db " \
711                                 "[%s, %s] of uid(%d), pkgmgr_ret(%d)",
712                                 pkgid, INSTALL_EXTERNAL, uid, pkgmgr_ret);
713                         return APP2EXT_ERROR_PKGMGR_ERROR;
714                 }
715         } else {
716                 pkgmgr_ret = pkgmgrinfo_pkginfo_set_usr_installed_storage(pkgid,
717                                 INSTALL_INTERNAL, uid);
718                 if (pkgmgr_ret < 0) {
719                         _E("failed to update installed location to db " \
720                                 "[%s, %s] of uid(%d), pkgmgr_ret(%d)",
721                                 pkgid, INSTALL_INTERNAL, uid, pkgmgr_ret);
722                         return APP2EXT_ERROR_PKGMGR_ERROR;
723                 }
724         }
725
726 END:
727         _app2sd_make_result_info_file((char*)pkgid, ret, uid);
728
729         return ret;
730 }
731
732 int app2sd_usr_pre_app_upgrade(const char *pkgid, GList* dir_list,
733                 int size, uid_t uid)
734 {
735         int ret = APP2EXT_SUCCESS;
736         char loopback_device[FILENAME_MAX] = { 0, };
737         char application_path[FILENAME_MAX] = { 0, };
738         char temp_uid[32] = { 0, };
739         char *temp_pkgid = NULL;
740         char *temp_loopback_device = NULL;
741         char *temp_application_path = NULL;
742         char *device_node = NULL;
743         char *encoded_id = NULL;
744         char *temp_encoded_id = NULL;
745         int len = 0;
746         unsigned long long curr_size = 0;
747         FILE *fp = NULL;
748         int reqd_disk_size = size + ceil(size * 0.2);
749
750         /* validate function arguments*/
751         if (pkgid == NULL || dir_list == NULL || size<=0) {
752                 _E("invalid function arguments");
753                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
754         }
755
756         /* check whether MMC is present or not */
757         ret = _app2sd_check_mmc_status();
758         if (ret) {
759                 _E("MMC not preset OR Not ready (%d)", ret);
760                 return APP2EXT_ERROR_MMC_STATUS;
761         }
762
763         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
764         if (encoded_id == NULL) {
765                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
766         }
767         if (_is_global(uid)) {
768                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
769                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
770                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
771                         APP2SD_PATH, encoded_id);
772         } else {
773                 tzplatform_set_user(uid);
774                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
775                         tzplatform_getenv(TZ_USER_APP), pkgid);
776                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
777                         APP2SD_PATH, encoded_id);
778                 tzplatform_reset_user();
779         }
780         free(encoded_id);
781
782         /* check app entry is there in sd card or not. */
783         fp = fopen(loopback_device, "r+");
784         if (fp == NULL) {
785                 _E("app entry is not present in SD Card");
786                 return APP2EXT_ERROR_INVALID_PACKAGE;
787         }
788         fclose(fp);
789
790         /* get installed app size*/
791         curr_size = _app2sd_calculate_file_size(loopback_device);
792         curr_size = (curr_size) / (1024 * 1024);
793         if (curr_size == 0) {
794                 _E("app entry is not present in SD Card");
795                 return APP2EXT_ERROR_LOOPBACK_DEVICE_UNAVAILABLE;
796         }
797         if ((int)curr_size < reqd_disk_size) {
798                 len = strlen(pkgid) + strlen(".new");
799                 temp_pkgid = calloc(len + 1, sizeof(char));
800                 if (temp_pkgid == NULL) {
801                         _E("memory alloc failed");
802                         return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
803                 }
804                 snprintf(temp_pkgid, len, "%s.new", pkgid);
805
806                 if (_is_global(uid)) {
807                         len = strlen(tzplatform_getenv(TZ_SYS_RW_APP)) + strlen(temp_pkgid) + 1;
808                         temp_application_path = calloc(len + 1, sizeof(char));
809                         if (temp_application_path == NULL) {
810                                 _E("memory alloc failed");
811                                 free(temp_pkgid);
812                                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
813                         }
814                         snprintf(temp_application_path, len, "%s/%s",
815                                 tzplatform_getenv(TZ_SYS_RW_APP), temp_pkgid);
816
817                         temp_encoded_id = _app2sd_get_encoded_name((const char *)temp_pkgid, uid);
818                         if (temp_encoded_id == NULL) {
819                                 free(temp_pkgid);
820                                 free(temp_application_path);
821                                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
822                         }
823                         len = strlen(APP2SD_PATH) + strlen(temp_encoded_id) + 1;
824                         temp_loopback_device = calloc(len + 1, sizeof(char));
825                         if (temp_loopback_device == NULL) {
826                                 _E("memory alloc failed");
827                                 free(temp_pkgid);
828                                 free(temp_application_path);
829                                 free(temp_encoded_id);
830                                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
831                         }
832                         snprintf(temp_loopback_device, len, "%s/%s",
833                                 APP2SD_PATH, temp_encoded_id);
834                         free(temp_encoded_id);
835                 } else {
836                         tzplatform_set_user(uid);
837                         len = strlen(tzplatform_getenv(TZ_USER_APP)) + strlen(temp_pkgid) + 1;
838                         temp_application_path = calloc(len + 1, sizeof(char));
839                         if (temp_application_path == NULL) {
840                                 _E("memory alloc failed");
841                                 free(temp_pkgid);
842                                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
843                         }
844                         snprintf(temp_application_path, len, "%s/%s",
845                                 tzplatform_getenv(TZ_USER_APP), temp_pkgid);
846
847                         temp_encoded_id = _app2sd_get_encoded_name((const char*)temp_pkgid, uid);
848                         if (temp_encoded_id == NULL) {
849                                 free(temp_pkgid);
850                                 free(temp_application_path);
851                                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
852                         }
853                         snprintf(temp_uid, 32, "%d", uid);
854                         len = strlen(APP2SD_PATH) + strlen(temp_uid) + strlen(temp_encoded_id) + 2;
855                         temp_loopback_device = calloc(len + 1, sizeof(char));
856                         if (temp_loopback_device == NULL) {
857                                 _E("memory alloc failed");
858                                 free(temp_pkgid);
859                                 free(temp_application_path);
860                                 free(temp_encoded_id);
861                                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
862                         }
863                         snprintf(temp_loopback_device, len, "%s/%s",
864                                 APP2SD_PATH, temp_encoded_id);
865                         free(temp_encoded_id);
866                         tzplatform_reset_user();
867                 }
868                 ret = _app2sd_update_loopback_device_size(pkgid,
869                         loopback_device, application_path, temp_pkgid,
870                         temp_loopback_device, temp_application_path,
871                         reqd_disk_size, dir_list, uid);
872                 free(temp_pkgid);
873                 free(temp_application_path);
874                 free(temp_loopback_device);
875                 if (APP2EXT_SUCCESS != ret) {
876                         _E("failed to update loopback device size");
877                         return ret;
878                 }
879         }
880
881         /* get the associated device node for SD card applicationer */
882         device_node = _app2sd_find_associated_device_node(loopback_device);
883         if (NULL == device_node) {
884                 /* do loopback setup */
885                 device_node = _app2sd_do_loopback_encryption_setup(pkgid,
886                         loopback_device, uid);
887                 if (device_node == NULL) {
888                         _E("loopback encryption setup failed");
889                         return APP2EXT_ERROR_DO_LOSETUP;
890                 }
891
892                 /* do mounting */
893                 ret = _app2sd_mount_app_content(application_path, pkgid,
894                         device_node, MOUNT_TYPE_RW, dir_list,
895                         APP2SD_PRE_UPGRADE, uid);
896                 if (ret) {
897                         _E("mount failed");
898                         if (device_node) {
899                                 free(device_node);
900                                 device_node = NULL;
901                         }
902                         return APP2EXT_ERROR_MOUNT_PATH;
903                 }
904         } else {
905                 /* do re-mounting */
906                 ret = _app2sd_mount_app_content(application_path, pkgid,
907                         device_node, MOUNT_TYPE_RW_REMOUNT, NULL,
908                         APP2SD_PRE_UPGRADE, uid);
909                 if (ret) {
910                         _E("remount failed");
911                         if (device_node) {
912                                 free(device_node);
913                                 device_node = NULL;
914                         }
915                         return APP2EXT_ERROR_MOUNT_PATH;
916                 }
917         }
918
919         if (device_node) {
920                 free(device_node);
921                 device_node = NULL;
922         }
923         return ret;
924 }
925
926 int app2sd_usr_post_app_upgrade(const char *pkgid,
927                 app2ext_status install_status, uid_t uid)
928 {
929         char *device_name = NULL;
930         char loopback_device[FILENAME_MAX] = { 0, };
931         char application_path[FILENAME_MAX] = { 0, };
932         char *encoded_id = NULL;
933         int ret = APP2EXT_SUCCESS;
934
935         /* validate the function parameter recieved */
936         if (pkgid == NULL || install_status < APP2EXT_STATUS_FAILED
937                 || install_status > APP2EXT_STATUS_SUCCESS) {
938                 _E("invalid func parameters");
939                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
940         }
941
942         /* check whether MMC is present or not */
943         ret = _app2sd_check_mmc_status();
944         if (ret) {
945                 _E("MMC not preset OR Not ready (%d)", ret);
946                 return APP2EXT_ERROR_MMC_STATUS;
947         }
948
949         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
950         if (encoded_id == NULL) {
951                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
952         }
953         if (_is_global(uid)) {
954                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
955                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
956                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
957                         APP2SD_PATH, encoded_id);
958         } else {
959                 tzplatform_set_user(uid);
960                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
961                         tzplatform_getenv(TZ_USER_APP), pkgid);
962                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
963                         APP2SD_PATH, encoded_id);
964                 tzplatform_reset_user();
965         }
966         free(encoded_id);
967
968         /* get the associated device node for SD card applicationer */
969         device_name = _app2sd_find_associated_device_node(loopback_device);
970         if (NULL == device_name) {
971                 return APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_NODE;
972         }
973
974         ret = _app2sd_unmount_app_content(application_path);
975         if (ret) {
976                 if (device_name) {
977                         free(device_name);
978                         device_name = NULL;
979                 }
980                 _E("unable to unmount the app content (%d)", ret);
981                 return APP2EXT_ERROR_UNMOUNT;
982         }
983
984         ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
985         if (ret) {
986                 if (device_name) {
987                         free(device_name);
988                         device_name = NULL;
989                 }
990                 _E("unable to detach the loopback encryption " \
991                         "setup for the application");
992                 return APP2EXT_ERROR_UNMOUNT;
993         }
994
995         if (device_name) {
996                 free(device_name);
997                 device_name = NULL;
998         }
999
1000         return ret;
1001 }
1002
1003 int app2sd_usr_force_clean(const char *pkgid, uid_t uid)
1004 {
1005         char loopback_device[FILENAME_MAX] = { 0, };
1006         char application_path[FILENAME_MAX] = { 0, };
1007         char *encoded_id = NULL;
1008         int ret = APP2EXT_SUCCESS;
1009
1010         /* validate the function parameter recieved */
1011         if (pkgid == NULL) {
1012                 _E("invalid func parameters");
1013                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
1014         }
1015
1016         sync();
1017
1018         encoded_id = _app2sd_get_encoded_name(pkgid, uid);
1019         if (encoded_id == NULL) {
1020                 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1021         }
1022         if (_is_global(uid)) {
1023                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1024                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
1025                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
1026                         APP2SD_PATH, encoded_id);
1027         } else {
1028                 tzplatform_set_user(uid);
1029                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
1030                         tzplatform_getenv(TZ_USER_APP), pkgid);
1031                 snprintf(loopback_device, FILENAME_MAX - 1, "%s/%s",
1032                         APP2SD_PATH, encoded_id);
1033                 tzplatform_reset_user();
1034         }
1035         free(encoded_id);
1036
1037         /* unmount the loopback encrypted pseudo device from the application installation path */
1038         ret = _app2sd_unmount_app_content(application_path);
1039         if (ret) {
1040                 _E("unable to unmount the app content (%d)", ret);
1041         }
1042
1043         /* detach the loopback encryption setup for the application */
1044         ret = _app2sd_remove_all_loopback_encryption_setups(pkgid);
1045         if (ret) {
1046                 _E("unable to detach the loopback encryption setup for the application");
1047         }
1048
1049         /* delete the loopback device from the SD card */
1050         ret = _app2sd_delete_loopback_device(loopback_device);
1051         if (ret) {
1052                 _E("unable to detach the loopback encryption setup for the application");
1053         }
1054
1055         /* delete symlink */
1056         _app2sd_delete_symlink(application_path);
1057
1058         /* remove passwrd from DB */
1059         ret = _app2sd_initialize_db();
1060         if (ret) {
1061                 _E("app2sd db initialize failed");
1062         }
1063         ret = _app2sd_remove_password_from_db(pkgid);
1064         if (ret) {
1065                 _E("cannot remove password from db");
1066         }
1067
1068         return 0;
1069 }