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